get_ch() now returns a memoryview

pull/3/merge
Peter Hinch 2016-11-03 16:57:44 +00:00
rodzic ae49472e90
commit bb4c0415d6
2 zmienionych plików z 47 dodań i 7 usunięć

Wyświetl plik

@ -88,6 +88,48 @@ import myfont
The ``myfont`` module name will then be passed to the device driver to render The ``myfont`` module name will then be passed to the device driver to render
strings on demand. strings on demand.
# Test Results: RAM utilisation
A font file was created, frozen as bytecode and deployed to a version 1.0
Pyboard. The font was saved as variable pitch with a height of 19 pixels. The
following code was then pasted at the REPL:
```python
import gc, micropython
gc.collect()
micropython.mem_info()
from uctypes import bytearray_at
import freeserif
gc.collect()
micropython.mem_info()
def foo():
addr, height, width = freeserif.get_ch('a')
arr = bytearray_at(addr, 3*2)
foo()
gc.collect()
micropython.mem_info()
print(len(freeserif._font) + len(freeserif._index))
```
The memory used was 4416, 4704, and 4736 bytes. As increments over the initial
state this corresponds to 288 and 320 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
character to a display. The local variables constitute memory which will be
reclaimed on exit from the function. Its additional RAM use was 32 bytes.
## Conclusion
With a font of height 19 pixels RAM saving was an order of magnitude. The
saving will be greater if larger fonts are used
# Dependencies, links and licence # Dependencies, links and licence
The code is released under the MIT licence. It requires Python 3.2 or later. The code is released under the MIT licence. It requires Python 3.2 or later.
@ -158,9 +200,9 @@ b'\x1b\x01\x35\x01\x4f\x01\x75\x01\x9e\x01\xb2\x01\xcc\x01\xe0\x01'\
def get_ch(ch): def get_ch(ch):
# validate ch, if out of range use '?' # validate ch, if out of range use '?'
# get offset into _font and retrieve char width # get offsets into _font and retrieve char width
# Return: address of start of bitmap, height and width # Return: address of start of bitmap, height and width
return addressof(_font) + offset + 2, height, width return memoryview(_font[offset + 2, next_offset]), height, width
``` ```
``height`` and ``width`` are specified in bits (pixels). ``height`` and ``width`` are specified in bits (pixels).
@ -172,9 +214,7 @@ will fit the available space. If it will fit on the assumption that all chars
are maximum width, it can be rendered rapidly without doing a character by are maximum width, it can be rendered rapidly without doing a character by
character check. character check.
There is a small amount of additional code designed to enable font files to be ``get_ch()`` returns a memoryview of an individual glyph with its dimensions.
tested under cPython: in this instance ``get_ch()`` is called with an optional
``test`` argument and returns a slice rather than a machine address.
## Mapping ## Mapping

Wyświetl plik

@ -143,7 +143,7 @@ def test_font(fontfile, string):
height = myfont.height() height = myfont.height()
for row in range(height): for row in range(height):
for char in string: for char in string:
data, _, width = myfont.get_ch(char, True) data, _, width = myfont.get_ch(char)
if myfont.hmap(): if myfont.hmap():
render_row_hmap(data, row, height, width, myfont.reverse()) render_row_hmap(data, row, height, width, myfont.reverse())
else: else:
@ -167,7 +167,7 @@ def test_file(fontfile, height, string, fixed=False, hmap=False,
height = myfont.height() height = myfont.height()
for row in range(height): for row in range(height):
for char in string: for char in string:
data, _, width = myfont.get_ch(char, True) data, _, width = myfont.get_ch(char)
if myfont.hmap(): if myfont.hmap():
render_row_hmap(data, row, height, width, myfont.reverse()) render_row_hmap(data, row, height, width, myfont.reverse())
else: else: