yog-ui 0.48.0

Yog UI framework — flexbox and WPF-style grid layout + GPU rendering via yog-gfx
Documentation
"""The game's default font's advances for printable ASCII, for yog-ui's
measuring outside a game (in one, the host's text renderer measures).
Run with the newest supported version's client jar (Loom's cache):

    python3 gen_widths.py glyph_widths.ydata

An advance is as the game's bitmap provider makes it: the glyph's width
trimmed of empty columns, scaled to the provider's height, plus one."""
import io, json, os, sys, zipfile
from PIL import Image

VERSION = "26.2"
FIRST, LAST = 0x20, 0x7E
z = zipfile.ZipFile(os.path.expanduser(f"~/.gradle/caches/fabric-loom/{VERSION}/minecraft-client.jar"))
advances = {}
for p in json.loads(z.read("assets/minecraft/font/include/space.json"))["providers"]:
    for c, a in p.get("advances", {}).items():
        advances[c] = a
for p in json.loads(z.read("assets/minecraft/font/include/default.json"))["providers"]:
    if p.get("type") != "bitmap":
        continue
    ns, path = p["file"].split(":")
    img = Image.open(io.BytesIO(z.read(f"assets/{ns}/textures/{path}"))).convert("RGBA")
    rows = p["chars"]
    cell_w, cell_h = img.width // len(rows[0]), img.height // len(rows)
    scale = p.get("height", 8) / cell_h
    for y, row in enumerate(rows):
        for x, c in enumerate(row):
            if c in advances or c == "\0":
                continue
            used = [cx for cx in range(cell_w) if any(img.getpixel((x * cell_w + cx, y * cell_h + cy))[3] for cy in range(cell_h))]
            width = (max(used) + 1) if used else 0
            advances[c] = int(width * scale + 1)
widths = [advances.get(chr(c), 0) for c in range(FIRST, LAST + 1)]
with open(sys.argv[1], "w") as f:
    f.write(f"// Minecraft {VERSION}'s default font: the advance of each printable ASCII\n")
    f.write("// character, from ' ' to '~', in GUI pixels. Generated by gen_widths.py.\n")
    f.write("[" + ", ".join(map(str, widths)) + "]\n")
print(dict(zip(map(chr, range(FIRST, LAST + 1)), widths)))