From ba3773714b13bacf891234db316103d943b226f2 Mon Sep 17 00:00:00 2001 From: Benedikt Stebner Date: Thu, 12 Oct 2023 13:49:05 +0200 Subject: [PATCH] Fix text wrapping for languages like chinese that can break at all characters and not just at spaces (#13193) --- .../Media/TextFormatting/TextFormatterImpl.cs | 18 ++++++------------ .../Media/TextFormatting/TextFormatterTests.cs | 16 ++++++++++++++++ 2 files changed, 22 insertions(+), 12 deletions(-) diff --git a/src/Avalonia.Base/Media/TextFormatting/TextFormatterImpl.cs b/src/Avalonia.Base/Media/TextFormatting/TextFormatterImpl.cs index 177ada4934..0b7e74cf1d 100644 --- a/src/Avalonia.Base/Media/TextFormatting/TextFormatterImpl.cs +++ b/src/Avalonia.Base/Media/TextFormatting/TextFormatterImpl.cs @@ -607,19 +607,19 @@ namespace Avalonia.Media.TextFormatting } break; - } + } var clusterLength = Math.Max(0, nextInfo.GlyphCluster - currentInfo.GlyphCluster); - if(clusterLength == 0) + if (clusterLength == 0) { clusterLength = currentRun.Length - runLength; } - if(clusterLength == 0) + if (clusterLength == 0) { clusterLength = shapedTextCharacters.GlyphRun.Metrics.FirstCluster + currentRun.Length - currentInfo.GlyphCluster; - } + } if (currentWidth + clusterWidth > paragraphWidth) { @@ -713,7 +713,7 @@ namespace Avalonia.Media.TextFormatting var measuredLength = MeasureLength(textRuns, paragraphWidth); - if(measuredLength == 0 && paragraphProperties.TextWrapping == TextWrapping.WrapWithOverflow) + if (measuredLength == 0 && paragraphProperties.TextWrapping == TextWrapping.WrapWithOverflow) { for (int i = 0; i < textRuns.Count; i++) { @@ -841,7 +841,7 @@ namespace Avalonia.Media.TextFormatting break; } - if (lineBreak.PositionMeasure != lineBreak.PositionWrap) + if (lineBreak.PositionMeasure != lineBreak.PositionWrap || lineBreak.PositionWrap != currentRun.Length) { lastWrapPosition = currentLength + lineBreak.PositionWrap; } @@ -858,12 +858,6 @@ namespace Avalonia.Media.TextFormatting continue; } - //We don't want to surpass the measuredLength with trailing whitespace when we are in a right to left setting. - if(currentPosition > measuredLength && resolvedFlowDirection == FlowDirection.RightToLeft) - { - break; - } - measuredLength = currentPosition; break; diff --git a/tests/Avalonia.Skia.UnitTests/Media/TextFormatting/TextFormatterTests.cs b/tests/Avalonia.Skia.UnitTests/Media/TextFormatting/TextFormatterTests.cs index a043d6cfa0..4e90425b5f 100644 --- a/tests/Avalonia.Skia.UnitTests/Media/TextFormatting/TextFormatterTests.cs +++ b/tests/Avalonia.Skia.UnitTests/Media/TextFormatting/TextFormatterTests.cs @@ -822,6 +822,22 @@ namespace Avalonia.Skia.UnitTests.Media.TextFormatting } + [Fact] + public void Should_Wrap_Chinese() + { + using (Start()) + { + var defaultRunProperties = new GenericTextRunProperties(Typeface.Default); + var paragraphProperties = new GenericTextParagraphProperties(defaultRunProperties, textWrap: TextWrapping.Wrap); + + var text = "一二三四 TEXT 一二三四五六七八九十零"; + + var textLine = TextFormatter.Current.FormatLine(new SimpleTextSource(text, defaultRunProperties), 0, 120, paragraphProperties); + + Assert.Equal(3, textLine.TextRuns.Count); + } + } + protected readonly record struct SimpleTextSource : ITextSource { private readonly string _text;