1 #!/usr/bin/env python 2 3 """ 4 Convert GNU Unifont format definitions into data statements for GNU as. 5 6 Copyright (C) 2017 Paul Boddie <paul@boddie.org.uk> 7 8 This program is free software; you can redistribute it and/or modify it under 9 the terms of the GNU General Public License as published by the Free Software 10 Foundation; either version 3 of the License, or (at your option) any later 11 version. 12 13 This program is distributed in the hope that it will be useful, but WITHOUT ANY 14 WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A 15 PARTICULAR PURPOSE. See the GNU General Public License for more details. 16 17 You should have received a copy of the GNU General Public License along 18 with this program. If not, see <http://www.gnu.org/licenses/>. 19 """ 20 21 from os.path import split 22 import sys 23 24 def convert_font(fin, fout, points, missing=32): 25 26 """ 27 Convert the font obtained via 'fin' to an assembly language representation, 28 writing to 'fout' the characters for the chosen sequence of 'points'. 29 30 A table of offsets is written to permit each character to be found in the 31 generated data. 32 33 If 'missing' is specified, the character of the given value will be used 34 for missing character data. 35 """ 36 37 points.sort() 38 base = points[0] 39 limit = points[-1] 40 41 # Store the offset of each chosen character. 42 43 table = [] 44 offset = 0 45 46 # Search for each character until no more remain to be found. 47 48 index = 0 49 end = len(points) 50 51 print >>fout, """\ 52 .globl fontchars 53 .globl fonttable 54 .globl fontbase 55 .globl fontlimit 56 57 .section .flash, "a" 58 59 fontchars:""" 60 61 line = fin.readline() 62 63 while line and index < end: 64 65 # Obtain the code point and data. 66 67 point, data = line.rstrip().split(":") 68 point = int(point, 16) 69 70 # Add null offsets for missing characters. 71 72 i = len(table) + base 73 while i < point: 74 table.append(None) 75 i += 1 76 77 # Add a null offset for unselected characters. 78 79 if point < points[index]: 80 if point >= base: 81 table.append(None) 82 line = fin.readline() 83 continue 84 85 # Obtain the byte values from the data. 86 87 bytes = [] 88 i = 0 89 while i < len(data): 90 bytes.append("0x%s" % data[i:i+2]) 91 i += 2 92 93 # Add an offset for the character. 94 95 table.append(offset) 96 offset += len(bytes) 97 98 # Write the character details. 99 100 print >>fout, "/* %s */" % point 101 print >>fout, ".byte", ", ".join(bytes) 102 103 index += 1 104 line = fin.readline() 105 106 # Add a final offset to mark the end of the data. 107 108 table.append(offset) 109 110 # Write the offset table. 111 112 print >>fout, """ 113 fonttable:""" 114 115 for offset in table: 116 if offset is None: 117 offset = table[missing - base] 118 print >>fout, ".word %d" % offset 119 120 print >>fout, """ 121 fontbase: 122 .byte %d 123 124 fontlimit: 125 .byte %d""" % (base, limit) 126 127 # Main program. 128 129 if __name__ == "__main__": 130 131 # Test options. 132 133 if "--help" in sys.argv or len(sys.argv) < 3: 134 basename = split(sys.argv[0])[1] 135 print >>sys.stderr, """\ 136 Usage: 137 138 %s <input filename> <output filename> 139 """ % basename 140 sys.exit(1) 141 142 base = 32 143 points = range(32, 127) 144 145 input_filename, output_filename = sys.argv[1:3] 146 fin = open(input_filename) 147 fout = open(output_filename, "w") 148 try: 149 convert_font(fin, fout, points, base) 150 finally: 151 fin.close() 152 fout.close() 153 154 # vim: tabstop=4 expandtab shiftwidth=4