I am trying to draw some text with Pillow, but the result has some jarring kerning issues. See the 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:
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")
I am trying to draw some text with Pillow, but the result has some jarring kerning issues. See the 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:
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:
This is the code I used to generate the example image: