[GH-ISSUE #144] TTF font rendering not perfect for some fonts #619

Closed
opened 2026-03-20 18:11:04 +01:00 by sascha_hemi · 6 comments
Owner

Originally created by @B0rax on GitHub (Oct 13, 2023).
Original GitHub issue: https://github.com/OpenEPaperLink/OpenEPaperLink/issues/144

Describe the bug
If fonts are rendered very big, smooth curves may be rendered incorrectly

To Reproduce
Steps to reproduce the behavior:

  1. use the font "Universe LT Std 49 light ultra condensed" (I attached it here Univers.ttf.zip)
  2. Send Print big characters (like text size 400). This is the json I used: [{"text":[26,5,"12.10.","fonts/Univers.ttf",1,0,400]}]
  3. This is the result:
    OEPL Render

Expected behavior
This is how it looks rendered on macOS:
Bildschirmfoto 2023-10-13 um 07 49 50

As you can see, the corners are rounded incorrectly on the OEPL image.
Here is an overlay of both images:
Overlay

OEPL AP used

env:                ESP32_S3_16_8_YELLOW_AP
build date:         2023-10-08 15:55
esp32 version:      2.01b
filesystem version: 2.01b
psram size:         8341447
flash size:         16777216
--------------------------
Originally created by @B0rax on GitHub (Oct 13, 2023). Original GitHub issue: https://github.com/OpenEPaperLink/OpenEPaperLink/issues/144 **Describe the bug** If fonts are rendered very big, smooth curves may be rendered incorrectly **To Reproduce** Steps to reproduce the behavior: 1. use the font "Universe LT Std 49 light ultra condensed" (I attached it here [Univers.ttf.zip](https://github.com/jjwbruijn/OpenEPaperLink/files/12889867/Univers.ttf.zip)) 2. Send Print big characters (like text size 400). This is the json I used: [{"text":[26,5,"12.10.","fonts/Univers.ttf",1,0,400]}] 3. This is the result: ![OEPL Render](https://github.com/jjwbruijn/OpenEPaperLink/assets/10982690/b07d2310-a2e3-4cbc-94f5-d20522f80481) **Expected behavior** This is how it looks rendered on macOS: ![Bildschirmfoto 2023-10-13 um 07 49 50](https://github.com/jjwbruijn/OpenEPaperLink/assets/10982690/901170f1-0d8f-47c7-95f8-a2a4505937e3) As you can see, the corners are rounded incorrectly on the OEPL image. Here is an overlay of both images: ![Overlay](https://github.com/jjwbruijn/OpenEPaperLink/assets/10982690/917b90ba-12f7-44f4-aa43-a20ebde6cc66) **OEPL AP used** ``` env: ESP32_S3_16_8_YELLOW_AP build date: 2023-10-08 15:55 esp32 version: 2.01b filesystem version: 2.01b psram size: 8341447 flash size: 16777216 -------------------------- ```
sascha_hemi added the bug label 2026-03-20 18:11:04 +01:00
Author
Owner

@nlimper commented on GitHub (Oct 13, 2023):

The truetype rendering is not perfect yet, that's right.

For smaller sizes, there are rounding issues because I didn't put in the 'hinting' part of the rendering (if you want to have a headache, try to read https://developer.apple.com/fonts/TrueType-Reference-Manual/RM03/Chap3.html and https://googlefonts.github.io/how-to-hint-variable-fonts/). But that shouldn't affect the rendering of the bigger font sizes. It indeed looks like there's something wrong with calculating the curves.

You can have a look at https://fontdrop.info/ to see detailed info about the coordinates and curves of individual characters of a font, it helped me a lot. Also, quality of rendering can vary from font to font, so maybe you have more success if you choose a similar but different font.

It's on my list to dive into it some day, but because of the complexity, I have to be in the mood for it. It will come eventually, but if somebody else want to dive into it, I would also be happy.

Pointers:
generateOutline-function in /src/truetype.cpp
reference manual: https://developer.apple.com/fonts/TrueType-Reference-Manual/

<!-- gh-comment-id:1761173395 --> @nlimper commented on GitHub (Oct 13, 2023): The truetype rendering is not perfect yet, that's right. For smaller sizes, there are rounding issues because I didn't put in the 'hinting' part of the rendering (if you want to have a headache, try to read https://developer.apple.com/fonts/TrueType-Reference-Manual/RM03/Chap3.html and https://googlefonts.github.io/how-to-hint-variable-fonts/). But that shouldn't affect the rendering of the bigger font sizes. It indeed looks like there's something wrong with calculating the curves. You can have a look at https://fontdrop.info/ to see detailed info about the coordinates and curves of individual characters of a font, it helped me a lot. Also, quality of rendering can vary from font to font, so maybe you have more success if you choose a similar but different font. It's on my list to dive into it some day, but because of the complexity, I have to be in the mood for it. It will come eventually, but if somebody else want to dive into it, I would also be happy. Pointers: `generateOutline`-function in /src/truetype.cpp reference manual: https://developer.apple.com/fonts/TrueType-Reference-Manual/
Author
Owner

@B0rax commented on GitHub (Oct 14, 2023):

Thanks for the pointers! Don't get me wrong, I think you did an amazing job with the truetype rendering. I just wanted a place to document my findings.

I used the analysing page you linked (font drop) to look how the characters of this particular font are made. For example, here is the top of the "0" character that shows the artefacts:
Bildschirmfoto 2023-10-14 um 09 38 27

This shows me that for this character, we have very long curves.
I looked into the generateOutline function. The calculation of the points on the spline is done here: c4beaa51c8/ESP32_AP-Flasher/src/truetype.cpp (L768-L769)

The calculations looked fine to me, but I plotted them in Geogebra to look at them. (maybe that is not the most efficient way to do it, but it works). This is the result and it looks like the spline is correctly calculated:
Bildschirmfoto 2023-10-14 um 09 47 13

So the calculations of the intermediate points are fine. I will look into it more.

<!-- gh-comment-id:1762704466 --> @B0rax commented on GitHub (Oct 14, 2023): Thanks for the pointers! Don't get me wrong, I think you did an amazing job with the truetype rendering. I just wanted a place to document my findings. I used the analysing page you linked (font drop) to look how the characters of this particular font are made. For example, here is the top of the "0" character that shows the artefacts: ![Bildschirmfoto 2023-10-14 um 09 38 27](https://github.com/jjwbruijn/OpenEPaperLink/assets/10982690/6c530f69-80ae-4254-8715-3c49f12500d4) This shows me that for this character, we have very long curves. I looked into the `generateOutline` function. The calculation of the points on the spline is done here: https://github.com/jjwbruijn/OpenEPaperLink/blob/c4beaa51c8171153472ed257c041242610317010/ESP32_AP-Flasher/src/truetype.cpp#L768-L769 The calculations looked fine to me, but I plotted them in Geogebra to look at them. (maybe that is not the most efficient way to do it, but it works). This is the result and it looks like the spline is correctly calculated: ![Bildschirmfoto 2023-10-14 um 09 47 13](https://github.com/jjwbruijn/OpenEPaperLink/assets/10982690/16988a56-a65d-4126-8152-fba7e65f9a04) So the calculations of the intermediate points are fine. I will look into it more.
Author
Owner

@nlimper commented on GitHub (Oct 15, 2023):

Thanks for checking. It's nice to investigate the cause together.
Is suspect there might be some amplified rounding issues somewhere, however I cannot pinpoint them yet.

The outline is generated in the generateOutline function, but it is not actually drawn. If you activate the commented out parts of the addLine function, the outline is actually drawn. If you then comment out call to the fillGlyph function in line 953, only the outline is generated, without a fill, which maybe give a bit clearer view. Next step I would do is to Serial.print the actual coordinates passed to the addLine function to see if they would make sense.

<!-- gh-comment-id:1763461052 --> @nlimper commented on GitHub (Oct 15, 2023): Thanks for checking. It's nice to investigate the cause together. Is suspect there might be some amplified rounding issues somewhere, however I cannot pinpoint them yet. The outline is generated in the `generateOutline` function, but it is not actually drawn. If you activate the commented out parts of the `addLine` function, the outline is actually drawn. If you then comment out call to the `fillGlyph` function in line 953, only the outline is generated, without a fill, which maybe give a bit clearer view. Next step I would do is to Serial.print the actual coordinates passed to the addLine function to see if they would make sense.
Author
Owner

@nlimper commented on GitHub (Oct 22, 2023):

Found it!
you were very close... It doesn't help to change the starting point during the drawing of the curve... x0 and y0 are needed to draw the line between the intermediate points on the curve, but of course it should not be used in the bezier formula as they change with every line segment.
Changed it to pointsOfCurve[0].x and pointsOfCurve[0].y -> fixed.

Will be soon in a commit in the repo, somewhere in the coming days. Thanks for diving in to this together.

<!-- gh-comment-id:1773952583 --> @nlimper commented on GitHub (Oct 22, 2023): Found it! you were very close... It doesn't help to change the starting point during the drawing of the curve... x0 and y0 are needed to draw the line between the intermediate points on the curve, but of course it should not be used in the bezier formula as they change with every line segment. Changed it to `pointsOfCurve[0].x` and `pointsOfCurve[0].y` -> fixed. Will be soon in a commit in the repo, somewhere in the coming days. Thanks for diving in to this together.
Author
Owner

@B0rax commented on GitHub (Oct 22, 2023):

Nice! Thank you!

<!-- gh-comment-id:1774013440 --> @B0rax commented on GitHub (Oct 22, 2023): Nice! Thank you!
Author
Owner

@nlimper commented on GitHub (Oct 22, 2023):

IMG_4331
IMG_4332

before and after :-)
Fixes in commit a4e19b19ab

<!-- gh-comment-id:1774067527 --> @nlimper commented on GitHub (Oct 22, 2023): ![IMG_4331](https://github.com/jjwbruijn/OpenEPaperLink/assets/4137036/29210a20-dccc-4fd2-8446-5325de34bac6) ![IMG_4332](https://github.com/jjwbruijn/OpenEPaperLink/assets/4137036/1908d1ec-a49b-4746-a717-b99921f3228b) before and after :-) Fixes in commit https://github.com/jjwbruijn/OpenEPaperLink/commit/a4e19b19ab78218cd3e6251c9de081c3aafeeb5a
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: starred/OpenEPaperLink#619