diff --git a/src/Avalonia.Base/Media/TextFormatting/TextLayout.cs b/src/Avalonia.Base/Media/TextFormatting/TextLayout.cs
index 24e9019084..d567ca3f14 100644
--- a/src/Avalonia.Base/Media/TextFormatting/TextLayout.cs
+++ b/src/Avalonia.Base/Media/TextFormatting/TextLayout.cs
@@ -294,7 +294,27 @@ namespace Avalonia.Media.TextFormatting
var endX = textLine.GetDistanceFromCharacterHit(nextCharacterHit);
- return new Rect(startX, currentY, endX - startX, textLine.Height);
+ var width = endX - startX;
+ var adjustedX = startX;
+
+ var lineContentLength = textLine.Length - textLine.NewLineLength;
+
+ if (lineContentLength > 0)
+ {
+ if (textPosition == textLine.FirstTextSourceIndex && textLine.OverhangLeading < 0 && startX > 0)
+ {
+ adjustedX += textLine.OverhangLeading;
+ width -= textLine.OverhangLeading;
+ }
+
+ var lastCharacterPosition = textLine.FirstTextSourceIndex + lineContentLength - 1;
+ if (textPosition >= lastCharacterPosition && textLine.OverhangTrailing < 0)
+ {
+ width -= textLine.OverhangTrailing;
+ }
+ }
+
+ return new Rect(adjustedX, currentY, width, textLine.Height);
}
return new Rect();
diff --git a/src/Avalonia.Base/Media/TextFormatting/TextLineImpl.cs b/src/Avalonia.Base/Media/TextFormatting/TextLineImpl.cs
index 12ae974c26..02f7252450 100644
--- a/src/Avalonia.Base/Media/TextFormatting/TextLineImpl.cs
+++ b/src/Avalonia.Base/Media/TextFormatting/TextLineImpl.cs
@@ -1328,7 +1328,7 @@ namespace Avalonia.Media.TextFormatting
}
}
- var inkBounds = new Rect();
+ Rect? inkBounds = null;
for (var index = 0; index < _textRuns.Length; index++)
{
@@ -1342,7 +1342,14 @@ namespace Avalonia.Media.TextFormatting
var runBounds = glyphRun.InkBounds.Translate(new Vector(widthIncludingWhitespace, offsetY));
- inkBounds = inkBounds.Union(runBounds);
+ if (inkBounds == null)
+ {
+ inkBounds = runBounds;
+ }
+ else
+ {
+ inkBounds = inkBounds.Value.Union(runBounds);
+ }
widthIncludingWhitespace += textRun.Size.Width;
@@ -1354,7 +1361,16 @@ namespace Avalonia.Media.TextFormatting
//Align the bounds at the common baseline
var offsetY = -ascent - drawableTextRun.Baseline;
- inkBounds = inkBounds.Union(new Rect(new Point(widthIncludingWhitespace, offsetY), drawableTextRun.Size));
+ var drawableBounds = new Rect(new Point(widthIncludingWhitespace, offsetY), drawableTextRun.Size);
+
+ if (inkBounds == null)
+ {
+ inkBounds = drawableBounds;
+ }
+ else
+ {
+ inkBounds = inkBounds.Value.Union(drawableBounds);
+ }
widthIncludingWhitespace += drawableTextRun.Size.Width;
@@ -1362,6 +1378,8 @@ namespace Avalonia.Media.TextFormatting
}
}
}
+
+ var finalInkBounds = inkBounds ?? new Rect();
var halfLineGap = lineGap * 0.5;
var naturalHeight = descent - ascent + lineGap;
@@ -1416,18 +1434,18 @@ namespace Avalonia.Media.TextFormatting
}
}
- var extent = inkBounds.Height;
+ var extent = finalInkBounds.Height;
//The height of overhanging pixels at the bottom
- var overhangAfter = inkBounds.Bottom - height + halfLineGap;
+ var overhangAfter = finalInkBounds.Bottom - height + halfLineGap;
//The width of overhanging pixels at the natural alignment point. Positive value means we are inside.
- var overhangLeading = inkBounds.Left;
+ var overhangLeading = finalInkBounds.Left;
//The width of overhanging pixels at the end of the natural bounds. Positive value means we are inside.
- var overhangTrailing = widthIncludingWhitespace - inkBounds.Right;
- var hasOverflowed = MathUtilities.GreaterThan(width, _paragraphWidth);
+ var overhangTrailing = widthIncludingWhitespace - finalInkBounds.Right;
+ var hasOverflowed = width > _paragraphWidth;
- var start = GetParagraphOffsetX(width, widthIncludingWhitespace);
+ var start = GetParagraphOffsetX(width, widthIncludingWhitespace, overhangLeading, overhangTrailing);
- _inkBounds = inkBounds.Translate(new Vector(start, 0));
+ _inkBounds = finalInkBounds.Translate(new Vector(start, 0));
_bounds = new Rect(start, 0, widthIncludingWhitespace, height);
@@ -1453,9 +1471,11 @@ namespace Avalonia.Media.TextFormatting
///
/// The line width.
/// The paragraph width including whitespace.
+ /// The leading overhang.
+ /// The trailing overhang.
/// The paragraph offset.
- private double GetParagraphOffsetX(double width, double widthIncludingTrailingWhitespace)
+ private double GetParagraphOffsetX(double width, double widthIncludingTrailingWhitespace, double overhangLeading, double overhangTrailing)
{
if (double.IsPositiveInfinity(_paragraphWidth))
{
@@ -1492,6 +1512,7 @@ namespace Avalonia.Media.TextFormatting
switch (textAlignment)
{
case TextAlignment.Center:
+ {
var start = (_paragraphWidth - width) / 2;
if (paragraphFlowDirection == FlowDirection.RightToLeft)
@@ -1500,8 +1521,12 @@ namespace Avalonia.Media.TextFormatting
}
return Math.Max(0, start);
+ }
case TextAlignment.Right:
- return Math.Max(0, _paragraphWidth - widthIncludingTrailingWhitespace);
+ {
+ var overhangAdjustment = Math.Min(0, overhangTrailing);
+ return Math.Max(0, _paragraphWidth - widthIncludingTrailingWhitespace + overhangAdjustment);
+ }
default:
return 0;
}
diff --git a/src/Avalonia.Controls/Presenters/TextPresenter.cs b/src/Avalonia.Controls/Presenters/TextPresenter.cs
index 05c74b39e5..7d1a21e020 100644
--- a/src/Avalonia.Controls/Presenters/TextPresenter.cs
+++ b/src/Avalonia.Controls/Presenters/TextPresenter.cs
@@ -370,6 +370,41 @@ namespace Avalonia.Controls.Presenters
return textLayout;
}
+ private double GetLineOffsetX(TextLine line, double controlWidth, TextAlignment textAlignment)
+ {
+ var lineInkStartOffset = line.OverhangLeading;
+ var lineTrailingOverhang = -Math.Min(0, line.OverhangTrailing);
+ var lineLeadingOverhang = -Math.Min(0, line.OverhangLeading);
+ var lineInkWidth = line.WidthIncludingTrailingWhitespace + lineLeadingOverhang + lineTrailingOverhang;
+
+ switch (textAlignment)
+ {
+ case TextAlignment.Center:
+ return (controlWidth - lineInkWidth) / 2 - lineInkStartOffset - line.Start;
+
+ case TextAlignment.Right:
+ return controlWidth - line.WidthIncludingTrailingWhitespace - lineTrailingOverhang - line.Start;
+
+ default: // Left, Justify
+ return -lineInkStartOffset - line.Start;
+ }
+ }
+
+ private TextAlignment GetResolvedTextAlignment()
+ {
+ var textAlignment = TextAlignment;
+ var flowDirection = FlowDirection;
+
+ if (textAlignment == TextAlignment.Start)
+ return flowDirection == FlowDirection.LeftToRight ? TextAlignment.Left : TextAlignment.Right;
+ else if (textAlignment == TextAlignment.End)
+ return flowDirection == FlowDirection.RightToLeft ? TextAlignment.Left : TextAlignment.Right;
+ else if (textAlignment == TextAlignment.DetectFromContent)
+ return TextAlignment.Left;
+
+ return textAlignment;
+ }
+
///
/// Renders the to a drawing context.
///
@@ -383,8 +418,12 @@ namespace Avalonia.Controls.Presenters
context.FillRectangle(background, new Rect(Bounds.Size));
}
+ if (TextLayout.TextLines.Count == 0)
+ {
+ return;
+ }
+
var top = 0d;
- var left = 0.0;
var textHeight = TextLayout.Height;
@@ -402,7 +441,17 @@ namespace Avalonia.Controls.Presenters
}
}
- TextLayout.Draw(context, new Point(left, top));
+ var controlWidth = Bounds.Width;
+ var textAlignment = GetResolvedTextAlignment();
+
+ var currentY = top;
+
+ foreach (var line in TextLayout.TextLines)
+ {
+ var offsetX = GetLineOffsetX(line, controlWidth, textAlignment);
+ line.Draw(context, new Point(offsetX, currentY));
+ currentY += line.Height;
+ }
}
public sealed override void Render(DrawingContext context)
@@ -417,10 +466,35 @@ namespace Avalonia.Controls.Presenters
var length = Math.Max(selectionStart, selectionEnd) - start;
var rects = TextLayout.HitTestTextRange(start, length);
+
+ var controlWidth = Bounds.Width;
+ var textAlignment = GetResolvedTextAlignment();
foreach (var rect in rects)
{
- context.FillRectangle(selectionBrush, PixelRect.FromRect(rect, 1).ToRect(1));
+ var currentY = 0d;
+ TextLine? targetLine = null;
+
+ foreach (var line in TextLayout.TextLines)
+ {
+ if (currentY + line.Height > rect.Y)
+ {
+ targetLine = line;
+ break;
+ }
+ currentY += line.Height;
+ }
+
+ if (targetLine != null)
+ {
+ var offsetX = GetLineOffsetX(targetLine, controlWidth, textAlignment);
+ var transformedRect = rect.WithX(rect.X + offsetX);
+ context.FillRectangle(selectionBrush, PixelRect.FromRect(transformedRect, 1).ToRect(1));
+ }
+ else
+ {
+ context.FillRectangle(selectionBrush, PixelRect.FromRect(rect, 1).ToRect(1));
+ }
}
}
@@ -472,11 +546,18 @@ namespace Avalonia.Controls.Presenters
var lineIndex = TextLayout.GetLineIndexFromCharacterIndex(caretIndex, _lastCharacterHit.TrailingLength > 0);
var textLine = TextLayout.TextLines[lineIndex];
- var x = Math.Floor(_caretBounds.X) + 0.5;
+ var caretX = Math.Max(0, _caretBounds.X);
+
+ var x = Math.Floor(caretX) + 0.5;
var y = Math.Floor(_caretBounds.Y) + 0.5;
var b = Math.Ceiling(_caretBounds.Bottom) - 0.5;
- if (_caretBounds.X > 0 && _caretBounds.X >= textLine.WidthIncludingTrailingWhitespace)
+ var controlWidth = Bounds.Width;
+ var textAlignment = GetResolvedTextAlignment();
+ var offsetX = GetLineOffsetX(textLine, controlWidth, textAlignment);
+ var lineEndX = textLine.WidthIncludingTrailingWhitespace + offsetX + textLine.Start;
+
+ if (caretX > 0 && caretX >= lineEndX)
{
x -= 1;
}
@@ -646,8 +727,17 @@ namespace Avalonia.Controls.Presenters
InvalidateArrange();
- // The textWidth used here is matching that TextBlock uses to measure the text.
- var textWidth = TextLayout.OverhangLeading + TextLayout.WidthIncludingTrailingWhitespace + TextLayout.OverhangTrailing;
+ var maxLeadingOverhang = 0.0;
+ var maxTrailingOverhang = 0.0;
+
+ foreach (var line in TextLayout.TextLines)
+ {
+ maxLeadingOverhang = Math.Max(maxLeadingOverhang, -Math.Min(0, line.OverhangLeading));
+ maxTrailingOverhang = Math.Max(maxTrailingOverhang, -Math.Min(0, line.OverhangTrailing));
+ }
+
+ var textWidth = TextLayout.WidthIncludingTrailingWhitespace + maxLeadingOverhang + maxTrailingOverhang;
+
return new Size(textWidth, TextLayout.Height);
}
@@ -655,8 +745,16 @@ namespace Avalonia.Controls.Presenters
{
var finalWidth = finalSize.Width;
- var textWidth = TextLayout.OverhangLeading + TextLayout.WidthIncludingTrailingWhitespace + TextLayout.OverhangTrailing;
- textWidth = Math.Ceiling(textWidth);
+ var maxLeadingOverhang = 0.0;
+ var maxTrailingOverhang = 0.0;
+
+ foreach (var line in TextLayout.TextLines)
+ {
+ maxLeadingOverhang = Math.Max(maxLeadingOverhang, -Math.Min(0, line.OverhangLeading));
+ maxTrailingOverhang = Math.Max(maxTrailingOverhang, -Math.Min(0, line.OverhangTrailing));
+ }
+
+ var textWidth = Math.Ceiling(TextLayout.WidthIncludingTrailingWhitespace + maxLeadingOverhang + maxTrailingOverhang);
if (finalSize.Width < textWidth)
{
@@ -715,7 +813,9 @@ namespace Avalonia.Controls.Presenters
public void MoveCaretToPoint(Point point)
{
- var hit = TextLayout.HitTestPoint(point);
+ var transformedPoint = TransformPointToTextLayout(point);
+
+ var hit = TextLayout.HitTestPoint(transformedPoint);
UpdateCaret(hit.CharacterHit);
@@ -723,6 +823,36 @@ namespace Avalonia.Controls.Presenters
CaretChanged();
}
+
+ private Point TransformPointToTextLayout(Point point)
+ {
+ if (TextLayout.TextLines.Count == 0)
+ {
+ return point;
+ }
+
+ var controlWidth = Bounds.Width;
+ var textAlignment = GetResolvedTextAlignment();
+
+ var currentY = 0d;
+ TextLine? targetLine = null;
+
+ foreach (var line in TextLayout.TextLines)
+ {
+ if (currentY + line.Height > point.Y)
+ {
+ targetLine = line;
+ break;
+ }
+ currentY += line.Height;
+ }
+
+ targetLine ??= TextLayout.TextLines[TextLayout.TextLines.Count - 1];
+
+ var offsetX = GetLineOffsetX(targetLine, controlWidth, textAlignment);
+
+ return new Point(point.X - offsetX, point.Y);
+ }
public void MoveCaretVertical(LogicalDirection direction = LogicalDirection.Forward)
{
@@ -917,7 +1047,11 @@ namespace Avalonia.Controls.Presenters
distanceY += currentLine.Height;
}
- var caretBounds = new Rect(distanceX, distanceY, 0, textLine.Height);
+ var controlWidth = Bounds.Width;
+ var textAlignment = GetResolvedTextAlignment();
+ var offsetX = GetLineOffsetX(textLine, controlWidth, textAlignment);
+
+ var caretBounds = new Rect(distanceX + offsetX, distanceY, 0, textLine.Height);
if (caretBounds != _caretBounds)
{
diff --git a/src/Avalonia.Controls/TextBlock.cs b/src/Avalonia.Controls/TextBlock.cs
index c70d06ae7f..faa7243535 100644
--- a/src/Avalonia.Controls/TextBlock.cs
+++ b/src/Avalonia.Controls/TextBlock.cs
@@ -628,9 +628,62 @@ namespace Avalonia.Controls
RenderTextLayout(context, new Point(padding.Left, top));
}
+ private double GetLineOffsetX(TextLine line, double controlWidth, TextAlignment textAlignment)
+ {
+ var lineInkStartOffset = line.OverhangLeading;
+ var lineTrailingOverhang = -Math.Min(0, line.OverhangTrailing);
+ var lineLeadingOverhang = -Math.Min(0, line.OverhangLeading);
+ var lineInkWidth = line.WidthIncludingTrailingWhitespace + lineLeadingOverhang + lineTrailingOverhang;
+
+ switch (textAlignment)
+ {
+ case TextAlignment.Center:
+ return (controlWidth - lineInkWidth) / 2 - lineInkStartOffset - line.Start;
+
+ case TextAlignment.Right:
+ return controlWidth - line.WidthIncludingTrailingWhitespace - lineTrailingOverhang - line.Start;
+
+ default: // Left, Justify
+ return -lineInkStartOffset - line.Start;
+ }
+ }
+
+ private TextAlignment GetResolvedTextAlignment()
+ {
+ var textAlignment = TextAlignment;
+ var flowDirection = FlowDirection;
+
+ if (textAlignment == TextAlignment.Start)
+ return flowDirection == FlowDirection.LeftToRight ? TextAlignment.Left : TextAlignment.Right;
+ else if (textAlignment == TextAlignment.End)
+ return flowDirection == FlowDirection.RightToLeft ? TextAlignment.Left : TextAlignment.Right;
+ else if (textAlignment == TextAlignment.DetectFromContent)
+ return TextAlignment.Left;
+
+ return textAlignment;
+ }
+
protected virtual void RenderTextLayout(DrawingContext context, Point origin)
{
- TextLayout.Draw(context, origin);
+ var textLayout = TextLayout;
+
+ if (textLayout.TextLines.Count == 0)
+ {
+ return;
+ }
+
+ var padding = Padding;
+ var controlWidth = Bounds.Width - padding.Left - padding.Right;
+ var textAlignment = GetResolvedTextAlignment();
+
+ var currentY = origin.Y;
+
+ foreach (var line in textLayout.TextLines)
+ {
+ var offsetX = GetLineOffsetX(line, controlWidth, textAlignment);
+ line.Draw(context, new Point(origin.X + offsetX, currentY));
+ currentY += line.Height;
+ }
}
private bool _clearTextInternal;
@@ -748,8 +801,18 @@ namespace Avalonia.Controls
//This implicitly recreated the TextLayout with a new constraint if we previously reset it.
var textLayout = TextLayout;
- // The textWidth used here is matching that TextPresenter uses to measure the text.
- return new Size(textLayout.WidthIncludingTrailingWhitespace, textLayout.Height).Inflate(padding);
+ var maxLeadingOverhang = 0.0;
+ var maxTrailingOverhang = 0.0;
+
+ foreach (var line in textLayout.TextLines)
+ {
+ maxLeadingOverhang = Math.Max(maxLeadingOverhang, -Math.Min(0, line.OverhangLeading));
+ maxTrailingOverhang = Math.Max(maxTrailingOverhang, -Math.Min(0, line.OverhangTrailing));
+ }
+
+ var totalWidth = textLayout.WidthIncludingTrailingWhitespace + maxLeadingOverhang + maxTrailingOverhang;
+
+ return new Size(totalWidth, textLayout.Height).Inflate(padding);
}
protected override Size ArrangeOverride(Size finalSize)
diff --git a/src/Skia/Avalonia.Skia/GlyphRunImpl.cs b/src/Skia/Avalonia.Skia/GlyphRunImpl.cs
index e7f772190d..fefa0d5872 100644
--- a/src/Skia/Avalonia.Skia/GlyphRunImpl.cs
+++ b/src/Skia/Avalonia.Skia/GlyphRunImpl.cs
@@ -67,7 +67,7 @@ namespace Avalonia.Skia
using var font = CreateFont(defaultTextOptions);
- var runBounds = new Rect();
+ Rect? runBounds = null;
var glyphBounds = ArrayPool.Shared.Rent(count);
font.GetGlyphWidths(_glyphIndices, null, glyphBounds.AsSpan(0, count));
@@ -79,14 +79,23 @@ namespace Avalonia.Skia
var gBounds = glyphBounds[i];
var advance = glyphInfos[i].GlyphAdvance;
- runBounds = runBounds.Union(new Rect(currentX + gBounds.Left, gBounds.Top, gBounds.Width, gBounds.Height));
+ var glyphRect = new Rect(currentX + gBounds.Left, gBounds.Top, gBounds.Width, gBounds.Height);
+
+ if (runBounds == null)
+ {
+ runBounds = glyphRect;
+ }
+ else
+ {
+ runBounds = runBounds.Value.Union(glyphRect);
+ }
currentX += advance;
}
ArrayPool.Shared.Return(glyphBounds);
BaselineOrigin = baselineOrigin;
- Bounds = runBounds.Translate(new Vector(baselineOrigin.X, baselineOrigin.Y));
+ Bounds = (runBounds ?? new Rect()).Translate(new Vector(baselineOrigin.X, baselineOrigin.Y));
}
public double FontRenderingEmSize { get; }
diff --git a/tests/Avalonia.RenderTests/Media/TextFormatting/TextLayoutTests.cs b/tests/Avalonia.RenderTests/Media/TextFormatting/TextLayoutTests.cs
index d5406c5593..b2e0936dad 100644
--- a/tests/Avalonia.RenderTests/Media/TextFormatting/TextLayoutTests.cs
+++ b/tests/Avalonia.RenderTests/Media/TextFormatting/TextLayoutTests.cs
@@ -178,7 +178,7 @@ namespace Avalonia.Skia.RenderTests
[Theory]
[InlineData("x", 0, 200, 200 - 7.20, 0, 7.20, FontSizeHeight)]
- [InlineData(stringword, 0, 200, 171.20, 0, 7.20, FontSizeHeight)]
+ [InlineData(stringword, 0, 200, 170.20, 0, 8.20, FontSizeHeight)]
[InlineData(stringword, 3, 200, 200 - 7.20, 0, 7.20, FontSizeHeight)]
public void Should_HitTestPosition_RightAlign_Correctly(
string input, int index, double widthConstraint,
@@ -197,7 +197,7 @@ namespace Avalonia.Skia.RenderTests
[Theory]
[InlineData("x", 0, 200, 100 - 7.20 / 2, 0, 7.20, FontSizeHeight)]
- [InlineData(stringword, 0, 200, 85.6, 0, 7.20, FontSizeHeight)]
+ [InlineData(stringword, 0, 200, 84.6, 0, 8.20, FontSizeHeight)]
[InlineData(stringword, 3, 200, 100 + 7.20, 0, 7.20, FontSizeHeight)]
public void Should_HitTestPosition_CenterAlign_Correctly(
string input, int index, double widthConstraint,
diff --git a/tests/Avalonia.Skia.UnitTests/Media/TextFormatting/TextFormatterTests.cs b/tests/Avalonia.Skia.UnitTests/Media/TextFormatting/TextFormatterTests.cs
index 182c633418..9f60d19c20 100644
--- a/tests/Avalonia.Skia.UnitTests/Media/TextFormatting/TextFormatterTests.cs
+++ b/tests/Avalonia.Skia.UnitTests/Media/TextFormatting/TextFormatterTests.cs
@@ -696,7 +696,8 @@ namespace Avalonia.Skia.UnitTests.Media.TextFormatting
expectedOffset = 50 - textLine.Width / 2;
break;
case TextAlignment.Right:
- expectedOffset = 100 - textLine.WidthIncludingTrailingWhitespace;
+ var overhangAdjustment = Math.Min(0, textLine.OverhangTrailing);
+ expectedOffset = 100 - textLine.WidthIncludingTrailingWhitespace + overhangAdjustment;
break;
}
diff --git a/tests/TestFiles/Skia/Controls/TextBlock/RestrictedHeight_VerticalAlign.expected.png b/tests/TestFiles/Skia/Controls/TextBlock/RestrictedHeight_VerticalAlign.expected.png
index 30e2ca8662..6115fd566f 100644
Binary files a/tests/TestFiles/Skia/Controls/TextBlock/RestrictedHeight_VerticalAlign.expected.png and b/tests/TestFiles/Skia/Controls/TextBlock/RestrictedHeight_VerticalAlign.expected.png differ
diff --git a/tests/TestFiles/Skia/Controls/TextBlock/Should_Account_For_Overhang_Leading_And_Trailing.expected.png b/tests/TestFiles/Skia/Controls/TextBlock/Should_Account_For_Overhang_Leading_And_Trailing.expected.png
index 23267da7df..78b4be7b44 100644
Binary files a/tests/TestFiles/Skia/Controls/TextBlock/Should_Account_For_Overhang_Leading_And_Trailing.expected.png and b/tests/TestFiles/Skia/Controls/TextBlock/Should_Account_For_Overhang_Leading_And_Trailing.expected.png differ
diff --git a/tests/TestFiles/Skia/Controls/TextBlock/Should_Draw_MultiLineText_WithOverHandLeadingTrailing.expected.png b/tests/TestFiles/Skia/Controls/TextBlock/Should_Draw_MultiLineText_WithOverHandLeadingTrailing.expected.png
index 7b4541d3f8..f1fedd01f3 100644
Binary files a/tests/TestFiles/Skia/Controls/TextBlock/Should_Draw_MultiLineText_WithOverHandLeadingTrailing.expected.png and b/tests/TestFiles/Skia/Controls/TextBlock/Should_Draw_MultiLineText_WithOverHandLeadingTrailing.expected.png differ
diff --git a/tests/TestFiles/Skia/Controls/TextBlock/Should_Keep_TrailingWhiteSpace.expected.png b/tests/TestFiles/Skia/Controls/TextBlock/Should_Keep_TrailingWhiteSpace.expected.png
index ff8f49b60b..f345fc35bb 100644
Binary files a/tests/TestFiles/Skia/Controls/TextBlock/Should_Keep_TrailingWhiteSpace.expected.png and b/tests/TestFiles/Skia/Controls/TextBlock/Should_Keep_TrailingWhiteSpace.expected.png differ
diff --git a/tests/TestFiles/Skia/Controls/TextBlock/Should_Measure_Arrange_TextBlock_44_NoWrap.expected.png b/tests/TestFiles/Skia/Controls/TextBlock/Should_Measure_Arrange_TextBlock_44_NoWrap.expected.png
index 0d407ba1ee..6be98a4fea 100644
Binary files a/tests/TestFiles/Skia/Controls/TextBlock/Should_Measure_Arrange_TextBlock_44_NoWrap.expected.png and b/tests/TestFiles/Skia/Controls/TextBlock/Should_Measure_Arrange_TextBlock_44_NoWrap.expected.png differ
diff --git a/tests/TestFiles/Skia/Controls/TextBlock/Should_Measure_Arrange_TextBlock_44_Wrap.expected.png b/tests/TestFiles/Skia/Controls/TextBlock/Should_Measure_Arrange_TextBlock_44_Wrap.expected.png
index 39f21bd807..e1d2a574c2 100644
Binary files a/tests/TestFiles/Skia/Controls/TextBlock/Should_Measure_Arrange_TextBlock_44_Wrap.expected.png and b/tests/TestFiles/Skia/Controls/TextBlock/Should_Measure_Arrange_TextBlock_44_Wrap.expected.png differ
diff --git a/tests/TestFiles/Skia/Controls/TextBox/Placeholder_With_Blue_Foreground.expected.png b/tests/TestFiles/Skia/Controls/TextBox/Placeholder_With_Blue_Foreground.expected.png
index d2262f7e52..fd82dfb4bc 100644
Binary files a/tests/TestFiles/Skia/Controls/TextBox/Placeholder_With_Blue_Foreground.expected.png and b/tests/TestFiles/Skia/Controls/TextBox/Placeholder_With_Blue_Foreground.expected.png differ
diff --git a/tests/TestFiles/Skia/Controls/TextBox/Placeholder_With_Default_Foreground.expected.png b/tests/TestFiles/Skia/Controls/TextBox/Placeholder_With_Default_Foreground.expected.png
index 770ff257b4..2ea296ee0e 100644
Binary files a/tests/TestFiles/Skia/Controls/TextBox/Placeholder_With_Default_Foreground.expected.png and b/tests/TestFiles/Skia/Controls/TextBox/Placeholder_With_Default_Foreground.expected.png differ
diff --git a/tests/TestFiles/Skia/Controls/TextBox/Placeholder_With_Red_Foreground.expected.png b/tests/TestFiles/Skia/Controls/TextBox/Placeholder_With_Red_Foreground.expected.png
index 4d2bc5d78b..05ecbea9a2 100644
Binary files a/tests/TestFiles/Skia/Controls/TextBox/Placeholder_With_Red_Foreground.expected.png and b/tests/TestFiles/Skia/Controls/TextBox/Placeholder_With_Red_Foreground.expected.png differ