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.
|
||||
* -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 "?").
|
||||
* -i or --iterate Specialist use. See below.
|
||||
* -c or --charset Option to restrict the characters in the font to a specific
|
||||
set. See below.
|
||||
* -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
|
||||
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
|
||||
|
||||
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.maxchar = maxchar
|
||||
self.monospaced = monospaced
|
||||
self.defchar = defchar
|
||||
# .def_charset is requested charset or '' if -c was not specified
|
||||
self.def_charset = charset
|
||||
# .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.
|
||||
# Font: {}{}
|
||||
version = '0.25'
|
||||
version = '0.26'
|
||||
"""
|
||||
|
||||
STR02 = """_mvfont = memoryview(_font)
|
||||
|
@ -390,7 +391,7 @@ def write_func(stream, name, arg):
|
|||
|
||||
# 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:
|
||||
fnt = Font(font_path, height, minchar, maxchar, monospaced, defchar, charset)
|
||||
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
|
||||
try:
|
||||
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:
|
||||
print("Can't open", op_path, 'for writing')
|
||||
return False
|
||||
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
|
||||
minchar = fnt.minchar
|
||||
maxchar = fnt.maxchar
|
||||
defchar = fnt.defchar
|
||||
charset = fnt.def_charset
|
||||
st = '' if charset == '' else ' Char set: {}'.format(charset)
|
||||
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, 'min_ch', minchar)
|
||||
write_func(stream, 'max_ch', maxchar)
|
||||
if iterate:
|
||||
stream.write(STR03.format(''.join(fnt.pop_charset)))
|
||||
data, index = fnt.build_arrays(hmap, reverse)
|
||||
bw_font = ByteWriter(stream, '_font')
|
||||
bw_font.odata(data)
|
||||
|
@ -427,7 +437,7 @@ def write_data(stream, fnt, font_path, hmap, reverse):
|
|||
bw_index = ByteWriter(stream, '_index')
|
||||
bw_index.odata(index)
|
||||
bw_index.eot()
|
||||
stream.write(STR02.format(minchar, maxchar, minchar, minchar, height))
|
||||
stream.write(STR02.format(minchar, maxchar, defchar, minchar, height))
|
||||
|
||||
# BINARY OUTPUT
|
||||
# hmap reverse magic bytes
|
||||
|
@ -493,6 +503,8 @@ if __name__ == "__main__":
|
|||
help='Fixed width (monospaced) font')
|
||||
parser.add_argument('-b', '--binary', action='store_true',
|
||||
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',
|
||||
type = int,
|
||||
|
@ -566,10 +578,13 @@ if __name__ == "__main__":
|
|||
sys.exit(1)
|
||||
else:
|
||||
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.')
|
||||
if not write_font(args.outfile, args.infile, args.height, args.fixed,
|
||||
args.xmap, args.reverse, args.smallest, args.largest,
|
||||
args.errchar, cset):
|
||||
args.errchar, cset, args.iterate):
|
||||
sys.exit(1)
|
||||
|
||||
print(args.outfile, 'written successfully.')
|
||||
|
|
|
@ -140,7 +140,8 @@ def get_ch(ch):
|
|||
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
|
||||
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,
|
||||
SSD1963 LCD displays, the official LCD160CR and the Digital Artists 2.7 inch
|
||||
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