Пример #1
0
        // ------------------------------------------------------------------
        // Fetch the next run at UIElment position.
        //
        //      position - current position in the text array
        //      dcp - current position in the text array
        // ------------------------------------------------------------------
        private TextRun HandleInlineObject(StaticTextPointer position, int dcp)
        {
            Debug.Assert(position.GetPointerContext(LogicalDirection.Forward) == TextPointerContext.EmbeddedElement, "TextPointer does not point to embedded object.");

            TextRun          run     = null;
            DependencyObject element = position.GetAdjacentElement(LogicalDirection.Forward) as DependencyObject;

            if (element is UIElement)
            {
                //


                TextRunProperties textProps = new TextProperties(element, position, true /* inline objects */, true /* get background */);

                // Create object run.
                run = new InlineObject(dcp, TextContainerHelper.EmbeddedObjectLength, (UIElement)element, textProps, _owner);
            }
            else
            {
                // If the embedded object is of an unknown type (not UIElement),
                // treat it as element edge.
                run = HandleElementEndEdge(position);
            }
            return(run);
        }
Пример #2
0
        // ------------------------------------------------------------------
        //
        //  TextSource Implementation
        //
        // ------------------------------------------------------------------

        #region TextSource Implementation

        // ------------------------------------------------------------------
        // Get a text run at specified text source position.
        // ------------------------------------------------------------------
        public override TextRun GetTextRun(int dcp)
        {
            TextRun           run      = null;
            StaticTextPointer position = _owner.TextContainer.CreateStaticPointerAtOffset(dcp);

            switch (position.GetPointerContext(LogicalDirection.Forward))
            {
            case TextPointerContext.Text:
                run = HandleText(position);
                break;

            case TextPointerContext.ElementStart:
                run = HandleElementStartEdge(position);
                break;

            case TextPointerContext.ElementEnd:
                run = HandleElementEndEdge(position);
                break;

            case TextPointerContext.EmbeddedElement:
                run = HandleInlineObject(position, dcp);
                break;

            case TextPointerContext.None:
                run = new TextEndOfParagraph(_syntheticCharacterLength);
                break;
            }
            Debug.Assert(run != null, "TextRun has not been created.");
            Debug.Assert(run.Length > 0, "TextRun has to have positive length.");
            return(run);
        }
