public ShapeableTextCharacters(ReadOnlySlice <char> text, TextRunProperties properties, sbyte biDiLevel)
 {
     TextSourceLength = text.Length;
     Text             = text;
     Properties       = properties;
     BidiLevel        = biDiLevel;
 }
Ejemplo n.º 2
0
 public FormattedTextSource(ReadOnlySlice <char> text, TextRunProperties defaultProperties,
                            IReadOnlyList <ValueSpan <TextRunProperties> > textModifier)
 {
     _text = text;
     _defaultProperties = defaultProperties;
     _textModifier      = textModifier;
 }
Ejemplo n.º 3
0
 public TextCharacters(ReadOnlySlice <char> text, int offsetToFirstCharacter, int length,
                       TextRunProperties properties)
 {
     Text             = text.Skip(offsetToFirstCharacter).Take(length);
     TextSourceLength = length;
     Properties       = properties;
 }
Ejemplo n.º 4
0
 public ShapedTextCharacters(ShapedBuffer shapedBuffer, TextRunProperties properties)
 {
     ShapedBuffer     = shapedBuffer;
     Text             = shapedBuffer.Text;
     Properties       = properties;
     TextSourceLength = Text.Length;
     FontMetrics      = new FontMetrics(properties.Typeface, properties.FontRenderingEmSize);
 }
Ejemplo n.º 5
0
 public ShapedTextCharacters(GlyphRun glyphRun, TextRunProperties properties)
 {
     Text             = glyphRun.Characters;
     Properties       = properties;
     TextSourceLength = Text.Length;
     FontMetrics      = new FontMetrics(Properties.Typeface, Properties.FontRenderingEmSize);
     GlyphRun         = glyphRun;
 }
Ejemplo n.º 6
0
 /// <summary>
 /// Construct a text trailing word ellipsis collapsing properties
 /// </summary>
 /// <param name="width">width in which collapsing is constrained to</param>
 /// <param name="textRunProperties">text run properties of ellispis symbol</param>
 public TextTrailingWordEllipsis(
     double width,
     TextRunProperties textRunProperties
     )
 {
     Width  = width;
     Symbol = new TextCharacters(s_ellipsis, textRunProperties);
 }
Ejemplo n.º 7
0
        /// <summary>
        /// Creates an ellipsis.
        /// </summary>
        /// <param name="properties">The text run properties.</param>
        /// <returns></returns>
        private static ShapedTextCharacters CreateEllipsisRun(TextRunProperties properties)
        {
            var formatterImpl = AvaloniaLocator.Current.GetService <ITextShaperImpl>();

            var glyphRun = formatterImpl.ShapeText(s_ellipsis, properties.Typeface, properties.FontRenderingEmSize,
                                                   properties.CultureInfo);

            return(new ShapedTextCharacters(glyphRun, properties));
        }
Ejemplo n.º 8
0
 /// <summary>
 /// Construct a text trailing word ellipsis collapsing properties.
 /// </summary>
 /// <param name="ellipsis">Text used as collapsing symbol.</param>
 /// <param name="width">width in which collapsing is constrained to.</param>
 /// <param name="textRunProperties">text run properties of ellipsis symbol.</param>
 public TextTrailingWordEllipsis(
     ReadOnlySlice <char> ellipsis,
     double width,
     TextRunProperties textRunProperties
     )
 {
     Width  = width;
     Symbol = new TextCharacters(ellipsis, textRunProperties);
 }
        /// <summary>
        /// Construct a text trailing word ellipsis collapsing properties.
        /// </summary>
        /// <param name="ellipsis">Text used as collapsing symbol.</param>
        /// <param name="prefixLength">Length of leading prefix.</param>
        /// <param name="width">width in which collapsing is constrained to</param>
        /// <param name="textRunProperties">text run properties of ellispis symbol</param>
        public TextLeadingPrefixCharacterEllipsis(
            ReadOnlySlice <char> ellipsis,
            int prefixLength,
            double width,
            TextRunProperties textRunProperties)
        {
            if (_prefixLength < 0)
            {
                throw new ArgumentOutOfRangeException(nameof(prefixLength));
            }

            _prefixLength = prefixLength;
            Width         = width;
            Symbol        = new TextCharacters(ellipsis, textRunProperties);
        }
