backyard/library/dwarf.py

390 lines
16 KiB
Python
Raw Permalink Blame History

#!/usr/bin/env python3
import numpy as np
def load(image_path):
from PIL import Image
image = np.array(Image.open(image_path).convert("RGB"))
height, width, channels = image.shape
charwidth = 0
separator = (255, 0, 255) # magenta, a la LÖVE
previous = -1
glyphs = []
for x, c in enumerate(image[0]):
if np.all(c == separator):
if not charwidth and previous < 0:
previous = x
continue
if not charwidth:
charwidth = x - previous
assert charwidth == x - previous, "font must be monospace"
glyph = image[:, previous + 1 : x]
glyphs.append(glyph)
previous = x
return np.any(glyphs, axis=-1).astype(np.uint8)
charset = "\
\x00☺☻♥♦♣♠•◘○◙♂♀♪♫☼\
►◄↕‼¶§▬↨↑↓→←∟↔▲▼\
!\"#$%&'()*+,-./\
0123456789:;<=>?\
@ABCDEFGHIJKLMNO\
PQRSTUVWXYZ[\\]^_\
`abcdefghijklmno\
pqrstuvwxyz{|}~⌂\
ÇüéâäàåçêëèïîìÄÅ\
ÉæÆôöòûùÿÖÜ¢£¥₧ƒ\
áíóúñѪº¿⌐¬½¼¡«»\
░▒▓│┤╡╢╖╕╣║╗╝╜╛┐\
└┴┬├─┼╞╟╚╔╩╦╠═╬╧\
╨╤╥╙╘╒╓╫╪┘┌█▄▌▐▀\
αßΓπΣσµτΦΘΩδ∞φε∩\
≡±≥≤⌠⌡÷≈°∙·√ⁿ²■<EFBFBD>"
assert len(charset) == 256
chars = b"\
\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\
\x00\x7E\xC3\x81\xA5\x81\xBD\x99\xC3\x7E\x00\x00\
\x00\x7E\xFF\xFF\xDB\xFF\xC3\xE7\xFF\x7E\x00\x00\
\x00\x00\x44\xEE\xFE\xFE\xFE\x7C\x38\x10\x00\x00\
\x00\x10\x38\x7C\xFE\xFE\x7C\x38\x10\x00\x00\x00\
\x00\x18\x3C\x3C\xFF\xE7\xE7\x18\x18\x7E\x00\x00\
\x00\x18\x3C\x7E\xFF\xFF\x7E\x18\x18\x7E\x00\x00\
\x00\x00\x00\x00\x3C\x7E\x7E\x3C\x00\x00\x00\x00\
\xFF\xFF\xFF\xFF\xC3\x81\x81\xC3\xFF\xFF\xFF\xFF\
\x00\x00\x3C\x7E\x66\x42\x42\x66\x7E\x3C\x00\x00\
\xFF\xFF\xC3\x81\x99\xBD\xBD\x99\x81\xC3\xFF\xFF\
\x00\x3E\x0E\x3A\x72\xF8\xCC\xCC\xCC\x78\x00\x00\
\x00\x3C\x66\x66\x66\x3C\x18\x7E\x18\x18\x00\x00\
\x00\x1F\x19\x19\x1F\x18\x18\x78\xF8\x70\x00\x00\
\x00\x7F\x63\x7F\x63\x63\x63\x67\xE7\xE6\xC0\x00\
\x00\x00\x18\xDB\x7E\xE7\xE7\x7E\xDB\x18\x00\x00\
\x00\x80\xC0\xE0\xF8\xFE\xF8\xE0\xC0\x80\x00\x00\
\x00\x02\x06\x0E\x3E\xFE\x3E\x0E\x06\x02\x00\x00\
\x00\x18\x3C\x7E\x18\x18\x18\x7E\x3C\x18\x00\x00\
\x00\x66\x66\x66\x66\x66\x00\x00\x66\x66\x00\x00\
\x00\x7F\xDB\xDB\xDB\x7B\x1B\x1B\x1B\x1B\x00\x00\
\x00\x7E\x63\x30\x3C\x66\x66\x3C\x0C\xC6\x7E\x00\
\x00\x00\x00\x00\x00\x00\x00\xFE\xFE\xFE\x00\x00\
\x00\x18\x3C\x7E\x18\x18\x18\x7E\x3C\x18\x7E\x00\
\x00\x18\x3C\x7E\x18\x18\x18\x18\x18\x18\x00\x00\
\x00\x18\x18\x18\x18\x18\x18\x7E\x3C\x18\x00\x00\
\x00\x00\x00\x18\x0C\xFE\x0C\x18\x00\x00\x00\x00\
\x00\x00\x00\x30\x60\xFE\x60\x30\x00\x00\x00\x00\
\x00\x00\x00\x00\xC0\xC0\xC0\xFE\x00\x00\x00\x00\
\x00\x00\x00\x24\x66\xFF\x66\x24\x00\x00\x00\x00\
\x00\x00\x10\x10\x38\x38\x7C\x7C\xFE\xFE\x00\x00\
\x00\x00\xFE\xFE\x7C\x7C\x38\x38\x10\x10\x00\x00\
\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\
\x00\x30\x78\x78\x78\x30\x30\x00\x30\x30\x00\x00\
\x00\x66\x66\x66\x24\x00\x00\x00\x00\x00\x00\x00\
\x00\x6C\x6C\xFE\x6C\x6C\x6C\xFE\x6C\x6C\x00\x00\
\x30\x30\x7C\xC0\xC0\x78\x0C\x0C\xF8\x30\x30\x00\
\x00\x00\x00\xC4\xCC\x18\x30\x60\xCC\x8C\x00\x00\
\x00\x70\xD8\xD8\x70\xFA\xDE\xCC\xDC\x76\x00\x00\
\x00\x30\x30\x30\x60\x00\x00\x00\x00\x00\x00\x00\
\x00\x0C\x18\x30\x60\x60\x60\x30\x18\x0C\x00\x00\
\x00\x60\x30\x18\x0C\x0C\x0C\x18\x30\x60\x00\x00\
\x00\x00\x00\x66\x3C\xFF\x3C\x66\x00\x00\x00\x00\
\x00\x00\x00\x18\x18\x7E\x18\x18\x00\x00\x00\x00\
\x00\x00\x00\x00\x00\x00\x00\x00\x38\x38\x60\x00\
\x00\x00\x00\x00\x00\xFE\x00\x00\x00\x00\x00\x00\
\x00\x00\x00\x00\x00\x00\x00\x00\x38\x38\x00\x00\
\x00\x00\x02\x06\x0C\x18\x30\x60\xC0\x80\x00\x00\
\x00\x7C\xC6\xCE\xDE\xD6\xF6\xE6\xC6\x7C\x00\x00\
\x00\x10\x30\xF0\x30\x30\x30\x30\x30\xFC\x00\x00\
\x00\x78\xCC\xCC\x0C\x18\x30\x60\xCC\xFC\x00\x00\
\x00\x78\xCC\x0C\x0C\x38\x0C\x0C\xCC\x78\x00\x00\
\x00\x0C\x1C\x3C\x6C\xCC\xFE\x0C\x0C\x1E\x00\x00\
\x00\xFC\xC0\xC0\xC0\xF8\x0C\x0C\xCC\x78\x00\x00\
\x00\x38\x60\xC0\xC0\xF8\xCC\xCC\xCC\x78\x00\x00\
\x00\xFE\xC6\xC6\x06\x0C\x18\x30\x30\x30\x00\x00\
\x00\x78\xCC\xCC\xEC\x78\xDC\xCC\xCC\x78\x00\x00\
\x00\x78\xCC\xCC\xCC\x7C\x18\x18\x30\x70\x00\x00\
\x00\x00\x00\x38\x38\x00\x00\x38\x38\x00\x00\x00\
\x00\x00\x00\x38\x38\x00\x00\x38\x38\x18\x30\x00\
\x00\x0C\x18\x30\x60\xC0\x60\x30\x18\x0C\x00\x00\
\x00\x00\x00\x00\x7E\x00\x7E\x00\x00\x00\x00\x00\
\x00\x60\x30\x18\x0C\x06\x0C\x18\x30\x60\x00\x00\
\x00\x78\xCC\x0C\x18\x30\x30\x00\x30\x30\x00\x00\
\x00\x7C\xC6\xC6\xDE\xDE\xDE\xC0\xC0\x7C\x00\x00\
\x00\x30\x78\xCC\xCC\xCC\xFC\xCC\xCC\xCC\x00\x00\
\x00\xFC\x66\x66\x66\x7C\x66\x66\x66\xFC\x00\x00\
\x00\x3C\x66\xC6\xC0\xC0\xC0\xC6\x66\x3C\x00\x00\
\x00\xF8\x6C\x66\x66\x66\x66\x66\x6C\xF8\x00\x00\
\x00\xFE\x62\x60\x64\x7C\x64\x60\x62\xFE\x00\x00\
\x00\xFE\x66\x62\x64\x7C\x64\x60\x60\xF0\x00\x00\
\x00\x3C\x66\xC6\xC0\xC0\xCE\xC6\x66\x3E\x00\x00\
\x00\xCC\xCC\xCC\xCC\xFC\xCC\xCC\xCC\xCC\x00\x00\
\x00\x78\x30\x30\x30\x30\x30\x30\x30\x78\x00\x00\
\x00\x1E\x0C\x0C\x0C\x0C\xCC\xCC\xCC\x78\x00\x00\
\x00\xE6\x66\x6C\x6C\x78\x6C\x6C\x66\xE6\x00\x00\
\x00\xF0\x60\x60\x60\x60\x62\x66\x66\xFE\x00\x00\
\x00\xC6\xEE\xFE\xFE\xD6\xC6\xC6\xC6\xC6\x00\x00\
\x00\xC6\xC6\xE6\xF6\xFE\xDE\xCE\xC6\xC6\x00\x00\
\x00\x38\x6C\xC6\xC6\xC6\xC6\xC6\x6C\x38\x00\x00\
\x00\xFC\x66\x66\x66\x7C\x60\x60\x60\xF0\x00\x00\
\x00\x38\x6C\xC6\xC6\xC6\xCE\xDE\x7C\x0C\x1E\x00\
\x00\xFC\x66\x66\x66\x7C\x6C\x66\x66\xE6\x00\x00\
\x00\x78\xCC\xCC\xC0\x70\x18\xCC\xCC\x78\x00\x00\
\x00\xFC\xB4\x30\x30\x30\x30\x30\x30\x78\x00\x00\
\x00\xCC\xCC\xCC\xCC\xCC\xCC\xCC\xCC\x78\x00\x00\
\x00\xCC\xCC\xCC\xCC\xCC\xCC\xCC\x78\x30\x00\x00\
\x00\xC6\xC6\xC6\xC6\xD6\xD6\x6C\x6C\x6C\x00\x00\
\x00\xCC\xCC\xCC\x78\x30\x78\xCC\xCC\xCC\x00\x00\
\x00\xCC\xCC\xCC\xCC\x78\x30\x30\x30\x78\x00\x00\
\x00\xFE\xCE\x98\x18\x30\x60\x62\xC6\xFE\x00\x00\
\x00\x3C\x30\x30\x30\x30\x30\x30\x30\x3C\x00\x00\
\x00\x00\x80\xC0\x60\x30\x18\x0C\x06\x02\x00\x00\
\x00\x3C\x0C\x0C\x0C\x0C\x0C\x0C\x0C\x3C\x00\x00\
\x10\x38\x6C\xC6\x00\x00\x00\x00\x00\x00\x00\x00\
\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xFF\x00\
\x30\x30\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00\
\x00\x00\x00\x00\x78\x0C\x7C\xCC\xCC\x76\x00\x00\
\x00\xE0\x60\x60\x7C\x66\x66\x66\x66\xDC\x00\x00\
\x00\x00\x00\x00\x78\xCC\xC0\xC0\xCC\x78\x00\x00\
\x00\x1C\x0C\x0C\x7C\xCC\xCC\xCC\xCC\x76\x00\x00\
\x00\x00\x00\x00\x78\xCC\xFC\xC0\xCC\x78\x00\x00\
\x00\x38\x6C\x60\x60\xF8\x60\x60\x60\xF0\x00\x00\
\x00\x00\x00\x00\x76\xCC\xCC\xCC\x7C\x0C\xCC\x78\
\x00\xE0\x60\x60\x6C\x76\x66\x66\x66\xE6\x00\x00\
\x00\x18\x18\x00\x78\x18\x18\x18\x18\x7E\x00\x00\
\x00\x0C\x0C\x00\x3C\x0C\x0C\x0C\x0C\xCC\xCC\x78\
\x00\xE0\x60\x60\x66\x6C\x78\x6C\x66\xE6\x00\x00\
\x00\x78\x18\x18\x18\x18\x18\x18\x18\x7E\x00\x00\
\x00\x00\x00\x00\xFC\xD6\xD6\xD6\xD6\xC6\x00\x00\
\x00\x00\x00\x00\xF8\xCC\xCC\xCC\xCC\xCC\x00\x00\
\x00\x00\x00\x00\x78\xCC\xCC\xCC\xCC\x78\x00\x00\
\x00\x00\x00\x00\xDC\x66\x66\x66\x66\x7C\x60\xF0\
\x00\x00\x00\x00\x76\xCC\xCC\xCC\xCC\x7C\x0C\x1E\
\x00\x00\x00\x00\xEC\x6E\x76\x60\x60\xF0\x00\x00\
\x00\x00\x00\x00\x78\xCC\x60\x18\xCC\x78\x00\x00\
\x00\x00\x20\x60\xFC\x60\x60\x60\x6C\x38\x00\x00\
\x00\x00\x00\x00\xCC\xCC\xCC\xCC\xCC\x76\x00\x00\
\x00\x00\x00\x00\xCC\xCC\xCC\xCC\x78\x30\x00\x00\
\x00\x00\x00\x00\xC6\xC6\xD6\xD6\x6C\x6C\x00\x00\
\x00\x00\x00\x00\xC6\x6C\x38\x38\x6C\xC6\x00\x00\
\x00\x00\x00\x00\x66\x66\x66\x66\x3C\x0C\x18\xF0\
\x00\x00\x00\x00\xFC\x8C\x18\x60\xC4\xFC\x00\x00\
\x00\x1C\x30\x30\x60\xC0\x60\x30\x30\x1C\x00\x00\
\x00\x18\x18\x18\x18\x00\x18\x18\x18\x18\x00\x00\
\x00\xE0\x30\x30\x18\x0C\x18\x30\x30\xE0\x00\x00\
\x00\x73\xDA\xCE\x00\x00\x00\x00\x00\x00\x00\x00\
\x00\x00\x00\x10\x38\x6C\xC6\xC6\xFE\x00\x00\x00\
\x00\x78\xCC\xCC\xC0\xC0\xC0\xCC\xCC\x78\x30\xF0\
\x00\xCC\xCC\x00\xCC\xCC\xCC\xCC\xCC\x76\x00\x00\
\x0C\x18\x30\x00\x78\xCC\xFC\xC0\xCC\x78\x00\x00\
\x30\x78\xCC\x00\x78\x0C\x7C\xCC\xCC\x76\x00\x00\
\x00\xCC\xCC\x00\x78\x0C\x7C\xCC\xCC\x76\x00\x00\
\xC0\x60\x30\x00\x78\x0C\x7C\xCC\xCC\x76\x00\x00\
\x38\x6C\x6C\x38\xF8\x0C\x7C\xCC\xCC\x76\x00\x00\
\x00\x00\x00\x00\x78\xCC\xC0\xC0\xCC\x78\x30\xF0\
\x30\x78\xCC\x00\x78\xCC\xFC\xC0\xC0\x7C\x00\x00\
\x00\xCC\xCC\x00\x78\xCC\xFC\xC0\xC0\x7C\x00\x00\
\xC0\x60\x30\x00\x78\xCC\xFC\xC0\xC0\x7C\x00\x00\
\x00\x6C\x6C\x00\x78\x18\x18\x18\x18\x7E\x00\x00\
\x10\x38\x6C\x00\x78\x18\x18\x18\x18\x7E\x00\x00\
\x60\x30\x18\x00\x78\x18\x18\x18\x18\x7E\x00\x00\
\x00\xCC\x00\x30\x78\xCC\xCC\xFC\xCC\xCC\x00\x00\
\x78\xCC\xCC\x78\x78\xCC\xCC\xFC\xCC\xCC\x00\x00\
\x0C\x18\x30\xFC\xC4\xC0\xF8\xC0\xC4\xFC\x00\x00\
\x00\x00\x00\x00\xFE\x1B\x7F\xD8\xD8\xEF\x00\x00\
\x00\x3E\x78\xD8\xD8\xFE\xD8\xD8\xD8\xDE\x00\x00\
\x30\x78\xCC\x00\x78\xCC\xCC\xCC\xCC\x78\x00\x00\
\x00\xCC\xCC\x00\x78\xCC\xCC\xCC\xCC\x78\x00\x00\
\xC0\x60\x30\x00\x78\xCC\xCC\xCC\xCC\x78\x00\x00\
\x30\x78\xCC\x00\xCC\xCC\xCC\xCC\xCC\x76\x00\x00\
\xC0\x60\x30\x00\xCC\xCC\xCC\xCC\xCC\x76\x00\x00\
\x00\x66\x66\x00\x66\x66\x66\x66\x3C\x0C\x18\xF0\
\xCC\x00\x78\xCC\xCC\xCC\xCC\xCC\xCC\x78\x00\x00\
\xCC\x00\xCC\xCC\xCC\xCC\xCC\xCC\xCC\x78\x00\x00\
\x00\x30\x30\x78\xCC\xC0\xC0\xCC\x78\x30\x30\x00\
\x3C\x66\x60\x60\x60\xFC\x60\x60\xC0\xFE\x00\x00\
\xCC\xCC\xCC\xCC\x78\xFC\x30\xFC\x30\x30\x00\x00\
\xF0\x88\x88\x88\xF0\x88\x9E\x8C\x8D\x86\x00\x00\
\x0E\x1B\x18\x18\x7E\x18\x18\x18\xD8\x70\x00\x00\
\x0C\x18\x30\x00\x78\x0C\x7C\xCC\xCC\x76\x00\x00\
\x0C\x18\x30\x00\x78\x18\x18\x18\x18\x7E\x00\x00\
\x0C\x18\x30\x00\x78\xCC\xCC\xCC\xCC\x78\x00\x00\
\x0C\x18\x30\x00\xCC\xCC\xCC\xCC\xCC\x76\x00\x00\
\x00\x76\xDC\x00\xF8\xCC\xCC\xCC\xCC\xCC\x00\x00\
\x76\xDC\x00\xC6\xE6\xF6\xDE\xCE\xC6\xC6\x00\x00\
\x00\x78\xCC\xCC\x7E\x00\xFE\x00\x00\x00\x00\x00\
\x00\x78\xCC\xCC\x78\x00\xFE\x00\x00\x00\x00\x00\
\x00\x30\x30\x00\x30\x60\xC0\xC0\xCC\x78\x00\x00\
\x00\x00\x00\x00\x00\xFC\xC0\xC0\xC0\x00\x00\x00\
\x00\x00\x00\x00\x00\xFC\x0C\x0C\x0C\x00\x00\x00\
\x00\x42\xC6\xCC\xD8\x30\x6E\xC3\x86\x0C\x1F\x00\
\x00\x63\xE6\x6C\x78\x37\x6F\xDB\xB3\x3F\x03\x00\
\x00\x30\x30\x00\x30\x30\x78\x78\x78\x30\x00\x00\
\x00\x00\x00\x00\x33\x66\xCC\xCC\x66\x33\x00\x00\
\x00\x00\x00\x00\xCC\x66\x33\x33\x66\xCC\x00\x00\
\x24\x92\x49\x24\x92\x49\x24\x92\x49\x24\x92\x49\
\x55\xAA\x55\xAA\x55\xAA\x55\xAA\x55\xAA\x55\xAA\
\x6D\xDB\xB6\x6D\xDB\xB6\x6D\xDB\xB6\x6D\xDB\xB6\
\x18\x18\x18\x18\x18\x18\x18\x18\x18\x18\x18\x18\
\x18\x18\x18\x18\x18\xF8\x18\x18\x18\x18\x18\x18\
\x18\x18\x18\x18\xF8\x18\x18\xF8\x18\x18\x18\x18\
\x66\x66\x66\x66\x66\xE6\x66\x66\x66\x66\x66\x66\
\x00\x00\x00\x00\x00\xFE\x66\x66\x66\x66\x66\x66\
\x00\x00\x00\x00\xF8\x18\x18\xF8\x18\x18\x18\x18\
\x66\x66\x66\x66\xE6\x06\x06\xE6\x66\x66\x66\x66\
\x66\x66\x66\x66\x66\x66\x66\x66\x66\x66\x66\x66\
\x00\x00\x00\x00\xFE\x06\x06\xE6\x66\x66\x66\x66\
\x66\x66\x66\x66\xE6\x06\x06\xFE\x00\x00\x00\x00\
\x66\x66\x66\x66\x66\xFE\x00\x00\x00\x00\x00\x00\
\x18\x18\x18\x18\xF8\x18\x18\xF8\x00\x00\x00\x00\
\x00\x00\x00\x00\x00\xF8\x18\x18\x18\x18\x18\x18\
\x18\x18\x18\x18\x18\x1F\x00\x00\x00\x00\x00\x00\
\x18\x18\x18\x18\x18\xFF\x00\x00\x00\x00\x00\x00\
\x00\x00\x00\x00\x00\xFF\x18\x18\x18\x18\x18\x18\
\x18\x18\x18\x18\x18\x1F\x18\x18\x18\x18\x18\x18\
\x00\x00\x00\x00\x00\xFF\x00\x00\x00\x00\x00\x00\
\x18\x18\x18\x18\x18\xFF\x18\x18\x18\x18\x18\x18\
\x18\x18\x18\x18\x1F\x18\x18\x1F\x18\x18\x18\x18\
\x66\x66\x66\x66\x66\x67\x66\x66\x66\x66\x66\x66\
\x66\x66\x66\x66\x67\x60\x60\x7F\x00\x00\x00\x00\
\x00\x00\x00\x00\x7F\x60\x60\x67\x66\x66\x66\x66\
\x66\x66\x66\x66\xE7\x00\x00\xFF\x00\x00\x00\x00\
\x00\x00\x00\x00\xFF\x00\x00\xE7\x66\x66\x66\x66\
\x66\x66\x66\x66\x67\x60\x60\x67\x66\x66\x66\x66\
\x00\x00\x00\x00\xFF\x00\x00\xFF\x00\x00\x00\x00\
\x66\x66\x66\x66\xE7\x00\x00\xE7\x66\x66\x66\x66\
\x18\x18\x18\x18\xFF\x00\x00\xFF\x00\x00\x00\x00\
\x66\x66\x66\x66\x66\xFF\x00\x00\x00\x00\x00\x00\
\x00\x00\x00\x00\xFF\x00\x00\xFF\x18\x18\x18\x18\
\x00\x00\x00\x00\x00\xFF\x66\x66\x66\x66\x66\x66\
\x66\x66\x66\x66\x66\x7F\x00\x00\x00\x00\x00\x00\
\x18\x18\x18\x18\x1F\x18\x18\x1F\x00\x00\x00\x00\
\x00\x00\x00\x00\x1F\x18\x18\x1F\x18\x18\x18\x18\
\x00\x00\x00\x00\x00\x7F\x66\x66\x66\x66\x66\x66\
\x66\x66\x66\x66\x66\xE7\x66\x66\x66\x66\x66\x66\
\x18\x18\x18\x18\xFF\x00\x00\xFF\x18\x18\x18\x18\
\x18\x18\x18\x18\x18\xF8\x00\x00\x00\x00\x00\x00\
\x00\x00\x00\x00\x00\x1F\x18\x18\x18\x18\x18\x18\
\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\
\x00\x00\x00\x00\x00\x00\xFF\xFF\xFF\xFF\xFF\xFF\
\xF0\xF0\xF0\xF0\xF0\xF0\xF0\xF0\xF0\xF0\xF0\xF0\
\x0F\x0F\x0F\x0F\x0F\x0F\x0F\x0F\x0F\x0F\x0F\x0F\
\xFF\xFF\xFF\xFF\xFF\xFF\x00\x00\x00\x00\x00\x00\
\x00\x00\x00\x00\x76\xDE\xCC\xCC\xDE\x76\x00\x00\
\x00\x78\xCC\xCC\xD8\xCC\xCC\xCC\xF8\xC0\x60\x00\
\x00\xFC\xCC\xCC\xC0\xC0\xC0\xC0\xC0\xC0\x00\x00\
\x00\xFE\x6C\x6C\x6C\x6C\x6C\x6C\x6C\x66\x00\x00\
\x00\xFC\xC4\x64\x60\x30\x60\x64\xC4\xFC\x00\x00\
\x00\x00\x00\x00\x7E\xC8\xCC\xCC\xCC\x78\x00\x00\
\x00\x00\x00\x00\x66\x66\x66\x66\x66\x7B\x60\xC0\
\x00\x00\x00\x76\xDC\x18\x18\x18\x18\x0E\x00\x00\
\x00\xFC\x30\x78\xCC\xCC\xCC\x78\x30\xFC\x00\x00\
\x00\x78\xCC\xCC\xCC\xFC\xCC\xCC\xCC\x78\x00\x00\
\x00\x7C\xC6\xC6\xC6\xC6\x6C\x6C\x6C\xEE\x00\x00\
\x00\x3C\x60\x30\x78\xCC\xCC\xCC\xCC\x78\x00\x00\
\x00\x00\x00\x76\xDB\xDB\xDB\x6E\x00\x00\x00\x00\
\x00\x00\x06\x7C\xDE\xD6\xF6\x7C\xC0\x00\x00\x00\
\x00\x3C\x60\xC0\xC0\xFC\xC0\xC0\x60\x3C\x00\x00\
\x00\x00\x78\xCC\xCC\xCC\xCC\xCC\xCC\xCC\x00\x00\
\x00\x00\xFC\x00\x00\xFC\x00\x00\xFC\x00\x00\x00\
\x00\x00\x30\x30\xFC\x30\x30\x00\xFC\x00\x00\x00\
\x00\x60\x30\x18\x18\x30\x60\x00\xFC\x00\x00\x00\
\x00\x18\x30\x60\x60\x30\x18\x00\xFC\x00\x00\x00\
\x00\x00\x0E\x1B\x1B\x18\x18\x18\x18\x18\x18\x18\
\x18\x18\x18\x18\x18\x18\x18\xD8\xD8\x70\x00\x00\
\x00\x00\x30\x30\x00\xFC\x00\x30\x30\x00\x00\x00\
\x00\x00\x73\xDB\xCE\x00\x73\xDB\xCE\x00\x00\x00\
\x00\x3C\x66\x66\x66\x3C\x00\x00\x00\x00\x00\x00\
\x00\x00\x00\x00\x1C\x1C\x00\x00\x00\x00\x00\x00\
\x00\x00\x00\x00\x00\x18\x00\x00\x00\x00\x00\x00\
\x00\x07\x04\x04\x04\x44\x64\x34\x1C\x0C\x00\x00\
\x00\xD8\x6C\x6C\x6C\x6C\x00\x00\x00\x00\x00\x00\
\x00\x78\x0C\x18\x30\x7C\x00\x00\x00\x00\x00\x00\
\x00\x00\x3C\x3C\x3C\x3C\x3C\x3C\x3C\x3C\x00\x00\
\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\
"
assert len(chars) == len(charset) * 12
glyphs = np.unpackbits(np.frombuffer(chars, np.uint8)).reshape(256, 12, 8)
def render(text, scale):
if isinstance(text, str):
inds = [charset.index(c) if c in charset else 255 for c in text]
else:
inds = list(text)
if len(inds) == 0:
return np.array((), np.uint8)
image = np.zeros((12, len(inds) * 8), np.uint8)
for i, ind in enumerate(inds):
a = i * 8
b = a + 8
# glyph = np.unpackbits(chars[a:b]) # BROKEN
# glyph.shape = (8, 12)
# image[:, a:b] = glyph
image[:, a:b] = glyphs[ind]
return image
# TODO: optional flip horizontal and vertical kwargs.
def render_to(text, image, *, x, y, scale=1, masked=0):
# TODO: maybe return whether or not
# the text had to be clipped within the image bounds?
assert scale > 0
assert isinstance(scale, int)
assert masked in (-1, 0, 1)
text = render(text, scale) * 255
if scale > 1:
text2 = np.repeat(text, scale)
text2.shape = (text.shape[0], text.shape[1] * scale)
x2 = x + text2.shape[1]
if masked == 0:
for yy in range(12):
for s in range(scale):
image[y + yy * scale + s, x:x2, ...] = text2[yy, :, None]
elif masked == 1:
for yy in range(12):
mask = text2[yy, :] != 0
for s in range(scale):
image[y + yy * scale + s, x:x2, ...][mask] = 255
elif masked == -1:
for yy in range(12):
mask = text2[yy, :] == 0
for s in range(scale):
image[y + yy * scale + s, x:x2, ...][mask] = 0
else:
x2 = x + text.shape[1]
y2 = y + text.shape[0]
if masked == 0:
image[y:y2, x:x2, ...] = text[:, :, None]
elif masked == 1:
mask = text[:, :] != 0
image[y:y2, x:x2, ...][mask] = 255
elif masked == -1:
mask = text[:, :] == 0
image[y:y2, x:x2, ...][mask] = 0
if __name__ == "__main__":
from sys import stderr
from base64 import b64encode
glyphs = load("dwarf.png")
for i, glyph in enumerate(glyphs):
print(f"<== {i} ==>", file=stderr)
for row in glyph:
print("".join("#" if col else "." for col in row), file=stderr)
packed = np.packbits(glyph) # 1 bit per pixel
formatted = "".join(f"\\x{byte:02X}" for byte in packed)
print(f'b"{formatted}",')
# print()
print(b64encode(glyphs.tobytes()))