diff --git a/src/Skia/Avalonia.Skia/PlatformRenderInterface.cs b/src/Skia/Avalonia.Skia/PlatformRenderInterface.cs index dd3badb2d8..f34e25299c 100644 --- a/src/Skia/Avalonia.Skia/PlatformRenderInterface.cs +++ b/src/Skia/Avalonia.Skia/PlatformRenderInterface.cs @@ -242,7 +242,7 @@ namespace Avalonia.Skia "Current GPU acceleration backend does not support OpenGL integration"); } - public IGlyphRunImpl CreateGlyphRun(IGlyphTypeface glyphTypeface, double fontRenderingEmSize, IReadOnlyList glyphIndices, + public IGlyphRunImpl CreateGlyphRun(IGlyphTypeface glyphTypeface, double fontRenderingEmSize, IReadOnlyList glyphIndices, IReadOnlyList glyphAdvances, IReadOnlyList glyphOffsets) { if (glyphTypeface == null) @@ -273,7 +273,7 @@ namespace Avalonia.Skia var count = glyphIndices.Count; - if(glyphOffsets != null && glyphAdvances != null) + if (glyphOffsets != null && glyphAdvances != null) { var runBuffer = builder.AllocatePositionedRun(font, count); @@ -295,7 +295,7 @@ namespace Avalonia.Skia } else { - if(glyphAdvances != null) + if (glyphAdvances != null) { var runBuffer = builder.AllocateHorizontalRun(font, count, 0); @@ -304,7 +304,7 @@ namespace Avalonia.Skia var currentX = 0.0; - for (int i = 0; i < glyphOffsets.Count; i++) + for (int i = 0; i < glyphAdvances.Count; i++) { glyphSpan[i] = glyphIndices[i]; @@ -319,7 +319,7 @@ namespace Avalonia.Skia var glyphSpan = runBuffer.GetGlyphSpan(); - for (int i = 0; i < glyphOffsets.Count; i++) + for (int i = 0; i < glyphIndices.Count; i++) { glyphSpan[i] = glyphIndices[i]; } diff --git a/tests/Avalonia.RenderTests/Media/GlyphRunTests.cs b/tests/Avalonia.RenderTests/Media/GlyphRunTests.cs index 1b0193bfdb..31e485448e 100644 --- a/tests/Avalonia.RenderTests/Media/GlyphRunTests.cs +++ b/tests/Avalonia.RenderTests/Media/GlyphRunTests.cs @@ -50,6 +50,66 @@ namespace Avalonia.Direct2D1.RenderTests.Media CompareImages(); } + [Win32Fact("For consistent results")] + public async Task Should_Render_GlyphRun_UnPositioned() + { + var control = new UnPositionedGlyphRunControl + { + [TextElement.ForegroundProperty] = new LinearGradientBrush + { + StartPoint = new RelativePoint(0, 0.5, RelativeUnit.Relative), + EndPoint = new RelativePoint(1, 0.5, RelativeUnit.Relative), + GradientStops = + { + new GradientStop { Color = Colors.Red, Offset = 0 }, + new GradientStop { Color = Colors.Blue, Offset = 1 } + } + } + }; + + Decorator target = new Decorator + { + Padding = new Thickness(8), + Width = 190, + Height = 120, + Child = control + }; + + await RenderToFile(target); + + CompareImages(); + } + + [Win32Fact("For consistent results")] + public async Task Should_Render_GlyphRun_Positioned() + { + var control = new PositionedGlyphRunControl + { + [TextElement.ForegroundProperty] = new LinearGradientBrush + { + StartPoint = new RelativePoint(0, 0.5, RelativeUnit.Relative), + EndPoint = new RelativePoint(1, 0.5, RelativeUnit.Relative), + GradientStops = + { + new GradientStop { Color = Colors.Red, Offset = 0 }, + new GradientStop { Color = Colors.Blue, Offset = 1 } + } + } + }; + + Decorator target = new Decorator + { + Padding = new Thickness(8), + Width = 190, + Height = 120, + Child = control + }; + + await RenderToFile(target); + + CompareImages(); + } + public class GlyphRunGeometryControl : Control { public GlyphRunGeometryControl() @@ -74,5 +134,58 @@ namespace Avalonia.Direct2D1.RenderTests.Media context.DrawGeometry(foreground, null, Geometry); } } + + public class UnPositionedGlyphRunControl : Control + { + public UnPositionedGlyphRunControl() + { + var glyphTypeface = new Typeface(TestFontFamily).GlyphTypeface; + + var glyphIndices = new[] { glyphTypeface.GetGlyph('A'), glyphTypeface.GetGlyph('B'), glyphTypeface.GetGlyph('C') }; + + var characters = new[] { 'A', 'B', 'C' }; + + GlyphRun = new GlyphRun(glyphTypeface, 100, characters, glyphIndices); + } + + public GlyphRun GlyphRun { get; } + + public override void Render(DrawingContext context) + { + var foreground = TextElement.GetForeground(this); + + context.DrawGlyphRun(foreground, GlyphRun); + } + } + + public class PositionedGlyphRunControl : Control + { + public PositionedGlyphRunControl() + { + var glyphTypeface = new Typeface(TestFontFamily).GlyphTypeface; + + var glyphIndices = new[] { glyphTypeface.GetGlyph('A'), glyphTypeface.GetGlyph('B'), glyphTypeface.GetGlyph('C') }; + + var scale = 100.0 / glyphTypeface.Metrics.DesignEmHeight; + + var advance = glyphTypeface.GetGlyphAdvance(glyphIndices[0]) * scale; + + var advances = new[] { advance, advance, advance}; + + var characters = new[] { 'A', 'B', 'C' }; + + GlyphRun = new GlyphRun(glyphTypeface, 100, characters, glyphIndices, advances); + } + + public GlyphRun GlyphRun { get; } + + public override void Render(DrawingContext context) + { + var foreground = TextElement.GetForeground(this); + + context.DrawGlyphRun(foreground, GlyphRun); + } + } + } } diff --git a/tests/TestFiles/Direct2D1/Media/GlyphRun/Should_Render_GlyphRun_Positioned.expected.png b/tests/TestFiles/Direct2D1/Media/GlyphRun/Should_Render_GlyphRun_Positioned.expected.png new file mode 100644 index 0000000000..913266b652 Binary files /dev/null and b/tests/TestFiles/Direct2D1/Media/GlyphRun/Should_Render_GlyphRun_Positioned.expected.png differ diff --git a/tests/TestFiles/Direct2D1/Media/GlyphRun/Should_Render_GlyphRun_UnPositioned.expected.png b/tests/TestFiles/Direct2D1/Media/GlyphRun/Should_Render_GlyphRun_UnPositioned.expected.png new file mode 100644 index 0000000000..913266b652 Binary files /dev/null and b/tests/TestFiles/Direct2D1/Media/GlyphRun/Should_Render_GlyphRun_UnPositioned.expected.png differ diff --git a/tests/TestFiles/Skia/Media/GlyphRun/Should_Render_GlyphRun_Positioned.expected.png b/tests/TestFiles/Skia/Media/GlyphRun/Should_Render_GlyphRun_Positioned.expected.png new file mode 100644 index 0000000000..4b8371541e Binary files /dev/null and b/tests/TestFiles/Skia/Media/GlyphRun/Should_Render_GlyphRun_Positioned.expected.png differ diff --git a/tests/TestFiles/Skia/Media/GlyphRun/Should_Render_GlyphRun_UnPositioned.expected.png b/tests/TestFiles/Skia/Media/GlyphRun/Should_Render_GlyphRun_UnPositioned.expected.png new file mode 100644 index 0000000000..4b8371541e Binary files /dev/null and b/tests/TestFiles/Skia/Media/GlyphRun/Should_Render_GlyphRun_UnPositioned.expected.png differ