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

"OSError: array allocation size too large" when setting stroke_width greater than 0 #7287

Closed

Description

@Impasse52

What did you do?

I tried changing the font family completely and trying different values of stroke_width. I can only reproduce this error with the font "Brush King" (link) which is the one that I need for my use case.

Setting stroke_width equal to 0 doesn't cause any exception to pop up and the image is rendered properly; everything else crashes the script immediately with the aforementioned error. Trying, for example, "A Absolute Empire" (link) doesn't crash the script.
I can only increase stroke_width (with no unreasonable restrictions, still works with values up to 100) if I also reduce the font's size down to 21: anything more than that causes trouble.

Something else that I've noticed is that Windows' font manager is particularly slow at opening "Brush King", to the point that the font manager can actually crash, which does not occur with other fonts.

What did you expect to happen?

I expected the script to generate a piece of text with an outline/border as thick as I can specify with stroke_width.

What actually happened?

The script crashes immediately, with a "OSError" exception being thrown. This is what the traceback looks like:

Traceback (most recent call last):
  File "e:\Documents\Misc\Syncthing\Code\Python\Thumbfair\main.py", line 8, in <module>
    draw.text((10, 10), "texttext", fill="white", font=font, stroke_fill='#000000', stroke_width=1)
  File "C:\Users\Impasse\AppData\Local\Programs\Python\Python310\lib\site-packages\PIL\ImageDraw.py", line 550, in text
    draw_text(stroke_ink, stroke_width)
  File "C:\Users\Impasse\AppData\Local\Programs\Python\Python310\lib\site-packages\PIL\ImageDraw.py", line 499, in draw_text
    mask, offset = font.getmask2(
  File "C:\Users\Impasse\AppData\Local\Programs\Python\Python310\lib\site-packages\PIL\ImageFont.py", line 573, in getmask2
    size, offset = self.font.render(
OSError: array allocation size too large

What are your OS, Python and Pillow versions?

  • OS: Windows 11, version 22H2, build 22621.1992
  • Python: 3.11.4
  • Pillow: 10.0.0

Piece of code that crashes immediately:

from PIL import Image, ImageDraw, ImageFont

im = Image.new('RGBA', (400, 400))
draw = ImageDraw.Draw(im)

font = ImageFont.truetype('Brush-King.otf', 50)

draw.text((10, 10), "texttext", fill="white", font=font, stroke_fill='#000000', stroke_width=1)

im.show()

Piece of code that works but does not satisfy my use case (note that the only difference is in the value of stroke_width):

from PIL import Image, ImageDraw, ImageFont

im = Image.new('RGBA', (400, 400))
draw = ImageDraw.Draw(im)

font = ImageFont.truetype('Brush-King.otf', 50)

draw.text((10, 10), "texttext", fill="white", font=font, stroke_fill='#000000', stroke_width=0)

im.show()

Activity

  1. radarhere commented on Jul 15, 2023

    @radarhere
    Member

    This is Array_Too_Large being returned from FreeType after FT_Glyph_Stroke - https://freetype.org/freetype2/docs/reference/ft2-error_code_values.html

    When I test it, this is happening on the letters 'abcdeghkmpqrvz', but not 'fijlnostuxy'.

    I expect that the font is malformed in some way, but I've sent an e-mail to freetype@nongnu.org to confirm with FreeType.

    Details Hi,

    Over at Python Pillow, we’ve had a user asking about https://www.dafont.com/brush-king.font. When Pillow calls FT_Glyph_Stroke on any of the letters abcdeghkmpqrvwz, FreeType returns Array_Too_Large.

    Here’s some code to reproduce the matter.

    FT_Face face = NULL;
    FT_New_Face(library, "Brush King.otf", 0, &face);
    
    FT_Stroker stroker = NULL;
    FT_Stroker_New(library, &stroker);
    
    FT_Stroker_Set(
    	stroker,
    	(FT_Fixed)64,
    	FT_STROKER_LINECAP_ROUND,
    	FT_STROKER_LINEJOIN_ROUND,
    	0);
    
    FT_Load_Glyph(face, 64, FT_LOAD_NO_BITMAP);
    FT_Glyph glyph;
    FT_Get_Glyph(face->glyph, &glyph);
    int error = FT_Glyph_Stroke(&glyph, stroker, 1);
    printf("error %d\n", error);
    

    So, my question - is there something I’ve done incorrectly in the above reproduction, is this a FreeType bug, or is the font simply broken?

    Thanks

  2. radarhere commented on Jul 16, 2023

    @radarhere
    Member

    Here is the response I received

    The font is broken (it contains self-overlapping contours), however, this isn't an issue here. Regardless of that, the error message is correct: For example, glyph 'A' in this font has more than 10000 (on and off) points! Stroking indeed overflows FreeType's built-in size guards.

    On the other hand, this font is completely unsuitable for stroking; it thus doesn't bother me in any way that FreeType can't do that :-)

    Werner

  3. radarhere commented on Jul 17, 2023

    @radarhere
    Member

    So it would seem that the font is complex - too complex for FreeType (a dependency that Pillow uses for text rendering) to handle. And they, in their expertise in dealing exclusively with fonts, feel this situation doesn't need to be solved.

    To be helpful though, I can offer this workaround - just draw black text at 1 pixel offsets in different directions behind the white text.

    from PIL import Image, ImageDraw, ImageFont
    
    im = Image.new('RGBA', (400, 400))
    draw = ImageDraw.Draw(im)
    
    font = ImageFont.truetype('Brush-King.otf', 50)
    
    for x in (-1, 1):
        for y in (-1, 1):
            draw.text((10+x, 10+y), "texttext", fill="black", font=font)
    draw.text((10, 10), "texttext", fill="white", font=font)
    
    im.show()

    workaround

  4. Impasse52 commented on Jul 17, 2023

    @Impasse52
    Author

    It's very unfortunate that the font is broken, because that's the only one that really really works for what I need it for, but your solution is very appreciated! Thank you so much for your effort, both for the email and for the workaround-script (which I'm using and works great).

    One thing that bothers me though, mostly out of curiosity: I've had a friend use the font in Photoshop (I'm basically automizing their workflow) and applying a contour to said font, and they had no problem in doing so, they didn't notice performance issues either. Does this mean that PS likely does not use FreeType's way of applying stroke? I don't know enough about fonts, but this is the only conclusion that I'm able to come to.

  5. radarhere commented on Jul 17, 2023

    @radarhere
    Member

    Photoshop is commercial software, so I don't know exactly what goes on inside - but I doubt it uses FreeType. I found an early comparison between FreeType and Photoshop output, which would hardly have been made if Photoshop was just using FreeType under the hood.

  6. radarhere commented on Jul 17, 2023

    @radarhere
    Member

    You liked the previous comment, which was an answer to your last question, so I'm going to imagine this is now resolved.

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