public void Should_Format_TextRuns_With_TextRunStyles()
        {
            using (Start())
            {
                const string text = "0123456789";

                var defaultStyle = new TextStyle(Typeface.Default, 12, Brushes.Black);

                var textStyleRuns = new[]
                {
                    new TextStyleRun(new TextPointer(0, 3), defaultStyle),
                    new TextStyleRun(new TextPointer(3, 3), new TextStyle(Typeface.Default, 13, Brushes.Black)),
                    new TextStyleRun(new TextPointer(6, 3), new TextStyle(Typeface.Default, 14, Brushes.Black)),
                    new TextStyleRun(new TextPointer(9, 1), defaultStyle)
                };

                var textSource = new FormattableTextSource(text, defaultStyle, textStyleRuns);

                var formatter = new SimpleTextFormatter();

                var textLine = formatter.FormatLine(textSource, 0, double.PositiveInfinity, new TextParagraphProperties());

                Assert.Equal(text.Length, textLine.Text.Length);

                for (var i = 0; i < textStyleRuns.Length; i++)
                {
                    var textStyleRun = textStyleRuns[i];

                    var textRun = textLine.TextRuns[i];

                    Assert.Equal(textStyleRun.TextPointer.Length, textRun.Text.Length);
                }
            }
        }
        public void Should_Format_TextRuns_With_Default_Style()
        {
            using (Start())
            {
                const string text = "0123456789";

                var defaultTextRunStyle = new TextStyle(Typeface.Default, 12, Brushes.Black);

                var textSource = new SimpleTextSource(text, defaultTextRunStyle);

                var formatter = new SimpleTextFormatter();

                var textLine = formatter.FormatLine(textSource, 0, double.PositiveInfinity, new TextParagraphProperties());

                Assert.Single(textLine.TextRuns);

                var textRun = textLine.TextRuns[0];

                Assert.Equal(defaultTextRunStyle.TextFormat, textRun.Style.TextFormat);

                Assert.Equal(defaultTextRunStyle.Foreground, textRun.Style.Foreground);

                Assert.Equal(text.Length, textRun.Text.Length);
            }
        }
        public void Should_Wrap_Text(string text, string familyName, int numberOfCharactersPerLine)
        {
            using (Start())
            {
                var lineBreaker = new LineBreakEnumerator(text.AsMemory());

                var expected = new List <int>();

                while (lineBreaker.MoveNext())
                {
                    expected.Add(lineBreaker.Current.PositionWrap - 1);
                }

                var typeface = new Typeface("resm:Avalonia.Skia.UnitTests.Assets?assembly=Avalonia.Skia.UnitTests#" +
                                            familyName);

                var defaultStyle = new TextStyle(typeface);

                var textSource = new SimpleTextSource(text, defaultStyle);

                var formatter = new SimpleTextFormatter();

                var glyph = typeface.GlyphTypeface.GetGlyph('a');

                var advance = typeface.GlyphTypeface.GetGlyphAdvance(glyph) *
                              (12.0 / typeface.GlyphTypeface.DesignEmHeight);

                var paragraphWidth = advance * numberOfCharactersPerLine;

                var currentPosition = 0;

                while (currentPosition < text.Length)
                {
                    var textLine =
                        formatter.FormatLine(textSource, currentPosition, paragraphWidth,
                                             new TextParagraphProperties(defaultStyle, textWrapping: TextWrapping.Wrap));

                    Assert.True(expected.Contains(textLine.Text.End));

                    var index = expected.IndexOf(textLine.Text.End);

                    for (var i = 0; i <= index; i++)
                    {
                        expected.RemoveAt(0);
                    }

                    currentPosition += textLine.Text.Length;
                }
            }
        }
        public void Should_Produce_Unique_Runs(string text, int numberOfRuns)
        {
            using (Start())
            {
                var textSource = new SimpleTextSource(text, new TextStyle(Typeface.Default));

                var formatter = new SimpleTextFormatter();

                var textLine =
                    formatter.FormatLine(textSource, 0, double.PositiveInfinity, new TextParagraphProperties());

                Assert.Equal(numberOfRuns, textLine.TextRuns.Count);
            }
        }
        public void Should_Split_Run_On_Script()
        {
            using (Start())
            {
                const string text = "1234الدولي";

                var textSource = new SimpleTextSource(text, new TextStyle(Typeface.Default));

                var formatter = new SimpleTextFormatter();

                var textLine =
                    formatter.FormatLine(textSource, 0, double.PositiveInfinity, new TextParagraphProperties());

                Assert.Equal(4, textLine.TextRuns[0].Text.Length);
            }
        }
        public void Should_Format_TextRuns_With_Multiple_Buffers()
        {
            using (Start())
            {
                var defaultTextRunStyle = new TextStyle(Typeface.Default, 12, Brushes.Black);

                var textSource = new MultiBufferTextSource(defaultTextRunStyle);

                var formatter = new SimpleTextFormatter();

                var textLine = formatter.FormatLine(textSource, 0, double.PositiveInfinity,
                                                    new TextParagraphProperties(defaultTextRunStyle));

                Assert.Equal(5, textLine.TextRuns.Count);

                Assert.Equal(50, textLine.Text.Length);
            }
        }
        public void Should_Get_CharacterHit_From_Distance()
        {
            using (Start())
            {
                var textSource = new MultiBufferTextSource(new TextStyle(Typeface.Default));

                var formatter = new SimpleTextFormatter();

                var textLine =
                    formatter.FormatLine(textSource, 0, double.PositiveInfinity, new TextParagraphProperties());

                var currentDistance = 0.0;

                CharacterHit characterHit;

                foreach (var run in textLine.TextRuns)
                {
                    var textRun = (ShapedTextRun)run;

                    var glyphRun = textRun.GlyphRun;

                    for (var i = 0; i < glyphRun.GlyphClusters.Length; i++)
                    {
                        var cluster = glyphRun.GlyphClusters[i];

                        var glyph = glyphRun.GlyphIndices[i];

                        var advance = glyphRun.GlyphTypeface.GetGlyphAdvance(glyph) * glyphRun.Scale;

                        characterHit = textLine.GetCharacterHitFromDistance(currentDistance);

                        Assert.Equal(cluster, characterHit.FirstCharacterIndex + characterHit.TrailingLength);

                        currentDistance += advance;
                    }
                }

                characterHit = textLine.GetCharacterHitFromDistance(textLine.LineMetrics.Size.Width);

                Assert.Equal(textSource.TextPointer.End, characterHit.FirstCharacterIndex);
            }
        }
        public void Should_Get_Distance_From_CharacterHit()
        {
            using (Start())
            {
                var textSource = new MultiBufferTextSource(new TextStyle(Typeface.Default));

                var formatter = new SimpleTextFormatter();

                var textLine =
                    formatter.FormatLine(textSource, 0, double.PositiveInfinity, new TextParagraphProperties());

                var currentDistance = 0.0;

                foreach (var run in textLine.TextRuns)
                {
                    var textRun = (ShapedTextRun)run;

                    var glyphRun = textRun.GlyphRun;

                    for (var i = 0; i < glyphRun.GlyphClusters.Length; i++)
                    {
                        var cluster = glyphRun.GlyphClusters[i];

                        var glyph = glyphRun.GlyphIndices[i];

                        var advance = glyphRun.GlyphTypeface.GetGlyphAdvance(glyph) * glyphRun.Scale;

                        var distance = textLine.GetDistanceFromCharacterHit(new CharacterHit(cluster));

                        Assert.Equal(currentDistance, distance);

                        currentDistance += advance;
                    }
                }

                Assert.Equal(currentDistance, textLine.GetDistanceFromCharacterHit(new CharacterHit(textSource.TextPointer.Length)));
            }
        }