109 lines
2.9 KiB
Plaintext
109 lines
2.9 KiB
Plaintext
|
#!/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()
|