#! /usr/bin/env python # # Broytman BDF-to-libGD font convrter, Copyright (C) 1997-2007 PhiloSoft Design # import sys, os from m_lib.opstring import bin, LeftPadCh font_w = 0 font_h = 0 char = None glyphs = {} bbx = None copyright = "" def parse_fontbbx(line): s = line.split() if s[0] == "FONTBOUNDINGBOX": global font_w, font_h, feed font_w = int(s[1]) font_h = int(s[2]) feed = parse_copyright def parse_copyright(line): s = line.split(' ', 1) global feed if s[0] == "COPYRIGHT": global copyright copyright = s[1][:-1] feed = parse_chars elif s[0] == "CHARS": feed = parse_startchar def parse_chars(line): s = line.split() if s[0] == "CHARS": global feed feed = parse_startchar def parse_startchar(line): s = line.split() if s[0] == "STARTCHAR": global feed feed = parse_encoding def parse_encoding(line): s = line.split() if s[0] == "ENCODING": global glyphs, char, feed x = int(s[1]) if x == -1: char = char + 1 else: char = x glyphs[char] = [] feed = parse_bbx def parse_bbx(line): s = line.split() if s[0] == "BBX": global bbx, feed bbx = map(int, tuple(s[1:5])) if bbx[3] < 0: bbx[3] = 0 feed = parse_bitmap def parse_bitmap(line): if line == "BITMAP\n": global feed feed = parse_endchar def parse_endchar(line): if line == "ENDCHAR\n": global feed gen_char() feed = parse_startchar else: # Parse bitmap data global glyphs, char line = line[:-1] x = '' for c in line: x = x + parse_char(c) glyphs[char].append(x) def parse_char(c): h = int(c, 16) s = bin(h) return LeftPadCh(s, '0', 4) def gen_char(): global font_w, font_h, glyphs, char, bbx zero_line = '0'*font_w glyph = [] for i in range(font_h - bbx[1] - bbx[3]): glyph.append(zero_line) #for i in range(font_h - bbx[1] - bbx[3], font_h - bbx[3]): for i in range(bbx[1]): bitmap_data = glyphs[char][i] line = '0'*bbx[2] + bitmap_data[0:bbx[0]] + '0'*(font_w - bbx[0] - bbx[2]) glyph.append(line) for i in range(font_h - bbx[3], font_h): glyph.append(zero_line) #print char, glyph glyphs[char] = glyph def gen_gdfont(fontname, fn, show_pbar): global glyphs, char, bbx outfile = open("gdfont%s.h" % fn, 'w') outfile.write('#ifndef GDFONT%s_H\n' % fn.upper()) outfile.write('#define GDFONT%s_H 1\n\n' % fn.upper()) outfile.write('/* gdfont%s.h */\n\n' % fn) outfile.write('/* This file is generated by */\n') outfile.write('/* Broytman BDF-to-libGD font converter */\n') outfile.write('/* Copyright (C) 1997-2007 PhiloSoft Design */\n\n') outfile.write('/* THIS IS AUTOMATICALLY GENERATED FILE */\n') outfile.write('/* DO NOT EDIT! */\n\n') if copyright: outfile.write('/* Original Font Copyright: %s */\n\n' % copyright) outfile.write('#include "gd.h"\n\n') outfile.write('extern gdFontPtr gdFont%s;\n\n' % fontname) outfile.write('#endif') outfile.close() outfile = open("gdfont%s.c" % fn, 'w') outfile.write('#include "gdfont%s.h"\n\n' % fn) outfile.write('/* This file is generated by */\n') outfile.write('/* Broytman BDF-to-libGD font converter */\n') outfile.write('/* Copyright (C) 1997-2007 PhiloSoft Design */\n\n') outfile.write('/* THIS IS AUTOMATICALLY GENERATED FILE */\n') outfile.write('/* DO NOT EDIT! */\n\n') if copyright: outfile.write('/* Original Font Copyright: %s */\n\n' % copyright) outfile.write('char gdFont%sData[] = {\n\n' % fontname) k = glyphs.keys() min_c = min(k) max_c = max(k) if show_pbar: try: from m_lib.pbar.tty_pbar import ttyProgressBar except ImportError: show_pbar = 0 if show_pbar: pbar = ttyProgressBar(min_c, max_c) for i in range(min_c, max_c+1): if show_pbar: pbar.display(i) if not glyphs.has_key(i): # BDF font did not defined char - define zero-filled box instead char = i bbx = [0, 0, 0, 0] gen_char() if len(glyphs[i]) <> font_h: sys.stderr.write("Wrong number of lines for char %d; expected %d, got %d\n" % (i, font_h, len(glyphs[i]))) outfile.close() os.unlink("gdfont%s.h" % fn) os.unlink("gdfont%s.c" % fn) sys.exit(1) outfile.write("/* Char %d */\n" % i) for line in glyphs[i]: l = len(line) if l < font_w: line = line + '0'*(font_w - l) elif l > font_w: line = line[:font_w] s = '' for c in line: s = s + c + ',' outfile.write(s[:font_w*2] + '\n') outfile.write('\n') if show_pbar: del pbar outfile.write('};\n\n') outfile.write('gdFont gdFont%sRep = {\n' % fontname) outfile.write('\t%d,\n' % (max_c - min_c + 1)) outfile.write('\t%d,\n' % min_c) outfile.write('\t%d,\n' % font_w) outfile.write('\t%d,\n' % font_h) outfile.write('\tgdFont%sData\n' % fontname) outfile.write('};\n\n') outfile.write('gdFontPtr gdFont%s = &gdFont%sRep;\n\n' % (fontname, fontname)) outfile.close() def run(): print "Broytman BDF-to-libGD font converter, Copyright (C) 1997-2007 PhiloSoft Design" if len(sys.argv) == 4: infile = open(sys.argv[1], 'r') fontname = sys.argv[2] fn = sys.argv[3] else: sys.stderr.write("Usage : bdftogd font.bdf FontName fn\n") sys.stderr.write("Example: bdftogd helv.bdf HelveticaBold hb\n") sys.exit(1) show_pbar = sys.stderr.isatty() if show_pbar: try: from m_lib.pbar.tty_pbar import ttyProgressBar except ImportError: show_pbar = 0 lines = infile.readlines() if len(sys.argv) == 2: infile.close() sys.stderr.write("Converting: ") sys.stderr.flush() if show_pbar: pbar = ttyProgressBar(0, len(lines)) global feed feed = parse_fontbbx for i in range(0, len(lines)): if show_pbar: pbar.display(i+1) feed(lines[i]) if show_pbar: del pbar gen_gdfont(fontname, fn, show_pbar) sys.stderr.write("Ok\n") if __name__ == "__main__": run()