Пример #3
0
        // ------------------------------------------------------------------
        //
        //  TextSource Implementation
        //
        // ------------------------------------------------------------------

        #region TextSource Implementation

        /// <summary>
        /// Get a text run at specified text source position and return it.
        /// </summary>
        /// <param name="dcp">
        /// dcp of position relative to start of line
        /// </param>
        internal override TextRun GetTextRun(int dcp)
        {
            TextRun           run           = null;
            ITextContainer    textContainer = _paraClient.Paragraph.StructuralCache.TextContainer;
            StaticTextPointer position      = textContainer.CreateStaticPointerAtOffset(_cpPara + dcp);

            switch (position.GetPointerContext(LogicalDirection.Forward))
            {
            case TextPointerContext.Text:
                run = HandleText(position);
                break;

            case TextPointerContext.ElementStart:
                run = HandleElementStartEdge(position);
                break;

            case TextPointerContext.ElementEnd:
                run = HandleElementEndEdge(position);
                break;

            case TextPointerContext.EmbeddedElement:
                run = HandleEmbeddedObject(dcp, position);
                break;

            case TextPointerContext.None:
                run = new ParagraphBreakRun(_syntheticCharacterLength, PTS.FSFLRES.fsflrEndOfParagraph);
                break;
            }
            Invariant.Assert(run != null, "TextRun has not been created.");
            Invariant.Assert(run.Length > 0, "TextRun has to have positive length.");

            return(run);
        }
        // Token: 0x0600688D RID: 26765 RVA: 0x001D7D74 File Offset: 0x001D5F74
        protected TextRun HandleText(StaticTextPointer position)
        {
            Invariant.Assert(position.GetPointerContext(LogicalDirection.Forward) == TextPointerContext.Text, "TextPointer does not point to characters.");
            DependencyObject target;

            if (position.Parent != null)
            {
                target = position.Parent;
            }
            else
            {
                target = this._paraClient.Paragraph.Element;
            }
            TextProperties    textRunProperties = new TextProperties(target, position, false, true, this._paraClient.Paragraph.StructuralCache.TextFormatterHost.PixelsPerDip);
            StaticTextPointer position2         = position.TextContainer.Highlights.GetNextPropertyChangePosition(position, LogicalDirection.Forward);

            if (position.GetOffsetToPosition(position2) > 4096)
            {
                position2 = position.CreatePointer(4096);
            }
            char[] array     = new char[position.GetOffsetToPosition(position2)];
            int    textInRun = position.GetTextInRun(LogicalDirection.Forward, array, 0, array.Length);

            return(new TextCharacters(array, 0, textInRun, textRunProperties));
        }
        // Token: 0x06004131 RID: 16689 RVA: 0x0012A0E0 File Offset: 0x001282E0
        public override TextRun GetTextRun(int dcp)
        {
            TextRun           textRun  = null;
            StaticTextPointer position = this._owner.Host.TextContainer.CreateStaticPointerAtOffset(dcp);

            switch (position.GetPointerContext(LogicalDirection.Forward))
            {
            case TextPointerContext.None:
                textRun = new TextEndOfParagraph(1);
                goto IL_5C;

            case TextPointerContext.Text:
                textRun = this.HandleText(position);
                goto IL_5C;
            }
            Invariant.Assert(false, "Unsupported position type.");
IL_5C:
            Invariant.Assert(textRun != null, "TextRun has not been created.");
            Invariant.Assert(textRun.Length > 0, "TextRun has to have positive length.");
            if (textRun.Properties != null)
            {
                textRun.Properties.PixelsPerDip = base.PixelsPerDip;
            }
            return(textRun);
        }
        // Token: 0x060065FF RID: 26111 RVA: 0x001CAA74 File Offset: 0x001C8C74
        public override TextRun GetTextRun(int dcp)
        {
            TextRun           textRun  = null;
            StaticTextPointer position = this._owner.TextContainer.CreateStaticPointerAtOffset(dcp);

            switch (position.GetPointerContext(LogicalDirection.Forward))
            {
            case TextPointerContext.None:
                textRun = new TextEndOfParagraph(Line._syntheticCharacterLength);
                break;

            case TextPointerContext.Text:
                textRun = this.HandleText(position);
                break;

            case TextPointerContext.EmbeddedElement:
                textRun = this.HandleInlineObject(position, dcp);
                break;

            case TextPointerContext.ElementStart:
                textRun = this.HandleElementStartEdge(position);
                break;

            case TextPointerContext.ElementEnd:
                textRun = this.HandleElementEndEdge(position);
                break;
            }
            if (textRun.Properties != null)
            {
                textRun.Properties.PixelsPerDip = base.PixelsPerDip;
            }
            return(textRun);
        }
Пример #7
0
        /// <summary>
        /// Get a text run at specified text source position.
        /// </summary>
        public override TextRun GetTextRun(int dcp)
        {
            TextRun           run      = null;
            StaticTextPointer position = _owner.Host.TextContainer.CreateStaticPointerAtOffset(dcp);

            switch (position.GetPointerContext(LogicalDirection.Forward))
            {
            case TextPointerContext.Text:
                run = HandleText(position);
                break;

            case TextPointerContext.None:
                run = new TextEndOfParagraph(_syntheticCharacterLength);
                break;

            case TextPointerContext.ElementStart:
            case TextPointerContext.ElementEnd:
            case TextPointerContext.EmbeddedElement:
            default:
                Invariant.Assert(false, "Unsupported position type.");
                break;
            }
            Invariant.Assert(run != null, "TextRun has not been created.");
            Invariant.Assert(run.Length > 0, "TextRun has to have positive length.");

            return(run);
        }
        // Token: 0x06006890 RID: 26768 RVA: 0x001D80F4 File Offset: 0x001D62F4
        protected TextRun HandleEmbeddedObject(int dcp, StaticTextPointer position)
        {
            Invariant.Assert(position.GetPointerContext(LogicalDirection.Forward) == TextPointerContext.EmbeddedElement, "TextPointer does not point to embedded object.");
            DependencyObject dependencyObject = position.GetAdjacentElement(LogicalDirection.Forward) as DependencyObject;
            TextRun          result;

            if (dependencyObject is UIElement)
            {
                TextRunProperties textProps = new TextProperties(dependencyObject, position, true, true, this._paraClient.Paragraph.StructuralCache.TextFormatterHost.PixelsPerDip);
                result = new InlineObjectRun(TextContainerHelper.EmbeddedObjectLength, (UIElement)dependencyObject, textProps, this._paraClient.Paragraph as TextParagraph);
            }
            else
            {
                result = new TextHidden(TextContainerHelper.EmbeddedObjectLength);
            }
            return(result);
        }
