make_font.py 1.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445
  1. #!/usr/bin/env python3
  2. from PIL import Image
  3. from sys import argv,stderr
  4. assert len(argv) > 2, "Usage:\n\t{} input_file output_file".format(argv[0])
  5. CHARACTER_WIDTH = 9
  6. CHARACTER_HEIGHT = 8
  7. with Image.open(argv[1]) as img:
  8. bg_color = img.getpixel((0, 0))
  9. fg_color = img.getpixel((1, 0))
  10. null_color = img.getpixel((2, 0))
  11. width, height = img.size
  12. assert width % CHARACTER_WIDTH == 0, f"The source image's width must be a multiple of {CHARACTER_WIDTH}!"
  13. assert height % CHARACTER_HEIGHT == 1, f"The source image's height must be a multiple of {CHARACTER_HEIGHT}, plus 1!"
  14. data = []
  15. for ty in range(0, height - 1, CHARACTER_HEIGHT):
  16. for tx in range(0, width, CHARACTER_WIDTH):
  17. size = 0
  18. for y in range(ty + 1, ty + 1 + CHARACTER_HEIGHT):
  19. byte = 0
  20. size = CHARACTER_WIDTH
  21. for x in range(tx, tx + CHARACTER_WIDTH):
  22. byte <<= 1
  23. pixel = img.getpixel((x, y))
  24. if pixel == fg_color:
  25. byte |= 1
  26. elif pixel == null_color:
  27. size -= 1
  28. elif pixel != bg_color:
  29. print(f"WARNING: pixel at (x:{x}, y:{y}) is none of the 3 font pixels; treating as blank. Note: only monochrome fonts are supported!", file=stderr)
  30. if byte & (1 << (CHARACTER_WIDTH - 8) - 1):
  31. raise ValueError(f"Row at (x:{tx}, y:{y}): only the first 8 pixels of a character can be non-blank!")
  32. data.append(byte >> (CHARACTER_WIDTH - 8))
  33. data.append(size)
  34. with open(argv[2], "wb") as output:
  35. output.write(bytes(data))