kopia lustrzana https://github.com/peterhinch/micropython-font-to-py
Add --iterate argument.
rodzic
6eb8adb31c
commit
793c805f4f
|
@ -56,6 +56,7 @@ Example usage to produce a file `myfont.py` with height of 23 pixels:
|
||||||
* -l or --largest Ordinal value of largest character to be stored. Default 126.
|
* -l or --largest Ordinal value of largest character to be stored. Default 126.
|
||||||
* -e or --errchar Ordinal value of character to be rendered if an attempt is
|
* -e or --errchar Ordinal value of character to be rendered if an attempt is
|
||||||
made to display an out-of-range character. Default 63 (ASCII "?").
|
made to display an out-of-range character. Default 63 (ASCII "?").
|
||||||
|
* -i or --iterate Specialist use. See below.
|
||||||
* -c or --charset Option to restrict the characters in the font to a specific
|
* -c or --charset Option to restrict the characters in the font to a specific
|
||||||
set. See below.
|
set. See below.
|
||||||
* -k or --charset_file Obtain the character set from a file. Typical use is
|
* -k or --charset_file Obtain the character set from a file. Typical use is
|
||||||
|
@ -85,6 +86,11 @@ value > 127) from ttf files is unreliable. If the expected results are not
|
||||||
achieved, use an otf font. However I have successfully created the Cyrillic
|
achieved, use an otf font. However I have successfully created the Cyrillic
|
||||||
font from a `ttf`. Perhaps not all fonts are created equal...
|
font from a `ttf`. Perhaps not all fonts are created equal...
|
||||||
|
|
||||||
|
The `-i` or `--iterate` argument. For specialist applications. Specifying this
|
||||||
|
causes a generator function `glyphs` to be included in the Python font file. A
|
||||||
|
generator instantiated with this will yield `bitmap`, `height`, and `width` for
|
||||||
|
every glyph in the font.
|
||||||
|
|
||||||
### Output
|
### Output
|
||||||
|
|
||||||
The specified height is a target. The algorithm gets as close to the target
|
The specified height is a target. The algorithm gets as close to the target
|
||||||
|
|
|
@ -261,6 +261,7 @@ class Font(dict):
|
||||||
self.minchar = minchar
|
self.minchar = minchar
|
||||||
self.maxchar = maxchar
|
self.maxchar = maxchar
|
||||||
self.monospaced = monospaced
|
self.monospaced = monospaced
|
||||||
|
self.defchar = defchar
|
||||||
# .def_charset is requested charset or '' if -c was not specified
|
# .def_charset is requested charset or '' if -c was not specified
|
||||||
self.def_charset = charset
|
self.def_charset = charset
|
||||||
# .charset has all defined characters with '' for those in range but undefined.
|
# .charset has all defined characters with '' for those in range but undefined.
|
||||||
|
@ -369,7 +370,7 @@ class Font(dict):
|
||||||
|
|
||||||
STR01 = """# Code generated by font-to-py.py.
|
STR01 = """# Code generated by font-to-py.py.
|
||||||
# Font: {}{}
|
# Font: {}{}
|
||||||
version = '0.25'
|
version = '0.26'
|
||||||
"""
|
"""
|
||||||
|
|
||||||
STR02 = """_mvfont = memoryview(_font)
|
STR02 = """_mvfont = memoryview(_font)
|
||||||
|
@ -390,7 +391,7 @@ def write_func(stream, name, arg):
|
||||||
|
|
||||||
# filename, size, minchar=32, maxchar=126, monospaced=False, defchar=ord('?'):
|
# filename, size, minchar=32, maxchar=126, monospaced=False, defchar=ord('?'):
|
||||||
|
|
||||||
def write_font(op_path, font_path, height, monospaced, hmap, reverse, minchar, maxchar, defchar, charset):
|
def write_font(op_path, font_path, height, monospaced, hmap, reverse, minchar, maxchar, defchar, charset, iterate):
|
||||||
try:
|
try:
|
||||||
fnt = Font(font_path, height, minchar, maxchar, monospaced, defchar, charset)
|
fnt = Font(font_path, height, minchar, maxchar, monospaced, defchar, charset)
|
||||||
except freetype.ft_errors.FT_Exception:
|
except freetype.ft_errors.FT_Exception:
|
||||||
|
@ -398,17 +399,24 @@ def write_font(op_path, font_path, height, monospaced, hmap, reverse, minchar, m
|
||||||
return False
|
return False
|
||||||
try:
|
try:
|
||||||
with open(op_path, 'w') as stream:
|
with open(op_path, 'w') as stream:
|
||||||
write_data(stream, fnt, font_path, hmap, reverse)
|
write_data(stream, fnt, font_path, hmap, reverse, iterate)
|
||||||
except OSError:
|
except OSError:
|
||||||
print("Can't open", op_path, 'for writing')
|
print("Can't open", op_path, 'for writing')
|
||||||
return False
|
return False
|
||||||
return True
|
return True
|
||||||
|
|
||||||
|
STR03 = '''
|
||||||
|
def glyphs():
|
||||||
|
for c in """{}""":
|
||||||
|
yield c, get_ch(c)
|
||||||
|
|
||||||
def write_data(stream, fnt, font_path, hmap, reverse):
|
'''
|
||||||
|
|
||||||
|
def write_data(stream, fnt, font_path, hmap, reverse, iterate):
|
||||||
height = fnt.height # Actual height, not target height
|
height = fnt.height # Actual height, not target height
|
||||||
minchar = fnt.minchar
|
minchar = fnt.minchar
|
||||||
maxchar = fnt.maxchar
|
maxchar = fnt.maxchar
|
||||||
|
defchar = fnt.defchar
|
||||||
charset = fnt.def_charset
|
charset = fnt.def_charset
|
||||||
st = '' if charset == '' else ' Char set: {}'.format(charset)
|
st = '' if charset == '' else ' Char set: {}'.format(charset)
|
||||||
stream.write(STR01.format(os.path.split(font_path)[1], st))
|
stream.write(STR01.format(os.path.split(font_path)[1], st))
|
||||||
|
@ -420,6 +428,8 @@ def write_data(stream, fnt, font_path, hmap, reverse):
|
||||||
write_func(stream, 'monospaced', fnt.monospaced)
|
write_func(stream, 'monospaced', fnt.monospaced)
|
||||||
write_func(stream, 'min_ch', minchar)
|
write_func(stream, 'min_ch', minchar)
|
||||||
write_func(stream, 'max_ch', maxchar)
|
write_func(stream, 'max_ch', maxchar)
|
||||||
|
if iterate:
|
||||||
|
stream.write(STR03.format(''.join(fnt.pop_charset)))
|
||||||
data, index = fnt.build_arrays(hmap, reverse)
|
data, index = fnt.build_arrays(hmap, reverse)
|
||||||
bw_font = ByteWriter(stream, '_font')
|
bw_font = ByteWriter(stream, '_font')
|
||||||
bw_font.odata(data)
|
bw_font.odata(data)
|
||||||
|
@ -427,7 +437,7 @@ def write_data(stream, fnt, font_path, hmap, reverse):
|
||||||
bw_index = ByteWriter(stream, '_index')
|
bw_index = ByteWriter(stream, '_index')
|
||||||
bw_index.odata(index)
|
bw_index.odata(index)
|
||||||
bw_index.eot()
|
bw_index.eot()
|
||||||
stream.write(STR02.format(minchar, maxchar, minchar, minchar, height))
|
stream.write(STR02.format(minchar, maxchar, defchar, minchar, height))
|
||||||
|
|
||||||
# BINARY OUTPUT
|
# BINARY OUTPUT
|
||||||
# hmap reverse magic bytes
|
# hmap reverse magic bytes
|
||||||
|
@ -493,6 +503,8 @@ if __name__ == "__main__":
|
||||||
help='Fixed width (monospaced) font')
|
help='Fixed width (monospaced) font')
|
||||||
parser.add_argument('-b', '--binary', action='store_true',
|
parser.add_argument('-b', '--binary', action='store_true',
|
||||||
help='Produce binary (random access) font file.')
|
help='Produce binary (random access) font file.')
|
||||||
|
parser.add_argument('-i', '--iterate', action='store_true',
|
||||||
|
help='Include generator function to iterate over character set.')
|
||||||
|
|
||||||
parser.add_argument('-s', '--smallest',
|
parser.add_argument('-s', '--smallest',
|
||||||
type = int,
|
type = int,
|
||||||
|
@ -566,10 +578,13 @@ if __name__ == "__main__":
|
||||||
sys.exit(1)
|
sys.exit(1)
|
||||||
else:
|
else:
|
||||||
cset = args.charset
|
cset = args.charset
|
||||||
|
cs = {c for c in cset if c.isprintable()} - {args.errchar} # dedupe and remove default char
|
||||||
|
cs = sorted(list(cs))
|
||||||
|
cset = ''.join(cs) # Back to string
|
||||||
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.errchar, cset, args.iterate):
|
||||||
sys.exit(1)
|
sys.exit(1)
|
||||||
|
|
||||||
print(args.outfile, 'written successfully.')
|
print(args.outfile, 'written successfully.')
|
||||||
|
|
|
@ -140,7 +140,8 @@ def get_ch(ch):
|
||||||
return mvfont[offset + 2, next_offset], height, width
|
return mvfont[offset + 2, next_offset], height, width
|
||||||
```
|
```
|
||||||
|
|
||||||
`height` and `width` are specified in bits (pixels).
|
`height` and `width` are specified in bits (pixels). See Appendix 1 for extra
|
||||||
|
code in fonts created with the `--iterate` arg.
|
||||||
|
|
||||||
In the case of monospaced fonts the `max_width` function returns the width of
|
In the case of monospaced fonts the `max_width` function returns the width of
|
||||||
every character. For variable pitch fonts it returns the width of the widest
|
every character. For variable pitch fonts it returns the width of the widest
|
||||||
|
@ -235,3 +236,25 @@ Fonts created with the `font_to_py` utility have been extensively tested with
|
||||||
each of the mapping options. They are used with drivers for SSD1306 OLEDs,
|
each of the mapping options. They are used with drivers for SSD1306 OLEDs,
|
||||||
SSD1963 LCD displays, the official LCD160CR and the Digital Artists 2.7 inch
|
SSD1963 LCD displays, the official LCD160CR and the Digital Artists 2.7 inch
|
||||||
e-paper display.
|
e-paper display.
|
||||||
|
|
||||||
|
# Appendix 1. The -i --iterate argument
|
||||||
|
|
||||||
|
This specialist arg causes extra code to be included in the font file, to
|
||||||
|
provide for iterating over all the glyphs in the file. The following sample of
|
||||||
|
the extra code assumes a font comprising '0123456789:'
|
||||||
|
|
||||||
|
```python
|
||||||
|
def glyphs():
|
||||||
|
for c in """0123456789:""":
|
||||||
|
yield c, get_ch(c)
|
||||||
|
```
|
||||||
|
|
||||||
|
Typical usage under CPython 3 (for a font `cyrillic.py`) is
|
||||||
|
|
||||||
|
```python
|
||||||
|
import cyrillic
|
||||||
|
res = []
|
||||||
|
for glyph in cyrillic.glyphs():
|
||||||
|
res.append(list(glyph)) # Each element is [char, glyph, height, width]
|
||||||
|
```
|
||||||
|
|
||||||
|
|
Ładowanie…
Reference in New Issue