Пример #9
0
        //-------------------------------------------------------------------
        //
        //  Protected Methods
        //
        //-------------------------------------------------------------------

        #region Protected Methods

        /// <summary>
        /// Fetch the next run at text position.
        /// </summary>
        /// <param name="position">
        /// Current position in text array
        /// </param>
        /// <returns></returns>
        protected TextRun HandleText(StaticTextPointer position)
        {
            DependencyObject  element;
            StaticTextPointer endOfRunPosition;

            Invariant.Assert(position.GetPointerContext(LogicalDirection.Forward) == TextPointerContext.Text, "TextPointer does not point to characters.");

            if (position.Parent != null)
            {
                element = position.Parent;
            }
            else
            {
                element = _paraClient.Paragraph.Element;
            }

            // Extract the aggregated properties into something that the textrun can use.
            //


            TextProperties textProps = new TextProperties(element, position, false /* inline objects */, true /* get background */,
                                                          _paraClient.Paragraph.StructuralCache.TextFormatterHost.PixelsPerDip);

            // Calculate the end of the run by finding either:
            //      a) the next intersection of highlight ranges, or
            //      b) the natural end of this textrun
            endOfRunPosition = position.TextContainer.Highlights.GetNextPropertyChangePosition(position, LogicalDirection.Forward);

            // Clamp the text run at an arbitrary limit, so we don't make
            // an unbounded allocation.
            if (position.GetOffsetToPosition(endOfRunPosition) > 4096)
            {
                endOfRunPosition = position.CreatePointer(4096);
            }

            // Get character buffer for the text run.
            char[] textBuffer = new char[position.GetOffsetToPosition(endOfRunPosition)];

            // Copy characters from text run into buffer. Note the actual number of characters copied,
            // which may be different than the buffer's length. Buffer length only specifies the maximum
            // number of characters
            int charactersCopied = position.GetTextInRun(LogicalDirection.Forward, textBuffer, 0, textBuffer.Length);

            // Create text run using the actual number of characters copied
            return(new TextCharacters(textBuffer, 0, charactersCopied, textProps));
        }
Пример #10
0
        /// <summary>
        /// Fetch the next run at element end edge position.
        /// ElementEndEdge; we can have 2 possibilities:
        /// (1) Close edge of element associated with the text paragraph,
        ///     create synthetic LineBreak run to end the current line.
        /// (2) End of inline element, hide CloseEdge character and continue
        /// </summary>
        /// <param name="position"></param>
        /// Position in current text array
        protected TextRun HandleElementEndEdge(StaticTextPointer position)
        {
            Invariant.Assert(position.GetPointerContext(LogicalDirection.Forward) == TextPointerContext.ElementEnd, "TextPointer does not point to element end edge.");

            TextRun run;

            if (position.Parent == _paraClient.Paragraph.Element)
            {
                // (1) Close edge of element associated with the text paragraph,
                //     create synthetic LineBreak run to end the current line.
                run = new ParagraphBreakRun(_syntheticCharacterLength, PTS.FSFLRES.fsflrEndOfParagraph);
            }
            else
            {
                TextElement element = (TextElement)position.GetAdjacentElement(LogicalDirection.Forward);
                Debug.Assert(element != null, "Element should be here.");
                Inline           inline = (Inline)element;
                DependencyObject parent = inline.Parent;
                FlowDirection    parentFlowDirection = inline.FlowDirection;

                if (parent != null)
                {
                    parentFlowDirection = (FlowDirection)parent.GetValue(FrameworkElement.FlowDirectionProperty);
                }

                if (inline.FlowDirection != parentFlowDirection)
                {
                    run = new TextEndOfSegment(_elementEdgeCharacterLength);
                }
                else
                {
                    TextDecorationCollection textDecorations = DynamicPropertyReader.GetTextDecorations(inline);
                    if (textDecorations == null || textDecorations.Count == 0)
                    {
                        // (2) End of inline element, hide CloseEdge character and continue
                        run = new TextHidden(_elementEdgeCharacterLength);
                    }
                    else
                    {
                        run = new TextEndOfSegment(_elementEdgeCharacterLength);
                    }
                }
            }
            return(run);
        }
