Smaller, faster writer.py. Requires fw V1.17 or later.

pull/8/head
Peter Hinch 2021-09-07 10:55:37 +01:00
rodzic 7010e931f1
commit 6ff7206e72
2 zmienionych plików z 32 dodań i 70 usunięć

Wyświetl plik

@ -60,8 +60,9 @@ Code has been tested on ESP32, Pi Pico and Pyboard. The API shuld be stable.
Code is new and issues are likely: please report any found. The project is
under development so check for updates.
A recent firmware update [PR7682](https://github.com/micropython/micropython/pull/7682)
has provided a major boost to text rendering speed on color displays. See
Firmware V1.17 has provided a major boost to text rendering speed on color
display. V1.17 or later is now a requirement for color displays, although
there is a workround if it's impossible to upgrade. See
[section 1.8](./README.md#18-performance-and-hardware-notes) for details.
# 0. Contents
@ -127,6 +128,7 @@ has provided a major boost to text rendering speed on color displays. See
     23.3.1 [Class Curve](./README.md#2331-class-curve)
     23.3.2 [Class PolarCurve](./README.md#2332-class-polarcurve)
23.4 [Class TSequence](./README.md#234-class-tsequence) Plotting realtime, time sequential data.
24. [Old firmware](./README.md#24-old-firmware) For users of color displays who can't run current firmware.
[Appendix 1 Application design](./README.md#appendix-1-application-design) Tab order, button layout, encoder interface, use of graphics primitives
# 1. Basic concepts
@ -414,21 +416,20 @@ RAM usage. A smaller display or a Pyboard D would offer more headroom.
#### A performance boost
As of Aug 2021 a firmware update
[PR7682](https://github.com/micropython/micropython/pull/7682) means that color
displays can benefit from a substantial performance boost in rendering text. To
take advantage of this, firmware should be dated after 26 Aug 21. The display
driver and GUI core files should be updated. Ensure that the new file
`drivers/boolpalette.py` exists on the target hardware.
A firmware change in V1.17 has enabled the code size to be reduced. It has also
accelerated text rendering on color displays. Use of color displays now
requires firmware V1.17 or later. Existing users should update the display
driver and GUI core files and should ensure that the new file
`drivers/boolpalette.py` exists.
###### [Contents](./README.md#0-contents)
## 1.9 Firmware and dependencies
Firmware should be V1.15 or later. For fast text rendering a daily build or
a release build >= 1.17 should be used. The source tree includes all
dependencies. These are listed to enable users to check for newer versions or
to read docs:
Users of color displays should ensure that firmware is V1.17 or later. If this
cannot be met, there is a [workround](./README.md#24-old-firmware). The source
tree includes all dependencies. These are listed to enable users to check for
newer versions or to read docs:
* [writer.py](https://github.com/peterhinch/micropython-font-to-py/blob/master/writer/writer.py)
Provides text rendering of Python font files.
@ -2612,6 +2613,15 @@ class TSeq(Screen):
await asyncio.sleep_ms(400)
t += 1
```
###### [Contents](./README.md#0-contents)
# 24. Old firmware
Current firmware is highly recommended. For users of color displays who cannot
run V1.17 or later it is possible to run under V1.15+. This involves copying
[this file](https://github.com/peterhinch/micropython-font-to-py/blob/master/writer/old_versions/writer_fw_compatible.py)
to `gui/core/writer.py`. This uses Python code to render text if the firmware
or driver are unable to support fast rendering.
###### [Contents](./README.md#0-contents)

Wyświetl plik

@ -1,6 +1,7 @@
# writer.py Implements the Writer class.
# Handles colour, word wrap and tab stops
# V0.5.0 Sep 2021 Color now requires firmware >= 1.17.
# V0.4.3 Aug 2021 Support for fast blit to color displays (PR7682).
# V0.4.0 Jan 2021 Improved handling of word wrap and line clip. Upside-down
# rendering no longer supported: delegate to device driver.
@ -24,27 +25,9 @@ from uctypes import bytearray_at, addressof
from sys import implementation
import os
__version__ = (0, 4, 3)
__version__ = (0, 5, 0)
def buildcheck(device):
if not hasattr(device, 'palette'):
return False
i0, i1, _ = implementation[1]
if i0 > 1 or i1 > 16:
return True
# After release of V1.17 require that build. Until then check for date.
# TODO simplify this once V1.17 is released.
try:
datestring = os.uname()[3]
date = datestring.split(' on')[1]
date = date.lstrip()[:10]
idate = tuple([int(x) for x in date.split('-')])
return idate >= (2021, 8, 25)
except AttributeError:
return False
fast_mode = False # False for mono displays although actually these render fast
fast_mode = True # Does nothing. Kept to avoid breaking code.
class DisplayState():
def __init__(self):
@ -202,7 +185,7 @@ class Writer():
break
if mc + 1 == wd:
break # All done: no trailing space
print('Truelen', char, wd, mc + 1) # TEST
# print('Truelen', char, wd, mc + 1) # TEST
return mc + 1
def _get_char(self, char, recurse):
@ -272,19 +255,20 @@ class CWriter(Writer):
def __init__(self, device, font, fgcolor=None, bgcolor=None, verbose=True):
if not hasattr(device, 'palette'):
raise OSError('Incompatible device driver.')
if implementation[1] < (1, 17, 0):
raise OSError('Firmware must be >= 1.17.')
super().__init__(device, font, verbose)
global fast_mode
fast_mode = buildcheck(device)
if bgcolor is not None: # Assume monochrome.
self.bgcolor = bgcolor
if fgcolor is not None:
self.fgcolor = fgcolor
self.def_bgcolor = self.bgcolor
self.def_fgcolor = self.fgcolor
self._printchar = self._pchfast if fast_mode else self._pchslow
verbose and print('Render {} using fast mode'.format('is' if fast_mode else 'not'))
def _pchfast(self, char, invert=False, recurse=False):
def _printchar(self, char, invert=False, recurse=False):
s = self._getstate()
self._get_char(char, recurse)
if self.glyph is None:
@ -294,42 +278,10 @@ class CWriter(Writer):
palette = self.device.palette
palette.bg(self.fgcolor if invert else self.bgcolor)
palette.fg(self.bgcolor if invert else self.fgcolor)
self.device.blit(fbc, s.text_col, s.text_row, -1, palette)
s.text_col += self.char_width
self.cpos += 1
def _pchslow(self, char, invert=False, recurse=False):
s = self._getstate()
self._get_char(char, recurse)
if self.glyph is None:
return # All done
char_height = self.char_height
char_width = self.char_width
clip_width = self.clip_width
div, mod = divmod(char_width, 8)
gbytes = div + 1 if mod else div # No. of bytes per row of glyph
device = self.device
fgcolor = self.bgcolor if invert else self.fgcolor
bgcolor = self.fgcolor if invert else self.bgcolor
drow = s.text_row # Destination row
wcol = s.text_col # Destination column of character start
for srow in range(char_height): # Source row
for scol in range(clip_width): # Source column
# Destination column: add writer column
dcol = wcol + scol
gbyte, gbit = divmod(scol, 8)
if gbit == 0: # Next glyph byte
data = self.glyph[srow * gbytes + gbyte]
pixel = fgcolor if data & (1 << (7 - gbit)) else bgcolor
device.pixel(dcol, drow, pixel)
drow += 1
if drow >= self.screenheight or drow < 0:
break
s.text_col += char_width
self.cpos += 1
def setcolor(self, fgcolor=None, bgcolor=None):
if fgcolor is None and bgcolor is None:
self.fgcolor = self.def_fgcolor