kopia lustrzana https://github.com/peterhinch/micropython-font-to-py
font_to_py.py 1st pass at BDF and PCF support.
rodzic
081ef12d90
commit
0b253aa68a
|
@ -260,7 +260,7 @@ class Glyph(object):
|
||||||
# height (in pixels) of all characters
|
# height (in pixels) of all characters
|
||||||
# width (in pixels) for monospaced output (advance width of widest char)
|
# width (in pixels) for monospaced output (advance width of widest char)
|
||||||
class Font(dict):
|
class Font(dict):
|
||||||
def __init__(self, filename, size, minchar, maxchar, monospaced, defchar, charset):
|
def __init__(self, filename, size, minchar, maxchar, monospaced, defchar, charset, bitmapped):
|
||||||
super().__init__()
|
super().__init__()
|
||||||
self._face = freetype.Face(filename)
|
self._face = freetype.Face(filename)
|
||||||
# .crange is the inclusive range of ordinal values spanning the character set.
|
# .crange is the inclusive range of ordinal values spanning the character set.
|
||||||
|
@ -283,10 +283,35 @@ class Font(dict):
|
||||||
self.charset = [chr(defchar)] + cs
|
self.charset = [chr(defchar)] + cs
|
||||||
# Populate self with defined chars only
|
# Populate self with defined chars only
|
||||||
self.update(dict.fromkeys([c for c in self.charset if c]))
|
self.update(dict.fromkeys([c for c in self.charset if c]))
|
||||||
self.max_width = self.get_dimensions(size)
|
self.max_width = self.bmp_dimensions(size) if bitmapped else self.get_dimensions(size)
|
||||||
self.width = self.max_width if monospaced else 0
|
self.width = self.max_width if monospaced else 0
|
||||||
self._assign_values() # Assign values to existing keys
|
self._assign_values() # Assign values to existing keys
|
||||||
|
|
||||||
|
def bmp_dimensions(self, height):
|
||||||
|
#self._face.set_pixel_sizes(0, height) # TODO fails with PCF file: invalid pixel size
|
||||||
|
max_descent = 0
|
||||||
|
# For each character in the charset string we get the glyph
|
||||||
|
# and update the overall dimensions of the resulting bitmap.
|
||||||
|
max_width = 0
|
||||||
|
max_ascent = 0
|
||||||
|
for char in self.keys():
|
||||||
|
glyph = self._glyph_for_character(char)
|
||||||
|
max_ascent = max(max_ascent, glyph.ascent)
|
||||||
|
max_descent = max(max_descent, glyph.descent)
|
||||||
|
# for a few chars e.g. _ glyph.width > glyph.advance_width
|
||||||
|
max_width = int(max(max_width, glyph.advance_width,
|
||||||
|
glyph.width))
|
||||||
|
|
||||||
|
self.height = int(max_ascent + max_descent)
|
||||||
|
self._max_ascent = int(max_ascent)
|
||||||
|
self._max_descent = int(max_descent)
|
||||||
|
print('Requested height', height)
|
||||||
|
print('Actual height', self.height)
|
||||||
|
print('Max width', max_width)
|
||||||
|
print('Max descent', self._max_descent)
|
||||||
|
print('Max ascent', self._max_ascent)
|
||||||
|
return max_width
|
||||||
|
|
||||||
# n-pass solution to setting a precise height.
|
# n-pass solution to setting a precise height.
|
||||||
def get_dimensions(self, required_height):
|
def get_dimensions(self, required_height):
|
||||||
error = 0
|
error = 0
|
||||||
|
@ -468,9 +493,11 @@ def glyphs():
|
||||||
def write_func(stream, name, arg):
|
def write_func(stream, name, arg):
|
||||||
stream.write('def {}():\n return {}\n\n'.format(name, arg))
|
stream.write('def {}():\n return {}\n\n'.format(name, arg))
|
||||||
|
|
||||||
def write_font(op_path, font_path, height, monospaced, hmap, reverse, minchar, maxchar, defchar, charset, iterate):
|
def write_font(op_path, font_path, height, monospaced, hmap, reverse, minchar,
|
||||||
|
maxchar, defchar, charset, iterate, bitmapped):
|
||||||
|
# fnt = Font(font_path, height, minchar, maxchar, monospaced, defchar, charset, bitmapped)
|
||||||
try:
|
try:
|
||||||
fnt = Font(font_path, height, minchar, maxchar, monospaced, defchar, charset)
|
fnt = Font(font_path, height, minchar, maxchar, monospaced, defchar, charset, bitmapped)
|
||||||
except freetype.ft_errors.FT_Exception:
|
except freetype.ft_errors.FT_Exception:
|
||||||
print("Can't open", font_path)
|
print("Can't open", font_path)
|
||||||
return False
|
return False
|
||||||
|
@ -618,7 +645,7 @@ if __name__ == "__main__":
|
||||||
if not os.path.isfile(args.infile):
|
if not os.path.isfile(args.infile):
|
||||||
quit("Font filename does not exist")
|
quit("Font filename does not exist")
|
||||||
|
|
||||||
if not os.path.splitext(args.infile)[1].upper() in ('.TTF', '.OTF'):
|
if not os.path.splitext(args.infile)[1].upper() in ('.TTF', '.OTF', '.BDF', '.PCF'):
|
||||||
quit("Font file should be a ttf or otf file.")
|
quit("Font file should be a ttf or otf file.")
|
||||||
|
|
||||||
if args.binary:
|
if args.binary:
|
||||||
|
@ -663,10 +690,18 @@ if __name__ == "__main__":
|
||||||
cs = {c for c in cset if c.isprintable() or (0xE000 <= ord(c) <= 0xF8FF) } - {args.errchar}
|
cs = {c for c in cset if c.isprintable() or (0xE000 <= ord(c) <= 0xF8FF) } - {args.errchar}
|
||||||
cs = sorted(list(cs))
|
cs = sorted(list(cs))
|
||||||
cset = ''.join(cs) # Back to string
|
cset = ''.join(cs) # Back to string
|
||||||
|
bitmapped = os.path.splitext(args.infile)[1].upper() in ('.BDF', '.PCF')
|
||||||
|
if bitmapped:
|
||||||
|
if args.height != 0:
|
||||||
|
print('Warning: height arg ignored for bitmapped fonts.')
|
||||||
|
chkface = freetype.Face(args.infile)
|
||||||
|
args.height = chkface._get_available_sizes()[0].height
|
||||||
|
print("Found font with size " + str(args.height))
|
||||||
|
|
||||||
print('Writing Python font file.')
|
print('Writing Python font file.')
|
||||||
if not write_font(args.outfile, args.infile, args.height, args.fixed,
|
if not write_font(args.outfile, args.infile, args.height, args.fixed,
|
||||||
args.xmap, args.reverse, args.smallest, args.largest,
|
args.xmap, args.reverse, args.smallest, args.largest,
|
||||||
args.errchar, cset, args.iterate):
|
args.errchar, cset, args.iterate, bitmapped):
|
||||||
sys.exit(1)
|
sys.exit(1)
|
||||||
|
|
||||||
print(args.outfile, 'written successfully.')
|
print(args.outfile, 'written successfully.')
|
||||||
|
|
Ładowanie…
Reference in New Issue