diff options
author | Tor Andersson <tor@ccxvii.net> | 2024-08-24 01:17:17 +0200 |
---|---|---|
committer | Tor Andersson <tor@ccxvii.net> | 2024-08-24 01:19:42 +0200 |
commit | 3820856482017e0f206b0481856a86a2b4fc589c (patch) | |
tree | ff57b98648670583d0796d6ee0cbe500f7502f75 /tools/parse-layout.js | |
parent | 1c90c9ab2b7a97078d6a853c9d37d19e8a437ec8 (diff) | |
download | vijayanagara-3820856482017e0f206b0481856a86a2b4fc589c.tar.gz |
Start client.
Diffstat (limited to 'tools/parse-layout.js')
-rw-r--r-- | tools/parse-layout.js | 187 |
1 files changed, 187 insertions, 0 deletions
diff --git a/tools/parse-layout.js b/tools/parse-layout.js new file mode 100644 index 0000000..2060e17 --- /dev/null +++ b/tools/parse-layout.js @@ -0,0 +1,187 @@ +"use strict" + +const fs = require("fs") + +let circles = {} +let rects = {} +let edges = {} +let mode, name, subname, x, y, w, h, cx, cy, rx, ry, x2, y2 +let labels = [] + +function add_circle(cx, cy, rx, ry) { + if (!(name in circles)) + circles[name] = {} + circles[name][subname] = {cx,cy,rx,ry} +} + +function add_rect(x, y, w, h) { + if (!(name in rects)) + rects[name] = {} + rects[name][subname] = {x,y,w,h} +} + +function add_edge(x1, y1, x2, y2) { + if (name in edges) + edges[name].push({x1,y1,x2,y2}) + else + edges[name] = [ {x1,y1,x2,y2} ] +} + +function flush() { + if (mode === 'path') { + add_edge(x, y, x2, y2) + } + if (mode === 'rect') { + add_rect(x, y, w, h) + } + if (mode === 'circle') { + add_circle( cx, cy, rx, ry ) + } + x = y = x2 = y2 = w = h = cx = cy = rx = ry = 0 + subname = null +} + +function parse_path_data(path) { + let cx = 0 + let cy = 0 + let abs = 0 + for (let i = 0; i < path.length;) { + switch (path[i]) { + case 'M': + x2 = x = cx = Number(path[i+1]) + y2 = y = cy = Number(path[i+2]) + i += 3 + abs = true + break + case 'm': + x2 = x = cx = cx + Number(path[i+1]) + y2 = y = cy = cy + Number(path[i+2]) + i += 3 + abs = false + break + case 'C': + x2 = cx = Number(path[i+5]) + y2 = cy = Number(path[i+6]) + i += 7 + abs = true + break + case 'L': + i += 1 + abs = true + break + case 'H': + x2 = cx = Number(path[i+1]) + i += 2 + abs = true + break + case 'V': + y2 = cy = Number(path[i+1]) + i += 2 + abs = true + break + case 'c': + x2 = cx = cx + Number(path[i+5]) + y2 = cy = cy + Number(path[i+6]) + i += 7 + abs = false + break + case 'l': + i += 1 + abs = false + break + case 'h': + x2 = cx = cx + Number(path[i+1]) + i += 2 + abs = false + break + case 'v': + y2 = cy = cy + Number(path[i+1]) + i += 2 + abs = false + break + default: + if (abs) { + x2 = cx = Number(path[i+0]) + y2 = cy = Number(path[i+1]) + } else { + x2 = cx = cx + Number(path[i+0]) + y2 = cy = cy + Number(path[i+1]) + } + i += 2 + break + } + } +} + +for (let line of fs.readFileSync("tools/layout.svg", "utf-8").split("\n")) { + line = line.trim() + if (line.startsWith("<rect")) { + flush() + mode = "rect" + x = y = w = h = 0 + } + else if (line.startsWith("<ellipse") || line.startsWith("<circle")) { + flush() + mode = "circle" + cx = cy = rx = ry = 0 + } + else if (line.startsWith("<path")) { + flush() + mode = "path" + } + else if (line.startsWith("<g")) { + flush() + mode = "g" + } + else if (line.startsWith('x="')) + x = (Math.round(line.split('"')[1])) + else if (line.startsWith('y="')) + y = (Math.round(line.split('"')[1])) + else if (line.startsWith('width="')) + w = (Math.round(line.split('"')[1])) + else if (line.startsWith('height="')) + h = (Math.round(line.split('"')[1])) + else if (line.startsWith('cx="')) + cx = (Math.round(line.split('"')[1])) + else if (line.startsWith('cy="')) + cy = (Math.round(line.split('"')[1])) + else if (line.startsWith('r="')) + rx = ry = (Math.round(line.split('"')[1])) + else if (line.startsWith('rx="')) + rx = (Math.round(line.split('"')[1])) + else if (line.startsWith('ry="')) + ry = (Math.round(line.split('"')[1])) + else if (line.startsWith('inkscape:label="') && mode === "g") + name = line.split('"')[1] + else if (line.startsWith('inkscape:label="') && mode !== "g") + subname = line.split('"')[1] + else if (line.startsWith('d="')) + parse_path_data(line.split('"')[1].split(/[ ,]/)) + if (line.includes("</tspan>")) { + let name = line.replace(/^[^>]*>/, "").replace(/<\/tspan.*/, "") + labels.push({x, y, name}) + } +} + +flush() + +function find_closest_node(list, x, y) { + let nd = Infinity, nn = null + + for (let n of list) { + let d = Math.hypot(n.x - x, n.y - y) + if (d < nd) { + nd = d + nn = n + } + } + + if (!nn) { + console.log("NOT FOUND", x, y) + return [ null, 0 ] + } + + return [ nn, nd ] +} + +console.log("const layout = " + JSON.stringify({ circles, rects }, null, "\t")) |