#!/usr/bin/env python # Creates C program data files for each ttf file given on the command # line. Also a C header file is generated. The C files are compiled # using gcc and archived into a large library using gnu ar, the final # result can be linked with pcl. DEVELOPERS ONLY. # This program does not do any error checking, clean up data files or # anything that might be construed as user friendly - please use with # caution. # ./makeromttf.py /windows/fonts/*.ttf FILTER_NONE=0 FILTER_ZLIB=1 FILTER_GZIP=2 import tempfile, os, zlib def font_filter(ttfont, filter): if (filter == FILTER_NONE): return ttfont if (filter == FILTER_ZLIB): return zlib.compress(ttfont) if (filter == FILTER_GZIP): outfile=tempfile.mktemp() infile=tempfile.mktemp() open(infile, "wb").write(ttfont) command="gzip -c < %s > %s" % (infile, outfile) os.system(command) filtered_font=open(outfile, "rb").read() os.remove(outfile) os.remove(infile) return filtered_font return None import struct def find_table(ttfont, table_name): # index error not handled. num_tables = struct.unpack(">H", ttfont[4:6])[0] for table in range(num_tables): this_table_offset= 12 + (table * 16) if (ttfont[this_table_offset:this_table_offset+len(table_name)] == table_name): table_length = struct.unpack(">L", ttfont[this_table_offset+12:this_table_offset+16])[0] table_offset = struct.unpack(">L", ttfont[this_table_offset+8:this_table_offset+12])[0] return ttfont[table_offset:table_offset+table_length] return None def get_name(ttfont): name_table = find_table(ttfont, "name") if (name_table): storageOffset = struct.unpack(">H", name_table[4:6])[0] name_recs = name_table[6:] windows_name_len = struct.unpack(">H", name_recs[12*4+8:12*4+10])[0]; windows_name_offset = struct.unpack(">H", name_recs[12*4+10:12*4+12])[0]; # at last windows_name = name_table[storageOffset+windows_name_offset:storageOffset+windows_name_offset+windows_name_len] return_string = "" for ch in windows_name: if (ord(ch) in range(32, 127)): return_string += ch return return_string return None if __name__ == '__main__': import sys, os, tempfile if not sys.argv[1:]: print "Usage: %s pxl files" % sys.argv[0] files = sys.argv[1:] font_table_dict = {} font_cfile_name = {} for file in files: try: fp = open(file, 'rb') except: print "Cannot find file %s" % file continue # read the whole damn thing. If this get too cumbersome we # can switch to string i/o which will use a disk ttfont = fp.read() fp.close() font_name = get_name(ttfont) c_file = os.path.basename(file) + ".c" fp = open(c_file, 'wb') # no spaces in C variables. variable_name = font_name.replace(' ', '_') tmp_str = "const unsigned char " + variable_name + "[] = {\n" fp.write(tmp_str) # 6 dummy bytes tmp_str = "%c%c%c%c%c%c" % (0, 0, 0, 0, 0, 0) ttfont = tmp_str + ttfont for byte in font_filter(ttfont, FILTER_ZLIB): array_entry = "%d," % ord(byte) fp.write(array_entry) tmp_str = '};\n' fp.write(tmp_str) font_table_dict[variable_name] = font_name font_cfile_name[variable_name] = c_file fp.close() # Generate a header file with externs for each font print "put romfnttab.h and libttffont.a in the pl directory" fp = open("romfnttab.h", 'wb') # write out the externs for k in font_table_dict.keys(): tmp_str = "extern const unsigned char " + k + ";\n" fp.write(tmp_str) tmp_str = """typedef struct pcl_font_variable_name { const char font_name[40]; const unsigned char *data; } pcl_font_variable_name_t; const pcl_font_variable_name_t pcl_font_variable_name_table[] = {""" fp.write(tmp_str) # build the table for k in font_table_dict.keys(): fp.write("{\n") # font name tmp_str = "\"" + font_table_dict[k] + "\"," fp.write(tmp_str) tmp_str = "&" + k + "}," fp.write(tmp_str) # table terminator fp.write("{\"\", 0}};\n") fp.close() # compile the code for k in font_cfile_name.keys(): os.system("gcc -c " + font_cfile_name[k]); # archive the objects object_names = "" for k in font_cfile_name.keys(): object_names = object_names + font_cfile_name[k][:-1] + 'o' + " " os.system("rm libttffont.a") os.system("ar rcv libttffont.a " + object_names)