xen32os/gen/fontgen.py

67 lines
1.8 KiB
Python

import json
import struct
# generates:
# font_data.dat (binary file, expected to load at location 0xf000_0100)
# font_data.inc (fox32 assembly)
# font_data.inc defines constants
# N_CHARS: number of defined characters (u32)
# CHAR_TABLE: pointer to main char table (&Char)
# UNKNOWN_CHAR: pointer to unknown character (&Char)
#
# struct Char {
# width: u8, height: u8, baseline: u8,
# data_ptr: &[u8],
# } (7 bytes)
DATA_FILE_ORIGIN = 0xf000_0100
BASELINE = 7
N_CHARS = 127
codepoints = json.load(open("ultlf/codepoints.json"))
font_data = json.load(open("ultlf/data.json"))
baselines = json.load(open("ultlf/trimmed_baselines.json"))
UNKNOWN = [
"# ### #",
"# # # #",
"# # #",
"# # #",
"# # #",
"# #",
"# # #",
]
with open("xenrom/data/font_data.inc", "w") as inc, open("xenrom/data/font_data.dat", "wb") as dat:
table = b''
char_data = b''
for ch in [None] + list(range(N_CHARS)):
if ch in codepoints:
i = codepoints.index(ch)
glyph = font_data[i]
baseline = baselines[i]
if '?' in "".join(glyph):
print(f"Font doesn't have char {ch}")
glyph = UNKNOWN
baseline = 6
else:
glyph = UNKNOWN
baseline = 6
print(f"Couldn't find char {ch}")
table += struct.pack("BBBI", len(glyph[0]), len(glyph), baseline, DATA_FILE_ORIGIN + len(char_data))
for line in glyph:
for ch in glyph:
char_data += b'\x00' if ch == ' ' else b'\x01'
dat.write(char_data + table)
inc.write(f'''
const N_CHARS: {N_CHARS}
const CHAR_TABLE: {hex(DATA_FILE_ORIGIN + len(char_data))}
const UNKNOWN_CHAR: {hex(DATA_FILE_ORIGIN)}
''')