Beispiel #1
0
 public TextCharacters(ReadOnlySlice <char> text, int offsetToFirstCharacter, int length,
                       TextRunProperties properties)
 {
     Text             = text.Skip(offsetToFirstCharacter).Take(length);
     TextSourceLength = length;
     Properties       = properties;
 }
Beispiel #2
0
        public TextRun GetTextRun(int textSourceIndex)
        {
            if (textSourceIndex > _text.Length)
            {
                return(null);
            }

            var runText = _text.Skip(textSourceIndex);

            return(runText.IsEmpty ? null : new TextCharacters(runText, _defaultGenericPropertiesRunProperties));
        }
Beispiel #3
0
        public TextRun GetTextRun(int textSourceIndex)
        {
            var runText = _text.Skip(textSourceIndex);

            if (runText.IsEmpty)
            {
                return(new TextEndOfParagraph());
            }

            return(new TextCharacters(runText, _defaultGenericPropertiesRunProperties));
        }
        public void Should_Skip()
        {
            var buffer = new[] { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };

            var slice = new ReadOnlySlice <int>(buffer);

            var skipped = slice.Skip(2);

            var expected = buffer.Skip(2);

            Assert.Equal(expected, skipped);
        }
Beispiel #5
0
            public TextRun GetTextRun(int textSourceIndex)
            {
                var runText = _text.Skip(textSourceIndex);

                if (runText.IsEmpty)
                {
                    return(new TextEndOfLine());
                }

                var textStyleRun = CreateTextStyleRunWithOverride(runText, _defaultStyle, _textStyleOverrides);

                return(new TextCharacters(runText.Take(textStyleRun.TextPointer.Length), textStyleRun.Style));
            }
            public TextRun GetTextRun(int textSourceIndex)
            {
                if (_textStyleRuns.IsEmpty)
                {
                    return(new TextEndOfParagraph());
                }

                var styleRun = _textStyleRuns[0];

                _textStyleRuns = _textStyleRuns.Skip(1);

                return(new TextCharacters(_text.AsSlice(styleRun.TextPointer.Start, styleRun.TextPointer.Length),
                                          _defaultStyle));
            }
        public TextRun GetTextRun(int textSourceIndex)
        {
            if (_styleSpans.IsEmpty)
            {
                return(new TextEndOfParagraph());
            }

            var currentSpan = _styleSpans[0];

            _styleSpans = _styleSpans.Skip(1);

            return(new TextCharacters(_text.AsSlice(currentSpan.Start, currentSpan.Length),
                                      _defaultStyle));
        }
        /// <summary>
        /// Moves to the next <see cref="Codepoint"/>.
        /// </summary>
        /// <returns></returns>
        public bool MoveNext()
        {
            if (_text.IsEmpty)
            {
                Current = Codepoint.ReplacementCodepoint;

                return(false);
            }

            Current = Codepoint.ReadAt(_text, 0, out var count);

            _text = _text.Skip(count);

            return(true);
        }
Beispiel #9
0
            public TextRun GetTextRun(int textSourceIndex)
            {
                if (textSourceIndex > _text.End)
                {
                    return(new TextEndOfLine());
                }

                var runText = _text.Skip(textSourceIndex);

                if (runText.IsEmpty)
                {
                    return(new TextEndOfLine());
                }

                var textStyleRun = CreateTextStyleRun(runText, _defaultProperties, _textModifier);

                return(new TextCharacters(runText.Take(textStyleRun.Length), textStyleRun.Value));
            }
Beispiel #10
0
        /// <summary>
        /// Gets a list of <see cref="ShapeableTextCharacters"/>.
        /// </summary>
        /// <returns>The shapeable text characters.</returns>
        internal IReadOnlyList <ShapeableTextCharacters> GetShapeableCharacters(ReadOnlySlice <char> runText, sbyte biDiLevel,
                                                                                ref TextRunProperties?previousProperties)
        {
            var shapeableCharacters = new List <ShapeableTextCharacters>(2);

            while (!runText.IsEmpty)
            {
                var shapeableRun = CreateShapeableRun(runText, Properties, biDiLevel, ref previousProperties);

                shapeableCharacters.Add(shapeableRun);

                runText = runText.Skip(shapeableRun.Text.Length);

                previousProperties = shapeableRun.Properties;
            }

            return(shapeableCharacters);
        }
Beispiel #11
0
        /// <summary>
        /// Creates a shapeable text run with unique properties.
        /// </summary>
        /// <param name="text">The text to create text runs from.</param>
        /// <param name="defaultProperties">The default text run properties.</param>
        /// <param name="biDiLevel">The bidi level of the run.</param>
        /// <param name="previousProperties"></param>
        /// <returns>A list of shapeable text runs.</returns>
        private static ShapeableTextCharacters CreateShapeableRun(ReadOnlySlice <char> text,
                                                                  TextRunProperties defaultProperties, sbyte biDiLevel, ref TextRunProperties?previousProperties)
        {
            var defaultTypeface  = defaultProperties.Typeface;
            var currentTypeface  = defaultTypeface;
            var previousTypeface = previousProperties?.Typeface;

            if (TryGetShapeableLength(text, currentTypeface, null, out var count, out var script))
            {
                if (script == Script.Common && previousTypeface is not null)
                {
                    if (TryGetShapeableLength(text, previousTypeface.Value, defaultTypeface, out var fallbackCount, out _))
                    {
                        return(new ShapeableTextCharacters(text.Take(fallbackCount),
                                                           defaultProperties.WithTypeface(previousTypeface.Value), biDiLevel));
                    }
                }

                return(new ShapeableTextCharacters(text.Take(count), defaultProperties.WithTypeface(currentTypeface),
                                                   biDiLevel));
            }

            if (previousTypeface is not null)
            {
                if (TryGetShapeableLength(text, previousTypeface.Value, defaultTypeface, out count, out _))
                {
                    return(new ShapeableTextCharacters(text.Take(count),
                                                       defaultProperties.WithTypeface(previousTypeface.Value), biDiLevel));
                }
            }

            var codepoint = Codepoint.ReplacementCodepoint;

            var codepointEnumerator = new CodepointEnumerator(text.Skip(count));

            while (codepointEnumerator.MoveNext())
            {
                if (codepointEnumerator.Current.IsWhiteSpace)
                {
                    continue;
                }

                codepoint = codepointEnumerator.Current;

                break;
            }

            //ToDo: Fix FontFamily fallback
            var matchFound =
                FontManager.Current.TryMatchCharacter(codepoint, defaultTypeface.Style, defaultTypeface.Weight,
                                                      defaultTypeface.Stretch, defaultTypeface.FontFamily, defaultProperties.CultureInfo,
                                                      out currentTypeface);

            if (matchFound && TryGetShapeableLength(text, currentTypeface, defaultTypeface, out count, out _))
            {
                //Fallback found
                return(new ShapeableTextCharacters(text.Take(count), defaultProperties.WithTypeface(currentTypeface),
                                                   biDiLevel));
            }

            // no fallback found
            currentTypeface = defaultTypeface;

            var glyphTypeface = currentTypeface.GlyphTypeface;

            var enumerator = new GraphemeEnumerator(text);

            while (enumerator.MoveNext())
            {
                var grapheme = enumerator.Current;

                if (!grapheme.FirstCodepoint.IsWhiteSpace && glyphTypeface.TryGetGlyph(grapheme.FirstCodepoint, out _))
                {
                    break;
                }

                count += grapheme.Text.Length;
            }

            return(new ShapeableTextCharacters(text.Take(count), defaultProperties, biDiLevel));
        }