SixLabors / ImageSharp.Drawing

:pen: Extensions to ImageSharp containing a cross-platform 2D polygon manipulation API and drawing operations.
https://sixlabors.com/products/imagesharp-drawing/
Other
282 stars 38 forks source link

Can't render this text input by a user. #172

Closed Voochichichi closed 2 years ago

Voochichichi commented 2 years ago

Prerequisites

Description

We generate images of reviews that are left by our users, so really it can be any user input. But there's been a few recent examples where sometimes the user's input doesn't work and here's an example. We THINK that there's some sort of invisible modified character that's causing the issue, and we'd be happy to strip this out if we knew what we were looking for...

Steps to Reproduce

I made the smallest code example I could with only the example text that's breaking. We've used SEGUIEMJ.TTF, taken from a default windows installation, but have also tried some open source fonts such as Google NotoColorEmoji and they also break the same way.

        static async Task Main()
        {
            Image image = new Image<Rgba32>(300, 100);

            FontCollection collection = new FontCollection();
            FontFamily family = collection.Install("C:\\SEGUIEMJ.TTF");
            Font font = family.CreateFont(12, FontStyle.Italic);

            string yourText = "star ⭐️ 🌟 Hands";

            image.Mutate( x=> x.DrawText(yourText, font, Color.Black, new PointF(10, 10))); 
        }

Resultin in the following exception:

This exception was originally thrown at this call stack: System.ThrowHelper.ThrowArgumentOutOfRange_IndexException() System.Collections.Generic.List.this[int].get(int) SixLabors.ImageSharp.Drawing.Shapes.TessellatedMultipolygon.Create(SixLabors.ImageSharp.Drawing.IPath, SixLabors.ImageSharp.Memory.MemoryAllocator) in TessellatedMultipolygon.cs SixLabors.ImageSharp.Drawing.Shapes.Rasterization.PolygonScanner.Create(SixLabors.ImageSharp.Drawing.IPath, int, int, int, SixLabors.ImageSharp.Drawing.IntersectionRule, SixLabors.ImageSharp.Memory.MemoryAllocator) in PolygonScanner.cs SixLabors.ImageSharp.Drawing.Processing.Processors.Text.DrawTextProcessor.CachingGlyphRenderer.Render(SixLabors.ImageSharp.Drawing.IPath) in DrawTextProcessor1.cs SixLabors.ImageSharp.Drawing.Processing.Processors.Text.DrawTextProcessor<TPixel>.CachingGlyphRenderer.EndGlyph() in DrawTextProcessor1.cs SixLabors.Fonts.GlyphInstance.RenderTo(SixLabors.Fonts.IGlyphRenderer, float, System.Numerics.Vector2, System.Numerics.Vector2, float) SixLabors.Fonts.Glyph.RenderTo(SixLabors.Fonts.IGlyphRenderer, System.Numerics.Vector2, float, float, float) SixLabors.Fonts.TextRenderer.RenderText(System.ReadOnlySpan, SixLabors.Fonts.RendererOptions) SixLabors.Fonts.TextRenderer.RenderText(string, SixLabors.Fonts.RendererOptions)

System Configuration

We've experienced this both in production (AWS Lambda netcore3.1) and local dev (windows 10, netcore 3.1)

Voochichichi commented 2 years ago

After the first star (https://www.fileformat.info/info/unicode/char/2b50/index.htm) is We have this character which I think might be the culprit https://www.fileformat.info/info/unicode/char/fe0f/index.htm

And it seems to be this "emoji variation selector" character that is breaking in this scenario?

This the answer to strip any character from this block range? https://www.fileformat.info/info/unicode/block/variation_selectors/index.htm

JimBobSquarePants commented 2 years ago

Can you try running the latest betas from our MyGet feed (linked from the readme). Some local testing suggests we've fixed this.

star ⭐️ 🌟 Hands

Voochichichi commented 2 years ago

@JimBobSquarePants Thanks that actually did the trick! We're just trying to figure out how to get this into our CI/CD pipeline, when do you envision that version being published to nuget?

sherlyTam1 commented 2 years ago

@JimBobSquarePants Thanks for the solution, that worked. But the library seems to be adding some space in place of the "emoji variation selector" character. So the output text on image looks like -> asset when there is actually only a single space in the input text passed to DrawText. Is there a workaround for that?

JimBobSquarePants commented 2 years ago

Yeah. See https://github.com/SixLabors/Fonts/pull/198

This contains a complete rewrite of the layout engine which renders the correct example which I posted above. I’m hoping to get that merged shortly. Once merged we’ll ship a new develop build. A NuGet build will come in the RC.

JimBobSquarePants commented 2 years ago

Hi @AirEssY and @sherlyTam1 I've just pushed an update into the MyGet feed 1.0.0-beta13.15 which contains the fix for this. You can get the feed details from the readme.