diff --git a/src/Avalonia.Base/Media/TextFormatting/CharacterBufferRange.cs b/src/Avalonia.Base/Media/TextFormatting/CharacterBufferRange.cs
index f5d39e4371..499026e8b3 100644
--- a/src/Avalonia.Base/Media/TextFormatting/CharacterBufferRange.cs
+++ b/src/Avalonia.Base/Media/TextFormatting/CharacterBufferRange.cs
@@ -140,7 +140,7 @@ namespace Avalonia.Media.TextFormatting
throw new ArgumentOutOfRangeException(nameof(index));
}
#endif
- return CharacterBufferReference.CharacterBuffer.Span[CharacterBufferReference.OffsetToFirstChar + index];
+ return CharacterBuffer.Span[CharacterBufferReference.OffsetToFirstChar + index];
}
}
@@ -157,8 +157,7 @@ namespace Avalonia.Media.TextFormatting
///
/// Gets a span from the character buffer range
///
- public ReadOnlySpan Span =>
- CharacterBufferReference.CharacterBuffer.Span.Slice(CharacterBufferReference.OffsetToFirstChar, Length);
+ public ReadOnlySpan Span => CharacterBuffer.Span.Slice(OffsetToFirstChar, Length);
///
/// Gets the character memory buffer
@@ -174,7 +173,7 @@ namespace Avalonia.Media.TextFormatting
///
/// Indicate whether the character buffer range is empty
///
- internal bool IsEmpty => CharacterBufferReference.CharacterBuffer.Length == 0 || Length <= 0;
+ internal bool IsEmpty => CharacterBuffer.Length == 0 || Length <= 0;
internal CharacterBufferRange Take(int length)
{
@@ -208,9 +207,7 @@ namespace Avalonia.Media.TextFormatting
return new CharacterBufferRange(new CharacterBufferReference(), 0);
}
- var characterBufferReference = new CharacterBufferReference(
- CharacterBufferReference.CharacterBuffer,
- CharacterBufferReference.OffsetToFirstChar + length);
+ var characterBufferReference = new CharacterBufferReference(CharacterBuffer, OffsetToFirstChar + length);
return new CharacterBufferRange(characterBufferReference, Length - length);
}
diff --git a/src/Avalonia.Base/Media/TextFormatting/TextFormatterImpl.cs b/src/Avalonia.Base/Media/TextFormatting/TextFormatterImpl.cs
index 544800ecea..989bf7749d 100644
--- a/src/Avalonia.Base/Media/TextFormatting/TextFormatterImpl.cs
+++ b/src/Avalonia.Base/Media/TextFormatting/TextFormatterImpl.cs
@@ -130,7 +130,7 @@ namespace Avalonia.Media.TextFormatting
first.Add(split.First);
second.Add(split.Second!);
- }
+ }
for (var j = 1; j < secondCount; j++)
{
@@ -237,7 +237,7 @@ namespace Avalonia.Media.TextFormatting
var shaperOptions = new TextShaperOptions(currentRun.Properties!.Typeface.GlyphTypeface,
currentRun.Properties.FontRenderingEmSize,
- shapeableRun.BidiLevel, currentRun.Properties.CultureInfo,
+ shapeableRun.BidiLevel, currentRun.Properties.CultureInfo,
paragraphProperties.DefaultIncrementalTab, paragraphProperties.LetterSpacing);
shapedRuns.AddRange(ShapeTogether(groupedRuns, characterBufferReference, length, shaperOptions));
@@ -478,7 +478,7 @@ namespace Avalonia.Media.TextFormatting
{
case ShapedTextRun shapedTextCharacters:
{
- if(shapedTextCharacters.ShapedBuffer.Length > 0)
+ if (shapedTextCharacters.ShapedBuffer.Length > 0)
{
var firstCluster = shapedTextCharacters.ShapedBuffer.GlyphInfos[0].GlyphCluster;
var lastCluster = firstCluster;
@@ -499,7 +499,7 @@ namespace Avalonia.Media.TextFormatting
}
measuredLength += currentRun.Length;
- }
+ }
break;
}
@@ -525,7 +525,7 @@ namespace Avalonia.Media.TextFormatting
}
}
- found:
+ found:
return measuredLength != 0;
}
@@ -565,9 +565,9 @@ namespace Avalonia.Media.TextFormatting
double paragraphWidth, TextParagraphProperties paragraphProperties, FlowDirection resolvedFlowDirection,
TextLineBreak? currentLineBreak)
{
- if(textRuns.Count == 0)
+ if (textRuns.Count == 0)
{
- return CreateEmptyTextLine(firstTextSourceIndex,paragraphWidth, paragraphProperties);
+ return CreateEmptyTextLine(firstTextSourceIndex, paragraphWidth, paragraphProperties);
}
if (!TryMeasureLength(textRuns, paragraphWidth, out var measuredLength))
@@ -583,46 +583,24 @@ namespace Avalonia.Media.TextFormatting
for (var index = 0; index < textRuns.Count; index++)
{
- var currentRun = textRuns[index];
-
- var runText = new CharacterBufferRange(currentRun.CharacterBufferReference, currentRun.Length);
-
- var lineBreaker = new LineBreakEnumerator(runText);
-
var breakFound = false;
- while (lineBreaker.MoveNext())
- {
- if (lineBreaker.Current.Required &&
- currentLength + lineBreaker.Current.PositionMeasure <= measuredLength)
- {
- //Explicit break found
- breakFound = true;
-
- currentPosition = currentLength + lineBreaker.Current.PositionWrap;
-
- break;
- }
+ var currentRun = textRuns[index];
- if (currentLength + lineBreaker.Current.PositionMeasure > measuredLength)
- {
- if (paragraphProperties.TextWrapping == TextWrapping.WrapWithOverflow)
+ switch (currentRun)
+ {
+ case ShapedTextRun:
{
- if (lastWrapPosition > 0)
- {
- currentPosition = lastWrapPosition;
+ var runText = new CharacterBufferRange(currentRun.CharacterBufferReference, currentRun.Length);
- breakFound = true;
+ var lineBreaker = new LineBreakEnumerator(runText);
- break;
- }
-
- //Find next possible wrap position (overflow)
- if (index < textRuns.Count - 1)
+ while (lineBreaker.MoveNext())
{
- if (lineBreaker.Current.PositionWrap != currentRun.Length)
+ if (lineBreaker.Current.Required &&
+ currentLength + lineBreaker.Current.PositionMeasure <= measuredLength)
{
- //We already found the next possible wrap position.
+ //Explicit break found
breakFound = true;
currentPosition = currentLength + lineBreaker.Current.PositionWrap;
@@ -630,51 +608,81 @@ namespace Avalonia.Media.TextFormatting
break;
}
- while (lineBreaker.MoveNext() && index < textRuns.Count)
+ if (currentLength + lineBreaker.Current.PositionMeasure > measuredLength)
{
- currentPosition += lineBreaker.Current.PositionWrap;
-
- if (lineBreaker.Current.PositionWrap != currentRun.Length)
+ if (paragraphProperties.TextWrapping == TextWrapping.WrapWithOverflow)
{
- break;
- }
+ if (lastWrapPosition > 0)
+ {
+ currentPosition = lastWrapPosition;
- index++;
+ breakFound = true;
+
+ break;
+ }
+
+ //Find next possible wrap position (overflow)
+ if (index < textRuns.Count - 1)
+ {
+ if (lineBreaker.Current.PositionWrap != currentRun.Length)
+ {
+ //We already found the next possible wrap position.
+ breakFound = true;
+
+ currentPosition = currentLength + lineBreaker.Current.PositionWrap;
+
+ break;
+ }
+
+ while (lineBreaker.MoveNext() && index < textRuns.Count)
+ {
+ currentPosition += lineBreaker.Current.PositionWrap;
+
+ if (lineBreaker.Current.PositionWrap != currentRun.Length)
+ {
+ break;
+ }
+
+ index++;
+
+ if (index >= textRuns.Count)
+ {
+ break;
+ }
+
+ currentRun = textRuns[index];
+
+ runText = new CharacterBufferRange(currentRun.CharacterBufferReference, currentRun.Length);
+
+ lineBreaker = new LineBreakEnumerator(runText);
+ }
+ }
+ else
+ {
+ currentPosition = currentLength + lineBreaker.Current.PositionWrap;
+ }
+
+ breakFound = true;
- if (index >= textRuns.Count)
- {
break;
}
- currentRun = textRuns[index];
+ //We overflowed so we use the last available wrap position.
+ currentPosition = lastWrapPosition == 0 ? measuredLength : lastWrapPosition;
- runText = new CharacterBufferRange(currentRun.CharacterBufferReference, currentRun.Length);
+ breakFound = true;
- lineBreaker = new LineBreakEnumerator(runText);
+ break;
}
- }
- else
- {
- currentPosition = currentLength + lineBreaker.Current.PositionWrap;
- }
- breakFound = true;
+ if (lineBreaker.Current.PositionMeasure != lineBreaker.Current.PositionWrap)
+ {
+ lastWrapPosition = currentLength + lineBreaker.Current.PositionWrap;
+ }
+ }
break;
}
-
- //We overflowed so we use the last available wrap position.
- currentPosition = lastWrapPosition == 0 ? measuredLength : lastWrapPosition;
-
- breakFound = true;
-
- break;
- }
-
- if (lineBreaker.Current.PositionMeasure != lineBreaker.Current.PositionWrap)
- {
- lastWrapPosition = currentLength + lineBreaker.Current.PositionWrap;
- }
}
if (!breakFound)
@@ -694,7 +702,7 @@ namespace Avalonia.Media.TextFormatting
var remainingCharacters = splitResult.Second;
var lineBreak = remainingCharacters?.Count > 0 ?
- new TextLineBreak(currentLineBreak?.TextEndOfLine, resolvedFlowDirection, remainingCharacters) :
+ new TextLineBreak(null, resolvedFlowDirection, remainingCharacters) :
null;
if (lineBreak is null && currentLineBreak?.TextEndOfLine != null)
diff --git a/src/Avalonia.Base/Media/TextFormatting/TextLeadingPrefixCharacterEllipsis.cs b/src/Avalonia.Base/Media/TextFormatting/TextLeadingPrefixCharacterEllipsis.cs
index 42a84ec137..e30a0fe9f4 100644
--- a/src/Avalonia.Base/Media/TextFormatting/TextLeadingPrefixCharacterEllipsis.cs
+++ b/src/Avalonia.Base/Media/TextFormatting/TextLeadingPrefixCharacterEllipsis.cs
@@ -123,7 +123,7 @@ namespace Avalonia.Media.TextFormatting
switch (run)
{
- case ShapedTextCharacters endShapedRun:
+ case ShapedTextRun endShapedRun:
{
if (endShapedRun.TryMeasureCharactersBackwards(availableSuffixWidth,
out var suffixCount, out var suffixWidth))
diff --git a/src/Avalonia.Base/Media/TextFormatting/TextLineImpl.cs b/src/Avalonia.Base/Media/TextFormatting/TextLineImpl.cs
index 5a71bde522..a1f93bcd07 100644
--- a/src/Avalonia.Base/Media/TextFormatting/TextLineImpl.cs
+++ b/src/Avalonia.Base/Media/TextFormatting/TextLineImpl.cs
@@ -230,12 +230,12 @@ namespace Avalonia.Media.TextFormatting
currentRun = _textRuns[j];
- if(currentRun is not ShapedTextCharacters)
+ if(currentRun is not ShapedTextRun)
{
continue;
}
- shapedRun = (ShapedTextCharacters)currentRun;
+ shapedRun = (ShapedTextRun)currentRun;
if (currentDistance + shapedRun.Size.Width <= distance)
{
diff --git a/src/Avalonia.Base/Media/TextFormatting/TextRun.cs b/src/Avalonia.Base/Media/TextFormatting/TextRun.cs
index 21f85b898f..56232ec9c8 100644
--- a/src/Avalonia.Base/Media/TextFormatting/TextRun.cs
+++ b/src/Avalonia.Base/Media/TextFormatting/TextRun.cs
@@ -44,7 +44,7 @@ namespace Avalonia.Media.TextFormatting
fixed (char* charsPtr = characterBuffer.Span)
{
- return new string(charsPtr, _textRun.CharacterBufferReference.OffsetToFirstChar, _textRun.Length);
+ return new string(charsPtr, 0, _textRun.Length);
}
}
}