81 lines
2.0 KiB
Python
81 lines
2.0 KiB
Python
#!/usr/bin/env python3
|
|
from math import ceil
|
|
from sys import argv
|
|
from PIL import Image, ImageDraw, ImageFont
|
|
|
|
if (len(argv) < 4):
|
|
raise BaseException("At least three arguments expected: " + \
|
|
"<font path> <font size> <output image> " + \
|
|
"[initial char index] [char range]")
|
|
|
|
font_path = argv[1]
|
|
font_size = int(argv[2])
|
|
image_out = argv[3]
|
|
initial_char_index = int(argv[4]) if len(argv) > 4 else 0x20
|
|
char_range = int(argv[5]) if len(argv) > 5 else 96
|
|
line_count = ceil(char_range / 16)
|
|
scan_index = 0x20 if len(argv) > 4 else initial_char_index
|
|
scan_range = 0x30ff - 0x20 if len(argv) > 4 else char_range
|
|
|
|
assert char_range > 1
|
|
|
|
mode = '1' # 1-bit depth
|
|
background_color = (1) # white
|
|
foreground_color = (0) # black
|
|
|
|
# load font
|
|
font = ImageFont.truetype(font_path, font_size)
|
|
|
|
# find max char size
|
|
char_width = 0
|
|
char_height = 0
|
|
for i in range(scan_range):
|
|
bbox = list(font.getbbox(chr(scan_index + i)))
|
|
# don't you dare overlap
|
|
if (bbox[0] < 0):
|
|
bbox[2] = -bbox[0]
|
|
if (bbox[1] < 0):
|
|
bbox[3] -= bbox[1]
|
|
if bbox[2] > char_width:
|
|
char_width = bbox[2]
|
|
if bbox[3] > char_height:
|
|
char_height = bbox[3]
|
|
|
|
image_out_width = char_width * 16
|
|
image_out_height = char_height * line_count
|
|
|
|
# fxconv metadata
|
|
print(f"{image_out.split('/')[-1]}:")
|
|
print(" type: font")
|
|
print(" charset: print")
|
|
print(f" grid.size: {char_width}x{char_height}")
|
|
|
|
# create image
|
|
im = Image.new(mode, (image_out_width, image_out_height))
|
|
|
|
# draw
|
|
draw = ImageDraw.Draw(im)
|
|
draw.rectangle((0, 0, image_out_width, image_out_height), fill=background_color)
|
|
|
|
x = -char_width
|
|
y = 0
|
|
for i in range(char_range):
|
|
x += char_width
|
|
char = chr(initial_char_index + i)
|
|
bbox = font.getbbox(char)
|
|
x_mod = 0
|
|
y_mod = 0
|
|
# don't you dare overlap
|
|
if (bbox[0] < 0):
|
|
x_mod = -bbox[0]
|
|
if (bbox[1] < 0):
|
|
y_mod = -bbox[1]
|
|
if i != 0 and i % 16 == 0:
|
|
x = 0
|
|
y += char_height
|
|
draw.text((x + x_mod, y + y_mod), char, fill=foreground_color, font=font)
|
|
|
|
# save
|
|
im.save(image_out)
|
|
|