96 lines
3.1 KiB
Python
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)
|