예제 #1
0
        public override TextRun GetTextRun(int textSourceCharacterIndex)
        {
            var linePart = linePartsCollection.GetLinePartFromColumn(textSourceCharacterIndex, ref linePartIndex);

            if (linePart is null)
            {
                return(endOfLine);
            }
            var part = linePart.Value;

            if (part.AdornmentElement is not null)
            {
                return(new AdornmentTextRun(part));
            }
            else
            {
                int offs       = textSourceCharacterIndex - part.Column;
                int baseOffset = part.Span.Start + offs;
                int length     = part.ColumnLength - offs;
                Debug.Assert(length >= 0);
                if (length > maxLengthLeft)
                {
                    length = maxLengthLeft;
                }
                var text = this.text;
                for (int i = 0; i < length; i++)
                {
                    uint cp = text[baseOffset + i];
                    if (char.IsHighSurrogate((char)cp) && i + 1 < length)
                    {
                        uint lo = text[baseOffset + i + 1];
                        if (char.IsLowSurrogate((char)lo))
                        {
                            cp = 0x10000 + ((cp - 0xD800) << 10) + (lo - 0xDC00);
                            i++;
                        }
                    }
                    if (WpfUnicodeUtils.IsBadWpfFormatterChar(cp))
                    {
                        totalBadChars++;
                        Debug.Assert(totalBadChars <= WpfUnicodeUtils.MAX_BAD_CHARS);
                        if (totalBadChars == WpfUnicodeUtils.MAX_BAD_CHARS)
                        {
                            maxLengthLeft = i;
                            length        = i;
                            break;
                        }
                    }
                }
                if (length == 0)
                {
                    return(endOfLine);
                }
                maxLengthLeft -= length;
                return(new TextCharacters(text, baseOffset, length, part.TextRunProperties));
            }
        }
예제 #2
0
        public override TextRun GetTextRun(int textSourceCharacterIndex)
        {
            var linePart = linePartsCollection.GetLinePartFromColumn(textSourceCharacterIndex, ref linePartIndex);

            if (linePart == null)
            {
                return(endOfLine);
            }
            var part = linePart.Value;

            if (part.AdornmentElement != null)
            {
                return(new AdornmentTextRun(part));
            }
            else
            {
                int offs       = textSourceCharacterIndex - part.Column;
                int baseOffset = part.Span.Start + offs;
                int length     = part.ColumnLength - offs;
                Debug.Assert(length >= 0);
                if (length > maxLengthLeft)
                {
                    length = maxLengthLeft;
                }
                var text = this.text;
                for (int i = 0; i < length; i++)
                {
                    var c = text[baseOffset + i];
                    if (WpfUnicodeUtils.IsBadWpfCombiningMark(c))
                    {
                        totalBadChars++;
                        Debug.Assert(totalBadChars <= WpfUnicodeUtils.MAX_BAD_CHARS);
                        if (totalBadChars == WpfUnicodeUtils.MAX_BAD_CHARS)
                        {
                            maxLengthLeft = i;
                            length        = i;
                            break;
                        }
                    }
                }
                if (length == 0)
                {
                    return(endOfLine);
                }
                maxLengthLeft -= length;
                return(new TextCharacters(text, baseOffset, length, part.TextRunProperties));
            }
        }
예제 #3
0
        public static FrameworkElement Create(IClassificationFormatMap classificationFormatMap, string text, IList <TextClassificationTag> tags, TextElementFlags flags)
        {
            bool useFastTextBlock  = (flags & (TextElementFlags.TrimmingMask | TextElementFlags.WrapMask | TextElementFlags.FilterOutNewLines)) == (TextElementFlags.NoTrimming | TextElementFlags.NoWrap | TextElementFlags.FilterOutNewLines);
            bool filterOutNewLines = (flags & TextElementFlags.FilterOutNewLines) != 0;

            if (tags.Count != 0)
            {
                if (useFastTextBlock)
                {
                    return(new FastTextBlock((flags & TextElementFlags.NewFormatter) != 0, new TextSrc {
                        text = ToString(WpfUnicodeUtils.ReplaceBadChars(text), filterOutNewLines),
                        classificationFormatMap = classificationFormatMap,
                        tagsList = tags.ToArray(),
                    }));
                }

                var propsSpans = tags.Select(a => new TextRunPropertiesAndSpan(a.Span, classificationFormatMap.GetTextProperties(a.ClassificationType)));
                var textBlock  = TextBlockFactory.Create(text, classificationFormatMap.DefaultTextProperties, propsSpans, TextBlockFactory.Flags.DisableSetTextBlockFontFamily | TextBlockFactory.Flags.DisableFontSize | (filterOutNewLines ? TextBlockFactory.Flags.FilterOutNewlines : 0));
                textBlock.TextTrimming = GetTextTrimming(flags);
                textBlock.TextWrapping = GetTextWrapping(flags);
                return(textBlock);
            }

            FrameworkElement fwElem;

            if (useFastTextBlock)
            {
                fwElem = new FastTextBlock((flags & TextElementFlags.NewFormatter) != 0)
                {
                    Text = ToString(WpfUnicodeUtils.ReplaceBadChars(text), filterOutNewLines)
                };
            }
            else
            {
                fwElem = new TextBlock {
                    Text         = ToString(WpfUnicodeUtils.ReplaceBadChars(text), filterOutNewLines),
                    TextTrimming = GetTextTrimming(flags),
                    TextWrapping = GetTextWrapping(flags),
                };
            }
            return(InitializeDefault(classificationFormatMap, fwElem));
        }