Пример #11
0
        // ------------------------------------------------------------------
        // Fetch the next run at element close edge position.
        //
        //      position - current position in the text array
        // ------------------------------------------------------------------
        private TextRun HandleElementEndEdge(StaticTextPointer position)
        {
            Debug.Assert(position.GetPointerContext(LogicalDirection.Forward) == TextPointerContext.ElementEnd, "TextPointer does not point to element end edge.");

            TextRun run = null;

            TextElement element = (TextElement)position.GetAdjacentElement(LogicalDirection.Forward);

            Debug.Assert(element != null, "Element should be here.");
            Inline inline = element as Inline;

            if (inline == null)
            {
                run = new TextHidden(_elementEdgeCharacterLength);
            }
            else
            {
                DependencyObject parent = inline.Parent;
                FlowDirection    parentFlowDirection = inline.FlowDirection;

                if (parent != null)
                {
                    parentFlowDirection = (FlowDirection)parent.GetValue(FrameworkElement.FlowDirectionProperty);
                }

                if (inline.FlowDirection != parentFlowDirection)
                {
                    run = new TextEndOfSegment(_elementEdgeCharacterLength);
                }
                else
                {
                    TextDecorationCollection textDecorations = DynamicPropertyReader.GetTextDecorations(inline);
                    if (textDecorations == null || textDecorations.Count == 0)
                    {
                        // (2) End of inline element, hide CloseEdge character and continue
                        run = new TextHidden(_elementEdgeCharacterLength);
                    }
                    else
                    {
                        run = new TextEndOfSegment(_elementEdgeCharacterLength);
                    }
                }
            }
            return(run);
        }
Пример #12
0
        /// <summary>
        /// Fetch the next run at embedded object position.
        /// </summary>
        /// <param name="dcp">
        /// Character offset of this run.
        /// </param>
        /// <param name="position">
        /// Current position in the text array.
        /// </param>
        protected TextRun HandleEmbeddedObject(int dcp, StaticTextPointer position)
        {
            Invariant.Assert(position.GetPointerContext(LogicalDirection.Forward) == TextPointerContext.EmbeddedElement, "TextPointer does not point to embedded object.");

            TextRun          run            = null;
            DependencyObject embeddedObject = position.GetAdjacentElement(LogicalDirection.Forward) as DependencyObject;

            if (embeddedObject is UIElement)
            {
                // Extract the aggregated properties into something that the textrun can use.
                TextRunProperties textProps = new TextProperties(embeddedObject, position, true /* inline objects */, true /* get background */);

                // Create inline object run.
                run = new InlineObjectRun(TextContainerHelper.EmbeddedObjectLength, (UIElement)embeddedObject, textProps, _paraClient.Paragraph as TextParagraph);
            }
            else
            {
                // If the embedded object is of an unknown type, treat it as hidden content.
                run = new TextHidden(TextContainerHelper.EmbeddedObjectLength);
            }
            return(run);
        }
        // Token: 0x0600688F RID: 26767 RVA: 0x001D802C File Offset: 0x001D622C
        protected TextRun HandleElementEndEdge(StaticTextPointer position)
        {
            Invariant.Assert(position.GetPointerContext(LogicalDirection.Forward) == TextPointerContext.ElementEnd, "TextPointer does not point to element end edge.");
            TextRun result;

            if (position.Parent == this._paraClient.Paragraph.Element)
            {
                result = new ParagraphBreakRun(LineBase._syntheticCharacterLength, PTS.FSFLRES.fsflrEndOfParagraph);
            }
            else
            {
                TextElement      textElement   = (TextElement)position.GetAdjacentElement(LogicalDirection.Forward);
                Inline           inline        = (Inline)textElement;
                DependencyObject parent        = inline.Parent;
                FlowDirection    flowDirection = inline.FlowDirection;
                if (parent != null)
                {
                    flowDirection = (FlowDirection)parent.GetValue(FrameworkElement.FlowDirectionProperty);
                }
                if (inline.FlowDirection != flowDirection)
                {
                    result = new TextEndOfSegment(LineBase._elementEdgeCharacterLength);
                }
                else
                {
                    TextDecorationCollection textDecorations = DynamicPropertyReader.GetTextDecorations(inline);
                    if (textDecorations == null || textDecorations.Count == 0)
                    {
                        result = new TextHidden(LineBase._elementEdgeCharacterLength);
                    }
                    else
                    {
                        result = new TextEndOfSegment(LineBase._elementEdgeCharacterLength);
                    }
                }
            }
            return(result);
        }
