flashfloppy/scripts/mk_font.py
Keir Fraser 5538be6686 Remove double underscore prefix from __packed and __aligned() definitions.
It is polluting the GCC namespace and breaks the build with GCC v9.
2019-12-10 15:04:55 +00:00

96 lines
3.1 KiB
Python

# mk_font.py
#
# Translate Font BDF file into a C header.
#
# Written & released by Keir Fraser <keir.xen@gmail.com>
#
# This is free and unencumbered software released into the public domain.
# See the file COPYING for more details, or visit <http://unlicense.org>.
import re, sys
# Range of char codes we are interested in
first = 0x20
last = 0x7e
def main(argv):
in_f = open(argv[1], "r")
out_f = open(argv[2] + ".c", "w")
out_f.write("/* Autogenerated by " + argv[0] + " */\n")
prev = first - 1
# Find font size
for line in in_f:
match = re.match("^FONTBOUNDINGBOX ([0-9]+) ([0-9]+) ([0-9]+) ([-0-9]+)", line)
if match:
break
width = int(match.group(1))
height = int(match.group(2))
y_base = int(match.group(4))
gap = 16 - height
tgap = gap // 2
bgap = gap - tgap
out_f.write("const uint8_t %s[] aligned(4) = {\n" % argv[2])
for line in in_f:
# Look for a new character encoding
match = re.match("^ENCODING ([0-9]+)", line)
#match = re.match("[ \t]*([A-Za-z0-9-]+)[ \t]*=[ \t]*"
# "([A-Za-z0-9-]+|\".*\")", line)
if not match:
continue
# Extract the decimal character code point
code = int(match.group(1))
# Skip uninteresting code points
if code < first or code > last:
continue
# This script assumes the char set is in code-point order
assert code == prev + 1
prev = code
# Scan for start of bitmap data
x_shift = 0
top_space = 0
bottom_space = 0
for line in in_f:
bbx = re.match("^BBX ([0-9]+) ([0-9]+) ([0-9]+) ([-0-9]+)", line)
if bbx:
x_shift = int(bbx.group(3))
y_height = int(bbx.group(2))
y_shift = int(bbx.group(4))
bottom_space = y_shift - y_base
top_space = height - (bottom_space + y_height)
if re.match("BITMAP", line):
break
# Process bitmap data up to end-char
char = []
top_space += tgap
for i in range(top_space):
char.append(0)
for line in in_f:
if re.match("ENDCHAR", line):
break
match = re.match("([0-9A-F]+)", line)
char.append(int(match.group(1), 16) >> x_shift)
bottom_space += bgap
for i in range(bottom_space):
char.append(0)
# Convert row-wise data to column-wise
while char:
out_f.write(" ")
mask = 0x80
for i in range(width):
col = 0
for j in range(8):
col //= 2
if char[j] & mask:
col = col + 0x80
out_f.write("0x%02x, " % (col))
mask //= 2
char = char[8:]
if not char:
out_f.write(" /* '%c' %02u */" % (code, code-first))
out_f.write("\n")
out_f.write("};\n");
# Assert we found all interesting code points
assert prev == last
if __name__ == "__main__":
main(sys.argv)