예제 #4
0
        /// <summary>
        /// Creates a <see cref="TextBlock"/>
        /// </summary>
        /// <param name="text">Full text</param>
        /// <param name="defaultProperties">Default text run properties</param>
        /// <param name="orderedPropsAndSpans">Ordered enumerable of spans and text run properties</param>
        /// <param name="flags">Flags</param>
        /// <returns></returns>
        public static TextBlock Create(string text, TextFormattingRunProperties defaultProperties, IEnumerable <TextRunPropertiesAndSpan> orderedPropsAndSpans, Flags flags = Flags.None)
        {
            if (text == null)
            {
                throw new ArgumentNullException(nameof(text));
            }
            if (defaultProperties == null)
            {
                throw new ArgumentNullException(nameof(defaultProperties));
            }
            if (orderedPropsAndSpans == null)
            {
                throw new ArgumentNullException(nameof(orderedPropsAndSpans));
            }
            text = WpfUnicodeUtils.ReplaceBadChars(text);

            var  textBlock         = new TextBlock();
            bool filterOutNewlines = (flags & Flags.FilterOutNewlines) != 0;

            if (!defaultProperties.BackgroundBrushEmpty)
            {
                textBlock.Background = defaultProperties.BackgroundBrush;
            }
            if (!defaultProperties.ForegroundBrushEmpty)
            {
                textBlock.Foreground = defaultProperties.ForegroundBrush;
            }
            if (!defaultProperties.BoldEmpty)
            {
                textBlock.FontWeight = defaultProperties.Bold ? FontWeights.Bold : FontWeights.Normal;
            }
            if (!defaultProperties.ItalicEmpty)
            {
                textBlock.FontStyle = defaultProperties.Italic ? FontStyles.Italic : FontStyles.Normal;
            }
            if (!defaultProperties.FontRenderingEmSizeEmpty && (flags & Flags.DisableFontSize) == 0)
            {
                textBlock.FontSize = defaultProperties.FontRenderingEmSize;
            }
            if (!defaultProperties.TextDecorationsEmpty)
            {
                textBlock.TextDecorations = defaultProperties.TextDecorations;
            }
            if (!defaultProperties.TextEffectsEmpty)
            {
                textBlock.TextEffects = defaultProperties.TextEffects;
            }
            if ((flags & Flags.DisableSetTextBlockFontFamily) == 0 && !defaultProperties.TypefaceEmpty)
            {
                textBlock.FontFamily = defaultProperties.Typeface.FontFamily;
            }

            if ((flags & Flags.DisableWordWrap) == 0)
            {
                textBlock.TextWrapping = TextWrapping.Wrap;
            }

            propsAndSpansList.Clear();
            propsAndSpansList.AddRange(orderedPropsAndSpans);
            if (propsAndSpansList.Count == 0)
            {
                textBlock.Text = text;
            }
            else if (CanUseOnlyTextBlock(propsAndSpansList, text))
            {
                var properties = propsAndSpansList[0].Properties;
                if (!properties.BackgroundBrushEmpty)
                {
                    textBlock.Background = properties.BackgroundBrush;
                }
                if (!properties.ForegroundBrushEmpty)
                {
                    textBlock.Foreground = properties.ForegroundBrush;
                }
                if (!properties.BoldEmpty)
                {
                    textBlock.FontWeight = properties.Bold ? FontWeights.Bold : FontWeights.Normal;
                }
                if (!properties.ItalicEmpty)
                {
                    textBlock.FontStyle = properties.Italic ? FontStyles.Italic : FontStyles.Normal;
                }
                if (!properties.FontRenderingEmSizeEmpty && (flags & Flags.DisableFontSize) == 0)
                {
                    textBlock.FontSize = properties.FontRenderingEmSize;
                }
                if (!properties.TextDecorationsEmpty)
                {
                    textBlock.TextDecorations = properties.TextDecorations;
                }
                if (!properties.TextEffectsEmpty)
                {
                    textBlock.TextEffects = properties.TextEffects;
                }
                if (!properties.TypefaceEmpty && !IsSameTypeFace(defaultProperties, properties))
                {
                    textBlock.FontFamily = properties.Typeface.FontFamily;
                }
                textBlock.Text = ToString(text, filterOutNewlines);
            }
            else
            {
                int textOffset = 0;
                foreach (var tag in propsAndSpansList)
                {
                    if (textOffset < tag.Span.Start)
                    {
                        textBlock.Inlines.Add(CreateRun(ToString(text.Substring(textOffset, tag.Span.Start - textOffset), filterOutNewlines), defaultProperties, null, flags));
                    }
                    textBlock.Inlines.Add(CreateRun(ToString(text.Substring(tag.Span.Start, tag.Span.Length), filterOutNewlines), defaultProperties, tag.Properties, flags));
                    textOffset = tag.Span.End;
                }
                if (textOffset < text.Length)
                {
                    textBlock.Inlines.Add(CreateRun(ToString(text.Substring(textOffset), filterOutNewlines), defaultProperties, null, flags));
                }
            }

            propsAndSpansList.Clear();
            return(textBlock);
        }