Browse Source

Simply ShapedBuffer GlyphInfos access

Benedikt Stebner 2 years ago
parent
commit
edbfd96b2d

+ 6 - 5
Avalonia.sln

@@ -555,9 +555,14 @@ Global
 		{75C47156-C5D8-44BC-A5A7-E8657C2248D6}.Debug|Any CPU.Build.0 = Debug|Any CPU
 		{75C47156-C5D8-44BC-A5A7-E8657C2248D6}.Release|Any CPU.ActiveCfg = Release|Any CPU
 		{75C47156-C5D8-44BC-A5A7-E8657C2248D6}.Release|Any CPU.Build.0 = Release|Any CPU
+		{C810060E-3809-4B74-A125-F11533AF9C1B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
 		{C810060E-3809-4B74-A125-F11533AF9C1B}.Debug|Any CPU.Build.0 = Debug|Any CPU
 		{C810060E-3809-4B74-A125-F11533AF9C1B}.Release|Any CPU.ActiveCfg = Release|Any CPU
 		{C810060E-3809-4B74-A125-F11533AF9C1B}.Release|Any CPU.Build.0 = Release|Any CPU
+		{C692FE73-43DB-49CE-87FC-F03ED61F25C9}.Debug|Any CPU.ActiveCfg = Release|Any CPU
+		{C692FE73-43DB-49CE-87FC-F03ED61F25C9}.Debug|Any CPU.Build.0 = Release|Any CPU
+		{C692FE73-43DB-49CE-87FC-F03ED61F25C9}.Release|Any CPU.ActiveCfg = Release|Any CPU
+		{C692FE73-43DB-49CE-87FC-F03ED61F25C9}.Release|Any CPU.Build.0 = Release|Any CPU
 		{EE0F0DD4-A70D-472B-BD5D-B7D32D0E9386}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
 		{EE0F0DD4-A70D-472B-BD5D-B7D32D0E9386}.Debug|Any CPU.Build.0 = Debug|Any CPU
 		{EE0F0DD4-A70D-472B-BD5D-B7D32D0E9386}.Release|Any CPU.ActiveCfg = Release|Any CPU
@@ -566,10 +571,6 @@ Global
 		{F4E36AA8-814E-4704-BC07-291F70F45193}.Debug|Any CPU.Build.0 = Debug|Any CPU
 		{F4E36AA8-814E-4704-BC07-291F70F45193}.Release|Any CPU.ActiveCfg = Release|Any CPU
 		{F4E36AA8-814E-4704-BC07-291F70F45193}.Release|Any CPU.Build.0 = Release|Any CPU
-		{C692FE73-43DB-49CE-87FC-F03ED61F25C9}.Debug|Any CPU.ActiveCfg = Release|Any CPU
-		{C692FE73-43DB-49CE-87FC-F03ED61F25C9}.Debug|Any CPU.Build.0 = Release|Any CPU
-		{C692FE73-43DB-49CE-87FC-F03ED61F25C9}.Release|Any CPU.ActiveCfg = Release|Any CPU
-		{C692FE73-43DB-49CE-87FC-F03ED61F25C9}.Release|Any CPU.Build.0 = Release|Any CPU
 	EndGlobalSection
 	GlobalSection(SolutionProperties) = preSolution
 		HideSolutionNode = FALSE
@@ -635,8 +636,8 @@ Global
 		{90B08091-9BBD-4362-B712-E9F2CC62B218} = {9B9E3891-2366-4253-A952-D08BCEB71098}
 		{75C47156-C5D8-44BC-A5A7-E8657C2248D6} = {9B9E3891-2366-4253-A952-D08BCEB71098}
 		{C810060E-3809-4B74-A125-F11533AF9C1B} = {9B9E3891-2366-4253-A952-D08BCEB71098}
-		{F4E36AA8-814E-4704-BC07-291F70F45193} = {C5A00AC3-B34C-4564-9BDD-2DA473EF4D8B}
 		{C692FE73-43DB-49CE-87FC-F03ED61F25C9} = {4ED8B739-6F4E-4CD4-B993-545E6B5CE637}
+		{F4E36AA8-814E-4704-BC07-291F70F45193} = {C5A00AC3-B34C-4564-9BDD-2DA473EF4D8B}
 	EndGlobalSection
 	GlobalSection(ExtensibilityGlobals) = postSolution
 		SolutionGuid = {87366D66-1391-4D90-8999-95A620AD786A}

+ 3 - 3
src/Avalonia.Base/Media/TextFormatting/InterWordJustification.cs

@@ -89,13 +89,13 @@ namespace Avalonia.Media.TextFormatting
 
                         var offset = Math.Max(0, currentPosition - glyphRun.Metrics.FirstCluster);
                         var glyphIndex = glyphRun.FindGlyphIndex(characterIndex - offset);
-                        var glyphInfo = shapedBuffer.GlyphInfos[glyphIndex];
+                        var glyphInfo = shapedBuffer[glyphIndex];
 
-                        shapedBuffer.GlyphInfos[glyphIndex] = new GlyphInfo(glyphInfo.GlyphIndex,
+                        shapedBuffer[glyphIndex] = new GlyphInfo(glyphInfo.GlyphIndex,
                             glyphInfo.GlyphCluster, glyphInfo.GlyphAdvance + spacing);
                     }
 
-                    glyphRun.GlyphInfos = shapedBuffer.GlyphInfos;
+                    glyphRun.GlyphInfos = shapedBuffer;
                 }
 
                 currentPosition += textRun.Length;

