#!/usr/bin/env python3 import json import unicodedata import argparse import sys def get_glyph_name(ch): """ Return the official Unicode name of ch, or its codepoint if unnamed. """ try: return unicodedata.name(ch) except ValueError: # Fallback to codepoint string return f"U+{ord(ch):04X}" def format_rust_array(matrix): """ Given a 2D list of ints, return a Rust-style nested array string. """ lines = [] for row in matrix: # join numbers with commas, no spaces after commas to match example line = "[" + ",".join(str(v) for v in row) + "]," lines.append(" " + line) return "\n".join(lines) def main(): parser = argparse.ArgumentParser( description="Convert JSON glyph bitmaps to a Rust source file." ) parser.add_argument("input_json", help="Path to input JSON file") parser.add_argument("output_rs", help="Path to write Rust source file") args = parser.parse_args() # Load JSON with open(args.input_json, "r", encoding="utf-8") as f: data = json.load(f) if not data: print("No glyphs found in JSON.", file=sys.stderr) sys.exit(1) # Determine dimensions from first glyph first_matrix = next(iter(data.values())) rows = len(first_matrix) cols = len(first_matrix[0]) if rows > 0 else 0 # Begin emitting Rust code with open(args.output_rs, "w", encoding="utf-8") as out: out.write("// This file was generated by mkrust.py\n") out.write(f"pub const GLYPH_BITMAPS: &[(char, [[u8; {cols}]; {rows}])] = &[\n") for ch, matrix in data.items(): name = get_glyph_name(ch) # comment with the Unicode name out.write(f" // {name}\n") out.write(f" ('{ch}', [\n") out.write(format_rust_array(matrix) + "\n") out.write(" ]),\n\n") out.write("];\n") if __name__ == "__main__": main()