def read_block (fh) :
"""
Yield a series of non-empty lines from the given file, ignoring any leading empty lines, and stopping after the first empty line
"""
leading = True
for line in fh :
if line.strip() :
leading = False
# yield non-empty
yield line
elif leading :
# skip leading empty
continue
else :
# stop on empty
return
else :
# EOF
return
def read_charblock (lines) :
"""
Read in a char from the given lines, returning an
(ascii, rows)
tuple, or None, if there weren't any more blocks
"""
# the ascii code as a char
ascii = ''
# row data as ints
rows = []
for line in lines :
line = line.strip()
if line.startswith(';') :
# set ascii code
ascii = line.replace(';', '').strip()
if not ascii :
print 'read_charblock', 'empty'
# skip
return None
elif len(ascii) == 1 :
print 'read_charblock', 'simplechar', ascii
else :
ascii = ascii.decode('string_escape')
print 'read_charblock', 'decodechar', ascii
assert len(ascii) == 1
else :
# convert
row = line.replace('#', '1').replace('-', '0')
print 'read_charblock', 'row', row
# 6 columns
assert len(row) == 6
# from binary
row = int(row, 2)
rows.append(row)
# got data?
if ascii and rows :
# 8 rows
assert len(rows) == 8
return ascii, rows
else :
# nope, empty block, EOF
return None
def read_charblocks (fh) :
"""
Read in all char blocks as (ascii, rows) tuples from given file
"""
while True :
out = read_charblock(read_block(fh))
if out :
yield out
else :
break
def decode_rows (inrows) :
"""
Decode char def data from its 6x8 row format into the format we need (6x8 col format)
"""
outcols = [0x00] * 6
for rowidx, row in enumerate(inrows) :
for colidx, col in enumerate(outcols) :
# get bit from row
bit = (row >> (5 - colidx)) & 1
# set bit into column
outcols[colidx] |= (bit << rowidx)
# ok...
return outcols
def write_chardef (fh, ascii, cols) :
"""
Write out character definition block to given .def file, using given char code and column data
"""
fh.write(
("; %r\n" % ascii)
+ (".db %s\n" % (', '.join(bin(col) for col in cols)))
+ ("\n")
)
def compile_fonts (infh, outf) :
"""
Compile char blocks from infh, writing out definitions to outf
"""
charmap = dict()
# decode in
for charblock in read_charblocks(infh) :
# unpack
ascii, rows = charblock
# convert
cols = decode_rows(rows)
# map
charmap[ascii] = cols
print 'compile_fonts', 'read', ascii
# detect min/max syms
syms = charmap.keys()
font_start = min(syms)
font_end = max(syms)
assert(ord(font_start) < ord(font_end))
# write out
outf.write(
";; AUTOMATICALLY GENERATED - Do not edit!\n"
";; 8x6 font, '0' - '1', rows-by-col format\n"
+ (".equ FONT_8x6_START = %d ; %r\n" % (ord(font_start), font_start))
+ (".equ FONT_8x6_END = %d ; %r\n" % (ord(font_end), font_end))
+ (".equ FONT_8x6_COLS = %d\n" % (6, ))
+ (".equ FONT_8x6_ROWS = %d\n" % (8, ))
+ "FONT_8x6:\n"
"\n"
)
# default symbol for unknown chars
defsym = charmap['\0']
for char in xrange(ord(font_start), ord(font_end) + 1) :
ascii = chr(char)
cols = charmap.get(ascii, defsym)
write_chardef(outf, ascii, cols)
def main () :
import sys, getopt
opts, args = getopt.getopt(sys.argv[1:], '')
inpath, outpath = args
# run
compile_fonts(open(inpath, 'r'), open(outpath, 'w'))
if __name__ == '__main__' :
main()