writer.py: CWriter has create_color method for 4-bit drivers.

pull/45/head
peterhinch 2022-12-06 09:09:21 +00:00
rodzic e1c3f09441
commit 181061f25e
2 zmienionych plików z 77 dodań i 32 usunięć

Wyświetl plik

@ -51,12 +51,12 @@ The `CWriter` class (from nanogui): `Label` objects in two fonts.
     2.1.2.[Constructor](./WRITER.md#212-constructor)
     2.1.3 [Methods](./WRITER.md#213-methods)
2.2 [The CWriter class](./WRITER.md#22-the-cwriter-class) For colour displays.
     2.2.1 [Constructor](./WRITER.md#221-constructor)
     2.2.2 [Methods](./WRITER.md#222-methods)
2.3 [Example color code](./WRITER.md#23-example-color-code)
     2.2.3 [Performance](./WRITER.md#223-performance) A firmware enhancement for color displays.
     2.2.1 [Static Method](./WRITER.md#221-static-method)
     2.2.2 [Constructor](./WRITER.md#221-constructor)
     2.2.3 [Methods](./WRITER.md#222-methods)
2.3 [Example color code](./WRITER.md#23-example-color-code) For most display drivers.
2.4 [Use with 4 bit drivers](./WRITER.md#24-use-with-4-bit-drivers) Color definition uses a different technique.
3. [Icons](./WRITER.md#3-icons) How to render simple icons.
4. [Notes](./WRITER.md#4-notes)
###### [Main README](../README.md)
@ -83,6 +83,8 @@ very simple version still exists as `old_versions/writer_minimal.py`.
## 1.1 Release Notes
V0.5.1 Dec 2022__
Add support for 4 bit color display drivers.
V0.5.0 Sep 2021
With the release of firmware V1.17, color display now requires this version.
This enabled the code to be simplified. For old firmware V0.4.3 is available as
@ -98,11 +100,6 @@ avoids needless word wrapping. The clip option now displays as much of the last
visible glyph as possible: formerly a glyph which would not fit in its entirety
was discarded.
The inverted display option has been withdrawn. It added significant code size
and was not an optimal solution. Display inversion should be done at the device
driver level. Such a solution works for graphics objects and GUI widgets, while
the old option only affected rendered text.
## 1.2 Hardware
Tests and demos assume a 128*64 SSD1306 OLED display connected via I2C or SPI.
@ -254,6 +251,23 @@ drivers provide an `rgb` classmethod which converts RGB values to an integer
suitable for the driver. RGB values are integers in range `0 <= c <= 255` (see
example code below).
### 2.2.1 Static method
The `CWriter` class has one static method `create_color`. This is exclusively
for use with 4 bit color display drivers. It populates the driver's color
lookup table. Args:
1. `ssd` The display instance.
2. `idx` Color number in range 0 <= idx <= 15. These are arbitrary but by
convention 0 is black and 15 white.
3. `r` Red value. Values are in range 0 <= red <= 255.
4. `g` Green value.
5. `b` Blue value.
The return value is the `idx` value, hence a color can be defined as
```python
GREEN = CWriter.create_color(ssd, 1, 0, 255, 0)
```
### 2.2.1 Constructor
This takes the following args:
@ -279,17 +293,6 @@ The `printstring` method works as per the base class except that the string is
rendered in foreground color on background color (or reversed if `invert` is
`True`).
### 2.2.3 Performance
A firmware change [PR7682](https://github.com/micropython/micropython/pull/7682)
enables a substantial improvement to text rendering speed on color displays.
This was incorporated in firmware V1.17, and `writer.py` requires this or later
if using a color display.
The gain in speed resulting from this firmware change depends on the font size,
increasing for larger fonts. Numbers may be found in `writer.py` code comments.
Typical 10-20 pixel fonts see gains on the order of 5-10 times.
###### [Contents](./WRITER.md#contents)
## 2.3 Example color code
@ -346,7 +349,47 @@ wri.setcolor(RED, BLACK) # Colors can be set in constructor or changed dynamica
wri.printstring('Sunday\n12 Aug 2018\n10.30am')
ssd.show()
```
## 2.4 Use with 4 bit drivers
Some color display drivers for larger displays use 4-bit colors: this achieves
a substantial reduction in the size of the frame buffer at the cost of limiting
the number of colors that can be displayed. The driver expands the colors at
run time using a lookup table.
This means that colors must be defined using the `create_color` static method
described above.
```python
from machine import SPI, Pin
from writer import CWriter
import freesans20 # Font to use
from drivers.ili93xx.ili9341 import ILI9341 as SSD
spi = SPI(0, sck=Pin(6), mosi=Pin(7), miso=Pin(4), baudrate=30_000_000)
dc = Pin(8, Pin.OUT, value=0)
cs = Pin(10, Pin.OUT, value=1)
rst = Pin(9, Pin.OUT, value=1)
ssd = SSD(spi, cs, dc, rst)
# Define a few colors
BLACK = CWriter.create_color(ssd, 0, 0, 0, 0)
GREEN = CWriter.create_color(ssd, 1, 0, 255, 0)
RED = CWriter.create_color(ssd, 2, 255,0,0)
YELLOW = CWriter.create_color(ssd, 3, 255, 255, 0)
# Demo drawing geometric shapes using underlying framebuf methods
rhs = ssd.width -1
ssd.line(rhs - 20, 0, rhs, 20, GREEN)
square_side = 10
ssd.fill_rect(rhs - square_side, 0, square_side, square_side, GREEN)
# Instantiate a writer for a specific font
wri = CWriter(ssd, freesans20) # Can set verbose = False to suppress console output
CWriter.set_textpos(ssd, 0, 0) # In case a previous test has altered this
wri.setcolor(RED, BLACK) # Colors can be set in constructor or changed dynamically
wri.printstring('Tuesday\n6th December 2020\n10.30am\n')
wri.setcolor(YELLOW, BLACK)
wri.printstring('Running on a 4-bit driver.')
ssd.show()
```
###### [Contents](./WRITER.md#contents)
# 3. Icons
@ -360,13 +403,3 @@ Instantiate the buttons with e.g. `text="A"`.
Alternatively icons can be created as bitmaps and converted to Python font
files as [described here](../icon_fonts/README.md).
# 4. Notes
Possible future enhancements:
1. General rendering to a rectangular area. This may be problematic as the
`framebuf` scroll method is only capable of scrolling the entire buffer.
2. Extend word wrapping to cases where words are separated by tabs or hyphens.
3. An asynchronous version. Probably needless now we have fast rendering.
These may conflict too much with the desire to keep the RAM footprint low.

Wyświetl plik

@ -1,6 +1,7 @@
# writer.py Implements the Writer class.
# Handles colour, word wrap and tab stops
# V0.5.1 Dec 2022 Support 4-bit color display drivers.
# 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
@ -25,7 +26,7 @@ from uctypes import bytearray_at, addressof
from sys import implementation
import os
__version__ = (0, 5, 0)
__version__ = (0, 5, 1)
fast_mode = True # Does nothing. Kept to avoid breaking code.
@ -255,6 +256,17 @@ class Writer():
# Writer for colour displays.
class CWriter(Writer):
@staticmethod
def create_color(ssd, idx, r, g, b):
c = ssd.rgb(r, g, b)
if not hasattr(ssd, 'lut'):
return c
if not 0 <= idx <= 15:
raise ValueError('Color nos must be 0..15')
x = idx << 1
ssd.lut[x] = c & 0xff
ssd.lut[x + 1] = c >> 8
return idx
def __init__(self, device, font, fgcolor=None, bgcolor=None, verbose=True):
if not hasattr(device, 'palette'):