kopia lustrzana https://github.com/peterhinch/micropython-nano-gui
PR7682 improvements: drivers, writer.py, docs.
rodzic
31368b751c
commit
dbc4f4689b
16
DRIVERS.md
16
DRIVERS.md
|
@ -1085,6 +1085,22 @@ long as `.rgb()` and the "on the fly" converter match, this is arbitrary.
|
||||||
The `Writer` (monochrome) or `CWriter` (color) classes and the `nanogui` module
|
The `Writer` (monochrome) or `CWriter` (color) classes and the `nanogui` module
|
||||||
should then work automatically.
|
should then work automatically.
|
||||||
|
|
||||||
|
For color displays the following provides a substantial performance boost when
|
||||||
|
rendering text.
|
||||||
|
```python
|
||||||
|
from drivers.boolpalette import BoolPalette
|
||||||
|
```
|
||||||
|
and, in `__init__.py`:
|
||||||
|
```python
|
||||||
|
mode = framebuf.GS4_HMSB # The format to be used by the driver
|
||||||
|
self.palette = BoolPalette(mode)
|
||||||
|
gc.collect()
|
||||||
|
buf = bytearray(self.height * self.width // 2) # Computation must match the format
|
||||||
|
super().__init__(buf, self.width, self.height, mode)
|
||||||
|
```
|
||||||
|
Assuming firmware dated after 26th Aug 2021, a fast C blit will be used to
|
||||||
|
render glyphs instead of Python code.
|
||||||
|
|
||||||
The following script is useful for testing color display drivers after
|
The following script is useful for testing color display drivers after
|
||||||
configuring `color_setup.py`. It draws squares at the extreme corners of the
|
configuring `color_setup.py`. It draws squares at the extreme corners of the
|
||||||
display and a corner to corner diagonal.
|
display and a corner to corner diagonal.
|
||||||
|
|
23
README.md
23
README.md
|
@ -49,6 +49,7 @@ wiring details, pin names and hardware issues.
|
||||||
1.1 [Change log](./README.md#11-change-log)
|
1.1 [Change log](./README.md#11-change-log)
|
||||||
1.2 [Description](./README.md#12-description)
|
1.2 [Description](./README.md#12-description)
|
||||||
1.3 [Quick start](./README.md#13-quick-start)
|
1.3 [Quick start](./README.md#13-quick-start)
|
||||||
|
1.4 [A performance boost](./README.md#14-a-performance-boost)
|
||||||
2. [Files and Dependencies](./README.md#2-files-and-dependencies)
|
2. [Files and Dependencies](./README.md#2-files-and-dependencies)
|
||||||
2.1 [Files](./README.md#21-files)
|
2.1 [Files](./README.md#21-files)
|
||||||
2.1.1 [Core files](./README.md#211-core-files)
|
2.1.1 [Core files](./README.md#211-core-files)
|
||||||
|
@ -93,8 +94,7 @@ on ESP8266 is possible but frozen bytecode must be used owing to its restricted
|
||||||
RAM.
|
RAM.
|
||||||
|
|
||||||
As of 14th March 2021 it runs on the Raspberry Pi Pico; on that target firmware
|
As of 14th March 2021 it runs on the Raspberry Pi Pico; on that target firmware
|
||||||
must be of that date or later. The `color15` demo fails because the firmware
|
must be of that date or later.
|
||||||
lacks `uos.urandom()` but hopefully it will be fixed soon.
|
|
||||||
|
|
||||||
It uses synchronous code but is compatible with `uasyncio`. Some demo programs
|
It uses synchronous code but is compatible with `uasyncio`. Some demo programs
|
||||||
illustrate this. Code is standard MicroPython, but some device drivers use the
|
illustrate this. Code is standard MicroPython, but some device drivers use the
|
||||||
|
@ -112,6 +112,8 @@ my GUI's employ the American spelling of `color`.
|
||||||
|
|
||||||
## 1.1 Change log
|
## 1.1 Change log
|
||||||
|
|
||||||
|
26 Aug 2021 Support [PR7682](https://github.com/micropython/micropython/pull/7682)
|
||||||
|
for fast text rendering.
|
||||||
25 Apr 2021 Support TTGO T-Display.
|
25 Apr 2021 Support TTGO T-Display.
|
||||||
26 Mar 2021 Add ST7789. Alter uasyncio support on ili9341.
|
26 Mar 2021 Add ST7789. Alter uasyncio support on ili9341.
|
||||||
14 Mar 2021 Tested on Pi Pico.
|
14 Mar 2021 Tested on Pi Pico.
|
||||||
|
@ -204,12 +206,19 @@ OLED as per `color_setup.py`, move to the root directory of the repo and run
|
||||||
Note also that the `gui.demos.aclock.py` demo comprises 38 lines of actual
|
Note also that the `gui.demos.aclock.py` demo comprises 38 lines of actual
|
||||||
code. This stuff is easier than you might think.
|
code. This stuff is easier than you might think.
|
||||||
|
|
||||||
|
## 1.4 A performance boost
|
||||||
|
|
||||||
|
As of Aug 2021 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.
|
||||||
|
|
||||||
###### [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
|
Firmware should be V1.13 or later. On the Pi Pico firmware should be V1.15 or
|
||||||
later.
|
later. For fast text rendering use a daily build or 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
|
||||||
|
@ -248,10 +257,6 @@ The `gui/core` directory contains the GUI core and its principal dependencies:
|
||||||
* `writer.py` Module for rendering Python fonts.
|
* `writer.py` Module for rendering Python fonts.
|
||||||
* `fplot.py` The graph plotting module.
|
* `fplot.py` The graph plotting module.
|
||||||
* `colors.py` Color constants.
|
* `colors.py` Color constants.
|
||||||
* `framebuf_utils.mpy` Accelerator for the `CWriter` class. This optional file
|
|
||||||
is compiled for STM hardware. It is specific to Pyboards (1.x and D) and will
|
|
||||||
be ignored on other ports. Details may be found
|
|
||||||
[here](https://github.com/peterhinch/micropython-font-to-py/blob/master/writer/WRITER.md#224-a-performance-boost).
|
|
||||||
|
|
||||||
###### [Contents](./README.md#contents)
|
###### [Contents](./README.md#contents)
|
||||||
|
|
||||||
|
@ -348,10 +353,6 @@ to check for newer versions:
|
||||||
* [writer.py](https://github.com/peterhinch/micropython-font-to-py/blob/master/writer/writer.py)
|
* [writer.py](https://github.com/peterhinch/micropython-font-to-py/blob/master/writer/writer.py)
|
||||||
Provides text rendering of Python font files.
|
Provides text rendering of Python font files.
|
||||||
|
|
||||||
Optional feature:
|
|
||||||
* An STM32 implementation of
|
|
||||||
[this optimisation](https://github.com/peterhinch/micropython-font-to-py/blob/master/writer/WRITER.md#224-a-performance-boost).
|
|
||||||
|
|
||||||
A copy of the official driver for OLED displays using the SSD1306 chip is
|
A copy of the official driver for OLED displays using the SSD1306 chip is
|
||||||
provided. The official file is here:
|
provided. The official file is here:
|
||||||
* [SSD1306 driver](https://github.com/micropython/micropython/blob/master/drivers/display/ssd1306.py).
|
* [SSD1306 driver](https://github.com/micropython/micropython/blob/master/drivers/display/ssd1306.py).
|
||||||
|
|
|
@ -0,0 +1,20 @@
|
||||||
|
# boolpalette.py Implement BoolPalette class
|
||||||
|
# This is a 2-value color palette for rendering monochrome glyphs to color
|
||||||
|
# FrameBuffer instances. Supports destinations with up to 16 bit color.
|
||||||
|
|
||||||
|
# Copyright (c) Peter Hinch 2021
|
||||||
|
# Released under the MIT license see LICENSE
|
||||||
|
|
||||||
|
import framebuf
|
||||||
|
|
||||||
|
class BoolPalette(framebuf.FrameBuffer):
|
||||||
|
|
||||||
|
def __init__(self, mode):
|
||||||
|
buf = bytearray(4) # OK for <= 16 bit color
|
||||||
|
super().__init__(buf, 2, 1, mode)
|
||||||
|
|
||||||
|
def fg(self, color): # Set foreground color
|
||||||
|
self.pixel(1, 0, color)
|
||||||
|
|
||||||
|
def bg(self, color):
|
||||||
|
self.pixel(0, 0, color)
|
|
@ -13,6 +13,7 @@ from time import sleep_ms
|
||||||
import gc
|
import gc
|
||||||
import framebuf
|
import framebuf
|
||||||
import uasyncio as asyncio
|
import uasyncio as asyncio
|
||||||
|
from drivers.boolpalette import BoolPalette
|
||||||
|
|
||||||
@micropython.viper
|
@micropython.viper
|
||||||
def _lcopy(dest:ptr16, source:ptr8, lut:ptr16, length:int):
|
def _lcopy(dest:ptr16, source:ptr8, lut:ptr16, length:int):
|
||||||
|
@ -49,6 +50,7 @@ class ILI9341(framebuf.FrameBuffer):
|
||||||
self.width = width
|
self.width = width
|
||||||
self._spi_init = init_spi
|
self._spi_init = init_spi
|
||||||
mode = framebuf.GS4_HMSB
|
mode = framebuf.GS4_HMSB
|
||||||
|
self.palette = BoolPalette(mode)
|
||||||
gc.collect()
|
gc.collect()
|
||||||
buf = bytearray(self.height * self.width // 2)
|
buf = bytearray(self.height * self.width // 2)
|
||||||
self._mvb = memoryview(buf)
|
self._mvb = memoryview(buf)
|
||||||
|
|
|
@ -33,6 +33,8 @@ import framebuf
|
||||||
import utime
|
import utime
|
||||||
import gc
|
import gc
|
||||||
import sys
|
import sys
|
||||||
|
from drivers.boolpalette import BoolPalette
|
||||||
|
|
||||||
# https://github.com/peterhinch/micropython-nano-gui/issues/2
|
# https://github.com/peterhinch/micropython-nano-gui/issues/2
|
||||||
# The ESP32 does not work reliably in SPI mode 1,1. Waveforms look correct.
|
# The ESP32 does not work reliably in SPI mode 1,1. Waveforms look correct.
|
||||||
# Mode 0, 0 works on ESP and STM
|
# Mode 0, 0 works on ESP and STM
|
||||||
|
@ -54,6 +56,7 @@ class SSD1331(framebuf.FrameBuffer):
|
||||||
self.width = width
|
self.width = width
|
||||||
self._spi_init = init_spi
|
self._spi_init = init_spi
|
||||||
mode = framebuf.GS8 # Use 8bit greyscale for 8 bit color.
|
mode = framebuf.GS8 # Use 8bit greyscale for 8 bit color.
|
||||||
|
self.palette = BoolPalette(mode)
|
||||||
gc.collect()
|
gc.collect()
|
||||||
self.buffer = bytearray(self.height * self.width)
|
self.buffer = bytearray(self.height * self.width)
|
||||||
super().__init__(self.buffer, self.width, self.height, mode)
|
super().__init__(self.buffer, self.width, self.height, mode)
|
||||||
|
|
|
@ -30,6 +30,7 @@
|
||||||
import framebuf
|
import framebuf
|
||||||
import utime
|
import utime
|
||||||
import gc
|
import gc
|
||||||
|
from drivers.boolpalette import BoolPalette
|
||||||
|
|
||||||
# https://github.com/peterhinch/micropython-nano-gui/issues/2
|
# https://github.com/peterhinch/micropython-nano-gui/issues/2
|
||||||
# The ESP32 does not work reliably in SPI mode 1,1. Waveforms look correct.
|
# The ESP32 does not work reliably in SPI mode 1,1. Waveforms look correct.
|
||||||
|
@ -52,6 +53,7 @@ class SSD1331(framebuf.FrameBuffer):
|
||||||
self.width = width
|
self.width = width
|
||||||
self._spi_init = init_spi
|
self._spi_init = init_spi
|
||||||
mode = framebuf.RGB565
|
mode = framebuf.RGB565
|
||||||
|
self.palette = BoolPalette(mode)
|
||||||
gc.collect()
|
gc.collect()
|
||||||
self.buffer = bytearray(self.height * self.width * 2)
|
self.buffer = bytearray(self.height * self.width * 2)
|
||||||
super().__init__(self.buffer, self.width, self.height, mode)
|
super().__init__(self.buffer, self.width, self.height, mode)
|
||||||
|
|
|
@ -16,6 +16,7 @@ import utime
|
||||||
import gc
|
import gc
|
||||||
import micropython
|
import micropython
|
||||||
from uctypes import addressof
|
from uctypes import addressof
|
||||||
|
from drivers.boolpalette import BoolPalette
|
||||||
|
|
||||||
# Timings with standard emitter
|
# Timings with standard emitter
|
||||||
# 1.86ms * 128 lines = 240ms. copy dominates: show() took 272ms
|
# 1.86ms * 128 lines = 240ms. copy dominates: show() took 272ms
|
||||||
|
@ -90,6 +91,7 @@ class SSD1351(framebuf.FrameBuffer):
|
||||||
self.height = height # Required by Writer class
|
self.height = height # Required by Writer class
|
||||||
self.width = width
|
self.width = width
|
||||||
mode = framebuf.GS8 # Use 8bit greyscale for 8 bit color.
|
mode = framebuf.GS8 # Use 8bit greyscale for 8 bit color.
|
||||||
|
self.palette = BoolPalette(mode)
|
||||||
gc.collect()
|
gc.collect()
|
||||||
self.buffer = bytearray(self.height * self.width)
|
self.buffer = bytearray(self.height * self.width)
|
||||||
super().__init__(self.buffer, self.width, self.height, mode)
|
super().__init__(self.buffer, self.width, self.height, mode)
|
||||||
|
|
|
@ -15,6 +15,7 @@ import utime
|
||||||
import gc
|
import gc
|
||||||
import micropython
|
import micropython
|
||||||
from uctypes import addressof
|
from uctypes import addressof
|
||||||
|
from drivers.boolpalette import BoolPalette
|
||||||
|
|
||||||
# https://github.com/peterhinch/micropython-nano-gui/issues/2
|
# https://github.com/peterhinch/micropython-nano-gui/issues/2
|
||||||
# The ESP32 does not work reliably in SPI mode 1,1. Waveforms look correct.
|
# The ESP32 does not work reliably in SPI mode 1,1. Waveforms look correct.
|
||||||
|
@ -59,6 +60,7 @@ class SSD1351(framebuf.FrameBuffer):
|
||||||
self.height = height # Required by Writer class
|
self.height = height # Required by Writer class
|
||||||
self.width = width
|
self.width = width
|
||||||
mode = framebuf.RGB565
|
mode = framebuf.RGB565
|
||||||
|
self.palette = BoolPalette(mode)
|
||||||
gc.collect()
|
gc.collect()
|
||||||
self.buffer = bytearray(self.height * self.width * 2)
|
self.buffer = bytearray(self.height * self.width * 2)
|
||||||
super().__init__(self.buffer, self.width, self.height, mode)
|
super().__init__(self.buffer, self.width, self.height, mode)
|
||||||
|
|
|
@ -16,6 +16,7 @@ import utime
|
||||||
import gc
|
import gc
|
||||||
import micropython
|
import micropython
|
||||||
from uctypes import addressof
|
from uctypes import addressof
|
||||||
|
from drivers.boolpalette import BoolPalette
|
||||||
|
|
||||||
# https://github.com/peterhinch/micropython-nano-gui/issues/2
|
# https://github.com/peterhinch/micropython-nano-gui/issues/2
|
||||||
# The ESP32 does not work reliably in SPI mode 1,1. Waveforms look correct.
|
# The ESP32 does not work reliably in SPI mode 1,1. Waveforms look correct.
|
||||||
|
@ -87,6 +88,7 @@ class SSD1351(framebuf.FrameBuffer):
|
||||||
self.width = width
|
self.width = width
|
||||||
self.spi_init = init_spi
|
self.spi_init = init_spi
|
||||||
mode = framebuf.GS4_HMSB # Use 4bit greyscale.
|
mode = framebuf.GS4_HMSB # Use 4bit greyscale.
|
||||||
|
self.palette = BoolPalette(mode)
|
||||||
gc.collect()
|
gc.collect()
|
||||||
self.buffer = bytearray(self.height * self.width // 2)
|
self.buffer = bytearray(self.height * self.width // 2)
|
||||||
super().__init__(self.buffer, self.width, self.height, mode)
|
super().__init__(self.buffer, self.width, self.height, mode)
|
||||||
|
|
|
@ -17,6 +17,7 @@ import utime
|
||||||
import gc
|
import gc
|
||||||
import micropython
|
import micropython
|
||||||
from uctypes import addressof
|
from uctypes import addressof
|
||||||
|
from drivers.boolpalette import BoolPalette
|
||||||
|
|
||||||
import sys
|
import sys
|
||||||
# https://github.com/peterhinch/micropython-nano-gui/issues/2
|
# https://github.com/peterhinch/micropython-nano-gui/issues/2
|
||||||
|
@ -77,6 +78,7 @@ class SSD1351(framebuf.FrameBuffer):
|
||||||
self.height = height # Required by Writer class
|
self.height = height # Required by Writer class
|
||||||
self.width = width
|
self.width = width
|
||||||
mode = framebuf.GS8 # Use 8bit greyscale for 8 bit color.
|
mode = framebuf.GS8 # Use 8bit greyscale for 8 bit color.
|
||||||
|
self.palette = BoolPalette(mode)
|
||||||
gc.collect()
|
gc.collect()
|
||||||
self.buffer = bytearray(self.height * self.width)
|
self.buffer = bytearray(self.height * self.width)
|
||||||
super().__init__(self.buffer, self.width, self.height, mode)
|
super().__init__(self.buffer, self.width, self.height, mode)
|
||||||
|
|
|
@ -20,6 +20,7 @@ from time import sleep_ms
|
||||||
import framebuf
|
import framebuf
|
||||||
import gc
|
import gc
|
||||||
import micropython
|
import micropython
|
||||||
|
from drivers.boolpalette import BoolPalette
|
||||||
|
|
||||||
# Datasheet para 8.4 scl write cycle 66ns == 15MHz
|
# Datasheet para 8.4 scl write cycle 66ns == 15MHz
|
||||||
|
|
||||||
|
@ -60,6 +61,7 @@ class ST7735R(framebuf.FrameBuffer):
|
||||||
self.width = width
|
self.width = width
|
||||||
self._spi_init = init_spi
|
self._spi_init = init_spi
|
||||||
mode = framebuf.GS8 # Use 8bit greyscale for 8 bit color.
|
mode = framebuf.GS8 # Use 8bit greyscale for 8 bit color.
|
||||||
|
self.palette = BoolPalette(mode)
|
||||||
gc.collect()
|
gc.collect()
|
||||||
buf = bytearray(height * width)
|
buf = bytearray(height * width)
|
||||||
self._mvb = memoryview(buf)
|
self._mvb = memoryview(buf)
|
||||||
|
|
|
@ -20,6 +20,7 @@ from time import sleep_ms
|
||||||
import framebuf
|
import framebuf
|
||||||
import gc
|
import gc
|
||||||
import micropython
|
import micropython
|
||||||
|
from drivers.boolpalette import BoolPalette
|
||||||
|
|
||||||
# Datasheet para 8.4 scl write cycle 66ns == 15MHz
|
# Datasheet para 8.4 scl write cycle 66ns == 15MHz
|
||||||
|
|
||||||
|
@ -58,6 +59,7 @@ class ST7735R(framebuf.FrameBuffer):
|
||||||
self.width = width
|
self.width = width
|
||||||
self._spi_init = init_spi
|
self._spi_init = init_spi
|
||||||
mode = framebuf.GS8 # Use 8bit greyscale for 8 bit color.
|
mode = framebuf.GS8 # Use 8bit greyscale for 8 bit color.
|
||||||
|
self.palette = BoolPalette(mode)
|
||||||
gc.collect()
|
gc.collect()
|
||||||
buf = bytearray(self.height * self.width)
|
buf = bytearray(self.height * self.width)
|
||||||
self._mvb = memoryview(buf)
|
self._mvb = memoryview(buf)
|
||||||
|
|
|
@ -20,6 +20,7 @@ from time import sleep_ms
|
||||||
import framebuf
|
import framebuf
|
||||||
import gc
|
import gc
|
||||||
import micropython
|
import micropython
|
||||||
|
from drivers.boolpalette import BoolPalette
|
||||||
|
|
||||||
# Datasheet para 8.4 scl write cycle 66ns == 15MHz
|
# Datasheet para 8.4 scl write cycle 66ns == 15MHz
|
||||||
|
|
||||||
|
@ -61,6 +62,7 @@ class ST7735R(framebuf.FrameBuffer):
|
||||||
self.width = width
|
self.width = width
|
||||||
self._spi_init = init_spi
|
self._spi_init = init_spi
|
||||||
mode = framebuf.GS4_HMSB # Use 4bit greyscale.
|
mode = framebuf.GS4_HMSB # Use 4bit greyscale.
|
||||||
|
self.palette = BoolPalette(mode)
|
||||||
gc.collect()
|
gc.collect()
|
||||||
buf = bytearray(self.height * self.width // 2)
|
buf = bytearray(self.height * self.width // 2)
|
||||||
self._mvb = memoryview(buf)
|
self._mvb = memoryview(buf)
|
||||||
|
|
|
@ -20,6 +20,7 @@ from time import sleep_ms
|
||||||
import framebuf
|
import framebuf
|
||||||
import gc
|
import gc
|
||||||
import micropython
|
import micropython
|
||||||
|
from drivers.boolpalette import BoolPalette
|
||||||
|
|
||||||
# Datasheet para 8.4 scl write cycle 66ns == 15MHz
|
# Datasheet para 8.4 scl write cycle 66ns == 15MHz
|
||||||
|
|
||||||
|
@ -61,6 +62,7 @@ class ST7735R(framebuf.FrameBuffer):
|
||||||
self.width = width
|
self.width = width
|
||||||
self._spi_init = init_spi
|
self._spi_init = init_spi
|
||||||
mode = framebuf.GS4_HMSB # Use 4bit greyscale.
|
mode = framebuf.GS4_HMSB # Use 4bit greyscale.
|
||||||
|
self.palette = BoolPalette(mode)
|
||||||
gc.collect()
|
gc.collect()
|
||||||
buf = bytearray(height * width // 2)
|
buf = bytearray(height * width // 2)
|
||||||
self._mvb = memoryview(buf)
|
self._mvb = memoryview(buf)
|
||||||
|
|
|
@ -21,6 +21,7 @@ import framebuf
|
||||||
import gc
|
import gc
|
||||||
import micropython
|
import micropython
|
||||||
import uasyncio as asyncio
|
import uasyncio as asyncio
|
||||||
|
from drivers.boolpalette import BoolPalette
|
||||||
|
|
||||||
# User orientation constants
|
# User orientation constants
|
||||||
LANDSCAPE = 0 # Default
|
LANDSCAPE = 0 # Default
|
||||||
|
@ -73,6 +74,7 @@ class ST7789(framebuf.FrameBuffer):
|
||||||
self._spi_init = init_spi # Possible user callback
|
self._spi_init = init_spi # Possible user callback
|
||||||
self._lock = asyncio.Lock()
|
self._lock = asyncio.Lock()
|
||||||
mode = framebuf.GS4_HMSB # Use 4bit greyscale.
|
mode = framebuf.GS4_HMSB # Use 4bit greyscale.
|
||||||
|
self.palette = BoolPalette(mode)
|
||||||
gc.collect()
|
gc.collect()
|
||||||
buf = bytearray(height * -(-width // 2)) # Ceiling division for odd widths
|
buf = bytearray(height * -(-width // 2)) # Ceiling division for odd widths
|
||||||
self._mvb = memoryview(buf)
|
self._mvb = memoryview(buf)
|
||||||
|
|
Plik binarny nie jest wyświetlany.
|
@ -1,9 +1,10 @@
|
||||||
# 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.40 Jan 2021 Improved handling of word wrap and line clip. Upside-down
|
# 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.
|
# rendering no longer supported: delegate to device driver.
|
||||||
# V0.35 Sept 2020 Fast rendering option for color displays
|
# V0.3.5 Sept 2020 Fast rendering option for color displays
|
||||||
|
|
||||||
# Released under the MIT License (MIT). See LICENSE.
|
# Released under the MIT License (MIT). See LICENSE.
|
||||||
# Copyright (c) 2019-2021 Peter Hinch
|
# Copyright (c) 2019-2021 Peter Hinch
|
||||||
|
@ -14,35 +15,34 @@
|
||||||
|
|
||||||
# Timings based on a 20 pixel high proportional font, run on a pyboard V1.0.
|
# Timings based on a 20 pixel high proportional font, run on a pyboard V1.0.
|
||||||
# Using CWriter's slow rendering: _printchar 9.5ms typ, 13.5ms max.
|
# Using CWriter's slow rendering: _printchar 9.5ms typ, 13.5ms max.
|
||||||
# Using Writer's fast rendering: _printchar 115μs min 480μs typ 950μs max.
|
|
||||||
|
|
||||||
# CWriter on Pyboard D SF2W at standard clock rate
|
|
||||||
# Fast method 500-600μs typical, up to 1.07ms on larger fonts
|
|
||||||
# Revised fast method 691μs avg, up to 2.14ms on larger fonts
|
|
||||||
# Slow method 2700μs typical, up to 11ms on larger fonts
|
|
||||||
|
|
||||||
import framebuf
|
import framebuf
|
||||||
from uctypes import bytearray_at, addressof
|
from uctypes import bytearray_at, addressof
|
||||||
from sys import platform
|
from sys import implementation
|
||||||
|
import os
|
||||||
|
|
||||||
__version__ = (0, 4, 2)
|
__version__ = (0, 4, 3)
|
||||||
|
|
||||||
fast_mode = platform == 'pyboard'
|
def buildcheck(device):
|
||||||
if fast_mode:
|
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:
|
try:
|
||||||
try:
|
datestring = os.uname()[3]
|
||||||
from framebuf_utils import render
|
date = datestring.split(' on')[1]
|
||||||
except ImportError: # May be running in GUI. Try relative import.
|
date = date.lstrip()[:10]
|
||||||
try:
|
idate = tuple([int(x) for x in date.split('-')])
|
||||||
from .framebuf_utils import render
|
return idate >= (2021, 8, 25)
|
||||||
except ImportError:
|
except AttributeError:
|
||||||
fast_mode = False
|
return False
|
||||||
except ValueError:
|
|
||||||
fast_mode = False
|
|
||||||
if not fast_mode:
|
|
||||||
print('Ignoring missing or invalid framebuf_utils.mpy.')
|
|
||||||
|
|
||||||
|
|
||||||
|
fast_mode = False # False for mono displays although actually these render fast
|
||||||
|
|
||||||
class DisplayState():
|
class DisplayState():
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
self.text_row = 0
|
self.text_row = 0
|
||||||
|
@ -264,12 +264,14 @@ class Writer():
|
||||||
def setcolor(self, *_):
|
def setcolor(self, *_):
|
||||||
return self.fgcolor, self.bgcolor
|
return self.fgcolor, self.bgcolor
|
||||||
|
|
||||||
# Writer for colour displays or upside down rendering
|
# Writer for colour displays.
|
||||||
class CWriter(Writer):
|
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):
|
||||||
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:
|
||||||
|
@ -285,11 +287,12 @@ class CWriter(Writer):
|
||||||
if self.glyph is None:
|
if self.glyph is None:
|
||||||
return # All done
|
return # All done
|
||||||
buf = bytearray_at(addressof(self.glyph), len(self.glyph))
|
buf = bytearray_at(addressof(self.glyph), len(self.glyph))
|
||||||
fbc = framebuf.FrameBuffer(buf, self.char_width, self.char_height, self.map)
|
fbc = framebuf.FrameBuffer(buf, self.clip_width, self.char_height, self.map)
|
||||||
fgcolor = self.bgcolor if invert else self.fgcolor
|
palette = self.device.palette
|
||||||
bgcolor = self.fgcolor if invert else self.bgcolor
|
palette.bg(self.fgcolor if invert else self.bgcolor)
|
||||||
# render clips a glyph if outside bounds of destination
|
palette.fg(self.bgcolor if invert else self.fgcolor)
|
||||||
render(self.device, fbc, s.text_col, s.text_row, fgcolor, bgcolor)
|
|
||||||
|
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
|
||||||
|
|
||||||
|
|
Ładowanie…
Reference in New Issue