SixLabors / Fonts

:black_nib: Font loading and layout library.
https://sixlabors.com/products/fonts
Other
313 stars 72 forks source link

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

Closed JimBobSquarePants closed 9 months ago

JimBobSquarePants commented 9 months ago

Discussed in https://github.com/SixLabors/Fonts/discussions/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.
$(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