Pillow icon indicating copy to clipboard operation
Pillow copied to clipboard

Feature request: Check if glyph exists in font

Open glebm opened this issue 4 months ago • 7 comments

Using the freetype-py library, I can check if a glyph exists in a font like this:

ft_font = freetype.Face(font_path)
exists = ft_font.get_char_index(0x41) != 0

It'd be nice to have this functionality exposed in Pillow as well.

glebm avatar Aug 17 '25 11:08 glebm

Are you interested in immediate solutions at all? I suspect no, since using freetype-py would be a viable immediate solution.

Anyway, for an immediate Pillow-only solution, I would suggest comparing the character's output to the output of the replacement character, U+FFFD.

def checkIfCharacterIsMissing(fontPath, text):
    font = ImageFont.truetype(fontPath)

    w, h = font.getbbox(text)[2:]
    im = Image.new("L", (w, h), 255)
    draw = ImageDraw.Draw(im)
    draw.text((0, 0), text, font=font)

    w, h = font.getbbox("\ufffd")[2:]
    if im.size != (w, h):
        return False
    im2 = Image.new("L", (w, h), 255)
    draw = ImageDraw.Draw(im2)
    draw.text((0, 0), "\ufffd", font=font)

    return im.tobytes() == im2.tobytes()

radarhere avatar Aug 17 '25 12:08 radarhere

I'm using freetype-py for this at the moment, it'd just be nice to be able to do everything via pillow.

https://github.com/diasurgical/devilutionx-font-converter/blob/ac0f0e48bd690ace783c6c1b16e52b569e46f551/src/devilutionx_font_converter/convert.py#L178-L183

It'd also be nice if glyph properties (such as horiAdvance) were exposed via pillow.

glebm avatar Aug 17 '25 12:08 glebm

I can understand why a Pillow user might want to know if a glyph existed or not - so you can avoid drawing it with Pillow.

I'm less convinced that knowing the glyph properties directly fits into Pillow's overall goal. Could you explain to me how it would help a Pillow user generate an image? If you would like it in order to convert fonts, that indeed sounds like a job better suited to freetype-py.

radarhere avatar Aug 17 '25 21:08 radarhere

I'm using pillow to generate textured bitmap fonts for a game from OTF fonts.

For later rendering in-game, the width of each rasterized glyph should be its horizontal advance, which can be larger than the glyph itself. Knowing the horizontal advance lets us know the image width.

glebm avatar Aug 17 '25 22:08 glebm

If you're just talking about horiAdvance, then that should be the value returned by getlength() for horizontal directions.

https://github.com/python-pillow/Pillow/blob/9d39fe6adac233ccd26ba20bff9adda53a1ec89d/src/_imagingft.c#L486 https://github.com/python-pillow/Pillow/blob/9d39fe6adac233ccd26ba20bff9adda53a1ec89d/src/_imagingft.c#L555

radarhere avatar Aug 18 '25 02:08 radarhere

Ah, yeah, that indeed looks like exactly what I need. Thanks Andrew!

glebm avatar Aug 18 '25 08:08 glebm

The PR has received some feedback - https://github.com/python-pillow/Pillow/pull/9160#issuecomment-3405200697

I'm on the fence with this. It feels outside the core focus of Pillow, and it's not too tricky to do this with Pillow in Python:

https://github.com/python-pillow/Pillow/issues/9158#issuecomment-3194350459

Plus it's a even easier with a dedicated FreeType library:

https://github.com/python-pillow/Pillow/issues/9158#issue-3328268124

Any thoughts?

radarhere avatar Oct 20 '25 09:10 radarhere