Пример #14
0
        // Token: 0x06006B36 RID: 27446 RVA: 0x001EF6F4 File Offset: 0x001ED8F4
        internal override bool InvalidateStructure(int startPosition)
        {
            Invariant.Assert(base.ParagraphEndCharacterPosition >= startPosition);
            bool result = false;

            if (base.ParagraphStartCharacterPosition == startPosition)
            {
                result = true;
                AnchoredBlock anchoredBlock = null;
                if (this._attachedObjects != null && this._attachedObjects.Count > 0)
                {
                    anchoredBlock = (AnchoredBlock)this._attachedObjects[0].Element;
                }
                if (anchoredBlock != null && startPosition == anchoredBlock.ElementStartOffset)
                {
                    StaticTextPointer staticTextPointerFromCP = TextContainerHelper.GetStaticTextPointerFromCP(base.StructuralCache.TextContainer, startPosition);
                    if (staticTextPointerFromCP.GetPointerContext(LogicalDirection.Forward) == TextPointerContext.ElementStart)
                    {
                        result = (anchoredBlock != staticTextPointerFromCP.GetAdjacentElement(LogicalDirection.Forward));
                    }
                }
            }
            this.InvalidateTextFormatCache();
            if (this._attachedObjects != null)
            {
                for (int i = 0; i < this._attachedObjects.Count; i++)
                {
                    BaseParagraph para = this._attachedObjects[i].Para;
                    if (para.ParagraphEndCharacterPosition >= startPosition)
                    {
                        para.InvalidateStructure(startPosition);
                    }
                }
            }
            return(result);
        }