+ 62 - 36
src/Avalonia.Base/Media/TextFormatting/ShapedBuffer.cs

@@ -2,6 +2,7 @@
 using System.Buffers;
 using System.Collections;
 using System.Collections.Generic;
+using System.Runtime.CompilerServices;
 using Avalonia.Utilities;
 
 namespace Avalonia.Media.TextFormatting
@@ -9,12 +10,13 @@ namespace Avalonia.Media.TextFormatting
     public sealed class ShapedBuffer : IReadOnlyList<GlyphInfo>, IDisposable
     {
         private GlyphInfo[]? _rentedBuffer;
+        private ArraySlice<GlyphInfo> _glyphInfos;
 
         public ShapedBuffer(ReadOnlyMemory<char> text, int bufferLength, IGlyphTypeface glyphTypeface, double fontRenderingEmSize, sbyte bidiLevel)
         {
-            _rentedBuffer = ArrayPool<GlyphInfo>.Shared.Rent(bufferLength);
             Text = text;
-            GlyphInfos = new ArraySlice<GlyphInfo>(_rentedBuffer, 0, bufferLength);
+            _rentedBuffer = ArrayPool<GlyphInfo>.Shared.Rent(bufferLength);
+            _glyphInfos = new ArraySlice<GlyphInfo>(_rentedBuffer, 0, bufferLength);      
             GlyphTypeface = glyphTypeface;
             FontRenderingEmSize = fontRenderingEmSize;
             BidiLevel = bidiLevel;
@@ -23,27 +25,70 @@ namespace Avalonia.Media.TextFormatting
         internal ShapedBuffer(ReadOnlyMemory<char> text, ArraySlice<GlyphInfo> glyphInfos, IGlyphTypeface glyphTypeface, double fontRenderingEmSize, sbyte bidiLevel)
         {
             Text = text;
-            GlyphInfos = glyphInfos;
+            _glyphInfos = glyphInfos;
             GlyphTypeface = glyphTypeface;
             FontRenderingEmSize = fontRenderingEmSize;
             BidiLevel = bidiLevel;
         }
 
-        internal ArraySlice<GlyphInfo> GlyphInfos { get; private set; }
-
-        public int Length
-            => GlyphInfos.Length;
+        /// <summary>
+        /// The buffer's length.
+        /// </summary>
+        public int Length => _glyphInfos.Length;
 
+        /// <summary>
+        /// The buffer's glyph typeface.
+        /// </summary>
         public IGlyphTypeface GlyphTypeface { get; }
 
+        /// <summary>
+        /// The buffers font rendering em size.
+        /// </summary>
         public double FontRenderingEmSize { get; }
 
+        /// <summary>
+        /// The buffer's bidi level.
+        /// </summary>
         public sbyte BidiLevel { get; }
 
+        /// <summary>
+        /// The buffer's reading direction.
+        /// </summary>
         public bool IsLeftToRight => (BidiLevel & 1) == 0;
 
+        /// <summary>
+        /// The text that is represended by this buffer.
+        /// </summary>
         public ReadOnlyMemory<char> Text { get; }
         
+        /// <summary>
+        /// Reverses the buffer.
+        /// </summary>
+        public void Reverse()
+        {
+            _glyphInfos.Span.Reverse();
+        }
+
+        public void Dispose()
+        {
+            if (_rentedBuffer is not null)
+            {
+                ArrayPool<GlyphInfo>.Shared.Return(_rentedBuffer);
+                _rentedBuffer = null;
+                _glyphInfos = ArraySlice<GlyphInfo>.Empty; // ensure we don't misuse the returned array
+            }
+        }
+
+        public GlyphInfo this[int index]
+        {
+            [MethodImpl(MethodImplOptions.AggressiveInlining)]
+            get => _glyphInfos[index];
+            [MethodImpl(MethodImplOptions.AggressiveInlining)]
+            set => _glyphInfos[index] = value;
+        }
+
+        public IEnumerator<GlyphInfo> GetEnumerator() => _glyphInfos.GetEnumerator();
+
         /// <summary>
         /// Finds a glyph index for given character index.
         /// </summary>
@@ -53,20 +98,19 @@ namespace Avalonia.Media.TextFormatting
         /// </returns>
         private int FindGlyphIndex(int characterIndex)
         {
-            if (characterIndex < GlyphInfos[0].GlyphCluster)
+            if (characterIndex < _glyphInfos[0].GlyphCluster)
             {
                 return 0;
             }
 
-            if (characterIndex > GlyphInfos[GlyphInfos.Length - 1].GlyphCluster)
+            if (characterIndex > _glyphInfos[_glyphInfos.Length - 1].GlyphCluster)
             {
-                return GlyphInfos.Length - 1;
+                return _glyphInfos.Length - 1;
             }
 
-
             var comparer = GlyphInfo.ClusterAscendingComparer;
 
-            var glyphInfos = GlyphInfos.Span;
+            var glyphInfos = _glyphInfos.Span;
 
             var searchValue = new GlyphInfo(default, characterIndex, default);
 
@@ -109,42 +153,24 @@ namespace Avalonia.Media.TextFormatting
                 return new SplitResult<ShapedBuffer>(this, null);
             }
 
-            var firstCluster = GlyphInfos[0].GlyphCluster;
-            var lastCluster = GlyphInfos[GlyphInfos.Length - 1].GlyphCluster;
+            var firstCluster = _glyphInfos[0].GlyphCluster;
+            var lastCluster = _glyphInfos[_glyphInfos.Length - 1].GlyphCluster;
 
             var start = firstCluster < lastCluster ? firstCluster : lastCluster;
 
             var glyphCount = FindGlyphIndex(start + length);
 
             var first = new ShapedBuffer(Text.Slice(0, length),
-                GlyphInfos.Take(glyphCount), GlyphTypeface, FontRenderingEmSize, BidiLevel);
+                _glyphInfos.Take(glyphCount), GlyphTypeface, FontRenderingEmSize, BidiLevel);
 
             var second = new ShapedBuffer(Text.Slice(length),
-                GlyphInfos.Skip(glyphCount), GlyphTypeface, FontRenderingEmSize, BidiLevel);
+                _glyphInfos.Skip(glyphCount), GlyphTypeface, FontRenderingEmSize, BidiLevel);
 
             return new SplitResult<ShapedBuffer>(first, second);
         }
 
