A cross-platform UI framework for .NET
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 

140 lines
4.5 KiB

using System;
using Avalonia.Base.UnitTests.Media.Fonts.Tables;
using Avalonia.Media;
using Avalonia.Media.TextFormatting;
using Avalonia.Platform;
using Xunit;
namespace Avalonia.Base.UnitTests.Media.TextFormatting;
public class ShapedBufferTests
{
private const string InterFontUri =
"resm:Avalonia.Base.UnitTests.Assets.Inter-Regular.ttf?assembly=Avalonia.Base.UnitTests";
private static GlyphTypeface LoadInter()
{
var assetLoader = new StandardAssetLoader();
using var stream = assetLoader.Open(new Uri(InterFontUri));
return new GlyphTypeface(new CustomPlatformTypeface(stream));
}
[Fact]
public void GlyphIndices_Length_Matches_BufferLength()
{
var typeface = LoadInter();
using var buffer = new ShapedBuffer("hello".AsMemory(), 5, typeface, 16, 0);
Assert.Equal(5, buffer.GlyphIndices.Length);
Assert.Equal(5, buffer.Length);
}
[Fact]
public void Indexer_Set_Syncs_GlyphIndices()
{
var typeface = LoadInter();
using var buffer = new ShapedBuffer("ABC".AsMemory(), 3, typeface, 16, 0);
buffer[0] = new GlyphInfo(42, 0, 10);
buffer[1] = new GlyphInfo(99, 1, 11);
buffer[2] = new GlyphInfo(7, 2, 12);
Assert.Equal(42, buffer.GlyphIndices[0]);
Assert.Equal(99, buffer.GlyphIndices[1]);
Assert.Equal(7, buffer.GlyphIndices[2]);
// And the GlyphInfo accessor still works.
Assert.Equal(42, buffer[0].GlyphIndex);
Assert.Equal(99, buffer[1].GlyphIndex);
Assert.Equal(7, buffer[2].GlyphIndex);
}
[Fact]
public void Indexer_Set_Overwrite_Updates_GlyphIndices()
{
var typeface = LoadInter();
using var buffer = new ShapedBuffer("X".AsMemory(), 1, typeface, 16, 0);
buffer[0] = new GlyphInfo(10, 0, 1);
Assert.Equal(10, buffer.GlyphIndices[0]);
// Mutating the entry (as InterWordJustification does) keeps the parallel array in sync.
buffer[0] = new GlyphInfo(10, 0, 2);
Assert.Equal(10, buffer.GlyphIndices[0]);
buffer[0] = new GlyphInfo(33, 0, 1);
Assert.Equal(33, buffer.GlyphIndices[0]);
}
[Fact]
public void Split_Ascending_Preserves_GlyphIndices_Alignment()
{
var typeface = LoadInter();
// LTR (bidi 0): clusters ascending. Five 1-char clusters.
using var buffer = new ShapedBuffer("ABCDE".AsMemory(), 5, typeface, 16, 0);
buffer[0] = new GlyphInfo(10, 0, 5);
buffer[1] = new GlyphInfo(20, 1, 5);
buffer[2] = new GlyphInfo(30, 2, 5);
buffer[3] = new GlyphInfo(40, 3, 5);
buffer[4] = new GlyphInfo(50, 4, 5);
var split = buffer.Split(2);
Assert.NotNull(split.First);
Assert.NotNull(split.Second);
Assert.Equal(2, split.First!.GlyphIndices.Length);
Assert.Equal(3, split.Second!.GlyphIndices.Length);
Assert.Equal(10, split.First.GlyphIndices[0]);
Assert.Equal(20, split.First.GlyphIndices[1]);
Assert.Equal(30, split.Second.GlyphIndices[0]);
Assert.Equal(40, split.Second.GlyphIndices[1]);
Assert.Equal(50, split.Second.GlyphIndices[2]);
// Both halves stay in lockstep with the GlyphInfo indexer.
Assert.Equal(split.First[0].GlyphIndex, split.First.GlyphIndices[0]);
Assert.Equal(split.Second[1].GlyphIndex, split.Second.GlyphIndices[1]);
}
[Fact]
public void Split_At_Zero_Yields_Empty_Leading_With_Empty_Indices()
{
var typeface = LoadInter();
using var buffer = new ShapedBuffer("ABC".AsMemory(), 3, typeface, 16, 0);
buffer[0] = new GlyphInfo(10, 0, 5);
buffer[1] = new GlyphInfo(20, 1, 5);
buffer[2] = new GlyphInfo(30, 2, 5);
var split = buffer.Split(0);
Assert.NotNull(split.First);
Assert.Equal(0, split.First!.GlyphIndices.Length);
Assert.Equal(0, split.First.Length);
Assert.NotNull(split.Second);
Assert.Equal(3, split.Second!.GlyphIndices.Length);
}
[Fact]
public void Dispose_Clears_GlyphIndices_View()
{
var typeface = LoadInter();
var buffer = new ShapedBuffer("AB".AsMemory(), 2, typeface, 16, 0);
buffer[0] = new GlyphInfo(1, 0, 1);
buffer[1] = new GlyphInfo(2, 1, 1);
Assert.Equal(2, buffer.GlyphIndices.Length);
buffer.Dispose();
// After dispose the views are reset so we don't reach into the returned pool buffer.
Assert.Equal(0, buffer.GlyphIndices.Length);
Assert.Equal(0, buffer.Length);
}
}