#!/usr/bin/env python3 """Encode a TTF font as a valid GGUF file - outlines + rasterized cache. Stores the actual vector font data (bezier control points, contour structure, on-curve flags) as native tensors alongside rasterized bitmap cache. The outlines are lossless and resolution-independent - the real font, not a screenshot of it. Tensor layout: outline.U+XXXX.points [n_points, 2] I32 - bezier control points outline.U+XXXX.flags [n_points] I32 - 1=on-curve, 0=off-curve outline.U+XXXX.contours [n_contours] I32 - contour endpoint indices bitmap.U+XXXX [h, w] F32 - rasterized at render_size_px metrics.advance_widths [n_cp] I32 - horizontal advance per codepoint metrics.lsb [n_cp] I32 - left side bearing per codepoint metrics.bboxes [n_cp, 4] I32 - xMin/yMin/xMax/yMax per codepoint """ import struct from pathlib import Path import numpy as np from fontTools.ttLib import TTFont from PIL import Image, ImageDraw, ImageFont # --- GGUF constants --- GGUF_MAGIC = b"GGUF" GGUF_VERSION = 3 ALIGN = 32 GGML_TYPE_F32 = 0 GGML_TYPE_I32 = 26 KV_UINT32 = 4 KV_FLOAT32 = 6 KV_STRING = 8 KV_ARRAY = 9 KV_UINT64 = 10 RENDER_PX = 32 CANVAS = 48 def align_up(n, a): return n + (-n % a) class GGUFWriter: def __init__(self): self.kv = [] self.tensors = [] def _enc_str(self, s): raw = s.encode("utf-8") return struct.pack(" pos: f.write(b"\x00" * (o - pos)) pos = o f.write(t["data"]) pos += len(t["data"]) return data_start + pos def rasterize(pil_font, char): img = Image.new("L", (CANVAS, CANVAS), 0) ImageDraw.Draw(img).text((4, 4), char, font=pil_font, fill=255) arr = np.array(img, dtype=np.uint8) rows, cols = np.any(arr > 0, axis=1), np.any(arr > 0, axis=0) if not rows.any() or not cols.any(): return None r0, r1 = np.where(rows)[0][[0, -1]] c0, c1 = np.where(cols)[0][[0, -1]] return arr[r0 : r1 + 1, c0 : c1 + 1].astype(np.float32) / 255.0 def main(): ttf_path = "/home/claude/font/fonts/0xProto-Regular.ttf" out_path = "/home/claude/0xProto-Regular-v2.502-F32.gguf" tt = TTFont(ttf_path) pil_font = ImageFont.truetype(ttf_path, RENDER_PX) name_table = tt["name"] def get_name(nid): for r in name_table.names: if r.nameID == nid: try: return r.toUnicode() except: pass return "" head = tt["head"] os2 = tt["OS/2"] hmtx = tt["hmtx"] glyf = tt["glyf"] cmap = tt.getBestCmap() codepoints = sorted(cmap.keys()) license_path = Path(ttf_path).parent.parent / "LICENSE" license_text = license_path.read_text()[:2000] if license_path.exists() else "" w = GGUFWriter() # --- metadata --- w.add_str("general.architecture", "font") w.add_str("general.name", get_name(4)) w.add_u32("general.alignment", ALIGN) w.add_u32("general.file_type", 0) w.add_str("font.family", get_name(1)) w.add_str("font.style", get_name(2)) w.add_u32("font.weight", os2.usWeightClass) w.add_str("font.version", get_name(5)) w.add_str("font.postscript_name", get_name(6)) w.add_u32("font.units_per_em", head.unitsPerEm) w.add_str("font.author", get_name(0)) w.add_str("font.url", get_name(11)) if license_text: w.add_str("font.license", license_text) w.add_u32("font.render_size_px", RENDER_PX) w.add_u32("font.total_codepoints", len(codepoints)) w.add_f32("font.is_monospace", 1.0 if os2.panose.bProportion == 9 else 0.0) w.add_str_array("font.codepoint_labels", [f"U+{cp:04X}" for cp in codepoints]) w.add_str_array("font.glyph_names", [cmap[cp] for cp in codepoints]) # --- tensors --- outline_count = 0 bitmap_count = 0 composite_names = [] for cp in codepoints: tag = f"U+{cp:04X}" glyph_name = cmap[cp] # Vector outlines (the real font data) if glyph_name in glyf: g = glyf[glyph_name] if g.numberOfContours > 0: coords, end_pts, raw_flags = g.getCoordinates(glyf) pts = np.array([(int(x), int(y)) for x, y in coords], dtype=np.int32) on_curve = np.array([int(b & 1) for b in raw_flags], dtype=np.int32) contour_ends = np.array(list(end_pts), dtype=np.int32) w.add_tensor(f"outline.{tag}.points", pts, GGML_TYPE_I32) w.add_tensor(f"outline.{tag}.flags", on_curve, GGML_TYPE_I32) w.add_tensor(f"outline.{tag}.contours", contour_ends, GGML_TYPE_I32) outline_count += 1 elif g.isComposite(): # Store composite references as a flat array of # [glyph_index, x_offset, y_offset] per component refs = [] for comp in g.components: glyph_idx = tt.getGlyphID(comp.glyphName) refs.extend([ glyph_idx, getattr(comp, "x", 0), getattr(comp, "y", 0), ]) if refs: w.add_tensor( f"outline.{tag}.composite", np.array(refs, dtype=np.int32).reshape(-1, 3), GGML_TYPE_I32, ) composite_names.append(tag) # Rasterized bitmap cache bitmap = rasterize(pil_font, chr(cp)) if bitmap is not None: w.add_tensor(f"bitmap.{tag}", bitmap, GGML_TYPE_F32) bitmap_count += 1 # Global metric tensors adv, lsb, bbox = [], [], [] for cp in codepoints: gn = cmap[cp] wi, lb = hmtx.metrics.get(gn, (0, 0)) adv.append(wi) lsb.append(lb) if gn in glyf and glyf[gn].numberOfContours != 0: g = glyf[gn] try: bbox.extend([g.xMin, g.yMin, g.xMax, g.yMax]) except: bbox.extend([0, 0, 0, 0]) else: bbox.extend([0, 0, 0, 0]) w.add_tensor("metrics.advance_widths", np.array(adv, dtype=np.int32), GGML_TYPE_I32) w.add_tensor("metrics.lsb", np.array(lsb, dtype=np.int32), GGML_TYPE_I32) w.add_tensor( "metrics.bboxes", np.array(bbox, dtype=np.int32).reshape(-1, 4), GGML_TYPE_I32 ) total = w.write(out_path) tt.close() print(f"Font: {get_name(4)}") print(f"Output: {out_path}") print(f"Size: {total:,} bytes ({total / 1024:.1f} KB)") print(f"Metadata: {len(w.kv)} entries") print(f"Tensors: {len(w.tensors)} total") print(f" outline sets: {outline_count} simple + {len(composite_names)} composite") print(f" bitmaps: {bitmap_count}") print(" metric tables: 3") if __name__ == "__main__": main()