Add font loader
This commit is contained in:
1
pytools/.gitignore
vendored
Normal file
1
pytools/.gitignore
vendored
Normal file
@ -0,0 +1 @@
|
||||
venv/
|
10
pytools/BUILD
Normal file
10
pytools/BUILD
Normal 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
53
pytools/font.py
Normal 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
1
pytools/requirements.txt
Normal file
@ -0,0 +1 @@
|
||||
pillow==10.2.0
|
Reference in New Issue
Block a user