diff options
author | Tor Andersson <tor@ccxvii.net> | 2025-02-23 18:37:17 +0100 |
---|---|---|
committer | Tor Andersson <tor@ccxvii.net> | 2025-03-08 16:32:19 +0100 |
commit | fe2bc3961ec3b3164786074b37e36581b81fa68c (patch) | |
tree | bfc80bc4fb161e83f290da6294f0bffe9116500b /tools/parse-layout.js | |
parent | a4c2b8458d1059c373c4a714bce0b5f68a3ce20f (diff) | |
download | land-and-freedom-fe2bc3961ec3b3164786074b37e36581b81fa68c.tar.gz |
New client and client data processing tools.
Diffstat (limited to 'tools/parse-layout.js')
-rw-r--r-- | tools/parse-layout.js | 167 |
1 files changed, 167 insertions, 0 deletions
diff --git a/tools/parse-layout.js b/tools/parse-layout.js new file mode 100644 index 0000000..5dcf4f8 --- /dev/null +++ b/tools/parse-layout.js @@ -0,0 +1,167 @@ +const fs = require("fs") + +const { round, floor, ceil } = Math + +let boxes = {} +let nodes = [] +let edges = [] +let mode, name, x, y, w, h, cx, cy, rx, ry, x2, y2 +let scale = 1 + +function flush() { + if (mode === 'path') { + edges.push({ x1: x, y1: y, x2, y2 }) + } + if (mode === 'rect') { + boxes[name] = [ x * scale |0, y * scale |0, w * scale |0, h * scale |0 ] + nodes.push({ name, x: x + w/2, y: y + h/2 }) + } + if (mode === 'circle') { + x = cx - rx + y = cy - ry + w = rx * 2 + h = ry * 2 + boxes[name] = [ x * scale |0, y * scale |0, w * scale |0, h * scale |0 ] + nodes.push({ name, x: cx, y: cy }) + } + x = y = x2 = y2 = w = h = cx = cy = rx = ry = 0 + name = 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': + x = cx = Number(path[i+1]) + y = cy = Number(path[i+2]) + i += 3 + abs = true + break + case 'm': + x = cx = cx + Number(path[i+1]) + 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 + 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('x="')) + x = round(Number(line.split('"')[1])) + else if (line.startsWith('y="')) + y = round(Number(line.split('"')[1])) + else if (line.startsWith('width="')) + w = round(Number(line.split('"')[1])) + else if (line.startsWith('height="')) + h = round(Number(line.split('"')[1])) + else if (line.startsWith('cx="')) + cx = round(Number(line.split('"')[1])) + else if (line.startsWith('cy="')) + cy = round(Number(line.split('"')[1])) + else if (line.startsWith('r="')) + rx = ry = round(Number(line.split('"')[1])) + else if (line.startsWith('rx="')) + rx = round(Number(line.split('"')[1])) + else if (line.startsWith('ry="')) + ry = round(Number(line.split('"')[1])) + else if (line.startsWith('inkscape:label="')) + name = line.split('"')[1] + else if (line.startsWith('d="')) + parse_path_data(line.split('"')[1].split(/[ ,]/)) +} + +flush() + +console.log("const boxes = {") +for (let key in boxes) + console.log("\t\"" + key + "\": " + JSON.stringify(boxes[key]) + ",") +console.log("}") + +function find_closest_node(x, y) { + let nd = Infinity, nn = null + + for (let n of nodes) { + let d = Math.hypot(n.x - x, n.y - y) + if (d < nd) { + nd = d + nn = n.name + } + } + + if (!nn) + console.log("NOT FOUND", x, y) + + return nn +} + +for (let e of edges) { + let n1 = find_closest_node(e.x1, e.y1) + let n2 = find_closest_node(e.x2, e.y2) + console.log(`edge("${n1}", "${n2}", ${e.x1|0}, ${e.y1|0}, ${e.x2|0}, ${e.y2|0})`) +} |