Files
HaloKeymind/tools/bible/preview_reader.py
T

61 lines
2.6 KiB
Python

#!/usr/bin/env python3
"""Render reader captures: default GFX headers plus actual adaptive-font pixels."""
import argparse
from pathlib import Path
import re
from PIL import Image, ImageDraw
def main():
parser = argparse.ArgumentParser(description=__doc__)
parser.add_argument("capture", type=Path)
parser.add_argument("font", type=Path, help="Adafruit GFX Library/glcdfont.c")
parser.add_argument("output", type=Path)
args = parser.parse_args()
source = args.font.read_text(encoding="utf-8")
source = source[source.index("font[] PROGMEM = {"):].split("};", 1)[0]
source = re.sub(r"//[^\n]*|/\*.*?\*/", "", source, flags=re.S)
font = bytes(int(h, 16) for h in re.findall(r"0x([0-9a-fA-F]{2})", source))
assert len(font) == 256 * 5
frames = []
for line in args.capture.read_text(encoding="utf-8").splitlines():
if line.startswith("FRAME "):
fields = line[6:].split(" ", 2)
sized = len(fields) == 3 and fields[0].isdigit() and fields[1].isdigit()
width, height = map(int, fields[:2]) if sized else (128, 64)
panel = Image.new("RGB", (width, height), "black")
frames.append((fields[2] if sized else line[6:], panel))
if not sized: # Compatibility with the original text-only capture.
ImageDraw.Draw(panel).line((0, 10, 127, 10), fill="white")
elif line.startswith("PIXEL "):
_, x, y = line.split()
x, y = int(x), int(y)
assert 0 <= x < width and 0 <= y < height
panel.putpixel((x, y), (255, 255, 255))
else:
x, y, text = line.split("\t", 2)
x, y = int(x), int(y)
for char in text:
for column in range(5):
bits = font[ord(char) * 5 + column]
for row in range(8):
if bits & (1 << row):
assert 0 <= x + column < width and 0 <= y + row < height
panel.putpixel((x + column, y + row), (255, 255, 255))
x += 6
scale = 4
output = Image.new("RGB", (max(panel.width for _, panel in frames) * scale + 32,
sum(panel.height * scale + 48 for _, panel in frames) + 16), "#202733")
draw = ImageDraw.Draw(output)
top = 16
for title, panel in frames:
draw.text((16, top), title, fill="white")
output.paste(panel.resize((panel.width * scale, panel.height * scale),
Image.Resampling.NEAREST), (16, top + 24))
top += panel.height * scale + 48
output.save(args.output)
if __name__ == "__main__":
main()