|
|
|
@ -905,7 +905,7 @@ namespace Avalonia.Skia.UnitTests.Media.TextFormatting |
|
|
|
Assert.NotNull(textLine.TextLineBreak.TextEndOfLine); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
[Fact] |
|
|
|
public void Should_HitTestStringWithInvisibleRuns() |
|
|
|
{ |
|
|
|
@ -913,7 +913,7 @@ namespace Avalonia.Skia.UnitTests.Media.TextFormatting |
|
|
|
var paragraphProperties = new GenericTextParagraphProperties(defaultRunProperties); |
|
|
|
//var textSource = new ListTextSource(
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
using (Start()) |
|
|
|
{ |
|
|
|
@ -923,7 +923,7 @@ namespace Avalonia.Skia.UnitTests.Media.TextFormatting |
|
|
|
new GenericTextRunProperties(Typeface.Default, foregroundBrush: Brushes.Red)); |
|
|
|
|
|
|
|
var source = new ListTextSource(new InvisibleRun(1), hello, new InvisibleRun(1), world); |
|
|
|
|
|
|
|
|
|
|
|
var textLine = |
|
|
|
TextFormatter.Current.FormatLine(source, 0, double.PositiveInfinity, paragraphProperties); |
|
|
|
|
|
|
|
@ -939,7 +939,7 @@ namespace Avalonia.Skia.UnitTests.Media.TextFormatting |
|
|
|
VerifyHit(8); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
[Fact] |
|
|
|
public void GetTextBounds_For_TextLine_With_ZeroWidthSpaces_Does_Not_Freeze() |
|
|
|
{ |
|
|
|
@ -952,7 +952,7 @@ namespace Avalonia.Skia.UnitTests.Media.TextFormatting |
|
|
|
new GenericTextRunProperties(Typeface.Default, foregroundBrush: Brushes.Black)); |
|
|
|
|
|
|
|
var source = new ListTextSource(text, new InvisibleRun(1), new TextEndOfParagraph()); |
|
|
|
|
|
|
|
|
|
|
|
var textLine = |
|
|
|
TextFormatter.Current.FormatLine(source, 0, double.PositiveInfinity, paragraphProperties); |
|
|
|
|
|
|
|
@ -968,9 +968,9 @@ namespace Avalonia.Skia.UnitTests.Media.TextFormatting |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
[Theory] |
|
|
|
[InlineData(TextWrapping.NoWrap),InlineData(TextWrapping.Wrap),InlineData(TextWrapping.WrapWithOverflow)] |
|
|
|
[InlineData(TextWrapping.NoWrap), InlineData(TextWrapping.Wrap), InlineData(TextWrapping.WrapWithOverflow)] |
|
|
|
public void Line_Formatting_For_Oversized_Embedded_Runs_Does_Not_Produce_Empty_Lines(TextWrapping wrapping) |
|
|
|
{ |
|
|
|
var defaultRunProperties = new GenericTextRunProperties(Typeface.Default, foregroundBrush: Brushes.Black); |
|
|
|
@ -985,25 +985,25 @@ namespace Avalonia.Skia.UnitTests.Media.TextFormatting |
|
|
|
Assert.Equal(200d, textLine.WidthIncludingTrailingWhitespace); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
[Theory] |
|
|
|
[InlineData(TextWrapping.NoWrap),InlineData(TextWrapping.Wrap),InlineData(TextWrapping.WrapWithOverflow)] |
|
|
|
[InlineData(TextWrapping.NoWrap), InlineData(TextWrapping.Wrap), InlineData(TextWrapping.WrapWithOverflow)] |
|
|
|
public void Line_Formatting_For_Oversized_Embedded_Runs_Inside_Normal_Text_Does_Not_Produce_Empty_Lines( |
|
|
|
TextWrapping wrapping) |
|
|
|
{ |
|
|
|
var defaultRunProperties = new GenericTextRunProperties(Typeface.Default, foregroundBrush: Brushes.Black); |
|
|
|
var paragraphProperties = new GenericTextParagraphProperties(defaultRunProperties, |
|
|
|
textWrapping: wrapping); |
|
|
|
|
|
|
|
|
|
|
|
using (Start()) |
|
|
|
{ |
|
|
|
var typeface = new Typeface(FontFamily.Parse("resm:Avalonia.Skia.UnitTests.Fonts?assembly=Avalonia.Skia.UnitTests#DejaVu Sans")); |
|
|
|
|
|
|
|
|
|
|
|
var text1 = new TextCharacters("Hello", |
|
|
|
new GenericTextRunProperties(typeface, foregroundBrush: Brushes.Black)); |
|
|
|
var text2 = new TextCharacters("world", |
|
|
|
new GenericTextRunProperties(typeface, foregroundBrush: Brushes.Black)); |
|
|
|
|
|
|
|
|
|
|
|
var source = new ListTextSource( |
|
|
|
text1, |
|
|
|
new RectangleRun(new Rect(0, 0, 200, 10), Brushes.Aqua), |
|
|
|
@ -1014,15 +1014,15 @@ namespace Avalonia.Skia.UnitTests.Media.TextFormatting |
|
|
|
|
|
|
|
var lines = new List<TextLine>(); |
|
|
|
var dcp = 0; |
|
|
|
for (var c = 0;; c++) |
|
|
|
for (var c = 0; ; c++) |
|
|
|
{ |
|
|
|
Assert.True(c < 1000, "Infinite loop"); |
|
|
|
var textLine = TextFormatter.Current.FormatLine(source, dcp, 30, paragraphProperties); |
|
|
|
Assert.NotNull(textLine); |
|
|
|
lines.Add(textLine); |
|
|
|
dcp += textLine.Length; |
|
|
|
|
|
|
|
if (textLine.TextLineBreak is {} eol && eol.TextEndOfLine is TextEndOfParagraph) |
|
|
|
|
|
|
|
if (textLine.TextLineBreak is { } eol && eol.TextEndOfLine is TextEndOfParagraph) |
|
|
|
break; |
|
|
|
} |
|
|
|
|
|
|
|
@ -1046,25 +1046,25 @@ namespace Avalonia.Skia.UnitTests.Media.TextFormatting |
|
|
|
public override double Indent => default; |
|
|
|
public override double DefaultIncrementalTab => 64; |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
[Fact] |
|
|
|
public void Line_With_IncrementalTab_Should_Return_Correct_Backspace_Position() |
|
|
|
{ |
|
|
|
using (Start()) |
|
|
|
{ |
|
|
|
var typeface = new Typeface(FontFamily.Parse("resm:Avalonia.Skia.UnitTests.Fonts?assembly=Avalonia.Skia.UnitTests#DejaVu Sans")); |
|
|
|
|
|
|
|
|
|
|
|
var defaultRunProperties = new GenericTextRunProperties(typeface, foregroundBrush: Brushes.Black); |
|
|
|
var paragraphProperties = new IncrementalTabProperties(defaultRunProperties); |
|
|
|
|
|
|
|
var text = new TextCharacters("ff", |
|
|
|
new GenericTextRunProperties(typeface, foregroundBrush: Brushes.Black)); |
|
|
|
|
|
|
|
|
|
|
|
var source = new ListTextSource(text); |
|
|
|
|
|
|
|
|
|
|
|
var textLine = TextFormatter.Current.FormatLine(source, 0, double.PositiveInfinity, paragraphProperties); |
|
|
|
Assert.NotNull(textLine); |
|
|
|
|
|
|
|
|
|
|
|
var backspaceHit = textLine.GetBackspaceCaretCharacterHit(new CharacterHit(2)); |
|
|
|
Assert.Equal(1, backspaceHit.FirstCharacterIndex); |
|
|
|
Assert.Equal(0, backspaceHit.TrailingLength); |
|
|
|
@ -1114,6 +1114,102 @@ namespace Avalonia.Skia.UnitTests.Media.TextFormatting |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
[Fact] |
|
|
|
public void DrawableRun_With_Same_Baseline_And_Size_Should_Not_Alter_LineHeight() |
|
|
|
{ |
|
|
|
using (Start()) |
|
|
|
{ |
|
|
|
var text = "ABC"; |
|
|
|
|
|
|
|
var typeface = new Typeface(new FontFamily(new Uri("resm:Avalonia.Skia.UnitTests.Assets?assembly=Avalonia.Skia.UnitTests"), "Noto Mono")); |
|
|
|
var defaultRunProperties = new GenericTextRunProperties(typeface); |
|
|
|
var paragraphProperties = new GenericTextParagraphProperties(defaultRunProperties, textWrapping: TextWrapping.Wrap); |
|
|
|
|
|
|
|
var embeddedTextLine = TextFormatter.Current.FormatLine(new SimpleTextSource(text, defaultRunProperties), 0, 120, paragraphProperties); |
|
|
|
|
|
|
|
Assert.NotNull(embeddedTextLine); |
|
|
|
|
|
|
|
var expectedHeight = embeddedTextLine.Height; |
|
|
|
var expectedBaseline = embeddedTextLine.Baseline; |
|
|
|
|
|
|
|
var textSource = new ListTextSource(new TextCharacters("ABC", defaultRunProperties), new EmbeddedTextLineRun(embeddedTextLine)); |
|
|
|
|
|
|
|
var textLine = TextFormatter.Current.FormatLine(textSource, 0, double.PositiveInfinity, paragraphProperties); |
|
|
|
|
|
|
|
Assert.NotNull(textLine); |
|
|
|
|
|
|
|
Assert.Equal(expectedHeight, textLine.Height); |
|
|
|
|
|
|
|
Assert.Equal(expectedBaseline, textLine.Baseline); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
[Fact] |
|
|
|
public void DrawableRun_With_Same_Baseline_And_BiggerHeight_Should_Not_Alter_Baseline() |
|
|
|
{ |
|
|
|
using (Start()) |
|
|
|
{ |
|
|
|
var text = "ABC"; |
|
|
|
|
|
|
|
var typeface = new Typeface(new FontFamily(new Uri("resm:Avalonia.Skia.UnitTests.Assets?assembly=Avalonia.Skia.UnitTests"), "Noto Mono")); |
|
|
|
var defaultRunProperties = new GenericTextRunProperties(typeface); |
|
|
|
var paragraphProperties = new GenericTextParagraphProperties(defaultRunProperties, textWrapping: TextWrapping.Wrap); |
|
|
|
|
|
|
|
var embeddedTextLine = TextFormatter.Current.FormatLine(new SimpleTextSource(text, defaultRunProperties), 0, 120, paragraphProperties); |
|
|
|
|
|
|
|
Assert.NotNull(embeddedTextLine); |
|
|
|
|
|
|
|
var expectedHeight = embeddedTextLine.Height + 10; |
|
|
|
|
|
|
|
var embeddedSize = new Size(embeddedTextLine.Width, expectedHeight); |
|
|
|
|
|
|
|
var expectedBaseline = embeddedTextLine.Baseline; |
|
|
|
|
|
|
|
var textSource = new ListTextSource(new TextCharacters("ABC", defaultRunProperties), new CustomDrawableRun(embeddedSize, expectedBaseline)); |
|
|
|
|
|
|
|
var textLine = TextFormatter.Current.FormatLine(textSource, 0, double.PositiveInfinity, paragraphProperties); |
|
|
|
|
|
|
|
Assert.NotNull(textLine); |
|
|
|
|
|
|
|
Assert.Equal(expectedHeight, textLine.Height); |
|
|
|
|
|
|
|
Assert.Equal(expectedBaseline, textLine.Baseline); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
private class CustomDrawableRun : DrawableTextRun |
|
|
|
{ |
|
|
|
public CustomDrawableRun(Size size, double baseLine) |
|
|
|
{ |
|
|
|
Size = size; |
|
|
|
Baseline = baseLine; |
|
|
|
} |
|
|
|
|
|
|
|
public override Size Size { get; } |
|
|
|
|
|
|
|
public override double Baseline { get; } |
|
|
|
|
|
|
|
public override void Draw(DrawingContext drawingContext, Point origin) |
|
|
|
{ |
|
|
|
// no op
|
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
private class EmbeddedTextLineRun : DrawableTextRun |
|
|
|
{ |
|
|
|
private readonly TextLine _textLine; |
|
|
|
public EmbeddedTextLineRun(TextLine textLine) |
|
|
|
{ |
|
|
|
_textLine = textLine; |
|
|
|
} |
|
|
|
public override Size Size => new Size(_textLine.Width, _textLine.Height); |
|
|
|
public override double Baseline => _textLine.Baseline; |
|
|
|
public override void Draw(DrawingContext drawingContext, Point origin) |
|
|
|
{ |
|
|
|
_textLine.Draw(drawingContext, origin); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
protected readonly record struct SimpleTextSource : ITextSource |
|
|
|
{ |
|
|
|
private readonly string _text; |
|
|
|
@ -1183,21 +1279,21 @@ namespace Avalonia.Skia.UnitTests.Media.TextFormatting |
|
|
|
return new TextCharacters(_text, new GenericTextRunProperties(Typeface.Default, foregroundBrush: Brushes.Black)); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
internal class ListTextSource : ITextSource |
|
|
|
{ |
|
|
|
private readonly List<TextRun> _runs; |
|
|
|
|
|
|
|
public ListTextSource(params TextRun[] runs) : this((IEnumerable<TextRun>)runs) |
|
|
|
{ |
|
|
|
|
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
public ListTextSource(IEnumerable<TextRun> runs) |
|
|
|
{ |
|
|
|
_runs = runs.ToList(); |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
public TextRun? GetTextRun(int textSourceIndex) |
|
|
|
{ |
|
|
|
var off = 0; |
|
|
|
@ -1240,7 +1336,7 @@ namespace Avalonia.Skia.UnitTests.Media.TextFormatting |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
private class InvisibleRun : TextRun |
|
|
|
{ |
|
|
|
public InvisibleRun(int length) |
|
|
|
|