There are numerous devices offering bitmapped graphical displays with potential application on the Pyboard. To give two examples of devices which have been interfaced, the Nokia 5110 discussed here http://forum.micropython.org/viewtopic.php?f=5&t=467 and the ePaper display here https://github.com/peterhinch/micropython-epaper.git. A problem common to such devices is that of font rendering: a text character must be converted to a binary bitmap and the latter sent to the device.
My reasons for opening this discussion are as follows. Firstly it isn't my area of expertise and others may be able to offer suggestions. Secondly, my effort with the ePaper display is slow. For this display with its relatively long refresh time this is acceptable, but users of OLED or LCD displays would expect faster - much faster - performance. My interest is in interfacing larger displays such as those sold for the Raspberry Pi but my current view is that acceptably fast font rendering may be a limiting factor.
There are specific Pyboard issues which may limit the potential, primarily a lack of RAM. Limited flash storage is also a problem albeit one readily circumvented with a MicroSD card or other device. Bitmapped font files can be large, especially for larger fonts. The one used in my test program is 25KB in size which is excessive to load into RAM, especially as my device driver necessarily allocates other RAM buffers.
The approach I use is as follows. I use PC based tools to convert a specific size of system font to a bitmap file which is copied to media accessible to the Pyboard. To render a character I perform a file random access and retrieve the bitmap for the character into RAM, then write to the frame buffer on a pixel by pixel basis.
For smaller devices like the Nokia fonts will of necessity be smaller, so loading the entire font into RAM may be feasible. I can also envisage device specific optimisations such as choosing a font size corresponding to an integer number of bytes. But I'd like to explore the possibility of handling arbitrary font sizes on larger displays. I wonder if it's feasible to write fast font rendering code for the Pyboard which is portable between devices?
Font handling
- pythoncoder
- Posts: 5956
- Joined: Fri Jul 18, 2014 8:01 am
- Location: UK
- Contact:
Font handling
Peter Hinch
Index to my micropython libraries.
Index to my micropython libraries.
Re: Font handling
There is a 2D DMA engine built into the Hardware.
It supports graphical operations and can do things like take a 1-bit bitmap and use it to fill in a multi-bit frame-buffer. This copying is typically referred to as blitting.
Bitmapped fonts are typically 1-bit per pixel, black and white images. When you blit you can have it set each output pixel to one color wherever a 1 appears in the original, and a different color wherever a 0 occurs, or only set a pixel where a 1 is and ignore the zero pixels.
You tell 2D DMA engine things like how much to advance the dest pointer when going from line to line, so you normally setup a series of blits to copy each letter.
Some LCDs have their own frame buffer memory (this is typical only for the small ones). Once you get bigger than about 320x240 then the LCDs typically don't provide their own frame buffer and you need to provide one, typically using SDRAM.
The 429 Discovery and M7 Discovery are both LCDs where the frame buffer comes from SDRAM. LCDs like this one: http://www.adafruit.com/products/1480 provide their own framebuffer memory.
I know the 2D DMA engine works with the SDRAM style frame buffers, I'm not sure if it works with the other.
If you've got the extra SDRAM chip, then you can often store uncompressed font bitmaps there, or store them in flash.
Even when you use vector style fonts, you normally rasterize the font and cache the rasterized bitmap and then blit from the cache. That way when you use the same letters, you can grab the pre-rendered characters and blit them. But I would imagine for micropython style projects that just using raster (aka bitmapped) fonts would be sufficient.
It supports graphical operations and can do things like take a 1-bit bitmap and use it to fill in a multi-bit frame-buffer. This copying is typically referred to as blitting.
Bitmapped fonts are typically 1-bit per pixel, black and white images. When you blit you can have it set each output pixel to one color wherever a 1 appears in the original, and a different color wherever a 0 occurs, or only set a pixel where a 1 is and ignore the zero pixels.
You tell 2D DMA engine things like how much to advance the dest pointer when going from line to line, so you normally setup a series of blits to copy each letter.
Some LCDs have their own frame buffer memory (this is typical only for the small ones). Once you get bigger than about 320x240 then the LCDs typically don't provide their own frame buffer and you need to provide one, typically using SDRAM.
The 429 Discovery and M7 Discovery are both LCDs where the frame buffer comes from SDRAM. LCDs like this one: http://www.adafruit.com/products/1480 provide their own framebuffer memory.
I know the 2D DMA engine works with the SDRAM style frame buffers, I'm not sure if it works with the other.
If you've got the extra SDRAM chip, then you can often store uncompressed font bitmaps there, or store them in flash.
Even when you use vector style fonts, you normally rasterize the font and cache the rasterized bitmap and then blit from the cache. That way when you use the same letters, you can grab the pre-rendered characters and blit them. But I would imagine for micropython style projects that just using raster (aka bitmapped) fonts would be sufficient.
- pythoncoder
- Posts: 5956
- Joined: Fri Jul 18, 2014 8:01 am
- Location: UK
- Contact:
Re: Font handling
Thanks for that - plenty of food for thought there. The fundamental choice seems to be between displays suitable for the Pyboard like the Adafruit one you mentioned and those with an SDRAM framebuffer: the latter type presumably needs to be tightly integrated with the microcontroller. I see that a MicroPython port for the STM32F746G is in progress and graphics support for that using the 2D DMA engine would be a nice project once the port is complete. It looks like a very cost-effective board.
I have my doubts whether the 2D DMA engine has anything to offer for SPI connected devices like the Adafruit but it looks extremely capable for SDRAM devices.
I have my doubts whether the 2D DMA engine has anything to offer for SPI connected devices like the Adafruit but it looks extremely capable for SDRAM devices.
Peter Hinch
Index to my micropython libraries.
Index to my micropython libraries.