#!/usr/bin/env python3 """One-off: render every tracked .svg to a same-named .png via headless Chromium. Not part of the build; run manually. Leaves the source .svg untouched.""" import re import subprocess import sys from pathlib import Path CHROME = "/opt/pw-browsers/chromium-1194/chrome-linux/chrome" ROOT = Path("/home/user/StarForth") DIM_RE = re.compile(r'(width|height)\s*=\s*["\']([0-9.]+)(pt|px)?["\']') VIEWBOX_RE = re.compile(r'viewBox\s*=\s*["\']([\d.\-]+)\s+([\d.\-]+)\s+([\d.\-]+)\s+([\d.\-]+)["\']') def get_dims(svg_path: Path): text = svg_path.read_text(errors="replace") svg_open = re.search(r"]*>", text) head = svg_open.group(0) if svg_open else text[:4000] dims = {} for m in DIM_RE.finditer(head): name, val, unit = m.group(1), float(m.group(2)), m.group(3) or "px" if name in dims: continue # keep only the first (root ) match px = val * (4 / 3) if unit == "pt" else val dims[name] = px if "width" in dims and "height" in dims: return int(round(dims["width"])), int(round(dims["height"])) vb = VIEWBOX_RE.search(head) if vb: w, h = float(vb.group(3)), float(vb.group(4)) return int(round(w)), int(round(h)) return 1024, 768 def render(svg_path: Path) -> bool: png_path = svg_path.with_suffix(".png") w, h = get_dims(svg_path) w = max(w, 16) h = max(h, 16) cmd = [ CHROME, "--headless", "--disable-gpu", "--no-sandbox", "--hide-scrollbars", f"--screenshot={png_path}", f"--window-size={w},{h}", "--force-device-scale-factor=2", "--default-background-color=00000000", f"file://{svg_path}", ] r = subprocess.run(cmd, capture_output=True, text=True, timeout=60) ok = png_path.exists() and png_path.stat().st_size > 0 if not ok: print(f"FAIL {svg_path}: {r.stderr[-500:]}", file=sys.stderr) return ok def main(): svgs = sorted(ROOT.rglob("*.svg")) svgs = [s for s in svgs if "node_modules" not in s.parts] print(f"Found {len(svgs)} SVGs") failed = [] for i, svg in enumerate(svgs, 1): rel = svg.relative_to(ROOT) ok = render(svg) status = "ok" if ok else "FAIL" print(f"[{i}/{len(svgs)}] {status} {rel}") if not ok: failed.append(rel) if failed: print(f"\n{len(failed)} failed:") for f in failed: print(f" {f}") else: print("\nAll converted.") if __name__ == "__main__": main()