镜像站点 · 本页由第三方 GitHub 只读镜像提供,非 GitHub 官方站点,不接受任何登录或凭据输入。前往 github.com
Skip to content

Truetype fonts not being rendered correctly with the TEXT method #4177

Closed

Description

@ADBeasley

What did you do?

Created an image suitable for the Pimoroni InkyHat display
Added italic text onto the image object at different places

What did you expect to happen?

The whole of the last character of the text to be displayed as it did to render correctly on Stretch on the Pi Zero
Looking at the font from a Mac (Mojave), the characters look fine.

What actually happened?

Depending on the length of the text, some or all of the last character is missing when using some italic fonts. If the text length is around 105 - 110 pixels then you can lose some / all of the very last character.

Padding out the text string with spaces so it is longer than 110 pixels fixes the issue

What are your OS, Python and Pillow versions?

  • OS: Raspbian Buster Lite (10.1) Kernel 4.19.75+ TIFF incorrect colours #1270 Tue Sep 24 18:38:54 BST 2019 armv6l GNU/Linux (running on a Pi Zero)
  • Python: 3.7.3 - not tested under Python 2
  • Pillow: 6.2.1 (installed using pip3)

The fonts used are available from Font Squirrel - the two are:

Open Sans here
Ubuntu here

from PIL import Image, ImageDraw, ImageFont

image_obj = Image.new('P', (212, 104), color = (255,255,255))
screen_image = ImageDraw.Draw(image_obj)

osbi = ImageFont.truetype('Fonts/OpenSans-BoldItalic.ttf', 15)
screen_image.text((10,10), 'Network Status test',fill = (0,0,0) , font = osbi)
screen_image.text((10,30), 'Bit longer no iffy ending',fill = (0,0,0) , font = osbi)

ubuntu = ImageFont.truetype('Fonts/Ubuntu-BI.ttf', 15)
screen_image.text((10,60), 'Network Status test',fill = (0,0,0) , font = ubuntu)
screen_image.text((10,80), 'Bit longer no iffy ending',fill = (0,0,0) , font = ubuntu)

image_obj.save('italic-test.png')

italic-test

Activity

  1. changed the title [-]Italic true type fonts not being rendered correctly with the TEXT method[/-] [+]Italic truetype fonts not being rendered correctly with the TEXT method[/+] on Oct 29, 2019
  2. changed the title [-]Italic truetype fonts not being rendered correctly with the TEXT method[/-] [+]Truetype fonts not being rendered correctly with the TEXT method[/+] on Oct 29, 2019
  3. ADBeasley commented on Oct 29, 2019

    @ADBeasley
    Author

    Have now discovered that:

    1. It is not only Italic fonts (can reproduce on various 'light' fonts)
    2. The range of ending positions is not limited to 110 Pixels - I now have one at 129 pixels
  4. BeauSlim commented on Nov 5, 2019

    @BeauSlim

    I can replicate this error on macOS with updated libs. I've seen issues similar to this using Pillow to render text for little 1-bit OLED displays.
    It looks like Pillow is using fontmode='1' since you have chosen mode 'P'.
    What happens if you use 'L' or 'RGB' instead of 'P'?
    If you add screen_image.fontmode='L' before rendering text does the problem go away?
    This may be related to #2293 (i.e. it may be a libfreetype problem).

  5. ADBeasley commented on Nov 9, 2019

    @ADBeasley
    Author
  6. radarhere commented on May 21, 2020

    @radarhere
    Member

    @BeauSlim I'm not able to replicate this on my macOS machine. Are you still able to?

  7. BeauSlim commented on May 25, 2020

    @BeauSlim

    I'm not able to replicate this on my macOS machine. Are you still able to?

    Yes. ADBeasley's posted code produces exactly the same image as above on my macOS Catalina machine with Pillow 7.1.2 under brew's Python 3.7.7.

    I played with it a bit. If you manually set screen_image.fontmode='P' the text isn't clipped, so maybe it comes down to the old fontmode '1' problem? And it appears that #2293 is not related to an outdated FreeType library since ImageFont.core.freetype2_version gives me 2.10.1 and I am still getting problems with vertical alignment with mode '1' TTF text:

    ubuntu-sizes

    I ended up converting the fonts I wanted into .bdf format to solve this, so no big deal, but it definitely points to a bug somewhere.

  8. nulano commented on May 25, 2020

    @nulano
    Contributor

    I can actually reproduce #2293 with 7.1.1 from PyPI on Windows 10 using verdanab.ttf (not verdana.ttf). I will comment here, as the other issue is closed. I have a pretty good idea of what might be causing this, I will investigate more when I get more time. The issue happens with all four combinations, both layout_engine RAQM and BASIC, as well as fontmode 1 and L. It is hard to see on L due to the thicker symbols, but the digit 0 is actually clipped at the top, indicating that this is clearly a bug. Additionally, all symbols in that font have atrocious kerning (I suspect this part of the problem):

    verdanab-7 1 1

    My WIP branch (#4553) doesn't have these issues, although I'm not sure it is perfect either.
    Edit: The poor hinting is fixed in the new PR.

    verdanab-7 2 0 dev0

    from PIL import Image, ImageDraw, ImageFont
    im = Image.new("RGB", (400, 100), "white")
    d = ImageDraw.Draw(im)
    def line(y, engine, mode):
        f = ImageFont.truetype("verdanab.ttf", 13, layout_engine=engine)
        d.fontmode = mode
        d.text((10, y), "engine: {}, mode: {}".format(engine, mode), "black", f)
        d.text((170, y), "01234567890123456789", "black", f)
    line(10, 0, '1')  # 0 is basic layout
    line(30, 0, 'L')
    line(50, 1, '1')  # 1 is raqm layout
    line(70, 1, 'L')

    Edit: Corrected images.

  9. nulano commented on May 25, 2020

    @nulano
    Contributor

    I just realized that I forgot to actually test this bug specifically; I can reproduce this issue with both 7.1.1 and my WIP branch, getting practically the same images as OP. Note that it only happens with Basic layout.

  10. nulano commented on May 27, 2020

    @nulano
    Contributor

    I solved this one. The problems is that getsize is called without the mode parameter, thus performing layout with FT_LOAD_TARGET_NORMAL instead of FT_LOAD_TARGET_MONO hinting. The different hinting algorithms can in some circumstances give different results causing this bug.

    Raqm layout always uses FT_LOAD_TARGET_NORMAL hinting for layout, this error doesn't accumulate and in the worst case only one pixel is clipped. Raqm doesn't do hinting during layout, only rendering. Hinting can nudge glyphs at most one pixel which may be clipped.

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

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions