Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Invalid character spacing #7765

Closed
Askaniy opened this issue Jan 30, 2024 · 3 comments
Closed

Invalid character spacing #7765

Askaniy opened this issue Jan 30, 2024 · 3 comments

Comments

@Askaniy
Copy link

Askaniy commented Jan 30, 2024

What did you do?

Switched project development from openSUSE global Python environment to a virtual environment.

What did you expect to happen?

No changes in font rendering.

What actually happened?

Wrong font spacing appears. This results in uneven letter spacing and uneven alignment. Seems quite similar to #3977
I checked with different TrueType fonts, the problem persists.
There is confirmation that others in the virtual environment have the same render. And the problem has persisted for more than a year.
No bug on 9.1.1 and earlier ones.
On 9.2, the bug behaves a little different: rounding seems to be changed to the other side, and the effect sometimes disappears.

What are your OS, Python and Pillow versions?

  • OS: Linux, openSUSE Tumbleweed
  • Python: the bug tested on versions 3.9−3.11
  • Pillow:
from PIL import Image, ImageDraw, ImageFont
from pathlib import Path

noto = 'NotoSans-DisplayCondensed.ttf'

img = Image.new('RGB', (32, 32), (0, 0, 0))
draw = ImageDraw.Draw(img)
font = ImageFont.truetype(noto, 12)

draw.text((16, 16), '00000', fill=(230, 230, 230), font=font, anchor='mm')

img = img.resize((img.width*16, img.height*16), Image.Resampling.NEAREST)
img.save(Path(__file__).parent.resolve()/'test_img.png')

Comparison of the bagged and not-bagged test results:
image

The impact of this bug on the project looks like this:

@nulano
Copy link
Contributor

nulano commented Jan 30, 2024

This looks like a duplicate of #4483, partially related to #7747 and #6871 as well.
I expect adding layout_engine=ImageFont.Layout.BASIC will produce the results you expect:

font = ImageFont.truetype(noto, 12, layout_engine=ImageFont.Layout.BASIC)

To explain a bit: Pillow can use different methods to compute the positions of glyphs used when rendering text. BASIC layout simply converts character values directly to corresponding glyphs and sums their offsets. RAQM layout uses the libraqm library (which supports more advanced text layout and is recommended for all non-English text) to compute glyph mappings and positions. While BASIC layout rounds the current offset to an exact pixel after each glyph, RAQM layout doesn't seem to do this and IIRC libraqm did not support this at all when I tried it in the past. However, I would not call this a bug, just a different approach to the same problem -- making sure glyphs are rendered at exact pixel coordinates to avoid artifacts.

@Askaniy
Copy link
Author

Askaniy commented Jan 30, 2024

Yes, thanks a lot! The following line reproduces the 9.1.1 behavior.

This is not related to the issue, but can you tell me if there is a solution to the problem of subpixel rendering of shapes such as rounded_rectangle?

@nulano
Copy link
Contributor

nulano commented Jan 30, 2024

This is not related to the issue, but can you tell me if there is a solution to the problem of subpixel rendering of shapes such as rounded_rectangle?

See #5577 (comment)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

3 participants