Ejemplo n.º 10
0
            /// <summary>
            /// Creates a span of text run properties that has modifier applied.
            /// </summary>
            /// <param name="text">The text to create the properties for.</param>
            /// <param name="defaultProperties">The default text properties.</param>
            /// <param name="textModifier">The text properties modifier.</param>
            /// <returns>
            /// The created text style run.
            /// </returns>
            private static ValueSpan <TextRunProperties> CreateTextStyleRun(ReadOnlySlice <char> text,
                                                                            TextRunProperties defaultProperties, IReadOnlyList <ValueSpan <TextRunProperties> > textModifier)
            {
                if (textModifier == null || textModifier.Count == 0)
                {
                    return(new ValueSpan <TextRunProperties>(text.Start, text.Length, defaultProperties));
                }

                var currentProperties = defaultProperties;

                var hasOverride = false;

                var i = 0;

                var length = 0;

                for (; i < textModifier.Count; i++)
                {
                    var propertiesOverride = textModifier[i];

                    var textRange = new TextRange(propertiesOverride.Start, propertiesOverride.Length);

                    if (textRange.End < text.Start)
                    {
                        continue;
                    }

                    if (textRange.Start > text.End)
                    {
                        length = text.Length;
                        break;
                    }

                    if (textRange.Start > text.Start)
                    {
                        if (propertiesOverride.Value != currentProperties)
                        {
                            length = Math.Min(Math.Abs(textRange.Start - text.Start), text.Length);

                            break;
                        }
                    }

                    length += Math.Min(text.Length - length, textRange.Length);

                    if (hasOverride)
                    {
                        continue;
                    }

                    hasOverride = true;

                    currentProperties = propertiesOverride.Value;
                }

                if (length < text.Length && i == textModifier.Count)
                {
                    if (currentProperties == defaultProperties)
                    {
                        length = text.Length;
                    }
                }

                if (length != text.Length)
                {
                    text = text.Take(length);
                }

                return(new ValueSpan <TextRunProperties>(text.Start, length, currentProperties));
            }
Ejemplo n.º 11
0
        /// <summary>
        /// Creates a span of text run properties that has modifier applied.
        /// </summary>
        /// <param name="text">The text to create the properties for.</param>
        /// <param name="firstTextSourceIndex">The first text source index.</param>
        /// <param name="defaultProperties">The default text properties.</param>
        /// <param name="textModifier">The text properties modifier.</param>
        /// <returns>
        /// The created text style run.
        /// </returns>
        private static ValueSpan <TextRunProperties> CreateTextStyleRun(ReadOnlySlice <char> text, int firstTextSourceIndex,
                                                                        TextRunProperties defaultProperties, IReadOnlyList <ValueSpan <TextRunProperties> >?textModifier)
        {
            if (textModifier == null || textModifier.Count == 0)
            {
                return(new ValueSpan <TextRunProperties>(firstTextSourceIndex, text.Length, defaultProperties));
            }

            var currentProperties = defaultProperties;

            var hasOverride = false;

            var i = 0;

            var length = 0;

            for (; i < textModifier.Count; i++)
            {
                var propertiesOverride = textModifier[i];

                var textRange = new TextRange(propertiesOverride.Start, propertiesOverride.Length);

                if (textRange.Start + textRange.Length <= firstTextSourceIndex)
                {
                    continue;
                }

                if (textRange.Start > firstTextSourceIndex + text.Length)
                {
                    length = text.Length;
                    break;
                }

                if (textRange.Start > firstTextSourceIndex)
                {
                    if (propertiesOverride.Value != currentProperties)
                    {
                        length = Math.Min(Math.Abs(textRange.Start - firstTextSourceIndex), text.Length);

                        break;
                    }
                }

                length = Math.Max(0, textRange.Start + textRange.Length - firstTextSourceIndex);

                if (hasOverride)
                {
                    continue;
                }

                hasOverride = true;

                currentProperties = propertiesOverride.Value;
            }

            if (length < text.Length && i == textModifier.Count)
            {
                if (currentProperties == defaultProperties)
                {
                    length = text.Length;
                }
            }

            if (length == 0 && currentProperties != defaultProperties)
            {
                currentProperties = defaultProperties;
                length            = text.Length;
            }

            length = CoerceLength(text, length);

            return(new ValueSpan <TextRunProperties>(firstTextSourceIndex, length, currentProperties));
        }
Ejemplo n.º 12
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>
        /// <returns>A list of shapeable text runs.</returns>
        private ShapeableTextCharacters CreateShapeableRun(ReadOnlySlice <char> text, TextRunProperties defaultProperties)
        {
            var defaultTypeface = defaultProperties.Typeface;

            var currentTypeface = defaultTypeface;

            if (TryGetRunProperties(text, currentTypeface, defaultTypeface, out var count))
            {
                return(new ShapeableTextCharacters(text.Take(count),
                                                   new GenericTextRunProperties(currentTypeface, defaultProperties.FontRenderingEmSize,
                                                                                defaultProperties.TextDecorations, defaultProperties.ForegroundBrush)));
            }

            var codepoint = Codepoint.ReadAt(text, count, out _);

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

            if (matchFound && TryGetRunProperties(text, currentTypeface, defaultTypeface, out count))
            {
                //Fallback found
                return(new ShapeableTextCharacters(text.Take(count),
                                                   new GenericTextRunProperties(currentTypeface, defaultProperties.FontRenderingEmSize,
                                                                                defaultProperties.TextDecorations, defaultProperties.ForegroundBrush)));
            }

            // 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),
                                               new GenericTextRunProperties(currentTypeface, defaultProperties.FontRenderingEmSize,
                                                                            defaultProperties.TextDecorations, defaultProperties.ForegroundBrush)));
        }
Ejemplo n.º 13
0
 public TextCharacters(ReadOnlySlice <char> text, TextRunProperties properties)
 {
     TextSourceLength = text.Length;
     Text             = text;
     Properties       = properties;
 }
Ejemplo n.º 14
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));
        }