Add font loader

This commit is contained in:
2024-02-26 12:42:07 -08:00
parent e05f050e7d
commit cb44cab4f8
16 changed files with 1584 additions and 190 deletions

1
pytools/.gitignore vendored Normal file
View File

@ -0,0 +1 @@
venv/

10
pytools/BUILD Normal file
View File

@ -0,0 +1,10 @@
load("@pytools_deps//:requirements.bzl", "requirement")
py_binary(
name = "font",
srcs = ["font.py"],
deps = [
requirement("pillow"),
],
visibility = ["//visibility:public"],
)

53
pytools/font.py Normal file
View File

@ -0,0 +1,53 @@
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])

1
pytools/requirements.txt Normal file
View File

@ -0,0 +1 @@
pillow==10.2.0