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)))