From e9f969de11c24eda11c52f08d3fe23d8e4c72f3e Mon Sep 17 00:00:00 2001 From: Daniel Date: Wed, 26 Jan 2022 07:28:49 +0100 Subject: [PATCH 1/3] Added failing tests --- .../AvaloniaMocks/MockGlyphTypeface.cs | 6 +- .../Text/TextLineRunTests.cs | 76 ++++++++++++++++++- 2 files changed, 79 insertions(+), 3 deletions(-) diff --git a/test/AvaloniaEdit.Tests/AvaloniaMocks/MockGlyphTypeface.cs b/test/AvaloniaEdit.Tests/AvaloniaMocks/MockGlyphTypeface.cs index 112506f5..5a416fe5 100644 --- a/test/AvaloniaEdit.Tests/AvaloniaMocks/MockGlyphTypeface.cs +++ b/test/AvaloniaEdit.Tests/AvaloniaMocks/MockGlyphTypeface.cs @@ -8,10 +8,12 @@ public class MockGlyphTypeface : IGlyphTypefaceImpl { public const int GlyphAdvance = 8; public const short DefaultFontSize = 10; + public const int GlyphAscent = 2; + public const int GlyphDescent = 10; public short DesignEmHeight => DefaultFontSize; - public int Ascent => 2; - public int Descent => 10; + public int Ascent => GlyphAscent; + public int Descent => GlyphDescent; public int LineGap { get; } public int UnderlinePosition { get; } public int UnderlineThickness { get; } diff --git a/test/AvaloniaEdit.Tests/Text/TextLineRunTests.cs b/test/AvaloniaEdit.Tests/Text/TextLineRunTests.cs index e4fd1aa1..283a6edd 100644 --- a/test/AvaloniaEdit.Tests/Text/TextLineRunTests.cs +++ b/test/AvaloniaEdit.Tests/Text/TextLineRunTests.cs @@ -1,4 +1,5 @@ -using Avalonia.Media; +using Avalonia; +using Avalonia.Media; using Avalonia.Platform; using AvaloniaEdit.AvaloniaMocks; @@ -137,6 +138,79 @@ public void TextEmbeddedObject_Line_Run_Should_Have_Fixed_Glyph_Width() run.GetDistanceFromCharacter(1)); } + [Test] + public void TextEmbeddedObject_Should_Have_Valid_Baseline() + { + using var app = UnitTestApplication.Start(new TestServices().With( + renderInterface: new MockPlatformRenderInterface(), + fontManagerImpl: new MockFontManagerImpl(), + formattedTextImpl: Mock.Of())); + + int runWidth = 50; + + TextLine textLine = Mock.Of( + t => t.WidthIncludingTrailingWhitespace == runWidth); + + SpecialCharacterTextRun f = new SpecialCharacterTextRun( + new FormattedTextElement("BEL", 1) { TextLine = textLine }, + CreateDefaultTextProperties()); + + Mock ts = new Mock(); + ts.Setup(s => s.GetTextRun(It.IsAny())).Returns(f); + + TextLineRun run = TextLineRun.Create(ts.Object, 0, 0, 1, CreateDefaultParagraphProperties()); + + Assert.AreEqual(MockGlyphTypeface.GlyphAscent, run.Baseline); + } + + [Test] + public void Simple_Run_Should_Have_Valid_Baseline() + { + using var app = UnitTestApplication.Start(new TestServices().With( + renderInterface: new MockPlatformRenderInterface(), + fontManagerImpl: new MockFontManagerImpl(), + formattedTextImpl: Mock.Of())); + + SimpleTextSource s = new SimpleTextSource( + "a\ta", + CreateDefaultTextProperties()); + + var paragraphProperties = CreateDefaultParagraphProperties(); + + TextLineRun run = TextLineRun.Create(s, 0, 0, 1, paragraphProperties); + + Assert.AreEqual(MockGlyphTypeface.GlyphAscent, run.Baseline); + } + + [Test] + public void Tab_Glyph_Run_Shuld_Have_Valid_Bounds() + { + using var app = UnitTestApplication.Start(new TestServices().With( + renderInterface: new MockPlatformRenderInterface(), + fontManagerImpl: new MockFontManagerImpl(), + formattedTextImpl: Mock.Of())); + + double runWidth = 50; + double runHeight = 20; + + Mock textLineMock = new Mock(); + textLineMock.Setup( + t => t.WidthIncludingTrailingWhitespace).Returns(runWidth); + textLineMock.Setup( + t => t.Height).Returns(runHeight); + + TabTextElement tabTextElement = new TabTextElement(textLineMock.Object); + + TabGlyphRun tabRun = new TabGlyphRun( + tabTextElement, + CreateDefaultTextProperties()); + + Size runSize = tabRun.GetSize(double.PositiveInfinity); + + Assert.AreEqual(runWidth, runSize.Width, "Wrong run width"); + Assert.AreEqual(runHeight, runSize.Height, "Wrong run height"); + } + TextRunProperties CreateDefaultTextProperties() { return new TextRunProperties() From dd0744c025e12edd97d401d526a04094be4b56ad Mon Sep 17 00:00:00 2001 From: Daniel Date: Wed, 26 Jan 2022 07:29:30 +0100 Subject: [PATCH 2/3] Fixed baseline for TextEmbeddedObjects --- src/AvaloniaEdit/Text/TextLineRun.cs | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/AvaloniaEdit/Text/TextLineRun.cs b/src/AvaloniaEdit/Text/TextLineRun.cs index eac67865..b7ebc644 100644 --- a/src/AvaloniaEdit/Text/TextLineRun.cs +++ b/src/AvaloniaEdit/Text/TextLineRun.cs @@ -41,13 +41,16 @@ public double Baseline { return 0.0; } + + double defaultBaseLine = GetDefaultBaseline(TextRun.Properties.FontMetrics); + if (IsEmbedded && TextRun is TextEmbeddedObject embeddedObject) { var box = embeddedObject.ComputeBoundingBox(); - return box.Y; + return defaultBaseLine - box.Y; } - return GetDefaultBaseline(TextRun.Properties.FontMetrics); + return defaultBaseLine; } } From b0db3839ecf5a59adbebbd83b17014b468aaa5e8 Mon Sep 17 00:00:00 2001 From: Daniel Date: Wed, 26 Jan 2022 07:30:02 +0100 Subject: [PATCH 3/3] Fixed TabGlyphRun bounding box --- .../Rendering/SingleCharacterElementGenerator.cs | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/AvaloniaEdit/Rendering/SingleCharacterElementGenerator.cs b/src/AvaloniaEdit/Rendering/SingleCharacterElementGenerator.cs index c6fac5e5..0853d8f0 100644 --- a/src/AvaloniaEdit/Rendering/SingleCharacterElementGenerator.cs +++ b/src/AvaloniaEdit/Rendering/SingleCharacterElementGenerator.cs @@ -142,7 +142,7 @@ public override bool IsWhitespace(int visualColumn) } } - private sealed class TabTextElement : VisualLineElement + internal sealed class TabTextElement : VisualLineElement { internal readonly TextLine Text; @@ -175,7 +175,7 @@ public override bool IsWhitespace(int visualColumn) } } - private sealed class TabGlyphRun : TextEmbeddedObject + internal sealed class TabGlyphRun : TextEmbeddedObject { private readonly TabTextElement _element; @@ -195,8 +195,9 @@ public TabGlyphRun(TabTextElement element, TextRunProperties properties) public override Size GetSize(double remainingParagraphWidth) { - var width = Math.Min(0, _element.Text.WidthIncludingTrailingWhitespace - 1); - return new Size(width, _element.Text.Height); + return new Size( + _element.Text.WidthIncludingTrailingWhitespace, + _element.Text.Height); } public override Rect ComputeBoundingBox() @@ -206,7 +207,6 @@ public override Rect ComputeBoundingBox() public override void Draw(DrawingContext drawingContext, Point origin) { - origin = origin.WithY(origin.Y - _element.Text.Baseline); _element.Text.Draw(drawingContext, origin); } }