def test_property_quoting(self): """ Test that property values are quoted properly. """ self.font["AN_INTEGER"] = 42 self.font["A_STRING"] = "42" self.font["STRING_WITH_QUOTES"] = 'Neville "The Banker" Robinson' stream = StringIO() writer.write_bdf(self.font, stream) self.failUnlessEqual(stream.getvalue(), "STARTFONT 2.1\n" "FONT TestFont\n" "SIZE 12 100 100\n" "FONTBOUNDINGBOX 0 0 0 0\n" "STARTPROPERTIES 10\n" "AN_INTEGER 42\n" "A_STRING \"42\"\n" "FACE_NAME \"TestFont\"\n" "FONT_ASCENT 0\n" "FONT_DESCENT 0\n" "PIXEL_SIZE 17\n" "POINT_SIZE 120\n" "RESOLUTION_X 100\n" "RESOLUTION_Y 100\n" "STRING_WITH_QUOTES \"Neville \"\"The Banker\"\" Robinson\"\n" "ENDPROPERTIES\n" "CHARS 0\n" "ENDFONT\n" )
def writeBDF(self, name, fn): from bdflib import model, writer f = model.Font(name, 64, 96,96) for letter in self._data: f.new_glyph_from_data(letter, self.getBDFGlyphData(letter), 0, 0, self._width, self._height, 0, ord(letter)) if letter == letter.lower(): continue letter = letter.lower() f.new_glyph_from_data(letter, self.getBDFGlyphData(letter.upper()), 0, 0, self._width, self._height, 0, ord(letter)) fp = open(fn, "w") writer.write_bdf(f, fp) fp.close()
def test_default_char_setting(self): """ If a default char is explicitly set, it should be used. """ self.font.new_glyph_from_data("TestGlyph1", ["4", "8"], 0,0, 2,2, 3, 1) self.font.new_glyph_from_data("TestGlyph2", ["8", "4"], 0,0, 2,2, 3, 0xFFFD) self.font["DEFAULT_CHAR"] = 0xFFFD stream = StringIO() writer.write_bdf(self.font, stream) self.failUnlessEqual(stream.getvalue(), "STARTFONT 2.1\n" "FONT TestFont\n" "SIZE 12 100 100\n" "FONTBOUNDINGBOX 2 2 0 0\n" "STARTPROPERTIES 8\n" "DEFAULT_CHAR 65533\n" "FACE_NAME \"TestFont\"\n" "FONT_ASCENT 2\n" "FONT_DESCENT 0\n" "PIXEL_SIZE 17\n" "POINT_SIZE 120\n" "RESOLUTION_X 100\n" "RESOLUTION_Y 100\n" "ENDPROPERTIES\n" "CHARS 2\n" "STARTCHAR TestGlyph1\n" "ENCODING 1\n" "SWIDTH 176 0\n" "DWIDTH 3 0\n" "BBX 2 2 0 0\n" "BITMAP\n" "40\n" "80\n" "ENDCHAR\n" "STARTCHAR TestGlyph2\n" "ENCODING 65533\n" "SWIDTH 176 0\n" "DWIDTH 3 0\n" "BBX 2 2 0 0\n" "BITMAP\n" "80\n" "40\n" "ENDCHAR\n" "ENDFONT\n" )
def test_bounding_box_calculations(self): """ FONTBOUNDINGBOX should be calculated from individual glyphs. """ self.font.new_glyph_from_data("TestGlyph1", ["4", "8"], 1,3, 2,2, 3, 1) self.font.new_glyph_from_data("TestGlyph2", ["4", "8"], -5,-7, 2,2, 1, 2) stream = StringIO() writer.write_bdf(self.font, stream) self.failUnlessEqual(stream.getvalue(), "STARTFONT 2.1\n" "FONT TestFont\n" "SIZE 12 100 100\n" "FONTBOUNDINGBOX 8 12 -5 -7\n" "STARTPROPERTIES 8\n" "DEFAULT_CHAR 2\n" "FACE_NAME \"TestFont\"\n" "FONT_ASCENT 5\n" "FONT_DESCENT 7\n" "PIXEL_SIZE 17\n" "POINT_SIZE 120\n" "RESOLUTION_X 100\n" "RESOLUTION_Y 100\n" "ENDPROPERTIES\n" "CHARS 2\n" "STARTCHAR TestGlyph1\n" "ENCODING 1\n" "SWIDTH 176 0\n" "DWIDTH 3 0\n" "BBX 2 2 1 3\n" "BITMAP\n" "40\n" "80\n" "ENDCHAR\n" "STARTCHAR TestGlyph2\n" "ENCODING 2\n" "SWIDTH 58 0\n" "DWIDTH 1 0\n" "BBX 2 2 -5 -7\n" "BITMAP\n" "40\n" "80\n" "ENDCHAR\n" "ENDFONT\n" )
def test_resolution_calculations(self): """ The pixel size should be correctly calculated from the point size. """ tests = [ (12, 72, 12), (12, 100, 17), (12.2, 100, 17), (12, 144, 24), ] for pointSz, res, pixelSz in tests: deci_pointSz = int(pointSz * 10) font = model.Font("TestFont", pointSz, res, res) stream = StringIO() writer.write_bdf(font, stream) self.failUnlessEqual(stream.getvalue(), "STARTFONT 2.1\n" "FONT TestFont\n" "SIZE %(pointSz)g %(res)d %(res)d\n" "FONTBOUNDINGBOX 0 0 0 0\n" "STARTPROPERTIES 7\n" "FACE_NAME \"TestFont\"\n" "FONT_ASCENT 0\n" "FONT_DESCENT 0\n" "PIXEL_SIZE %(pixelSz)d\n" "POINT_SIZE %(deci_pointSz)d\n" "RESOLUTION_X %(res)s\n" "RESOLUTION_Y %(res)s\n" "ENDPROPERTIES\n" "CHARS 0\n" "ENDFONT\n" % locals() )
def test_empty_font(self): """ We should be able to write an empty font. """ stream = StringIO() writer.write_bdf(self.font, stream) self.failUnlessEqual(stream.getvalue(), "STARTFONT 2.1\n" "FONT TestFont\n" "SIZE 12 100 100\n" "FONTBOUNDINGBOX 0 0 0 0\n" "STARTPROPERTIES 7\n" "FACE_NAME \"TestFont\"\n" "FONT_ASCENT 0\n" "FONT_DESCENT 0\n" "PIXEL_SIZE 17\n" "POINT_SIZE 120\n" "RESOLUTION_X 100\n" "RESOLUTION_Y 100\n" "ENDPROPERTIES\n" "CHARS 0\n" "ENDFONT\n" )
def test_basic_writing(self): """ Writing out a simple font should work. """ self.font.new_glyph_from_data("TestGlyph", ["4", "8"], 0,0, 2,2, 3, 1) stream = StringIO() writer.write_bdf(self.font, stream) self.failUnlessEqual(stream.getvalue(), "STARTFONT 2.1\n" "FONT TestFont\n" "SIZE 12 100 100\n" "FONTBOUNDINGBOX 2 2 0 0\n" "STARTPROPERTIES 8\n" "DEFAULT_CHAR 1\n" "FACE_NAME \"TestFont\"\n" "FONT_ASCENT 2\n" "FONT_DESCENT 0\n" "PIXEL_SIZE 17\n" "POINT_SIZE 120\n" "RESOLUTION_X 100\n" "RESOLUTION_Y 100\n" "ENDPROPERTIES\n" "CHARS 1\n" "STARTCHAR TestGlyph\n" "ENCODING 1\n" "SWIDTH 176 0\n" "DWIDTH 3 0\n" "BBX 2 2 0 0\n" "BITMAP\n" "40\n" "80\n" "ENDCHAR\n" "ENDFONT\n" )
def dump(self, out): from bdflib.writer import write_bdf write_bdf(self.fnt, out)
# get the bits in each line glh = int(gl, 16) bits = bin(glh)[2:] double_bits = [] for bit in bits: # output two bits for each bit in the line double_bits.append(bit) double_bits.append(bit) double_bits = ''.join(double_bits) double_glh = int(double_bits, 2) double_gl = hex(double_glh)[2:].upper() # must 0-pad to two times the length of the original lines double_gl = "0" * (len(gl) * 2 - len(double_gl)) + double_gl # output the line two times ret.append(double_gl) ret.append(double_gl) return ret bdf = reader.read_bdf(sys.stdin) double_bdf = model.Font(bdf['FACE_NAME'], bdf['POINT_SIZE'], bdf['RESOLUTION_X'], bdf['RESOLUTION_Y']) for g in bdf.glyphs_by_codepoint.values(): double_bdf.new_glyph_from_data(g.name, double_glyph_data(g.get_data()), g.bbX * 2, g.bbY * 2, g.bbW * 2, g.bbH * 2, g.advance * 2, g.codepoint) writer.write_bdf(double_bdf, sys.stdout)
im = Image.new("1", (w, h), 0) draw = ImageDraw.Draw(im) for l in range(0,2): for c in range(0,2): x1 = c + l * 4; draw.line([(x1 + w0, 0), (x1, w0), (x1 + w0, w0 * 2)], fill = 1) return im t = font[asc(':')] defines += image_to_glyph('BACK', back(t.bbH), '^','a') #------------------------------------------------------------------------------ # write font fontname = fontname + mode[0] filename = "%s.bdf" % fontname with io.open(filename, 'wb') as file: writer.write_bdf(font, file) file.close() #------------------------------------------------------------------------------ # export to u8g #load bdf2u8g cmd_file = 'bdf2u8g.exe' urllib.urlretrieve ('https://github.com/olikraus/u8glib/raw/master/tools/font/bdf2u8g/bdf2u8g.exe', cmd_file) if platform.system() != 'Windows': cmd_file = 'wine ' + cmd_file if mode == 'numeric': begin = asc('.') end = asc('9')
draw = ImageDraw.Draw(im) for l in range(0, 2): for c in range(0, 2): x1 = c + l * 4 draw.line([(x1 + w0, 0), (x1, w0), (x1 + w0, w0 * 2)], fill=1) return im t = font[asc(':')] defines += image_to_glyph('BACK', back(t.bbH), '^', 'a') #------------------------------------------------------------------------------ # write font fontname = fontname + mode[0] filename = "%s.bdf" % fontname with io.open(filename, 'wb') as file: writer.write_bdf(font, file) file.close() #------------------------------------------------------------------------------ # export to u8g #load bdf2u8g cmd_file = 'bdf2u8g.exe' urllib.urlretrieve( 'https://github.com/olikraus/u8glib/raw/master/tools/font/bdf2u8g/bdf2u8g.exe', cmd_file) if platform.system() != 'Windows': cmd_file = 'wine ' + cmd_file if mode == 'numeric':
def main(): parser = argparse.ArgumentParser( description='Generates a BDF from a file of raw binary font data ' 'and a character mapping.') parser.add_argument('-cw', '--width', type=int, default=12, help='character width (default: %(default)d)') parser.add_argument('-ch', '--height', type=int, default=18, help='character height (default: %(default)d)') parser.add_argument('-cd', '--descent', type=int, default=-2, help='character descent (default: %(default)d)') parser.add_argument('-o', '--output', help='output file (default: stdout)') parser.add_argument('-n', '--name', help='font name to use for generated font. ' 'By default, auto-derived from the name ' 'of binfile.') parser.add_argument('binfile', help='file containing binary font data') parser.add_argument('mapfile', help='file containing character map. Each line ' 'identifies the hex value of the corresponding ' 'character, optionally followed by whitespace ' 'and a comment.') args = parser.parse_args() with open(args.binfile, 'rb') as fp: data = fp.read() with open(args.mapfile, 'r') as fp: mapping = [int(line.strip().split()[0], 16) for line in fp] fontname = os.path.splitext(os.path.basename(args.binfile))[0] \ if args.name is None else args.name char_width = args.width char_byte_width = (char_width+7)//8 char_height = args.height char_length = char_byte_width * char_height char_descent = args.descent num_chars = len(data) // char_length font = Font(fontname, char_height, 72, 72) for glyph_num in range(num_chars): if glyph_num >= len(mapping): break glyph_cp = mapping[glyph_num] if glyph_cp == 0: continue glyph_start = glyph_num*char_length rows = [] for row in range(char_height): row_start = glyph_start + char_byte_width * row row_data = data[row_start:row_start+char_byte_width] rows.append(binascii.hexlify(row_data)) if glyph_cp <= 0xFFFF: glyph_name = 'uni{0:04x}'.format(glyph_cp) else: glyph_name = 'U+{0:x}'.format(glyph_cp) font.new_glyph_from_data( name=glyph_name, codepoint=glyph_cp, data=rows, bbX=0, bbY=char_descent, bbW=char_width, bbH=char_height, advance=char_width) if args.output: fp = open(args.output, 'w') else: fp = sys.stdout writer.write_bdf(font, fp) if fp != sys.stdout: fp.close()
def _translate(data, dxdy): dx, dy = dxdy if dx > 0: data = [row >> dx for row in data] if dx < 0: data = [row << -dx for row in data] if dy > 0: dy -= len(data) if dy < 0: data = data[-dy:] + data[:-dy] return data if __name__ == '__main__': with open(sys.argv[1]) as f: bdf = reader.read_bdf(f) out = model.Font('vertical', bdf['POINT_SIZE'], bdf['RESOLUTION_X'], bdf['RESOLUTION_Y']) for cp in bdf.codepoints(): vg = vertical_glyph(bdf[cp]) if vg is None: continue out.glyphs.append(vg) out.glyphs_by_codepoint[cp] = vg writer.write_bdf(out, sys.stdout)