peterhinch / micropython-font-to-py

A Python 3 utility to convert fonts to Python source capable of being frozen as bytecode
MIT License
385 stars 69 forks source link

RAM usage of bigger fonts #11

Closed sistason closed 6 years ago

sistason commented 6 years ago

I'm using this project to get bigger fonts on an ESL8266 with an SSD1306 128x64.

Sadly, while a fontsize of 16, generated with font-to-py works perfectly, any size above that is too big for the ESP. It leads to MemoryError: memory allocation failed, allocating 11713 bytes with font-size 32, on importing the font.py.

As I want to basically get the SSD to display a single, big line (font-size ~60), this blocks me. Is this normal or, hopefully, am I doing something wrong? :)

Font generated by python3 font_to_py.py -f OpenSans_Regular.ttf 48 opensans_regular_48_mono.py Minimal example, crashes at the import:

import ssd1306
from display.writer import Writer
import display.fonts.opensans_regular_48_mono as opensans48

ssd = SSD1306_I2C(128, 64, machine.I2C(etc etc))
wri = Writer(ssd, opensans48)
wri.printstring('Test')
peterhinch commented 6 years ago

Have you installed the Python font file as frozen bytecode? Its RAM usage in that mode should be very low.

sistason commented 6 years ago

Hah, i wondered if bytearrays were always frozen in python or if I forgot something.

No, I just copied the resulting font.py to the ESP and imported it. That's what I got from the readme... Could you tell me where that missing part is written? Maybe I failed, or maybe the documentation is a bit vague there, in which case I could try to improve it? :)

peterhinch commented 6 years ago

See README.md introduction. I thought I'd made it pretty clear, e.g.

Note that the use of frozen bytecode is entirely optional: font files may be imported in the normal way if RAM usage is not an issue.

When you import a normal (non-frozen) Python file, the compiler translates the code into bytecode which is stored in RAM. To create frozen bytecode the Python compiler is run as part of the build process. This produces bytecode which is stored in flash. Even then some attention to detail is required to avoid inadvertent copying to RAM. If you look at the Python code generated by font-to-py you'll see that a memoryview object is used to ensure no copying takes place when a glyph is accessed.

sistason commented 6 years ago

Okay, I see my problem and am now off to building my own firmware ;)

I guess for me personally, dropping "import as frozen bytecode" a couple of time just wasn't enough, as I had no idea what that meant with regard to micropython/firmware.

I could argue that many people start off with an ESP8266 and a display and come to this project in a very early stage of their ESP-development to get bigger fonts. Inserting "build new firmware with the font.py as module, to get it frozen" as a step in the font-to-py, writer, device driver chain would point people in the direction of building custom firmware, which also is a nice way deeper into development and understanding the ESP :)

If you agree, I'd suggest to add something along the following line at the end of the font_to_py.py section in the readme:

The resulting Python source file can then be incorporated into your 
ESP-firmware to be accessible as frozen bytecode.
Note that the use of frozen bytecode is entirely optional: font files 
may be imported in the normal way if RAM usage is not an issue.

Thanks for clarifying that step for me and getting me into knowing how to build my own firmware :)