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

Odd and Even Positions #42

Closed Phisatho closed 1 year ago

Phisatho commented 1 year ago

Thanks to your nanogui and font-to-py, now I can have decent fonts on my ESP32 with built-in 128x64 OLED.

I have noticed that when the label's vertical position is on an even or odd pixel, the characters are displayed differently. Even Row: Arial16-even

Odd Row: Arial16-odd When the top date row starts on an even row, the horizontal lines at the middle and bottom (check the 8 and the twos) are displayed correctly, but the top row is cut-off. When at an odd row pixel, the middle and bottom lines disappear, but the top row is ok.

Is there a solution for this problem?

Font is Arial-16.

peterhinch commented 1 year ago

That is almost certainly a display driver issue. What display and driver combination are you using? I don't recognise your hardware so I'm not sure if I can replicate this.

Phisatho commented 1 year ago

ESP32 with built-in ssd1306 128x64 display

Phisatho commented 1 year ago

I am using theSSD1306 driver that came with nanogui from color_setup import ssd which in turn uses:

from drivers.ssd1306.ssd1306 import SSD1306_I2C as SSD
ssd = SSD(128, 64, i2c)
peterhinch commented 1 year ago

I'll try to replicate this later today.

However I am sure that the problem is with the display/driver combination. It cannot be with the font because a glyph in the Python font file is just a bitmap: its contents are the same wherever it is placed on the screen. Something is happening when that bitmap is rendered to your display.

I suggest you run a test like this (from the docs):

from color_setup import ssd  # Create a display instance
from gui.core.colors import WHITE
from gui.core.nanogui import refresh
refresh(ssd, True)  # Initialise and clear display.
ssd.fill(0)
ssd.line(0, 0, ssd.width - 1, ssd.height - 1, WHITE)  # Diagonal corner-to-corner
ssd.rect(0, 0, 15, 15, WHITE)  # square at top left
ssd.rect(ssd.width -15, ssd.height -15, 15, 15, WHITE)  # square at bottom right
ssd.show()

This should be pixel-perfect - anything less implies a problem with hardware or display driver. The display driver is actually an official driver and is widely used, so a gross fault such as you are seeing is unlikely.

Phisatho commented 1 year ago

Your code resulted in this: peter code Suspecting that some rows are disconnected, I did ssd.fill(1). The result is below. No issues on this. fill With ssd.rect(1,1,15,15, WHITE), I got this: 1,1,15,15 With ssd.rect(1,1,16,16,WHITE): 1,1,16,16 With ssd.rect(2,2,16,16,WHITE): 2,2,16,16 With ssd.rect(2,2,17,17,WHITE): 2,2,17,17

So it definitely has something to do with add/even row numbers. I have a discreet SSD1306 lying somewhere. I will give it a try and report later.

Phisatho commented 1 year ago

I did another test on the same display:

from color_setup import ssd  # Create a display instance
from gui.core.colors import WHITE
from gui.core.nanogui import refresh
refresh(ssd, True)  # Initialise and clear display.
ssd.fill(0)

for y in range(ssd.height-10):
    for x in range(ssd.width-10):
        ssd.fill(0)
        ssd.rect(x, y, 10, 10, WHITE)
        ssd.show()

https://user-images.githubusercontent.com/5249964/179740854-e9670b5f-2f8a-48b9-b984-dd99d4df2662.mp4

peterhinch commented 1 year ago

Your display is defective. If you count the lines on your Fill test there are 32. There should be 64. The diagonal line should not have gaps. The squares should show top and bottom. Every example you've posted confirms that alternate lines are not being displayed.

Sorry to be the bearer of bad news.

Phisatho commented 1 year ago

True. ssd.fill(1) was in fact, drawing alternate lines.