11 KiB
Writer and Cwriter classes
These classes facilitate rendering Python font files to displays where the
display driver is subclassed from the framebuf
class. Examples are:
- The official SSD1306 driver.
- The PCD8544/Nokia 5110.
- The Adafruit 0.96 inch color OLED with this driver.
Basic support is for scrolling text display using multiple fonts. The nanogui module has optional extensions for user interface objects displayed at arbitrary locations on screen.
Example code and images are for 128*64 SSD1306 OLED displays.
Scrolling text, multiple fonts.
A field containing variable length text with a border.
Labels and Fields (from nanogui.py).
Contents
- Introduction
1.1 Hardware
1.2 Files
1.3 Fonts - Writer and CWriter classes
2.1 The Writer class For monochrome displays.
2.1.1 Static Method
2.1.2.Constructor
2.1.3 Methods
2.2 The CWriter class For colour displays and for upside-down rendering.
2.2.1 Static Method
2.2.2 Constructor
2.2.3 Methods - Notes
Main README
1. Introduction
The original Writer
class was a proof of concept intended to demonstrate
rendering, on an SSD1306 OLED display, fonts created byfont_to_py.py
.
This update for practical applications has the following features:
- Genarality: capable of working with any
framebuf
derived driver. - Multiple display operation.
- Text display of fixed and variable pitch fonts with wrapping and vertical scrolling.
- Wrap/clip options: clip, character wrap or word wrap.
- Tab support.
- String metrics to enable right or centre justification.
- Inverse (background color on foreground color) display.
- Inverted display option.
Note that these changes have significantly increased code size. On the ESP8266
it is likely that writer.py
will need to be frozen as bytecode. The original
very simple version still exists as writer_minimal.py
.
1.1 Hardware
Tests and demos assume a 128*64 SSD1306 OLED display connected via I2C or SPI.
Wiring is specified in ssd1306_setup.py
. Edit this to use a different bus or
for a non-Pyboard target. At the time of writing the default of software I2C
should be used: the official SSD1306 driver is not compatible with hardware I2C
(see Notes).
1.2 Files
writer.py
SupportsWriter
andCWriter
classes.writer_gui.py
Provides optional GUI objects.ssd1306_setup.py
Hardware initialisation for SSD1306. Requires the official SSD1306 driver.writer_demo.py
Demo using a 128*64 SSD1306 OLED display. Import to see usage information.writer_tests.py
Test/demo scripts. Import to see usage information.writer_minimal.py
A minimal version for highly resource constrained devices.
Sample fonts:
freesans20.py
Variable pitch font file.courier20.py
Fixed pitch font file.font10.py
Smaller variable pitch fonts.font6.py
1.3 Fonts
Python font files should be created using font-to-py.py
using horizontal
mapping (-x
option). The -r
option is not required. If RAM is critical
fonts may be frozen as bytecode reducing the RAM impact of each font to about
340 bytes.
Contents
2. Writer and CWriter classes
The Writer
class provides fast rendering to monochrome displays using bit
blitting. Most applications will use this class.
The CWriter
class is a subclass of Writer
. It can optionally support color
displays. It provides additional functionality in the form of an upside-down
display option. Owing to limitations in the frmebuf.blit
method the
CWriter
class renders glyphs one pixel at a time; rendering is therefore
slower than the Writer
class.
Multiple screens are supported. On any screen multiple Writer
or CWriter
instances may be used, each using a different font. A class variable holds the
state of each screen to ensure that the insertion point is managed across
multiple instances/fonts.
Contents
2.1 The Writer class
This class facilitates rendering characters from Python font files to a device,
assuming the device has a driver subclassed from framebuf
. It supports three
ways of handling text which would overflow the display: clipping, character
wrapping and simple word wrapping.
It handles newline and tab characters, black-on-white inversion, and field blanking to enable variable length contents to be updated at a fixed location.
Typical use with an SSD1306 display and the official driver is as follows:
from ssd1306_setup import WIDTH, HEIGHT, setup
from writer import Writer
import freesans20 # Font to use
use_spi=False # Tested with a 128*64 I2C connected SSD1306 display
ssd = setup(use_spi) # Instantiate display: must inherit from framebuf
# Demo drawing geometric shpes
rhs = WIDTH -1
ssd.line(rhs - 20, 0, rhs, 20, 1) # Demo underlying framebuf methods
square_side = 10
ssd.fill_rect(rhs - square_side, 0, square_side, square_side, 1)
# Instantiate a writer for a specific font
wri = Writer(ssd, freesans20) # verbose = False to suppress console output
Writer.set_textpos(ssd, 0, 0) # In case a previous test has altered this
wri.printstring('Sunday\n12 Aug 2018\n10.30am')
ssd.show()
The file writer_demo.py
illustrates the use of font files with a 128*64
SSD1306 OLED display and the official
SSD1306 driver.
2.1.1 Static Method
The Writer
class exposes the following static method:
set_textpos
Args:device
,row=None
,col=None
. Thedevice
is the display instance. This method determines where on screen subsequent text is to be rendered. The initial value is (0, 0) - the top left corner. Arguments are in pixels with positive values representing down and right respectively. The insertion point defines the top left hand corner of the next character to be output.
Where None
is passed, the setting is left unchanged.
Return: row
, col
current settings.
The insertion point applies to all Writer
instances having the same device.
The insertion point on a given screen is maintained regardless of the font in
use.
2.1.2 Constructor
This takes the following args:
device
The hardware device driver instance for the screen in use.font
A Python font instance.verbose=True
IfTrue
the constructor emits console printout.
2.1.3 Methods
printstring
Args:string
,invert=False
. Outputs a text string at the current insertion point. Newline and Tab characters are honoured. Ifinvert
isTrue
the text is output as black on white.height
No args. Returns the font height in pixels.stringlen
Arg:string
. Returns the length of a string in pixels. Used for right or centre justification.set_clip
Args:row_clip=None
,col_clip=None
,wrap=None
. Ifrow_clip
and/orcol_clip
areTrue
, characters will be clipped if they extend beyond the boundaries of the physical display. Ifcol_clip
isFalse
characters will wrap onto the next line. Ifrow_clip
isFalse
the display will, where necessary, scroll up to ensure the line is rendered. Ifwrap
isTrue
word-wrapping will be performed, assuming words are separated by spaces.
If any arg isNone
, that value will be left unchanged.
Returns the current values ofrow_clip
,col_clip
andwrap
.tabsize
Argvalue=None
. Ifvalue
is an integer sets the tab size. Returns the current tab size (initial default is 4). Tabs only work properly with fixed pitch fonts.
Contents
2.2 The CWriter class
This extends the Writer
class by adding support for upside-down and/or color
displays. A color value is an integer whose interpretation is dependent on the
display hardware and device driver.
2.2.1 Static method
The following static method is added:
invert_display
Argsdevice
,value=True
. Thedevice
is the display instance. Ifvalue
is set, causes text to be rendered upside down. Theset_textpos
method should be called to ensure that text is rendered from the bottom right hand corner (viewing the display in its normal orientation).
If a display is to be run inverted, this method must be called prior to
instantiating a Writer
for this display.
2.2.2 Constructor
This takes the following args:
device
The hardware device driver instance for the screen in use.font
A Python font instance.fgcolor=None
Foreground color. IfNone
a monochrome display is assumed.bgcolor=None
Background color. IfNone
a monochrome display is assumed.verbose=True
IfTrue
the constructor emits console printout.
2.2.3 Methods
All methods of the base class are supported. Additional method:
setcolor
Args:fgcolor=None
,bgcolor=None
. Sets the foreground and background colors. If one isNone
that value is left unchanged. If both areNone
the constructor defaults are restored. Constructor defaults are 1 and 0 for monochrome displays (Writer
). Returns foreground and background color values.
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
).
3. Notes
Possible future enhancements:
- General rendering to a rectangular area. This may be problematic as the
framebuf
scroll method is only capable of scrolling the entire buffer. - Extend word wrapping to cases where words are separated by tabs or hyphens.
- An asynchronous version.
As stated above the official SSD1306 drriver is incompatible with hardware I2C and this problem cannot efficiently be fixed. PR4020 proposes an enhncement which will facilitate an improved SSD1306 driver capable of using hard or soft I2C.