-        int IReadOnlyCollection<GlyphInfo>.Count => GlyphInfos.Length;
-
-        public GlyphInfo this[int index]
-        {
-            get => GlyphInfos[index];
-            set => GlyphInfos[index] = value;
-        }
-
-        public IEnumerator<GlyphInfo> GetEnumerator() => GlyphInfos.GetEnumerator();
+        int IReadOnlyCollection<GlyphInfo>.Count => _glyphInfos.Length;
 
-        IEnumerator IEnumerable.GetEnumerator() => GetEnumerator();
-
-        public void Dispose()
-        {
-            if (_rentedBuffer is not null)
-            {
-                ArrayPool<GlyphInfo>.Shared.Return(_rentedBuffer);
-                _rentedBuffer = null;
-                GlyphInfos = ArraySlice<GlyphInfo>.Empty; // ensure we don't misuse the returned array
-            }
-        }
+        IEnumerator IEnumerable.GetEnumerator() => GetEnumerator();       
     }
 }

+ 3 - 3
src/Avalonia.Base/Media/TextFormatting/ShapedTextRun.cs

@@ -85,7 +85,7 @@ namespace Avalonia.Media.TextFormatting
         {
             _glyphRun = null;
 
-            ShapedBuffer.GlyphInfos.Span.Reverse();
+            ShapedBuffer.Reverse();
 
             IsReversed = !IsReversed;
         }
@@ -106,7 +106,7 @@ namespace Avalonia.Media.TextFormatting
 
             for (var i = 0; i < ShapedBuffer.Length; i++)
             {
-                var advance = ShapedBuffer.GlyphInfos[i].GlyphAdvance;
+                var advance = ShapedBuffer[i].GlyphAdvance;
 
                 if (currentWidth + advance > availableWidth)
                 {
@@ -130,7 +130,7 @@ namespace Avalonia.Media.TextFormatting
 
             for (var i = ShapedBuffer.Length - 1; i >= 0; i--)
             {
-                var advance = ShapedBuffer.GlyphInfos[i].GlyphAdvance;
+                var advance = ShapedBuffer[i].GlyphAdvance;
 
                 if (width + advance > availableWidth)
                 {

+ 1 - 1
src/Avalonia.Base/Media/TextFormatting/TextFormatterImpl.cs

@@ -583,7 +583,7 @@ namespace Avalonia.Media.TextFormatting
                         {
                             if (shapedTextCharacters.ShapedBuffer.Length > 0)
                             {
-                                var firstCluster = shapedTextCharacters.ShapedBuffer.GlyphInfos[0].GlyphCluster;
+                                var firstCluster = shapedTextCharacters.ShapedBuffer[0].GlyphCluster;
                                 var lastCluster = firstCluster;
 
                                 for (var j = 0; j < shapedTextCharacters.ShapedBuffer.Length; j++)

+ 1 - 3
src/Skia/Avalonia.Skia/TextShaperImpl.cs

@@ -56,8 +56,6 @@ namespace Avalonia.Skia
 
                 var shapedBuffer = new ShapedBuffer(text, bufferLength, typeface, fontRenderingEmSize, bidiLevel);
 
-                var targetInfos = shapedBuffer.GlyphInfos;
-
                 var glyphInfos = buffer.GetGlyphInfoSpan();
 
                 var glyphPositions = buffer.GetGlyphPositionSpan();
@@ -83,7 +81,7 @@ namespace Avalonia.Skia
                             4 * typeface.GetGlyphAdvance(glyphIndex) * textScale;
                     }
 
-                    targetInfos[i] = new Media.TextFormatting.GlyphInfo(glyphIndex, glyphCluster, glyphAdvance, glyphOffset);
+                    shapedBuffer[i] = new Media.TextFormatting.GlyphInfo(glyphIndex, glyphCluster, glyphAdvance, glyphOffset);
                 }
 
                 return shapedBuffer;

+ 1 - 3
src/Windows/Avalonia.Direct2D1/Media/TextShaperImpl.cs

@@ -52,8 +52,6 @@ namespace Avalonia.Direct2D1.Media
 
                 var shapedBuffer = new ShapedBuffer(text, bufferLength, typeface, fontRenderingEmSize, bidiLevel);
 
-                var targetInfos = shapedBuffer.GlyphInfos;
-
                 var glyphInfos = buffer.GetGlyphInfoSpan();
 
                 var glyphPositions = buffer.GetGlyphPositionSpan();
@@ -79,7 +77,7 @@ namespace Avalonia.Direct2D1.Media
                             4 * typeface.GetGlyphAdvance(glyphIndex) * textScale;
                     }
 
-                    targetInfos[i] = new Avalonia.Media.TextFormatting.GlyphInfo(glyphIndex, glyphCluster, glyphAdvance, glyphOffset);
+                    shapedBuffer[i] = new Avalonia.Media.TextFormatting.GlyphInfo(glyphIndex, glyphCluster, glyphAdvance, glyphOffset);
                 }
 
                 return shapedBuffer;

+ 2 - 2
tests/Avalonia.Skia.UnitTests/Media/GlyphRunTests.cs

@@ -216,12 +216,12 @@ namespace Avalonia.Skia.UnitTests.Media
                 shapedBuffer.GlyphTypeface,
                 shapedBuffer.FontRenderingEmSize,
                 shapedBuffer.Text,
-                shapedBuffer.GlyphInfos,
+                shapedBuffer,
                 biDiLevel: shapedBuffer.BidiLevel);
 
             if(shapedBuffer.BidiLevel == 1)
             {
-                shapedBuffer.GlyphInfos.Span.Reverse();
+                shapedBuffer.Reverse();
             }
 
             return glyphRun;

+ 9 - 9
tests/Avalonia.Skia.UnitTests/Media/TextFormatting/TextLayoutTests.cs

@@ -199,7 +199,7 @@ namespace Avalonia.Skia.UnitTests.Media.TextFormatting
                 => textLayout.TextLines
                     .Select(line => string.Join('|', line.TextRuns
                         .Cast<ShapedTextRun>()
-                        .SelectMany(run => run.ShapedBuffer.GlyphInfos, (_, glyph) => glyph.GlyphIndex)))
+                        .SelectMany(run => run.ShapedBuffer, (_, glyph) => glyph.GlyphIndex)))
                     .ToList();
         }
 
@@ -489,7 +489,7 @@ namespace Avalonia.Skia.UnitTests.Media.TextFormatting
                 {
                     var shapedRun = (ShapedTextRun)textRun;
 
-                    var glyphClusters = shapedRun.ShapedBuffer.GlyphInfos.Select(glyph => glyph.GlyphCluster).ToArray();
+                    var glyphClusters = shapedRun.ShapedBuffer.Select(glyph => glyph.GlyphCluster).ToArray();
 
                     var expected = clusters.Skip(index).Take(glyphClusters.Length).ToArray();
 
@@ -522,11 +522,11 @@ namespace Avalonia.Skia.UnitTests.Media.TextFormatting
 
                 Assert.Equal(expectedLength, ((ShapedTextRun)layout.TextLines[0].TextRuns[0]).GlyphRun.GlyphInfos.Count);
 
-                Assert.Equal(5, ((ShapedTextRun)layout.TextLines[0].TextRuns[0]).ShapedBuffer.GlyphInfos[5].GlyphCluster);
+                Assert.Equal(5, ((ShapedTextRun)layout.TextLines[0].TextRuns[0]).ShapedBuffer[5].GlyphCluster);
 
                 if (expectedLength == 7)
                 {
-                    Assert.Equal(5, ((ShapedTextRun)layout.TextLines[0].TextRuns[0]).ShapedBuffer.GlyphInfos[6].GlyphCluster);
+                    Assert.Equal(5, ((ShapedTextRun)layout.TextLines[0].TextRuns[0]).ShapedBuffer[6].GlyphCluster);
                 }
             }
         }
@@ -783,7 +783,7 @@ namespace Avalonia.Skia.UnitTests.Media.TextFormatting
 
                 var rects = layout.TextLines
                     .SelectMany(x => x.TextRuns.Cast<ShapedTextRun>())
-                    .SelectMany(x => x.ShapedBuffer.GlyphInfos, (_, glyph) => glyph.GlyphAdvance)
+                    .SelectMany(x => x.ShapedBuffer, (_, glyph) => glyph.GlyphAdvance)
                     .ToArray();
 
                 for (var i = 0; i < SingleLineText.Length; i++)
@@ -939,7 +939,7 @@ namespace Avalonia.Skia.UnitTests.Media.TextFormatting
 
                 var firstRun = (ShapedTextRun)textLine.TextRuns[0];
 
-                var firstCluster = firstRun.ShapedBuffer.GlyphInfos[0].GlyphCluster;
+                var firstCluster = firstRun.ShapedBuffer[0].GlyphCluster;
 
                 var characterHit = textLine.GetCharacterHitFromDistance(0);
 
@@ -953,7 +953,7 @@ namespace Avalonia.Skia.UnitTests.Media.TextFormatting
 
                 distance = textLine.GetDistanceFromCharacterHit(new CharacterHit(characterHit.FirstCharacterIndex));
 
-                var firstAdvance = firstRun.ShapedBuffer.GlyphInfos[0].GlyphAdvance;
+                var firstAdvance = firstRun.ShapedBuffer[0].GlyphAdvance;
 
                 Assert.Equal(firstAdvance, distance, 5);
 
@@ -996,9 +996,9 @@ namespace Avalonia.Skia.UnitTests.Media.TextFormatting
 
                     var shapedRuns = textLine.TextRuns.Cast<ShapedTextRun>().ToList();
 
-                    var clusters = shapedRuns.SelectMany(x => x.ShapedBuffer.GlyphInfos, (_, glyph) => glyph.GlyphCluster).ToList();
+                    var clusters = shapedRuns.SelectMany(x => x.ShapedBuffer, (_, glyph) => glyph.GlyphCluster).ToList();
 
-                    var glyphAdvances = shapedRuns.SelectMany(x => x.ShapedBuffer.GlyphInfos, (_, glyph) => glyph.GlyphAdvance).ToList();
+                    var glyphAdvances = shapedRuns.SelectMany(x => x.ShapedBuffer, (_, glyph) => glyph.GlyphAdvance).ToList();
 
                     var currentX = 0.0;
 

+ 7 - 7
tests/Avalonia.Skia.UnitTests/Media/TextFormatting/TextLineTests.cs

@@ -95,7 +95,7 @@ namespace Avalonia.Skia.UnitTests.Media.TextFormatting
                 {
                     var shapedRun = (ShapedTextRun)textRun;
 
-                    var runClusters = shapedRun.ShapedBuffer.GlyphInfos.Select(glyph => glyph.GlyphCluster);
+                    var runClusters = shapedRun.ShapedBuffer.Select(glyph => glyph.GlyphCluster);
 
                     clusters.AddRange(shapedRun.IsReversed ? runClusters.Reverse() : runClusters);
                 }
@@ -142,7 +142,7 @@ namespace Avalonia.Skia.UnitTests.Media.TextFormatting
                 {
                     var shapedRun = (ShapedTextRun)textRun;
 
-                    var runClusters = shapedRun.ShapedBuffer.GlyphInfos.Select(glyph => glyph.GlyphCluster);
+                    var runClusters = shapedRun.ShapedBuffer.Select(glyph => glyph.GlyphCluster);
 
                     clusters.AddRange(shapedRun.IsReversed ? runClusters.Reverse() : runClusters);
                 }
@@ -249,7 +249,7 @@ namespace Avalonia.Skia.UnitTests.Media.TextFormatting
 
                 var clusters = textLine.TextRuns
                     .Cast<ShapedTextRun>()
-                    .SelectMany(x => x.ShapedBuffer.GlyphInfos, (_, glyph) => glyph.GlyphCluster)
+                    .SelectMany(x => x.ShapedBuffer, (_, glyph) => glyph.GlyphCluster)
                     .ToArray();
 
                 var previousCharacterHit = new CharacterHit(text.Length);
