Skip to content

TextRenderer.RenderTextTo throws ArgumentOutOfRangeException when use WordBreaking.BreakAll and small WrappingLength #384

Description

@JimBobSquarePants

Discussed in #383

Originally posted by mes51 February 14, 2024

Description

WordBreaking.BreakAll and set WrappingLength to a small value, an ArgumentOutOfRangeException will be thrown when attempting to render the glyphs.
As far as I have tried, it appears to be affected by the size of the first character.

Unhandled exception. System.ArgumentOutOfRangeException: Index was out of range. Must be non-negative and less than the size of the collection. (Parameter 'index')
   at System.Collections.Generic.List`1.get_Item(Int32 index)
   at SixLabors.Fonts.TextLayout.TextLine.BidiReOrder()
   at SixLabors.Fonts.TextLayout.BreakLines(ReadOnlySpan`1 text, TextOptions options, BidiRun[] bidiRuns, Dictionary`2 bidiMap, GlyphPositioningCollection positionings, LayoutMode layoutMode)
   at SixLabors.Fonts.TextLayout.ProcessText(ReadOnlySpan`1 text, TextOptions options)
   at SixLabors.Fonts.TextLayout.GenerateLayout(ReadOnlySpan`1 text, TextOptions options)
   at SixLabors.Fonts.TextRenderer.RenderText(ReadOnlySpan`1 text, TextOptions options)
   at SixLabors.Fonts.TextRenderer.RenderText(String text, TextOptions options)
   at SixLabors.Fonts.TextRenderer.RenderTextTo(IGlyphRenderer renderer, String text, TextOptions options)
   at Program.<Main>$(String[] args) in C:\dev\WrappingLengthTest\WrappingLengthTest\Program.cs:line 18

Steps to Reproduce

using SixLabors.Fonts;
using System.Numerics;

var fontFamily = SystemFonts.Get("Yu Gothic");
var font = fontFamily.CreateFont(20.0F);

var textOption = new TextOptions(font);
textOption.WrappingLength = 10.0F;
textOption.WordBreaking = WordBreaking.BreakAll;

// OK
TextRenderer.RenderTextTo(new DummyGlyphRenderer(), "i", textOption);

// OK
TextRenderer.RenderTextTo(new DummyGlyphRenderer(), "v", textOption);

// raise ArgumentOutOfRangeException
TextRenderer.RenderTextTo(new DummyGlyphRenderer(), "a", textOption);

textOption.WrappingLength = 9.0F;

// OK
TextRenderer.RenderTextTo(new DummyGlyphRenderer(), "i", textOption);

// raise ArgumentOutOfRangeException
TextRenderer.RenderTextTo(new DummyGlyphRenderer(), "v", textOption);

// OK
TextRenderer.RenderTextTo(new DummyGlyphRenderer(), "i\r\nv", textOption);

// raise ArgumentOutOfRangeException
TextRenderer.RenderTextTo(new DummyGlyphRenderer(), "v\r\ni", textOption);


class DummyGlyphRenderer : IGlyphRenderer
{
    public void BeginFigure() { }

    public bool BeginGlyph(in FontRectangle bounds, in GlyphRendererParameters parameters) => true;

    public void BeginText(in FontRectangle bounds) { }

    public void CubicBezierTo(Vector2 secondControlPoint, Vector2 thirdControlPoint, Vector2 point) { }

    public TextDecorations EnabledDecorations() => new TextDecorations();

    public void EndFigure() { }

    public void EndGlyph() { }

    public void EndText() { }

    public void LineTo(Vector2 point) { }

    public void MoveTo(Vector2 point) { }

    public void QuadraticBezierTo(Vector2 secondControlPoint, Vector2 point) { }

    public void SetDecoration(TextDecorations textDecorations, Vector2 start, Vector2 end, float thickness) { }
}

System configuration

  • Windows 11 Home 23H2
  • .NET 7
  • SixLabors.Fonts v2.0.1

Metadata

Metadata

Labels

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions