diff --git a/unihex2uf2 b/unihex2uf2 new file mode 100755 index 0000000..6592105 --- /dev/null +++ b/unihex2uf2 @@ -0,0 +1,108 @@ +#!/usr/bin/env python3 + +import os +import re +import sys + +line_re = re.compile(r'^([0-9A-Fa-f]{4}):((?:[0-9A-Fa-f]{32}){1,2})$') +def parse(line): + m = line_re.match(line) + if not m: + raise Exception('could not parse line: %r' % line) + n = int(m.group(1), 16) + data = m.group(2) + return (n, data) + +blank_line = ' '.join(['00'] * 16) + +def split16(data): + return ' '.join([data[i:i+2] for i in range(0, 32, 2)]) + +def split(data): + if len(data) == 32: + return (split16(data),) + elif len(data) == 64: + return (split16(data[0:32]), split16(data[32:64])) + else: + raise Exception('invalid data length: %d' % len(data)) + +def run(path, start): + limit = start + 256 + widths = [8] * 256 + lines = [] + + def emit(n, line1, line2): + lines.append(('( %04x ) ' % n) + line1) + lines.append(' ' + line2) + + with open(path, 'r') as f: + seeking = start + for line in f: + n, data = parse(line.lower()) + if n < seeking: + continue + if n > seeking: + for i in range(seeking, min(limit, seeking)): + emit(i, blank_line, blank_line) + if n >= limit: + break + tpl = split(data) + if len(tpl) == 1: + emit(n, tpl[0], blank_line) + widths[n - start] = 8 + else: + emit(n, tpl[0], tpl[1]) + widths[n - start] = 16 + seeking = n + 1 + for i in range(seeking, limit): + emit(i, blank_line, blank_line) + + print('( unifont: %04x to %04x )' % (start, limit - 1)) + print('') + print('( widths )') + for i in range(16): + j = i * 16 + width_line = ' '.join([('%02x' % widths[k]) for k in range(j, j + 16)]) + print(('( %04x ) ' % j) + width_line) + print('') + print('( font data, 2x2 tiles )') + for line in lines: + print(line) + +def usage(message=None): + if message: + print('ERROR: %s' % message) + print('') + print('USAGE: %s PATH START' % sys.argv[0]) + print('') + print(' PATH is a hex file, e.g. /usr/share/unifont/unifont.hex') + print(' START is a code point in hex, e.g. 0, 3c0, 7f00, etc.') + print('') + print(' each .uf2 file contains 256 characters, so the output') + print(' will contains widths and data for all characters from') + print(' START to START+255 (inclusive).') + print('') + sys.exit(1) + +def main(): + args = sys.argv[1:] + if len(args) != 2: + return usage() + path, start = args + if not os.path.exists(path): + return usage('could not read .hex file: %s' % path) + + try: + n = int(start, 16) + except: + return usage('could not parse start character: %s' % start) + + if n < 0: + return usage('start must be >= 0: %s' % start) + if n > 65280: + return usage('start must be <= ff00: %s' % start) + + run(path, n) + +if __name__ == "__main__": + main()