uf5x7/gen.py

127 lines
2.8 KiB
Python
Executable File

#! /usr/bin/python3
import PIL.Image
import sys
import os
import re
if len(sys.argv) <= 1:
print(f"usage: {sys.argv[0]} <block files...>")
sys.exit(1)
files = sorted(sys.argv[1:])
chars = PIL.Image.open("gen-chars.png")
WHITE = (255, 255, 255)
BLACK = (0, 0, 0)
def empty_separator():
img = PIL.Image.new("RGB", (112, 9), color=WHITE)
for j in range(3, 6):
for i in range(1, 111):
if not ((i + j) & 1):
img.putpixel((i, j), BLACK)
return img
def char_index(c):
o = ord(c)
if ord('0') <= o <= ord('9'):
return o - ord('0')
if ord('A') <= o <= ord('F'):
return o - ord('A') + 10
if c == 'U':
return 16
if c == '+':
return 17
raise Exception(f"Unsupported char '{c}'")
def char_image(c):
index = 4 * char_index(c)
return chars.crop((index, 0, index + 3, 5))
def separator(start, end):
img = PIL.Image.new("RGB", (112, 9), color=WHITE)
for j in range(3, 6):
for i in range(1, 26):
if not ((i + j) & 1):
img.putpixel((i, j), BLACK)
for i in range(86, 111):
if not ((i + j) & 1):
img.putpixel((i, j), BLACK)
x = 27
for c in "U+{:04X}".format(start):
img.paste(char_image(c), (x, 2))
x += 4
for i in range(54, 58):
img.putpixel((i, 4), BLACK)
x = 62
for c in "U+{:04X}".format(end):
img.paste(char_image(c), (x, 2))
x += 4
return img
class Block:
def __init__(self, path):
basename = os.path.basename(path)
match = re.search(r'U\+([0-9A-Za-z]{4})', basename)
self.block_start = None
self.block_end = None
self.img = PIL.Image.open(path)
if match is not None:
self.block_start = int(match[1], 16)
self.block_end = self.block_start + 16 * (self.img.height // 9) - 1
print('{} U+{:04X} - U+{:04X}'.format(basename, self.block_start,
self.block_end))
else:
print(f'{basename} not a block')
def header(self):
if self.block_start is not None:
return separator(self.block_start, self.block_end)
else:
return empty_separator()
def body(self):
return self.img
def height(self):
return self.img.height + 9
blocks = [ Block(file) for file in files ]
height = sum(b.height() for b in blocks)
left_height = 0
for b in blocks:
left_height += b.height()
if 2 * left_height >= height: break
result = PIL.Image.new("RGB", (2 * 112 + 8, left_height), color=WHITE)
x = 0
y = 0
for b in blocks:
header = b.header()
result.paste(header, (x, y))
y += header.height
body = b.body()
result.paste(body, (x, y))
y += body.height
if y >= left_height:
y = 0
x += 112 + 8
result.save("uf5x7.png")