Пример #15
0
        /// <summary>
        /// Return next TextRun at element edge start position
        /// </summary>
        /// <param name="position">
        /// Current position in text array
        /// </param>
        protected TextRun HandleElementStartEdge(StaticTextPointer position)
        {
            Invariant.Assert(position.GetPointerContext(LogicalDirection.Forward) == TextPointerContext.ElementStart, "TextPointer does not point to element start edge.");

            //      In the future, handle visibility collapsed.
            TextRun     run     = null;
            TextElement element = (TextElement)position.GetAdjacentElement(LogicalDirection.Forward);

            Debug.Assert(element != null, "Cannot use ITextContainer that does not provide TextElement instances.");

            Invariant.Assert(!(element is Block), "We do not expect any Blocks inside Paragraphs");

            // Treat figure and floaters as special hidden runs.
            if (element is Figure || element is Floater)
            {
                // Get the length of the element
                int cch = TextContainerHelper.GetElementLength(_paraClient.Paragraph.StructuralCache.TextContainer, element);
                // Create special hidden run.
                run = new FloatingRun(cch, element is Figure);
                if (element is Figure)
                {
                    _hasFigures = true;
                }
                else
                {
                    _hasFloaters = true;
                }
            }
            else if (element is LineBreak)
            {
                int cch = TextContainerHelper.GetElementLength(_paraClient.Paragraph.StructuralCache.TextContainer, element);
                run = new LineBreakRun(cch, PTS.FSFLRES.fsflrSoftBreak);
            }
            else if (element.IsEmpty)
            {
                // Empty TextElement should affect line metrics.
                // TextFormatter does not support this feature right now, so as workaround
                // TextRun with ZERO WIDTH SPACE is used.
                TextProperties textProps = new TextProperties(element, position, false /* inline objects */, true /* get background */,
                                                              _paraClient.Paragraph.StructuralCache.TextFormatterHost.PixelsPerDip);

                char[] textBuffer = new char[_elementEdgeCharacterLength * 2];

                // Assert that _elementEdgeCharacterLength is 1 before we use hard-coded indices
                Invariant.Assert(_elementEdgeCharacterLength == 1, "Expected value of _elementEdgeCharacterLength is 1");

                textBuffer[0] = (char)0x200B;
                textBuffer[1] = (char)0x200B;

                run = new TextCharacters(textBuffer, 0, textBuffer.Length, textProps);
            }
            else
            {
                Inline           inline = (Inline)element;
                DependencyObject parent = inline.Parent;

                FlowDirection inlineFlowDirection = inline.FlowDirection;
                FlowDirection parentFlowDirection = inlineFlowDirection;

                TextDecorationCollection inlineTextDecorations = DynamicPropertyReader.GetTextDecorations(inline);

                if (parent != null)
                {
                    parentFlowDirection = (FlowDirection)parent.GetValue(FrameworkElement.FlowDirectionProperty);
                }

                if (inlineFlowDirection != parentFlowDirection)
                {
                    // Inline's flow direction is different from its parent. Need to create new TextSpanModifier with flow direction
                    if (inlineTextDecorations == null || inlineTextDecorations.Count == 0)
                    {
                        run = new TextSpanModifier(
                            _elementEdgeCharacterLength,
                            null,
                            null,
                            inlineFlowDirection
                            );
                    }
                    else
                    {
                        run = new TextSpanModifier(
                            _elementEdgeCharacterLength,
                            inlineTextDecorations,
                            inline.Foreground,
                            inlineFlowDirection
                            );
                    }
                }
                else
                {
                    if (inlineTextDecorations == null || inlineTextDecorations.Count == 0)
                    {
                        run = new TextHidden(_elementEdgeCharacterLength);
                    }
                    else
                    {
                        run = new TextSpanModifier(
                            _elementEdgeCharacterLength,
                            inlineTextDecorations,
                            inline.Foreground
                            );
                    }
                }
            }
            return(run);
        }
        // Token: 0x0600688E RID: 26766 RVA: 0x001D7E38 File Offset: 0x001D6038
        protected TextRun HandleElementStartEdge(StaticTextPointer position)
        {
            Invariant.Assert(position.GetPointerContext(LogicalDirection.Forward) == TextPointerContext.ElementStart, "TextPointer does not point to element start edge.");
            TextElement textElement = (TextElement)position.GetAdjacentElement(LogicalDirection.Forward);

            Invariant.Assert(!(textElement is Block), "We do not expect any Blocks inside Paragraphs");
            TextRun result;

            if (textElement is Figure || textElement is Floater)
            {
                int elementLength = TextContainerHelper.GetElementLength(this._paraClient.Paragraph.StructuralCache.TextContainer, textElement);
                result = new FloatingRun(elementLength, textElement is Figure);
                if (textElement is Figure)
                {
                    this._hasFigures = true;
                }
                else
                {
                    this._hasFloaters = true;
                }
            }
            else if (textElement is LineBreak)
            {
                int elementLength2 = TextContainerHelper.GetElementLength(this._paraClient.Paragraph.StructuralCache.TextContainer, textElement);
                result = new LineBreakRun(elementLength2, PTS.FSFLRES.fsflrSoftBreak);
            }
            else if (textElement.IsEmpty)
            {
                TextProperties textRunProperties = new TextProperties(textElement, position, false, true, this._paraClient.Paragraph.StructuralCache.TextFormatterHost.PixelsPerDip);
                char[]         array             = new char[LineBase._elementEdgeCharacterLength * 2];
                Invariant.Assert(LineBase._elementEdgeCharacterLength == 1, "Expected value of _elementEdgeCharacterLength is 1");
                array[0] = '​';
                array[1] = '​';
                result   = new TextCharacters(array, 0, array.Length, textRunProperties);
            }
            else
            {
                Inline                   inline          = (Inline)textElement;
                DependencyObject         parent          = inline.Parent;
                FlowDirection            flowDirection   = inline.FlowDirection;
                FlowDirection            flowDirection2  = flowDirection;
                TextDecorationCollection textDecorations = DynamicPropertyReader.GetTextDecorations(inline);
                if (parent != null)
                {
                    flowDirection2 = (FlowDirection)parent.GetValue(FrameworkElement.FlowDirectionProperty);
                }
                if (flowDirection != flowDirection2)
                {
                    if (textDecorations == null || textDecorations.Count == 0)
                    {
                        result = new TextSpanModifier(LineBase._elementEdgeCharacterLength, null, null, flowDirection);
                    }
                    else
                    {
                        result = new TextSpanModifier(LineBase._elementEdgeCharacterLength, textDecorations, inline.Foreground, flowDirection);
                    }
                }
                else if (textDecorations == null || textDecorations.Count == 0)
                {
                    result = new TextHidden(LineBase._elementEdgeCharacterLength);
                }
                else
                {
                    result = new TextSpanModifier(LineBase._elementEdgeCharacterLength, textDecorations, inline.Foreground);
                }
            }
            return(result);
        }
Пример #17
0
        // ------------------------------------------------------------------
        // Fetch the next run at element open edge position.
        //
        //      position - current position in the text array
        // ------------------------------------------------------------------
        private TextRun HandleElementStartEdge(StaticTextPointer position)
        {
            Debug.Assert(position.GetPointerContext(LogicalDirection.Forward) == TextPointerContext.ElementStart, "TextPointer does not point to element start edge.");

            //

            TextRun     run     = null;
            TextElement element = (TextElement)position.GetAdjacentElement(LogicalDirection.Forward);

            Debug.Assert(element != null, "Cannot use ITextContainer that does not provide TextElement instances.");

            if (element is LineBreak)
            {
                run = new TextEndOfLine(_elementEdgeCharacterLength * 2);
            }
            else if (element.IsEmpty)
            {
                // Empty TextElement should affect line metrics.
                // TextFormatter does not support this feature right now, so as workaround
                // TextRun with ZERO WIDTH SPACE is used.
                TextRunProperties textProps  = new TextProperties(element, position, false /* inline objects */, true /* get background */);
                char[]            textBuffer = new char[_elementEdgeCharacterLength * 2];
                textBuffer[0] = (char)0x200B;
                textBuffer[1] = (char)0x200B;
                run           = new TextCharacters(textBuffer, 0, textBuffer.Length, textProps);
            }
            else
            {
                Inline inline = element as Inline;
                if (inline == null)
                {
                    run = new TextHidden(_elementEdgeCharacterLength);
                }
                else
                {
                    DependencyObject parent = inline.Parent;
                    FlowDirection    inlineFlowDirection = inline.FlowDirection;
                    FlowDirection    parentFlowDirection = inlineFlowDirection;

                    if (parent != null)
                    {
                        parentFlowDirection = (FlowDirection)parent.GetValue(FrameworkElement.FlowDirectionProperty);
                    }

                    TextDecorationCollection inlineTextDecorations = DynamicPropertyReader.GetTextDecorations(inline);

                    if (inlineFlowDirection != parentFlowDirection)
                    {
                        // Inline's flow direction is different from its parent. Need to create new TextSpanModifier with flow direction
                        if (inlineTextDecorations == null || inlineTextDecorations.Count == 0)
                        {
                            run = new TextSpanModifier(
                                _elementEdgeCharacterLength,
                                null,
                                null,
                                inlineFlowDirection
                                );
                        }
                        else
                        {
                            run = new TextSpanModifier(
                                _elementEdgeCharacterLength,
                                inlineTextDecorations,
                                inline.Foreground,
                                inlineFlowDirection
                                );
                        }
                    }
                    else
                    {
                        if (inlineTextDecorations == null || inlineTextDecorations.Count == 0)
                        {
                            run = new TextHidden(_elementEdgeCharacterLength);
                        }
                        else
                        {
                            run = new TextSpanModifier(
                                _elementEdgeCharacterLength,
                                inlineTextDecorations,
                                inline.Foreground
                                );
                        }
                    }
                }
            }
            return(run);
        }