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
|
# 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
|
# Dependency
|
||||||
|
|
||||||
|
@ -14,8 +17,8 @@ at a root prompt:
|
||||||
|
|
||||||
# Usage
|
# Usage
|
||||||
|
|
||||||
``font_to_py.py`` is a command line utility written in Python 3. It is run on 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
|
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
|
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
|
is determined by command arguments. By default fonts are stored in variable
|
||||||
pitch form. This may be overidden by a command line argument.
|
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
|
target display hardware. Their usage should be specified in the documentation
|
||||||
for the device driver.
|
for the device driver.
|
||||||
|
|
||||||
Example usage to produce a file ``myfont.py`` with height of 23 pixels:
|
Example usage to produce a file `myfont.py` with height of 23 pixels:
|
||||||
``font_to_py.py FreeSans.ttf 23 myfont.py``
|
`font_to_py.py FreeSans.ttf 23 myfont.py`
|
||||||
|
|
||||||
## Arguments
|
## Arguments
|
||||||
|
|
||||||
|
@ -69,23 +72,23 @@ creation of a binary font file may not be intended.
|
||||||
|
|
||||||
## The font file
|
## 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
|
your code you will issue
|
||||||
|
|
||||||
```python
|
```python
|
||||||
import myfont
|
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
|
to render strings on demand. A practical example may be studied
|
||||||
[here](https://github.com/peterhinch/micropython-samples/blob/master/SSD1306/ssd1306_test.py).
|
[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).
|
The detailed layout of the Python file may be seen [here](./DRIVERS.md).
|
||||||
|
|
||||||
### Binary font files
|
### Binary font files
|
||||||
|
|
||||||
There is an option to create a binary font file, specified with a ``-b`` or
|
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
|
`--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
|
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
|
in applications where the file is to be stored on the display's internal flash
|
||||||
memory rather than using frozen Python modules.
|
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
|
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.
|
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
|
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.
|
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
|
the form of flash memory. Font files tend to be relatively large. The
|
||||||
conventional technique of rendering strings to a device involves loading 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
|
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.
|
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
|
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
|
declared as `bytes` objects. Such a file may be frozen as bytecode: this
|
||||||
very little RAM is used, yet the data may be accessed fast. Note that the use
|
involves building the firmware from source with the Python file in a specific
|
||||||
of frozen bytecode is entirely optional: font files may be imported in the
|
directory. On import very little RAM is used, yet the data may be accessed
|
||||||
normal way if RAM usage is not an issue.
|
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
|
It is intended that the resultant file be usable with two varieties of display
|
||||||
devices and drivers. These comprise:
|
devices and drivers. These comprise:
|
||||||
|
|
||||||
1. Drivers using ``bytearray`` instances as frame buffers, including the
|
1. Drivers using `bytearray` instances as frame buffers, including the
|
||||||
official ``framebuffer`` class.
|
official `framebuffer` class.
|
||||||
2. Drivers for displays where the frame buffer is implemented in the display
|
2. Drivers for displays where the frame buffer is implemented in the display
|
||||||
device hardware.
|
device hardware.
|
||||||
|
|
||||||
|
@ -40,7 +41,7 @@ This consists of three components:
|
||||||
# font_to_py.py
|
# font_to_py.py
|
||||||
|
|
||||||
This is a command line utility written in Python 3 to be run on a PC. It takes
|
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
|
and outputs a Python source file containing the font data. Fixed and variable
|
||||||
pitch rendering are supported. The design has the following aims:
|
pitch rendering are supported. The design has the following aims:
|
||||||
|
|
||||||
|
@ -56,9 +57,9 @@ RAM usage when importing fonts stored as frozen bytecode.
|
||||||
|
|
||||||
# Limitations
|
# 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
|
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
|
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
|
driver can add colour information at the rendering stage. It does assume that
|
||||||
all pixels of a character are rendered identically.
|
all pixels of a character are rendered identically.
|
||||||
|
@ -70,37 +71,25 @@ size.
|
||||||
|
|
||||||
# Font file interface
|
# 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
|
the following methods which return values defined by the arguments which were
|
||||||
provided to font-to-py:
|
provided to font-to-py:
|
||||||
|
|
||||||
``height`` Returns height in pixels.
|
`height` Returns height in pixels.
|
||||||
``max_width`` Returns maximum width of a glyph in pixels.
|
`max_width` Returns maximum width of a glyph in pixels.
|
||||||
``hmap`` Returns ``True`` if font is horizontally mapped. Should return ``True``
|
`hmap` Returns `True` if font is horizontally mapped. Should return `True`
|
||||||
``reverse`` Returns ``True`` if bit reversal was specified. Should return ``False``
|
`reverse` Returns `True` if bit reversal was specified. Should return `False`
|
||||||
``monospaced`` Returns ``True`` if monospaced rendering was specified.
|
`monospaced` Returns `True` if monospaced rendering was specified.
|
||||||
``min_ch`` Returns the ordinal value of the lowest character in the file.
|
`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.
|
`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:
|
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 height in pixels.
|
||||||
* The character width 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
|
# Licence
|
||||||
|
|
||||||
All code is released under the MIT licence.
|
All code is released under the MIT licence.
|
||||||
|
|
Ładowanie…
Reference in New Issue