@@ -752,7 +752,7 @@ namespace Avalonia.Skia.UnitTests.Media.TextFormatting
             {
                 var shapedBuffer = textRun.ShapedBuffer;
 
-                var currentClusters = shapedBuffer.GlyphInfos.Select(glyph => glyph.GlyphCluster).ToList();
+                var currentClusters = shapedBuffer.Select(glyph => glyph.GlyphCluster).ToList();
 
                 foreach (var currentCluster in currentClusters)
                 {
@@ -785,11 +785,11 @@ namespace Avalonia.Skia.UnitTests.Media.TextFormatting
             {
                 var shapedBuffer = textRun.ShapedBuffer;
 
-                for (var index = 0; index < shapedBuffer.GlyphInfos.Length; index++)
+                for (var index = 0; index < shapedBuffer.Length; index++)
                 {
-                    var currentCluster = shapedBuffer.GlyphInfos[index].GlyphCluster;
+                    var currentCluster = shapedBuffer[index].GlyphCluster;
 
-                    var advance = shapedBuffer.GlyphInfos[index].GlyphAdvance;
+                    var advance = shapedBuffer[index].GlyphAdvance;
 
                     if (lastCluster != currentCluster)
                     {

+ 5 - 5
tests/Avalonia.Skia.UnitTests/Media/TextFormatting/TextShaperTests.cs

@@ -19,10 +19,10 @@ namespace Avalonia.Skia.UnitTests.Media.TextFormatting
                 var shapedBuffer = TextShaper.Current.ShapeText(text, options);
                 
                 Assert.Equal(shapedBuffer.Length, text.Length);
-                Assert.Equal(shapedBuffer.GlyphInfos.Length, text.Length);
-                Assert.Equal(0, shapedBuffer.GlyphInfos[0].GlyphCluster);
-                Assert.Equal(1, shapedBuffer.GlyphInfos[1].GlyphCluster);
-                Assert.Equal(1, shapedBuffer.GlyphInfos[2].GlyphCluster);
+                Assert.Equal(shapedBuffer.Length, text.Length);
+                Assert.Equal(0, shapedBuffer[0].GlyphCluster);
+                Assert.Equal(1, shapedBuffer[1].GlyphCluster);
+                Assert.Equal(1, shapedBuffer[2].GlyphCluster);
             }
         }
 
@@ -36,7 +36,7 @@ namespace Avalonia.Skia.UnitTests.Media.TextFormatting
                 var shapedBuffer = TextShaper.Current.ShapeText(text, options);
 
                 Assert.Equal(shapedBuffer.Length, text.Length);
-                Assert.Equal(100, shapedBuffer.GlyphInfos[0].GlyphAdvance);
+                Assert.Equal(100, shapedBuffer[0].GlyphAdvance);
             }
         }
 

+ 1 - 3
tests/Avalonia.UnitTests/HarfBuzzTextShaperImpl.cs

@@ -52,8 +52,6 @@ namespace Avalonia.UnitTests
 
                 var shapedBuffer = new ShapedBuffer(text, bufferLength, typeface, fontRenderingEmSize, bidiLevel);
 
-                var targetInfos = shapedBuffer.GlyphInfos;
-
                 var glyphInfos = buffer.GetGlyphInfoSpan();
 
                 var glyphPositions = buffer.GetGlyphPositionSpan();
@@ -79,7 +77,7 @@ namespace Avalonia.UnitTests
                             4 * typeface.GetGlyphAdvance(glyphIndex) * textScale;
                     }
 
-                    targetInfos[i] = new Media.TextFormatting.GlyphInfo(glyphIndex, glyphCluster, glyphAdvance, glyphOffset);
+                    shapedBuffer[i] = new Media.TextFormatting.GlyphInfo(glyphIndex, glyphCluster, glyphAdvance, glyphOffset);
                 }
 
                 return shapedBuffer;

+ 1 - 2
tests/Avalonia.UnitTests/MockTextShaperImpl.cs

@@ -13,7 +13,6 @@ namespace Avalonia.UnitTests
             var fontRenderingEmSize = options.FontRenderingEmSize;
             var bidiLevel = options.BidiLevel;
             var shapedBuffer = new ShapedBuffer(text, text.Length, typeface, fontRenderingEmSize, bidiLevel);
-            var targetInfos = shapedBuffer.GlyphInfos;
             var textSpan = text.Span;
             var textStartIndex = TextTestHelper.GetStartCharIndex(text);
 
@@ -27,7 +26,7 @@ namespace Avalonia.UnitTests
 
                 for (var j = 0; j < count; ++j)
                 {
-                    targetInfos[i + j] = new GlyphInfo(glyphIndex, glyphCluster, 10);
+                    shapedBuffer[i + j] = new GlyphInfo(glyphIndex, glyphCluster, 10);
                 }
 
                 i += count;