peterhinch / micropython-font-to-py

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

TT-GO Display fonts shifting right #34

Closed psyc0 closed 3 years ago

psyc0 commented 3 years ago

Hi,

I realize that this might not be an issue in regards to this repo as the intended use with writer is not implemented, however I though I would give it a shot and any pointers would be appreciated.

So basically I'm trying to implement the DS-Digital Font on the https://github.com/russhughes/st7789_mpy driver for micropython and needed some large fonts for a scale. The font itself supports scaling

fc-scan DS-DIGIB.TTF
Pattern has 22 elts (size 32)
        family: "DS-Digital"(s)
        familylang: "en"(s)
        style: "Bold"(s)
        stylelang: "en"(s)
        fullname: "DS-Digital Bold"(s)
        fullnamelang: "en"(s)
        slant: 0(i)(s)
        weight: 200(i)(s)
        width: 100(i)(s)
        foundry: "unknown"(s)
        file: "DS-DIGIB.TTF"(s)
        index: 0(i)(s)
        outline: True(s)
        scalable: True(s)
        charset: 
        0000: 00000000 ffffffff ffffffff 7fffffff 00000000 00000000 00000000 00000000
        0020: 32180000 00010004 00000000 00000000 00000000 00000000 00000000 00000000
(s)
        lang: fj|ho|ia|ie|io|nr|om|so|ss|st|sw|ts|uz|xh|zu|kj|kwm|ms|ng|rn|rw|sn|za(s)
        fontversion: 65536(i)(s)
        fontformat: "TrueType"(s)
        decorative: False(s)
        postscriptname: "DS-Digital-Bold"(s)
        color: False(s)
        symbol: False(s)

converted with: python3 font_to_py.py ds_digital/DS-DIGIB.TTF 96 -c 1234567890 -x -f digit.py trying out in terminal works just fine. python3 font_test.py digit 9

the tft.text() function implemented takes the font as an input as long as I provide some extra vars: WIDTH = 64 #(max_width) HEIGHT = 96 #(height) FIRST = 0x30 #(min_ch) LAST = 0x3F #(max_ch) INDEX = memoryview(_index) FONT = memoryview(_font)

parenthesis are given by functions in your output so thats what I reused for the display driver. FIRST is also given by your script, but in that case it starts one char later since the ?/unknown seems to be first, so in my case with FIRST -1 the corresponding digits are shown for the correct input.

however, my issue is that each char is slightly shifted right, i noticed this when looking at the code, basically where I marked in blue in the screenshot below is what is display on the lcd, and for each digit it is shifted, so 6 for example works just fine and is completely centered on screen, while 0 is just showing tho halves of the digit. Ie they start overlapping as if the width was wrong.

4,5,6 shown how they happen to align, and only 6 gets displayed correctly. https://imgur.com/a/qCwT6bP

Im not sure if they are supposed to be compatible, the original devbis repo linked to your script as a resource so thats why I ended up here :)

I've tried to understand your code as well as I could but its a bit to low-level and intricate for me sadly. Any tips or ideas would help me alot. Thanks

peterhinch commented 3 years ago

Hard for me to comment as I don't have an ST7789 display. Looking at the devbis driver doc I think what he has in mind is to use

map_bitarray_to_rgb565(bitarray, buffer, width, color=WHITE, bg_color=BLACK)

to produce a buffer which can be blitted to the display using

ST7789.blit_buffer(buffer, x, y, width, height)

My utility produces a 1-bit bitarray, so it would seem to be a plausible approach. Perhaps this is what you are doing. If your font is proportional you need to ensure that width is correct for each glyph. But I really don't know how I can help without access to the relevant hardware.

Further, if I were going to tackle this problem I would use a completely different approach. I would write an ST7789 device driver in Python, subclassing the ST7789 from framebuf. The driver would then be compatible with Writer and nano-gui.

psyc0 commented 3 years ago

Yes I understand, I was using the code-example from fonts.py and those seem to bitmapped fonts just like the script created but I'm not sure since some of this info is from devbis and some from russ. :)

But I will try your approach and thanks for the help/tip, very much appreciated.

peterhinch commented 3 years ago

Just a note to keep you in the loop.

To date I've ignored ST7789 because of the size of the required frame buffer. Adafruit displays using this chip are 240*240, so even with 4-bit color it needs 28,800 bytes.

In light of the number of people using this I've changed my mind: I've ordered a display and will write a 4-bit driver which will support Writer and nano-gui. This should be ready in a week or two.

This may or may not meet your needs. Using four bits restricts you to a palette of 16 colors which can be user-defined RGB565 colors. Text can be rendered in arbitrary fonts, basic graphics primitives are supplied by the framebuffer class, and nano-gui provides a range of widgets. However rendering full color images is an obvious non-starter. My drivers are written in Python so are much slower than C drivers. Their intended use case is displaying data from sensors or from connected devices. They are fast enough for this purpose, but you won't be writing shoot-em-up games :)

psyc0 commented 3 years ago

Nice, yeah I really like the TT-GO Display both for size and functionality, but it was really hard to find drivers the first time around though but hopefully they might become more mainstream.

for the purpose of the current build which is just a personal wifi-scale, 16 colors would suffice, it was primarily the bigger size font left so I could use the whole width of the screen, no FPS-games this time :) Yeah I had a look at those and would probably come in handy with the widgets so looking forward to test then, I will keep an eye out here for eventual updates.

peterhinch commented 3 years ago

I have pushed a driver for this display which works on Adafruit hardware.

It is likely to need some adaptation for your display - I will help as far as I can, but lacking hardware I'm afraid you'll need to do most of the work.

A starting point would be to try the demo in the docs (adapted for your physical connections) experimenting with the display mode to see which (if any) produces something vaguely reasonable. Often X or Y offsets are required, as the mapping between the chip RAM and the LCD hardware varies according to the board design. Good luck :)

psyc0 commented 3 years ago

Thanks, I will have a go at it!

peterhinch commented 3 years ago

Any luck?