Improve docs to clarify frozen bytecode technique.

pull/16/head
Peter Hinch 2018-07-04 07:38:00 +01:00
rodzic ba3d585162
commit 0d4883fa4e
2 zmienionych plików z 36 dodań i 44 usunięć

Wyświetl plik

@ -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.

Wyświetl plik

@ -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.