Skip to content

Kerning woes #9898

Description

@rarogcoh

I am trying to draw some text with Pillow, but the result has some jarring kerning issues. See the image:

Image

At bigger sizes the distance between the letter P and the letter o in the word "Power" is as big as half a space, give or take. At lower sizes, the distance between the letter o and the letters lt in the word bolt is also pretty huge (particularly in the line that is 15px or 16px in size).

This is with Noto Sans, but I also tried Droid Sans, Adwaita Sans and Open Sans and they all had this problem, usually with the same letter clusters, although the problem was less prominent in Open Sans.

I do not have this problem with apps on my system that use these fonts. I attached image showing how Kate, Geany and Libre Office Writer display that string and the kerning there looks ok:

Image

The sizes in the apps are standard 12pts, so are the equivalent of the 16px string in Pillow.

I am on Linux (kernel version: 7.1.9-354.current). This is what python3 -m PIL.report says:

--------------------------------------------------------------------
Pillow 12.3.0
Python 3.14.0 (main, Oct 25 2025, 05:06:07) [GCC 15.1.1 20250508]
--------------------------------------------------------------------
...
--------------------------------------------------------------------
--- PIL CORE support ok, compiled for 12.3.0
--- TKINTER support ok, loaded 8.6
--- FREETYPE2 support ok, loaded 2.14.3
--- LITTLECMS2 support ok, loaded 2.19
--- WEBP support ok, loaded 1.6.0
--- AVIF support ok, loaded 1.4.2
--- JPEG support ok, compiled for libjpeg-turbo 3.1.4.1
--- OPENJPEG (JPEG2000) support ok, loaded 2.5.4
--- ZLIB (PNG/ZIP) support ok, loaded 1.3.1.zlib-ng, compiled for zlib-ng 2.3.3
--- LIBTIFF support ok, loaded 4.7.1
--- RAQM (Bidirectional Text) support ok, loaded 0.10.5, fribidi 1.0.15, harfbuzz 14.2.1
*** LIBIMAGEQUANT (Quantization method) support not installed
--- XCB (X protocol) support ok
--------------------------------------------------------------------

This is the code I used to generate the example image:

from PIL import Image, ImageDraw, ImageFont, ImageText

image = Image.new("RGBA", (220, 140), "#fff")
increments = [0, 1, 2, 3, 4, 8, 12]
y = 5
for i in increments:
    font_size = 12 + i
    font = ImageFont.truetype(
        "/usr/share/fonts/truetype/noto-sans-ttf/NotoSans-Regular.ttf",
        font_size,
        layout_engine=ImageFont.Layout.RAQM,
    )
    text_draw = ImageDraw.Draw(image)
    im_text = ImageText.Text(f"Power bolt ({12 + i}px)", font)
    text_draw.text((5, y), im_text, anchor="la", font=font, fill="#000")
    y += font_size
image.save("power_bolt_pillow_raqm.png")

Activity

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

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions