/// <summary>
            /// Sets parentPosition to be a valid TextPointer in the parent document.  This could either
            /// be the textPosition passed in (if its already on the parent document) or a conversion
            /// of the textPosition passed in.
            /// </summary>
            /// <returns>whether or not parentPosition is valid and should be used</returns>
            private bool EnsureParentPosition(StaticTextPointer textPosition, LogicalDirection direction, out StaticTextPointer parentPosition)
            {
                // Simple case - textPosition is already in the parent TextContainer
                parentPosition = textPosition;

                // If textPosition is on a child TextContainer, we convert it
                if (textPosition.TextContainer.Highlights != this)
                {
                    // This case can't be converted so return false, out parameter should not be used
                    if (textPosition.GetPointerContext(direction) == TextPointerContext.None)
                    {
                        return(false);
                    }

                    // Turn the textPosition (which should be in the scope of a FixedDocument)
                    // into a position in the scope of the DocumentSequence.
                    ITextPointer dynamicTextPointer = textPosition.CreateDynamicTextPointer(LogicalDirection.Forward);
                    ITextPointer parentTextPointer  = ((DocumentSequenceTextContainer)this.TextContainer).MapChildPositionToParent(dynamicTextPointer);
                    Debug.Assert(parentTextPointer != null);
                    parentPosition = parentTextPointer.CreateStaticPointer();
                }

                // Returning true - either we started with a parent position or we converted to one
                return(true);
            }
Ejemplo n.º 2
0
        /// <summary>
        /// Returns the closest neighboring TextPointer in an indicated
        /// direction where a property value calculated from an embedded
        /// object, scoping text element, or scoping highlight could
        /// change.
        /// </summary>
        /// <param name="textPosition">
        /// Position to query.
        /// </param>
        /// <param name="direction">
        /// Direction of content to query.
        /// </param>
        /// <returns>
        /// If the following symbol is TextPointerContext.EmbeddedElement,
        /// TextPointerContext.ElementBegin, or TextPointerContext.ElementEnd, returns
        /// a TextPointer exactly one symbol distant.
        ///
        /// If the following symbol is TextPointerContext.Text, the distance
        /// of the returned TextPointer is the minimum of the value returned
        /// by textPosition.GetTextLength and the distance to any highlight
        /// start or end edge.
        ///
        /// If the following symbol is TextPointerContext.None, returns null.
        /// </returns>
        internal virtual StaticTextPointer GetNextPropertyChangePosition(StaticTextPointer textPosition, LogicalDirection direction)
        {
            StaticTextPointer changePosition;
            StaticTextPointer characterRunEndPosition;

            switch (textPosition.GetPointerContext(direction))
            {
            case TextPointerContext.None:
                changePosition = StaticTextPointer.Null;
                break;

            case TextPointerContext.Text:
                changePosition          = GetNextHighlightChangePosition(textPosition, direction);
                characterRunEndPosition = textPosition.GetNextContextPosition(LogicalDirection.Forward);

                if (changePosition.IsNull ||
                    characterRunEndPosition.CompareTo(changePosition) < 0)
                {
                    changePosition = characterRunEndPosition;
                }

                break;

            case TextPointerContext.EmbeddedElement:
            case TextPointerContext.ElementStart:
            case TextPointerContext.ElementEnd:
            default:
                changePosition = textPosition.CreatePointer(+1);
                break;
            }

            return(changePosition);
        }
Ejemplo n.º 3
0
 // Token: 0x0600847B RID: 33915 RVA: 0x00248358 File Offset: 0x00246558
 private bool EnsureParentPosition(StaticTextPointer textPosition, LogicalDirection direction, out StaticTextPointer parentPosition)
 {
     parentPosition = textPosition;
     if (textPosition.TextContainer.Highlights != this)
     {
         if (textPosition.GetPointerContext(direction) == TextPointerContext.None)
         {
             return(false);
         }
         ITextPointer tp          = textPosition.CreateDynamicTextPointer(LogicalDirection.Forward);
         ITextPointer textPointer = ((DocumentSequenceTextContainer)base.TextContainer).MapChildPositionToParent(tp);
         parentPosition = textPointer.CreateStaticPointer();
     }
     return(true);
 }
        // Token: 0x06003007 RID: 12295 RVA: 0x000D8070 File Offset: 0x000D6270
        internal virtual StaticTextPointer GetNextPropertyChangePosition(StaticTextPointer textPosition, LogicalDirection direction)
        {
            StaticTextPointer staticTextPointer;

            switch (textPosition.GetPointerContext(direction))
            {
            case TextPointerContext.None:
                return(StaticTextPointer.Null);

            case TextPointerContext.Text:
            {
                staticTextPointer = this.GetNextHighlightChangePosition(textPosition, direction);
                StaticTextPointer nextContextPosition = textPosition.GetNextContextPosition(LogicalDirection.Forward);
                if (staticTextPointer.IsNull || nextContextPosition.CompareTo(staticTextPointer) < 0)
                {
                    return(nextContextPosition);
                }
                return(staticTextPointer);
            }
            }
            staticTextPointer = textPosition.CreatePointer(1);
            return(staticTextPointer);
        }
Ejemplo n.º 5
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 */);

            // 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);
        }
Ejemplo n.º 6
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;
        }
Ejemplo n.º 7
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;
        }
Ejemplo n.º 8
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.");

            // 

            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 */);

                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;
        }
Ejemplo n.º 9
0
        /// <summary>
        /// Returns the closest neighboring TextPointer in an indicated
        /// direction where a property value calculated from an embedded
        /// object, scoping text element, or scoping highlight could
        /// change.
        /// </summary>
        /// <param name="textPosition">
        /// Position to query.
        /// </param>
        /// <param name="direction">
        /// Direction of content to query.
        /// </param>
        /// <returns>
        /// If the following symbol is TextPointerContext.EmbeddedElement,
        /// TextPointerContext.ElementBegin, or TextPointerContext.ElementEnd, returns
        /// a TextPointer exactly one symbol distant.
        ///
        /// If the following symbol is TextPointerContext.Text, the distance
        /// of the returned TextPointer is the minimum of the value returned
        /// by textPosition.GetTextLength and the distance to any highlight
        /// start or end edge.
        ///
        /// If the following symbol is TextPointerContext.None, returns null.
        /// </returns>
        internal virtual StaticTextPointer GetNextPropertyChangePosition(StaticTextPointer textPosition, LogicalDirection direction)
        {
            StaticTextPointer changePosition;
            StaticTextPointer characterRunEndPosition;

            switch (textPosition.GetPointerContext(direction))
            {
                case TextPointerContext.None:
                    changePosition = StaticTextPointer.Null;
                    break;

                case TextPointerContext.Text:
                    changePosition = GetNextHighlightChangePosition(textPosition, direction);
                    characterRunEndPosition = textPosition.GetNextContextPosition(LogicalDirection.Forward);

                    if (changePosition.IsNull ||
                        characterRunEndPosition.CompareTo(changePosition) < 0)
                    {
                        changePosition = characterRunEndPosition;
                    }

                    break;

                case TextPointerContext.EmbeddedElement:
                case TextPointerContext.ElementStart:
                case TextPointerContext.ElementEnd:
                default:
                    changePosition = textPosition.CreatePointer(+1);
                    break;
            }

            return changePosition;
        }
            /// <summary>
            /// Sets parentPosition to be a valid TextPointer in the parent document.  This could either
            /// be the textPosition passed in (if its already on the parent document) or a conversion 
            /// of the textPosition passed in.
            /// </summary> 
            /// <returns>whether or not parentPosition is valid and should be used</returns> 
            private bool EnsureParentPosition(StaticTextPointer textPosition, LogicalDirection direction, out StaticTextPointer parentPosition)
            { 
                // Simple case - textPosition is already in the parent TextContainer
                parentPosition = textPosition;

                // If textPosition is on a child TextContainer, we convert it 
                if (textPosition.TextContainer.Highlights != this)
                { 
                    // This case can't be converted so return false, out parameter should not be used 
                    if (textPosition.GetPointerContext(direction) == TextPointerContext.None)
                        return false; 

                    // Turn the textPosition (which should be in the scope of a FixedDocument)
                    // into a position in the scope of the DocumentSequence.
                    ITextPointer dynamicTextPointer = textPosition.CreateDynamicTextPointer(LogicalDirection.Forward); 
                    ITextPointer parentTextPointer = ((DocumentSequenceTextContainer)this.TextContainer).MapChildPositionToParent(dynamicTextPointer);
                    Debug.Assert(parentTextPointer != null); 
                    parentPosition = parentTextPointer.CreateStaticPointer(); 
                }
 
                // Returning true - either we started with a parent position or we converted to one
                return true;
            }
Ejemplo n.º 11
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; 
        } 
Ejemplo n.º 12
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;
        }
Ejemplo n.º 13
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; 
        }