kopia lustrzana https://github.com/peterhinch/micropython-font-to-py
Improve docs to clarify frozen bytecode technique.
rodzic
ba3d585162
commit
0d4883fa4e
|
@ -1,6 +1,9 @@
|
|||
# font_to_py.py
|
||||
|
||||
Convert a font file to Python source code.
|
||||
Convert a font file to Python source code. The principal reason for doing this
|
||||
is to save RAM on resource-limited targets: the font file may be incorporated
|
||||
into a firmware build such that it occupies flash memory rather than scarce
|
||||
RAM. Python code built into firmware is known as frozen bytecode.
|
||||
|
||||
# Dependency
|
||||
|
||||
|
@ -14,8 +17,8 @@ at a root prompt:
|
|||
|
||||
# Usage
|
||||
|
||||
``font_to_py.py`` is a command line utility written in Python 3. It is run on a
|
||||
PC. It takes as input a font file with a ``ttf`` or ``otf`` extension and a
|
||||
`font_to_py.py` is a command line utility written in Python 3. It is run on a
|
||||
PC. It takes as input a font file with a `ttf` or `otf` extension and a
|
||||
required height in pixels and outputs a Python 3 source file. The pixel layout
|
||||
is determined by command arguments. By default fonts are stored in variable
|
||||
pitch form. This may be overidden by a command line argument.
|
||||
|
@ -28,8 +31,8 @@ Further arguments ensure that the byte contents and layout are correct for the
|
|||
target display hardware. Their usage should be specified in the documentation
|
||||
for the device driver.
|
||||
|
||||
Example usage to produce a file ``myfont.py`` with height of 23 pixels:
|
||||
``font_to_py.py FreeSans.ttf 23 myfont.py``
|
||||
Example usage to produce a file `myfont.py` with height of 23 pixels:
|
||||
`font_to_py.py FreeSans.ttf 23 myfont.py`
|
||||
|
||||
## Arguments
|
||||
|
||||
|
@ -69,23 +72,23 @@ creation of a binary font file may not be intended.
|
|||
|
||||
## The font file
|
||||
|
||||
Assume that the you have employed the utility to create a file ``myfont.py``. In
|
||||
Assume that the you have employed the utility to create a file `myfont.py`. In
|
||||
your code you will issue
|
||||
|
||||
```python
|
||||
import myfont
|
||||
```
|
||||
|
||||
The ``myfont`` module name will then be used to instantiate a ``Writer`` object
|
||||
The `myfont` module name will then be used to instantiate a `Writer` object
|
||||
to render strings on demand. A practical example may be studied
|
||||
[here](https://github.com/peterhinch/micropython-samples/blob/master/SSD1306/ssd1306_test.py).
|
||||
The detailed layout of the Python file may be seen [here](./DRIVERS.md).
|
||||
|
||||
### Binary font files
|
||||
|
||||
There is an option to create a binary font file, specified with a ``-b`` or
|
||||
``--binary`` command line argument. In this instance the output filename must
|
||||
not have a ``.py`` extension. This is primarily intended for the e-paper driver
|
||||
There is an option to create a binary font file, specified with a `-b` or
|
||||
`--binary` command line argument. In this instance the output filename must
|
||||
not have a `.py` extension. This is primarily intended for the e-paper driver
|
||||
in applications where the file is to be stored on the display's internal flash
|
||||
memory rather than using frozen Python modules.
|
||||
|
||||
|
@ -138,10 +141,10 @@ print(len(freeserif._font) + len(freeserif._index))
|
|||
```
|
||||
|
||||
The memory used was 5408, 5648, and 5696 bytes. As increments over the initial
|
||||
state this corresponds to 240 and 288 bytes. The ``print`` statement shows the
|
||||
state this corresponds to 240 and 288 bytes. The `print` statement shows the
|
||||
RAM which would be consumed by the data arrays: this was 3271 bytes.
|
||||
|
||||
The ``foo()`` function emulates the behaviour of a device driver in rendering a
|
||||
The `foo()` function emulates the behaviour of a device driver in rendering a
|
||||
character to a display. The local variables constitute memory which will be
|
||||
reclaimed on exit from the function. Its additional RAM use was 48 bytes.
|
||||
|
||||
|
|
53
README.md
53
README.md
|
@ -9,20 +9,21 @@ MicroPython platforms generally have limited RAM, but more abundant storage in
|
|||
the form of flash memory. Font files tend to be relatively large. The
|
||||
conventional technique of rendering strings to a device involves loading the
|
||||
entire font into RAM. This is fast but RAM intensive. The alternative of storing
|
||||
the font as a random access file and loading individual characters into RAM on
|
||||
the font as a random access file and loading individual glyphs into RAM on
|
||||
demand is too slow for reasonable performance on most display devices.
|
||||
|
||||
This alternative implements a font as a Python source file, with the data being
|
||||
declared as ``bytes`` objects. Such a file may be frozen as bytecode. On import
|
||||
very little RAM is used, yet the data may be accessed fast. Note that the use
|
||||
of frozen bytecode is entirely optional: font files may be imported in the
|
||||
normal way if RAM usage is not an issue.
|
||||
declared as `bytes` objects. Such a file may be frozen as bytecode: this
|
||||
involves building the firmware from source with the Python file in a specific
|
||||
directory. On import very little RAM is used, yet the data may be accessed
|
||||
fast. Note that the use of frozen bytecode is entirely optional: font files may
|
||||
be imported in the normal way if RAM usage is not an issue.
|
||||
|
||||
It is intended that the resultant file be usable with two varieties of display
|
||||
devices and drivers. These comprise:
|
||||
|
||||
1. Drivers using ``bytearray`` instances as frame buffers, including the
|
||||
official ``framebuffer`` class.
|
||||
1. Drivers using `bytearray` instances as frame buffers, including the
|
||||
official `framebuffer` class.
|
||||
2. Drivers for displays where the frame buffer is implemented in the display
|
||||
device hardware.
|
||||
|
||||
|
@ -40,7 +41,7 @@ This consists of three components:
|
|||
# font_to_py.py
|
||||
|
||||
This is a command line utility written in Python 3 to be run on a PC. It takes
|
||||
as input a font file in ``ttf`` or ``otf`` form together with a height in pixels
|
||||
as input a font file in `ttf` or `otf` form together with a height in pixels
|
||||
and outputs a Python source file containing the font data. Fixed and variable
|
||||
pitch rendering are supported. The design has the following aims:
|
||||
|
||||
|
@ -56,9 +57,9 @@ RAM usage when importing fonts stored as frozen bytecode.
|
|||
|
||||
# Limitations
|
||||
|
||||
By default the ASCII character set from ``chr(32)`` to ``chr(126)`` is supported
|
||||
By default the ASCII character set from `chr(32)` to `chr(126)` is supported
|
||||
but command line arguments enable the range to be modified with extended ASCII
|
||||
characters to ``chr(255)`` being included if required. Kerning is not supported.
|
||||
characters to `chr(255)` being included if required. Kerning is not supported.
|
||||
Fonts are one bit per pixel. This does not rule out colour displays: the device
|
||||
driver can add colour information at the rendering stage. It does assume that
|
||||
all pixels of a character are rendered identically.
|
||||
|
@ -70,37 +71,25 @@ size.
|
|||
|
||||
# Font file interface
|
||||
|
||||
A font file is imported in the usual way e.g. ``import font14``. It contains
|
||||
A font file is imported in the usual way e.g. `import font14`. It contains
|
||||
the following methods which return values defined by the arguments which were
|
||||
provided to font-to-py:
|
||||
|
||||
``height`` Returns height in pixels.
|
||||
``max_width`` Returns maximum width of a glyph in pixels.
|
||||
``hmap`` Returns ``True`` if font is horizontally mapped. Should return ``True``
|
||||
``reverse`` Returns ``True`` if bit reversal was specified. Should return ``False``
|
||||
``monospaced`` Returns ``True`` if monospaced rendering was specified.
|
||||
``min_ch`` Returns the ordinal value of the lowest character in the file.
|
||||
``max_ch`` Returns the ordinal value of the highest character in the file.
|
||||
`height` Returns height in pixels.
|
||||
`max_width` Returns maximum width of a glyph in pixels.
|
||||
`hmap` Returns `True` if font is horizontally mapped. Should return `True`
|
||||
`reverse` Returns `True` if bit reversal was specified. Should return `False`
|
||||
`monospaced` Returns `True` if monospaced rendering was specified.
|
||||
`min_ch` Returns the ordinal value of the lowest character in the file.
|
||||
`max_ch` Returns the ordinal value of the highest character in the file.
|
||||
|
||||
Glyphs are returned with the ``get_ch`` method. Its argument is a character
|
||||
Glyphs are returned with the `get_ch` method. Its argument is a character
|
||||
and it returns the following values:
|
||||
|
||||
* A ``memoryview`` object containg the glyph bytes.
|
||||
* A `memoryview` object containg the glyph bytes.
|
||||
* The height in pixels.
|
||||
* The character width in pixels.
|
||||
|
||||
# An alternative solution
|
||||
|
||||
Brian Cappello has produced [this fork](https://github.com/briancappello/micropython-font-to-py.git).
|
||||
This has an enhanced `font_to_py.py` program offering a fast line mapping along
|
||||
with some clever optimisations designed to reduce font file size. He also has
|
||||
an enhanced Writer class of interest to anyone producing a driver for display
|
||||
hardware.
|
||||
|
||||
His `font_to_py.py` solution has not been implemented here because the font
|
||||
files are incompatible with existing device drivers and GUI projects. Its use
|
||||
should be considered for new projects.
|
||||
|
||||
# Licence
|
||||
|
||||
All code is released under the MIT licence.
|
||||
|
|
Ładowanie…
Reference in New Issue