kopia lustrzana https://github.com/peterhinch/micropython-nano-gui
Smaller, faster writer.py. Requires fw V1.17 or later.
rodzic
c344aebf27
commit
5638dcd8c7
29
README.md
29
README.md
|
@ -72,6 +72,7 @@ wiring details, pin names and hardware issues.
|
||||||
3.7 [Class Textbox](./README.md#37-class-textbox) Scrolling text display.
|
3.7 [Class Textbox](./README.md#37-class-textbox) Scrolling text display.
|
||||||
4. [ESP8266](./README.md#4-esp8266) This can work. Contains information on
|
4. [ESP8266](./README.md#4-esp8266) This can work. Contains information on
|
||||||
minimising the RAM and flash footprints of the GUI.
|
minimising the RAM and flash footprints of the GUI.
|
||||||
|
5. [Old firmware](./README.md#5-old-firmware) For users of color displays who can't run current firmware.
|
||||||
|
|
||||||
#### [Graph plotting module.](./FPLOT.md)
|
#### [Graph plotting module.](./FPLOT.md)
|
||||||
|
|
||||||
|
@ -113,6 +114,8 @@ my GUI's employ the American spelling of `color`.
|
||||||
|
|
||||||
## 1.1 Change log
|
## 1.1 Change log
|
||||||
|
|
||||||
|
7 Sep 2021 Code reduction and faster color text display. Color use now requires
|
||||||
|
firmware V1.17 or later.
|
||||||
26 Aug 2021 Support [PR7682](https://github.com/micropython/micropython/pull/7682)
|
26 Aug 2021 Support [PR7682](https://github.com/micropython/micropython/pull/7682)
|
||||||
for fast text rendering.
|
for fast text rendering.
|
||||||
25 Apr 2021 Support TTGO T-Display.
|
25 Apr 2021 Support TTGO T-Display.
|
||||||
|
@ -236,19 +239,19 @@ active.
|
||||||
|
|
||||||
## 1.4 A performance boost
|
## 1.4 A performance boost
|
||||||
|
|
||||||
As of Aug 2021 color displays can benefit from a substantial performance boost
|
A firmware change in V1.17 has enabled the code size to be reduced. It has also
|
||||||
in rendering text. To take advantage of this, firmware should be dated after
|
accelerated text rendering on color displays. Use of color displays now
|
||||||
26 Aug 21. The display driver and GUI core files should be updated. Ensure that
|
requires firmware V1.17 or later. Existing users should update the display
|
||||||
the new file `drivers/boolpalette.py` exists on the target hardware. Usge of
|
driver and GUI core files and should ensure that the new file
|
||||||
this mode is automatic but can be checked by running the `aclock.py` demo which
|
`drivers/boolpalette.py` exists.
|
||||||
reports the status at the REPL.
|
|
||||||
|
|
||||||
###### [Contents](./README.md#contents)
|
###### [Contents](./README.md#contents)
|
||||||
|
|
||||||
# 2. Files and Dependencies
|
# 2. Files and Dependencies
|
||||||
|
|
||||||
Firmware should be V1.13 or later. On the Pi Pico firmware should be V1.15 or
|
On monochrome displays firmware should be V1.13 or later. On the Pi Pico
|
||||||
later. For fast text rendering use a daily build or V1.17 or later.
|
firmware should be V1.15 or later. For color displays it should be V1.17 or
|
||||||
|
later.
|
||||||
|
|
||||||
Installation comprises copying the `gui` and `drivers` directories, with their
|
Installation comprises copying the `gui` and `drivers` directories, with their
|
||||||
contents, plus a hardware configuration file, to the target. The directory
|
contents, plus a hardware configuration file, to the target. The directory
|
||||||
|
@ -939,4 +942,14 @@ bytes, `tbox.py` reported 10512 bytes, sometimes more, as the demo progressed.
|
||||||
With the 4 bit driver `scale.py` reported 18112 bytes. In conclusion I think
|
With the 4 bit driver `scale.py` reported 18112 bytes. In conclusion I think
|
||||||
that applications of moderate complexity should be feasible.
|
that applications of moderate complexity should be feasible.
|
||||||
|
|
||||||
|
# 5. Old firmware
|
||||||
|
|
||||||
|
Current firmware is highly recommended. For users of color displays who cannot
|
||||||
|
meet the requirements of
|
||||||
|
[Files and Dependencies](./README.md#2-files-and-dependencies) it is possible
|
||||||
|
to run. 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#contents)
|
###### [Contents](./README.md#contents)
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
# writer.py Implements the Writer class.
|
# writer.py Implements the Writer class.
|
||||||
# Handles colour, word wrap and tab stops
|
# 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.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
|
# V0.4.0 Jan 2021 Improved handling of word wrap and line clip. Upside-down
|
||||||
# rendering no longer supported: delegate to device driver.
|
# rendering no longer supported: delegate to device driver.
|
||||||
|
@ -24,27 +25,9 @@ from uctypes import bytearray_at, addressof
|
||||||
from sys import implementation
|
from sys import implementation
|
||||||
import os
|
import os
|
||||||
|
|
||||||
__version__ = (0, 4, 3)
|
__version__ = (0, 5, 0)
|
||||||
|
|
||||||
def buildcheck(device):
|
fast_mode = True # Does nothing. Kept to avoid breaking code.
|
||||||
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
|
|
||||||
|
|
||||||
class DisplayState():
|
class DisplayState():
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
|
@ -202,7 +185,7 @@ class Writer():
|
||||||
break
|
break
|
||||||
if mc + 1 == wd:
|
if mc + 1 == wd:
|
||||||
break # All done: no trailing space
|
break # All done: no trailing space
|
||||||
print('Truelen', char, wd, mc + 1) # TEST
|
# print('Truelen', char, wd, mc + 1) # TEST
|
||||||
return mc + 1
|
return mc + 1
|
||||||
|
|
||||||
def _get_char(self, char, recurse):
|
def _get_char(self, char, recurse):
|
||||||
|
@ -272,19 +255,20 @@ class CWriter(Writer):
|
||||||
|
|
||||||
|
|
||||||
def __init__(self, device, font, fgcolor=None, bgcolor=None, verbose=True):
|
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)
|
super().__init__(device, font, verbose)
|
||||||
global fast_mode
|
|
||||||
fast_mode = buildcheck(device)
|
|
||||||
if bgcolor is not None: # Assume monochrome.
|
if bgcolor is not None: # Assume monochrome.
|
||||||
self.bgcolor = bgcolor
|
self.bgcolor = bgcolor
|
||||||
if fgcolor is not None:
|
if fgcolor is not None:
|
||||||
self.fgcolor = fgcolor
|
self.fgcolor = fgcolor
|
||||||
self.def_bgcolor = self.bgcolor
|
self.def_bgcolor = self.bgcolor
|
||||||
self.def_fgcolor = self.fgcolor
|
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()
|
s = self._getstate()
|
||||||
self._get_char(char, recurse)
|
self._get_char(char, recurse)
|
||||||
if self.glyph is None:
|
if self.glyph is None:
|
||||||
|
@ -294,42 +278,10 @@ class CWriter(Writer):
|
||||||
palette = self.device.palette
|
palette = self.device.palette
|
||||||
palette.bg(self.fgcolor if invert else self.bgcolor)
|
palette.bg(self.fgcolor if invert else self.bgcolor)
|
||||||
palette.fg(self.bgcolor if invert else self.fgcolor)
|
palette.fg(self.bgcolor if invert else self.fgcolor)
|
||||||
|
|
||||||
self.device.blit(fbc, s.text_col, s.text_row, -1, palette)
|
self.device.blit(fbc, s.text_col, s.text_row, -1, palette)
|
||||||
s.text_col += self.char_width
|
s.text_col += self.char_width
|
||||||
self.cpos += 1
|
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):
|
def setcolor(self, fgcolor=None, bgcolor=None):
|
||||||
if fgcolor is None and bgcolor is None:
|
if fgcolor is None and bgcolor is None:
|
||||||
self.fgcolor = self.def_fgcolor
|
self.fgcolor = self.def_fgcolor
|
||||||
|
|
Ładowanie…
Reference in New Issue