crocparty/pytools/font.py
2024-02-26 12:42:07 -08:00

54 lines
1.6 KiB
Python

from typing import Tuple
from PIL import Image
import sys
def main(font_name, n_glyphs, fname_png, fname_c):
glyphs = load_glyphs(fname_png)
assert(len(glyphs) == n_glyphs), f"must be exactly {n_glyphs} glyphs"
with open(fname_c, "wt") as output:
output.writelines([
"// generated code! be nice!\n",
"#include \"sys/sys.h\";\n",
f"sys_glyph {font_name}[{n_glyphs}] = {{{', '.join(str(g) for g in glyphs)}}};\n"
])
def load_glyphs(fname_png: str):
with Image.open(fname_png) as im:
width = im.width
height = im.height
assert width % 8 == 0, "width must be a multiple of 8"
assert height % 8 == 0, "height must be a multiple of 8"
data = list(im.convert("RGBA").getdata())
monochrome = [pixel_to_monochrome(p) for p in data]
glyphs = []
for gy in range(0, height, 8):
for gx in range(0, width, 8):
glyph = 0
for py in range(0, 8):
for px in range(0, 8):
x = gx + px
y = gy + py
if monochrome[y * width + x]:
glyph |= 1 << (py * 8 + px)
glyphs.append(glyph)
return glyphs
def pixel_to_monochrome(rgba: Tuple[int, int, int, int]):
if rgba[3] < 128: return False
if (rgba[0] + rgba[1] + rgba[2])/3 < 128: return False
return True
if __name__ == "__main__":
assert len(sys.argv) == 5, \
"there must be four args (font name, n glyphs, src png, out c)"
main(sys.argv[1], int(sys.argv[2]), sys.argv[3], sys.argv[4])