Ejemplo n.º 1
0
        // Token: 0x06006B2D RID: 27437 RVA: 0x001EF394 File Offset: 0x001ED594
        private List <TextElement> GetAttachedObjectElements(int dcpFirst, int dcpLast)
        {
            List <TextElement> list              = new List <TextElement>();
            ITextPointer       contentStart      = TextContainerHelper.GetContentStart(base.StructuralCache.TextContainer, base.Element);
            ITextPointer       textPointerFromCP = TextContainerHelper.GetTextPointerFromCP(base.StructuralCache.TextContainer, base.ParagraphStartCharacterPosition + dcpFirst, LogicalDirection.Forward);

            if (dcpLast > base.Cch)
            {
                dcpLast = base.Cch;
            }
            while (contentStart.GetOffsetToPosition(textPointerFromCP) < dcpLast)
            {
                if (textPointerFromCP.GetPointerContext(LogicalDirection.Forward) == TextPointerContext.ElementStart)
                {
                    TextElement adjacentElementFromOuterPosition = ((TextPointer)textPointerFromCP).GetAdjacentElementFromOuterPosition(LogicalDirection.Forward);
                    if (adjacentElementFromOuterPosition is Figure || adjacentElementFromOuterPosition is Floater)
                    {
                        list.Add(adjacentElementFromOuterPosition);
                        textPointerFromCP.MoveByOffset(adjacentElementFromOuterPosition.SymbolCount);
                    }
                    else
                    {
                        textPointerFromCP.MoveToNextContextPosition(LogicalDirection.Forward);
                    }
                }
                else
                {
                    textPointerFromCP.MoveToNextContextPosition(LogicalDirection.Forward);
                }
            }
            return(list);
        }
Ejemplo n.º 2
0
        // Token: 0x06007245 RID: 29253 RVA: 0x0020AA54 File Offset: 0x00208C54
        internal static List <AutomationPeer> GetAutomationPeersFromRange(ITextPointer start, ITextPointer end, ITextPointer ownerContentStart)
        {
            List <AutomationPeer> list = new List <AutomationPeer>();

            start = start.CreatePointer();
            while (start.CompareTo(end) < 0)
            {
                bool flag = false;
                if (start.GetPointerContext(LogicalDirection.Forward) == TextPointerContext.ElementStart)
                {
                    object adjacentElement = start.GetAdjacentElement(LogicalDirection.Forward);
                    if (adjacentElement is ContentElement)
                    {
                        AutomationPeer automationPeer = ContentElementAutomationPeer.CreatePeerForElement((ContentElement)adjacentElement);
                        if (automationPeer != null)
                        {
                            if (ownerContentStart == null || TextContainerHelper.IsImmediateAutomationChild(start, ownerContentStart))
                            {
                                list.Add(automationPeer);
                            }
                            start.MoveToNextContextPosition(LogicalDirection.Forward);
                            start.MoveToElementEdge(ElementEdge.AfterEnd);
                            flag = true;
                        }
                    }
                }
                else if (start.GetPointerContext(LogicalDirection.Forward) == TextPointerContext.EmbeddedElement)
                {
                    object adjacentElement = start.GetAdjacentElement(LogicalDirection.Forward);
                    if (adjacentElement is UIElement)
                    {
                        if (ownerContentStart == null || TextContainerHelper.IsImmediateAutomationChild(start, ownerContentStart))
                        {
                            AutomationPeer automationPeer = UIElementAutomationPeer.CreatePeerForElement((UIElement)adjacentElement);
                            if (automationPeer != null)
                            {
                                list.Add(automationPeer);
                            }
                            else
                            {
                                TextContainerHelper.iterate((Visual)adjacentElement, list);
                            }
                        }
                    }
                    else if (adjacentElement is ContentElement)
                    {
                        AutomationPeer automationPeer = ContentElementAutomationPeer.CreatePeerForElement((ContentElement)adjacentElement);
                        if (automationPeer != null && (ownerContentStart == null || TextContainerHelper.IsImmediateAutomationChild(start, ownerContentStart)))
                        {
                            list.Add(automationPeer);
                        }
                    }
                }
                if (!flag && !start.MoveToNextContextPosition(LogicalDirection.Forward))
                {
                    break;
                }
            }
            return(list);
        }
Ejemplo n.º 3
0
        // Token: 0x060068B0 RID: 26800 RVA: 0x001D8BE4 File Offset: 0x001D6DE4
        protected override BaseParagraph GetParagraph(ITextPointer textPointer, bool fEmptyOk)
        {
            Invariant.Assert(textPointer is TextPointer);
            BaseParagraph baseParagraph = null;

            while (baseParagraph == null)
            {
                TextPointerContext pointerContext = textPointer.GetPointerContext(LogicalDirection.Forward);
                if (pointerContext == TextPointerContext.ElementStart)
                {
                    TextElement adjacentElementFromOuterPosition = ((TextPointer)textPointer).GetAdjacentElementFromOuterPosition(LogicalDirection.Forward);
                    if (adjacentElementFromOuterPosition is ListItem)
                    {
                        baseParagraph = new ListItemParagraph(adjacentElementFromOuterPosition, base.StructuralCache);
                        break;
                    }
                    if (adjacentElementFromOuterPosition is List)
                    {
                        baseParagraph = new ListParagraph(adjacentElementFromOuterPosition, base.StructuralCache);
                        break;
                    }
                    if (((TextPointer)textPointer).IsFrozen)
                    {
                        textPointer = textPointer.CreatePointer();
                    }
                    textPointer.MoveToPosition(adjacentElementFromOuterPosition.ElementEnd);
                }
                else if (pointerContext == TextPointerContext.ElementEnd)
                {
                    if (base.Element == ((TextPointer)textPointer).Parent)
                    {
                        break;
                    }
                    if (((TextPointer)textPointer).IsFrozen)
                    {
                        textPointer = textPointer.CreatePointer();
                    }
                    textPointer.MoveToNextContextPosition(LogicalDirection.Forward);
                }
                else
                {
                    if (((TextPointer)textPointer).IsFrozen)
                    {
                        textPointer = textPointer.CreatePointer();
                    }
                    textPointer.MoveToNextContextPosition(LogicalDirection.Forward);
                }
            }
            if (baseParagraph != null)
            {
                base.StructuralCache.CurrentFormatContext.DependentMax = (TextPointer)textPointer;
            }
            return(baseParagraph);
        }
Ejemplo n.º 4
0
        // Token: 0x060038D8 RID: 14552 RVA: 0x00100E4C File Offset: 0x000FF04C
        private static bool IsErrorAtNonMergeableInlineEdge(SpellingError spellingError, out ITextPointer textStart, out ITextPointer textEnd)
        {
            bool result = false;

            textStart = spellingError.Start.CreatePointer(LogicalDirection.Backward);
            while (textStart.CompareTo(spellingError.End) < 0 && textStart.GetPointerContext(LogicalDirection.Forward) != TextPointerContext.Text)
            {
                textStart.MoveToNextContextPosition(LogicalDirection.Forward);
            }
            textEnd = spellingError.End.CreatePointer();
            while (textEnd.CompareTo(spellingError.Start) > 0 && textEnd.GetPointerContext(LogicalDirection.Backward) != TextPointerContext.Text)
            {
                textEnd.MoveToNextContextPosition(LogicalDirection.Backward);
            }
            if (textStart.GetPointerContext(LogicalDirection.Forward) != TextPointerContext.Text || textStart.CompareTo(spellingError.End) == 0)
            {
                return(false);
            }
            Invariant.Assert(textEnd.GetPointerContext(LogicalDirection.Backward) == TextPointerContext.Text && textEnd.CompareTo(spellingError.Start) != 0);
            if ((TextPointerBase.IsAtNonMergeableInlineStart(textStart) || TextPointerBase.IsAtNonMergeableInlineEnd(textEnd)) && typeof(Run).IsAssignableFrom(textStart.ParentType) && textStart.HasEqualScope(textEnd))
            {
                result = true;
            }
            return(result);
        }
            // Token: 0x06008E5B RID: 36443 RVA: 0x0025BE9C File Offset: 0x0025A09C
            private void GetContent()
            {
                this._contentSegments.Clear();
                ITextPointer textPointer  = this._segment.Start.CreatePointer();
                ITextPointer textPointer2 = null;

                while (textPointer.CompareTo(this._segment.End) < 0)
                {
                    TextPointerContext pointerContext = textPointer.GetPointerContext(LogicalDirection.Forward);
                    if (pointerContext == TextPointerContext.ElementStart)
                    {
                        Type elementType = textPointer.GetElementType(LogicalDirection.Forward);
                        if (typeof(Run).IsAssignableFrom(elementType) || typeof(BlockUIContainer).IsAssignableFrom(elementType))
                        {
                            this.OpenSegment(ref textPointer2, textPointer);
                        }
                        else if (typeof(Table).IsAssignableFrom(elementType) || typeof(Floater).IsAssignableFrom(elementType) || typeof(Figure).IsAssignableFrom(elementType))
                        {
                            this.CloseSegment(ref textPointer2, textPointer, this._segment.End);
                        }
                        textPointer.MoveToNextContextPosition(LogicalDirection.Forward);
                        if (typeof(Run).IsAssignableFrom(elementType) || typeof(BlockUIContainer).IsAssignableFrom(elementType))
                        {
                            textPointer.MoveToElementEdge(ElementEdge.AfterEnd);
                        }
                    }
                    else if (pointerContext == TextPointerContext.ElementEnd)
                    {
                        Type parentType = textPointer.ParentType;
                        if (typeof(TableCell).IsAssignableFrom(parentType) || typeof(Floater).IsAssignableFrom(parentType) || typeof(Figure).IsAssignableFrom(parentType))
                        {
                            this.CloseSegment(ref textPointer2, textPointer, this._segment.End);
                        }
                        textPointer.MoveToNextContextPosition(LogicalDirection.Forward);
                    }
                    else if (pointerContext == TextPointerContext.Text || pointerContext == TextPointerContext.EmbeddedElement)
                    {
                        this.OpenSegment(ref textPointer2, textPointer);
                        textPointer.MoveToNextContextPosition(LogicalDirection.Forward);
                    }
                    else
                    {
                        Invariant.Assert(false, "unexpected TextPointerContext");
                    }
                }
                this.CloseSegment(ref textPointer2, textPointer, this._segment.End);
            }
Ejemplo n.º 6
0
        // Candidate for replacing MoveToNextContextPosition for immutable TextPointer model
        ITextPointer ITextPointer.GetNextContextPosition(LogicalDirection direction)
        {
            ITextPointer pointer = ((ITextPointer)this).CreatePointer();

            if (pointer.MoveToNextContextPosition(direction))
            {
                pointer.Freeze();
            }
            else
            {
                pointer = null;
            }
            return(pointer);
        }
Ejemplo n.º 7
0
        // Token: 0x06003282 RID: 12930 RVA: 0x000DD010 File Offset: 0x000DB210
        internal static bool HasNoTextContent(Paragraph paragraph)
        {
            ITextPointer textPointer = paragraph.ContentStart.CreatePointer();
            ITextPointer contentEnd  = paragraph.ContentEnd;

            while (textPointer.CompareTo(contentEnd) < 0)
            {
                TextPointerContext pointerContext = textPointer.GetPointerContext(LogicalDirection.Forward);
                if (pointerContext == TextPointerContext.Text || pointerContext == TextPointerContext.EmbeddedElement || typeof(LineBreak).IsAssignableFrom(textPointer.ParentType) || typeof(AnchoredBlock).IsAssignableFrom(textPointer.ParentType))
                {
                    return(false);
                }
                textPointer.MoveToNextContextPosition(LogicalDirection.Forward);
            }
            return(true);
        }
Ejemplo n.º 8
0
            // Token: 0x06008465 RID: 33893 RVA: 0x002480A0 File Offset: 0x002462A0
            private void AddMultipleCompositionLines(ITextPointer start, ITextPointer end)
            {
                ITextPointer textPointer  = start;
                ITextPointer textPointer2 = textPointer;

                while (textPointer2.CompareTo(end) < 0)
                {
                    TextSegment lineRange = this._textView.GetLineRange(textPointer2);
                    if (lineRange.IsNull)
                    {
                        textPointer = textPointer2;
                    }
                    else
                    {
                        if (textPointer.CompareTo(lineRange.Start) < 0)
                        {
                            textPointer = lineRange.Start;
                        }
                        if (textPointer2.CompareTo(lineRange.End) < 0)
                        {
                            if (end.CompareTo(lineRange.End) < 0)
                            {
                                textPointer2 = end.CreatePointer();
                            }
                            else
                            {
                                textPointer2 = lineRange.End.CreatePointer(LogicalDirection.Backward);
                            }
                        }
                        Rect rectangleFromTextPosition  = this._textView.GetRectangleFromTextPosition(textPointer);
                        Rect rectangleFromTextPosition2 = this._textView.GetRectangleFromTextPosition(textPointer2);
                        this._compositionLines.Add(new CompositionAdorner.CompositionLine(rectangleFromTextPosition, rectangleFromTextPosition2, this._textServicesDisplayAttribute.GetLineColor(textPointer)));
                        textPointer = lineRange.End.CreatePointer(LogicalDirection.Forward);
                    }
                    while (textPointer.GetPointerContext(LogicalDirection.Forward) != TextPointerContext.None && textPointer.GetPointerContext(LogicalDirection.Forward) != TextPointerContext.Text)
                    {
                        textPointer.MoveToNextContextPosition(LogicalDirection.Forward);
                    }
                    textPointer2 = textPointer;
                }
            }
Ejemplo n.º 9
0
            //------------------------------------------------------
            //
            //  Internal Methods
            //
            //------------------------------------------------------

            #region Internal Methods

            // Add the composition lines for rendering the composition lines.
            internal void AddCompositionLines()
            {
                // Erase any current lines.
                _compositionLines.Clear();

                ITextPointer start = _textView.TextContainer.Start.CreatePointer(_startOffset, LogicalDirection.Forward);
                ITextPointer end   = _textView.TextContainer.Start.CreatePointer(_endOffset, LogicalDirection.Backward);

                while (start.CompareTo(end) < 0 && start.GetPointerContext(LogicalDirection.Forward) != TextPointerContext.Text)
                {
                    start.MoveToNextContextPosition(LogicalDirection.Forward);
                }

                Invariant.Assert(start.GetPointerContext(LogicalDirection.Forward) == TextPointerContext.Text);

                if (end.HasValidLayout)
                {
                    // Get the rectangle for start/end position
                    _startRect = _textView.GetRectangleFromTextPosition(start);
                    _endRect   = _textView.GetRectangleFromTextPosition(end);

                    // Check whether the composition line is single or multiple lines
                    if (_startRect.Top != _endRect.Top)
                    {
                        // Add the composition lines to be rendered for the composition string
                        AddMultipleCompositionLines(start, end);
                    }
                    else
                    {
                        // Set the start/end pointer to draw the line
                        Color lineColor = _textServicesDisplayAttribute.GetLineColor(start);
                        // Add the composition line to be rendered
                        _compositionLines.Add(new CompositionLine(_startRect, _endRect, lineColor));
                    }
                }
            }
Ejemplo n.º 10
0
            // Token: 0x06008461 RID: 33889 RVA: 0x00247F80 File Offset: 0x00246180
            internal void AddCompositionLines()
            {
                this._compositionLines.Clear();
                ITextPointer textPointer  = this._textView.TextContainer.Start.CreatePointer(this._startOffset, LogicalDirection.Forward);
                ITextPointer textPointer2 = this._textView.TextContainer.Start.CreatePointer(this._endOffset, LogicalDirection.Backward);

                while (textPointer.CompareTo(textPointer2) < 0 && textPointer.GetPointerContext(LogicalDirection.Forward) != TextPointerContext.Text)
                {
                    textPointer.MoveToNextContextPosition(LogicalDirection.Forward);
                }
                Invariant.Assert(textPointer.GetPointerContext(LogicalDirection.Forward) == TextPointerContext.Text);
                if (textPointer2.HasValidLayout)
                {
                    this._startRect = this._textView.GetRectangleFromTextPosition(textPointer);
                    this._endRect   = this._textView.GetRectangleFromTextPosition(textPointer2);
                    if (this._startRect.Top != this._endRect.Top)
                    {
                        this.AddMultipleCompositionLines(textPointer, textPointer2);
                        return;
                    }
                    Color lineColor = this._textServicesDisplayAttribute.GetLineColor(textPointer);
                    this._compositionLines.Add(new CompositionAdorner.CompositionLine(this._startRect, this._endRect, lineColor));
                }
            }
Ejemplo n.º 11
0
        // Token: 0x06002C1F RID: 11295 RVA: 0x000C8584 File Offset: 0x000C6784
        private static bool xGapAwareScan(DocumentSequenceTextPointer thisTp, int distance)
        {
            ChildDocumentBlock childDocumentBlock = thisTp.ChildBlock;
            bool         flag        = true;
            ITextPointer textPointer = thisTp.ChildPointer;

            if (textPointer == null)
            {
                flag        = false;
                textPointer = thisTp.ChildPointer.CreatePointer();
            }
            LogicalDirection logicalDirection = (distance > 0) ? LogicalDirection.Forward : LogicalDirection.Backward;

            distance = Math.Abs(distance);
            while (distance > 0)
            {
                switch (textPointer.GetPointerContext(logicalDirection))
                {
                case TextPointerContext.None:
                    if ((childDocumentBlock.IsHead && logicalDirection == LogicalDirection.Backward) || (childDocumentBlock.IsTail && logicalDirection == LogicalDirection.Forward))
                    {
                        return(false);
                    }
                    childDocumentBlock = ((logicalDirection == LogicalDirection.Forward) ? childDocumentBlock.NextBlock : childDocumentBlock.PreviousBlock);
                    textPointer        = ((logicalDirection == LogicalDirection.Forward) ? childDocumentBlock.ChildContainer.Start.CreatePointer(textPointer.LogicalDirection) : childDocumentBlock.ChildContainer.End.CreatePointer(textPointer.LogicalDirection));
                    break;

                case TextPointerContext.Text:
                {
                    int textRunLength = textPointer.GetTextRunLength(logicalDirection);
                    int num           = (textRunLength < distance) ? textRunLength : distance;
                    distance -= num;
                    if (logicalDirection == LogicalDirection.Backward)
                    {
                        num *= -1;
                    }
                    textPointer.MoveByOffset(num);
                    break;
                }

                case TextPointerContext.EmbeddedElement:
                    textPointer.MoveToNextContextPosition(logicalDirection);
                    distance--;
                    break;

                case TextPointerContext.ElementStart:
                    textPointer.MoveToNextContextPosition(logicalDirection);
                    distance--;
                    break;

                case TextPointerContext.ElementEnd:
                    textPointer.MoveToNextContextPosition(logicalDirection);
                    distance--;
                    break;
                }
            }
            thisTp.ChildBlock = childDocumentBlock;
            if (flag)
            {
                thisTp.ChildPointer = textPointer;
            }
            else
            {
                thisTp.ChildPointer = textPointer.CreatePointer();
            }
            return(true);
        }
Ejemplo n.º 12
0
        private void TextPositionsFromITfRange(UnsafeNativeMethods.ITfRange range, out ITextPointer start, out ITextPointer end)
        {
            UnsafeNativeMethods.ITfRangeACP rangeACP;
            int startIndex;
            int length;

            rangeACP = range as UnsafeNativeMethods.ITfRangeACP;
            rangeACP.GetExtent(out startIndex, out length);

            start = CreatePointerAtCharOffset(startIndex, LogicalDirection.Backward);
            end = CreatePointerAtCharOffset(startIndex + length, LogicalDirection.Forward);

            while (start.CompareTo(end) < 0 && start.GetPointerContext(LogicalDirection.Forward) != TextPointerContext.Text)
            {
                start.MoveToNextContextPosition(LogicalDirection.Forward);
            }
        }
Ejemplo n.º 13
0
        // GetText handler for text runs.
        private static bool WalkTextRun(ITextPointer navigator, ITextPointer limit, char[] text, int cchReq, ref int charsCopied, UnsafeNativeMethods.TS_RUNINFO[] runInfo, int cRunInfoReq, ref int cRunInfoRcv)
        {
            int runCount;
            int offset;
            bool hitLimit;

            Invariant.Assert(navigator.GetPointerContext(LogicalDirection.Forward) == TextPointerContext.Text);
            Invariant.Assert(limit == null || navigator.CompareTo(limit) <= 0);

            hitLimit = false;

            if (cchReq > 0)
            {
                runCount = TextPointerBase.GetTextWithLimit(navigator, LogicalDirection.Forward, text, charsCopied, Math.Min(cchReq, text.Length - charsCopied), limit);
                navigator.MoveByOffset(runCount);
                charsCopied += runCount;
                hitLimit = (text.Length == charsCopied) || (limit != null && navigator.CompareTo(limit) == 0);
            }
            else
            {
                // Caller doesn't want text, just run info.
                // Advance the navigator.
                runCount = navigator.GetTextRunLength(LogicalDirection.Forward);
                navigator.MoveToNextContextPosition(LogicalDirection.Forward);

                // If the caller passed in a non-null limit, backup to the limit if
                // we've passed it.
                if (limit != null)
                {
                    if (navigator.CompareTo(limit) >= 0)
                    {
                        offset = limit.GetOffsetToPosition(navigator);
                        Invariant.Assert(offset >= 0 && offset <= runCount, "Bogus offset -- extends past run!");
                        runCount -= offset;
                        navigator.MoveToPosition(limit);
                        hitLimit = true;
                    }
                }
            }

            if (cRunInfoReq > 0 && runCount > 0)
            {
                // Be sure to merge this text run with the previous run, if they are both text runs.
                // (A good robustness fix would be to make cicero handle this, if we ever get the chance.)
                if (cRunInfoRcv > 0 && runInfo[cRunInfoRcv - 1].type == UnsafeNativeMethods.TsRunType.TS_RT_PLAIN)
                {
                    runInfo[cRunInfoRcv - 1].count += runCount;
                }
                else
                {
                    runInfo[cRunInfoRcv].count = runCount;
                    runInfo[cRunInfoRcv].type = UnsafeNativeMethods.TsRunType.TS_RT_PLAIN;
                    cRunInfoRcv++;
                }
            }

            return hitLimit;
        }
Ejemplo n.º 14
0
        // Exits the scope of a non-mergeable inline with inner edge in the direction indicated.
        private static int LeaveNonMergeableAncestor(ITextPointer thisNavigator, LogicalDirection direction)
        {
            int symbolCount = 0;
            int increment = (direction == LogicalDirection.Forward) ? +1 : -1;

            while (TextSchema.IsMergeableInline(thisNavigator.ParentType))
            {
                thisNavigator.MoveToNextContextPosition(direction);
                symbolCount += increment;
            }

            thisNavigator.MoveToNextContextPosition(direction);
            symbolCount += increment;

            return symbolCount;
        }
Ejemplo n.º 15
0
        /// <summary>
        /// Moves the navigator in the given direction to a position of the next
        /// word boundary.
        /// </summary>
        /// <param name="thisNavigator">ITextPointer to advance.</param>
        /// <param name="movingDirection">
        /// Direction to move.
        /// </param>
        /// <returns></returns>
        // 




        internal static bool MoveToNextWordBoundary(ITextPointer thisNavigator, LogicalDirection movingDirection)
        {
            int moveCounter = 0;

            Invariant.Assert(!thisNavigator.IsFrozen, "Can't reposition a frozen pointer!");
            ITextPointer startPosition = thisNavigator.CreatePointer();

            while (thisNavigator.MoveToNextInsertionPosition(movingDirection))
            {
                moveCounter++;

                // Need to break the loop for weird case when there is no word break in text content.
                // When the word looks too long, consider end of textRun as a word break.
                // 
                if (moveCounter > 64) // 64 was taken as a random number. Probably not big enough though...
                {
                    thisNavigator.MoveToPosition(startPosition);
                    thisNavigator.MoveToNextContextPosition(movingDirection);
                    break;
                }

                if (IsAtWordBoundary(thisNavigator, /*insideWordDirection:*/LogicalDirection.Forward))
                {
                    // Note that we always use Forward direction for word orientation.
                    break;
                }
            }

            return moveCounter > 0;
        }
Ejemplo n.º 16
0
 // Part of plain text converter: called from GetTextInternal when processing ElementEnd for Listelements 
 // Pops a current value from a stack of list item indices. 
 private static void PlainConvertListEnd(ITextPointer navigator, ref Stack<int> listItemCounter)
 { 
     // Note that we do not expect List tag balansing:
     // We can get more List closing tags than we had opening ones -
     // it happens when range starts in the middle of a list.
     if (listItemCounter != null && listItemCounter.Count > 0) 
     {
         listItemCounter.Pop(); 
     } 
     navigator.MoveToNextContextPosition(LogicalDirection.Forward);
 } 
Ejemplo n.º 17
0
 // Part of plain text converter: called from GetTextInternal when processing Text runs 
 private static void PlainConvertTextRun(StringBuilder textBuffer, ITextPointer navigator, ITextPointer endPosition, ref Char[] charArray)
 { 
     // Copy this text run into destination
     int runLength = navigator.GetTextRunLength(LogicalDirection.Forward);
     charArray = EnsureCharArraySize(charArray, runLength);
     runLength = TextPointerBase.GetTextWithLimit(navigator, LogicalDirection.Forward, charArray, 0, runLength, endPosition); 
     textBuffer.Append(charArray, 0, runLength);
     navigator.MoveToNextContextPosition(LogicalDirection.Forward); 
 } 
Ejemplo n.º 18
0
        // Token: 0x060065D1 RID: 26065 RVA: 0x001C8918 File Offset: 0x001C6B18
        ITextRangeProvider ITextProvider.RangeFromChild(IRawElementProviderSimple childElementProvider)
        {
            if (childElementProvider == null)
            {
                throw new ArgumentNullException("childElementProvider");
            }
            DependencyObject dependencyObject;

            if (this._textPeer is TextAutomationPeer)
            {
                dependencyObject = ((TextAutomationPeer)this._textPeer).ElementFromProvider(childElementProvider);
            }
            else
            {
                dependencyObject = ((ContentTextAutomationPeer)this._textPeer).ElementFromProvider(childElementProvider);
            }
            TextRangeAdaptor textRangeAdaptor = null;

            if (dependencyObject != null)
            {
                ITextPointer textPointer  = null;
                ITextPointer textPointer2 = null;
                if (dependencyObject is TextElement)
                {
                    textPointer  = ((TextElement)dependencyObject).ElementStart;
                    textPointer2 = ((TextElement)dependencyObject).ElementEnd;
                }
                else
                {
                    DependencyObject parent = LogicalTreeHelper.GetParent(dependencyObject);
                    if (parent is InlineUIContainer || parent is BlockUIContainer)
                    {
                        textPointer  = ((TextElement)parent).ContentStart;
                        textPointer2 = ((TextElement)parent).ContentEnd;
                    }
                    else
                    {
                        ITextPointer textPointer3 = this._textContainer.Start.CreatePointer();
                        while (textPointer3.CompareTo(this._textContainer.End) < 0)
                        {
                            TextPointerContext pointerContext = textPointer3.GetPointerContext(LogicalDirection.Forward);
                            if (pointerContext == TextPointerContext.ElementStart)
                            {
                                if (dependencyObject == textPointer3.GetAdjacentElement(LogicalDirection.Forward))
                                {
                                    textPointer = textPointer3.CreatePointer(LogicalDirection.Forward);
                                    textPointer3.MoveToElementEdge(ElementEdge.AfterEnd);
                                    textPointer2 = textPointer3.CreatePointer(LogicalDirection.Backward);
                                    break;
                                }
                            }
                            else if (pointerContext == TextPointerContext.EmbeddedElement && dependencyObject == textPointer3.GetAdjacentElement(LogicalDirection.Forward))
                            {
                                textPointer = textPointer3.CreatePointer(LogicalDirection.Forward);
                                textPointer3.MoveToNextContextPosition(LogicalDirection.Forward);
                                textPointer2 = textPointer3.CreatePointer(LogicalDirection.Backward);
                                break;
                            }
                            textPointer3.MoveToNextContextPosition(LogicalDirection.Forward);
                        }
                    }
                }
                if (textPointer != null && textPointer2 != null)
                {
                    textRangeAdaptor = new TextRangeAdaptor(this, textPointer, textPointer2, this._textPeer);
                }
            }
            if (textRangeAdaptor == null)
            {
                throw new InvalidOperationException(SR.Get("TextProvider_InvalidChildElement"));
            }
            return(textRangeAdaptor);
        }
Ejemplo n.º 19
0
        //-------------------------------------------------------------------
        // 
        //  Internal Methods 
        //
        //------------------------------------------------------------------- 

        #region Internal Methods

        /// <summary> 
        /// Retrieves a collection of AutomationPeers that fall within the range.
        /// Children that overlap with the range but are not entirely enclosed by 
        /// it will also be included in the collection. 
        /// </summary>
        internal static List<AutomationPeer> GetAutomationPeersFromRange(ITextPointer start, ITextPointer end, ITextPointer ownerContentStart) 
        {
            bool positionMoved;
            AutomationPeer peer = null;
            object element; 
            List<AutomationPeer> peers = new List<AutomationPeer>();
            start = start.CreatePointer(); 
 
            while (start.CompareTo(end) < 0)
            { 
                // Indicate that 'start' position is not moved yet.
                positionMoved = false;

                if (start.GetPointerContext(LogicalDirection.Forward) == TextPointerContext.ElementStart) 
                {
                    // Get adjacent element and try to retrive AutomationPeer for it. 
                    element = start.GetAdjacentElement(LogicalDirection.Forward); 
                    if (element is ContentElement)
                    { 
                        peer = ContentElementAutomationPeer.CreatePeerForElement((ContentElement)element);
                        // If AutomationPeer has been retrieved, add it to the collection.
                        // And skip entire element.
                        if (peer != null) 
                        {
                            if (ownerContentStart == null || IsImmediateAutomationChild(start, ownerContentStart)) 
                            { 
                                peers.Add(peer);
                            } 
                            start.MoveToNextContextPosition(LogicalDirection.Forward);
                            start.MoveToElementEdge(ElementEdge.AfterEnd);
                            positionMoved = true;
                        } 
                    }
                } 
                else if (start.GetPointerContext(LogicalDirection.Forward) == TextPointerContext.EmbeddedElement) 
                {
                    // Get adjacent element and try to retrive AutomationPeer for it. 
                    element = start.GetAdjacentElement(LogicalDirection.Forward);
                    if (element is UIElement)
                    {
                        if (ownerContentStart == null || IsImmediateAutomationChild(start, ownerContentStart)) 
                        {
                            peer = UIElementAutomationPeer.CreatePeerForElement((UIElement)element); 
                            // If AutomationPeer has been retrieved, add it to the collection. 
                            if (peer != null)
                            { 
                                peers.Add(peer);
                            }
                            else
                            { 
                                iterate((Visual)element, peers);
                            } 
                        } 
                    }
                    else if (element is ContentElement) 
                    {
                        peer = ContentElementAutomationPeer.CreatePeerForElement((ContentElement)element);
                        // If AutomationPeer has been retrieved, add it to the collection.
                        if (peer != null) 
                        {
                            if (ownerContentStart == null || IsImmediateAutomationChild(start, ownerContentStart)) 
                            { 
                                peers.Add(peer);
                            } 
                        }
                    }
                }
                // Move to the next content position, if position has not been moved already. 
                if (!positionMoved)
                { 
                    if (!start.MoveToNextContextPosition(LogicalDirection.Forward)) 
                    {
                        break; 
                    }
                }
            }
 
            return peers;
        } 
Ejemplo n.º 20
0
        // Returns true when one or both ends of the error lies at the inner edge of non-mergeable inline
        // such as Hyperlink.  In this case, a TextRange will normalize its ends outside
        // the scope of the inline, and the corrected text will not be covered by it.
        //
        // We work around the common case, when the error is contained within a single
        // Run.  In more complex cases we'll fail and fall back to using a TextRange.
        private static bool IsErrorAtNonMergeableInlineEdge(SpellingError spellingError, out ITextPointer textStart, out ITextPointer textEnd)
        {
            bool result = false;

            textStart = spellingError.Start.CreatePointer(LogicalDirection.Backward);
            while (textStart.CompareTo(spellingError.End) < 0 &&
                   textStart.GetPointerContext(LogicalDirection.Forward) != TextPointerContext.Text)
            {
                textStart.MoveToNextContextPosition(LogicalDirection.Forward);
            }
            textEnd = spellingError.End.CreatePointer();
            while (textEnd.CompareTo(spellingError.Start) > 0 &&
                   textEnd.GetPointerContext(LogicalDirection.Backward) != TextPointerContext.Text)
            {
                textEnd.MoveToNextContextPosition(LogicalDirection.Backward);
            }

            if (textStart.GetPointerContext(LogicalDirection.Forward) != TextPointerContext.Text ||
                textStart.CompareTo(spellingError.End) == 0)
            {
                return false;
            }
            Invariant.Assert(textEnd.GetPointerContext(LogicalDirection.Backward) == TextPointerContext.Text &&
                             textEnd.CompareTo(spellingError.Start) != 0);

            if (TextPointerBase.IsAtNonMergeableInlineStart(textStart) ||
                TextPointerBase.IsAtNonMergeableInlineEnd(textEnd))
            {
                if (typeof(Run).IsAssignableFrom(textStart.ParentType) &&
                    textStart.HasEqualScope(textEnd))
                {
                    result = true;
                }
            }

            return result;
        }
        // Token: 0x06002D1F RID: 11551 RVA: 0x000CBAC0 File Offset: 0x000C9CC0
        internal object BuildObjectTree()
        {
            FixedElement.ElementType type = this._type;
            IAddChild addChild;

            if (type != FixedElement.ElementType.Paragraph)
            {
                switch (type)
                {
                case FixedElement.ElementType.Table:
                    addChild = new Table();
                    goto IL_C7;

                case FixedElement.ElementType.TableRowGroup:
                    addChild = new TableRowGroup();
                    goto IL_C7;

                case FixedElement.ElementType.TableRow:
                    addChild = new TableRow();
                    goto IL_C7;

                case FixedElement.ElementType.TableCell:
                    addChild = new TableCell();
                    goto IL_C7;

                case FixedElement.ElementType.Hyperlink:
                {
                    Hyperlink hyperlink = new Hyperlink();
                    hyperlink.NavigateUri      = (base.GetValue(FixedElement.NavigateUriProperty) as Uri);
                    hyperlink.RequestNavigate += this.ClickHyperlink;
                    AutomationProperties.SetHelpText(hyperlink, (string)base.GetValue(FixedElement.HelpTextProperty));
                    AutomationProperties.SetName(hyperlink, (string)base.GetValue(FixedElement.NameProperty));
                    addChild = hyperlink;
                    goto IL_C7;
                }
                }
                addChild = null;
            }
            else
            {
                addChild = new Paragraph();
            }
IL_C7:
            ITextPointer textPointer = ((ITextPointer)this._start).CreatePointer();

            while (textPointer.CompareTo(this._end) < 0)
            {
                TextPointerContext pointerContext = textPointer.GetPointerContext(LogicalDirection.Forward);
                if (pointerContext == TextPointerContext.Text)
                {
                    addChild.AddText(textPointer.GetTextInRun(LogicalDirection.Forward));
                }
                else if (pointerContext == TextPointerContext.EmbeddedElement)
                {
                    addChild.AddChild(textPointer.GetAdjacentElement(LogicalDirection.Forward));
                }
                else if (pointerContext == TextPointerContext.ElementStart)
                {
                    object adjacentElement = textPointer.GetAdjacentElement(LogicalDirection.Forward);
                    if (adjacentElement != null)
                    {
                        addChild.AddChild(adjacentElement);
                        textPointer.MoveToNextContextPosition(LogicalDirection.Forward);
                        textPointer.MoveToElementEdge(ElementEdge.BeforeEnd);
                    }
                }
                textPointer.MoveToNextContextPosition(LogicalDirection.Forward);
            }
            return(addChild);
        }
Ejemplo n.º 22
0
        // Move this TP by distance, and respect virtualization of child TextContainer
        // Return true if distance is within boundary of the aggregated container, false otherwise
        private static bool xGapAwareScan(DocumentSequenceTextPointer thisTp, int distance)
        {
            //
            // Note: To calculate distance between thisTp.ChildPointer to
            // it container Start/End position would have been devastating
            // for those who implemented vitualization.
            // Ideally we would need a new API on ITextPointer
            //      ITextPointer.IsDistanceOutOfRange
            ChildDocumentBlock cdb   = thisTp.ChildBlock;
            bool         isNavigator = true;
            ITextPointer childTn     = thisTp.ChildPointer;

            if (childTn == null)
            {
                isNavigator = false;
                childTn     = thisTp.ChildPointer.CreatePointer();
            }
            LogicalDirection scanDir = (distance > 0 ? LogicalDirection.Forward : LogicalDirection.Backward);

            distance = Math.Abs(distance);
            while (distance > 0)
            {
                TextPointerContext tst = childTn.GetPointerContext(scanDir);
                switch (tst)
                {
                case TextPointerContext.ElementStart:
                    childTn.MoveToNextContextPosition(scanDir);
                    distance--;
                    break;

                case TextPointerContext.ElementEnd:
                    childTn.MoveToNextContextPosition(scanDir);
                    distance--;
                    break;

                case TextPointerContext.EmbeddedElement:
                    childTn.MoveToNextContextPosition(scanDir);
                    distance--;
                    break;

                case TextPointerContext.Text:
                    int runLength  = childTn.GetTextRunLength(scanDir);
                    int moveLength = runLength < distance ? runLength : distance;
                    distance -= moveLength;
                    //agurcan: Fix for 1098225
                    //We need to propagate direction info to MoveByOffset
                    if (scanDir == LogicalDirection.Backward)
                    {
                        moveLength *= -1;
                    }
                    childTn.MoveByOffset(moveLength);
                    break;

                case TextPointerContext.None:
                    if (!((cdb.IsHead && scanDir == LogicalDirection.Backward) ||
                          (cdb.IsTail && scanDir == LogicalDirection.Forward)
                          )
                        )
                    {
                        cdb     = (scanDir == LogicalDirection.Forward ? cdb.NextBlock : cdb.PreviousBlock);
                        childTn = (scanDir == LogicalDirection.Forward ?
                                   cdb.ChildContainer.Start.CreatePointer(childTn.LogicalDirection)
                                    : cdb.ChildContainer.End.CreatePointer(childTn.LogicalDirection)
                                   );
                    }
                    else
                    {
                        return(false);
                    }
                    break;

                default:
                    Debug.Assert(false, "invalid TextPointerContext");
                    break;
                }
            }

            // Re-position thisTp to the new location.
            thisTp.ChildBlock = cdb;
            if (isNavigator)
            {
                thisTp.ChildPointer = childTn;
            }
            else
            {
                thisTp.ChildPointer = childTn.CreatePointer();
            }
            return(true);
        }
        internal object BuildObjectTree()
        {
            IAddChild root;

            switch (_type)
            {
            case ElementType.Table:
                root = new Table();
                break;

            case ElementType.TableRowGroup:
                root = new TableRowGroup();
                break;

            case ElementType.TableRow:
                root = new TableRow();
                break;

            case ElementType.TableCell:
                root = new TableCell();
                break;

            case ElementType.Paragraph:
                root = new Paragraph();
                break;

            case ElementType.Hyperlink:
                Hyperlink link = new Hyperlink();
                link.NavigateUri      = GetValue(NavigateUriProperty) as Uri;
                link.RequestNavigate += new RequestNavigateEventHandler(ClickHyperlink);
                AutomationProperties.SetHelpText(link, (String)this.GetValue(HelpTextProperty));
                AutomationProperties.SetName(link, (String)this.GetValue(NameProperty));
                root = link;
                break;

            default:
                Debug.Assert(false);
                root = null;
                break;
            }

            ITextPointer pos = ((ITextPointer)_start).CreatePointer();

            while (pos.CompareTo((ITextPointer)_end) < 0)
            {
                TextPointerContext tpc = pos.GetPointerContext(LogicalDirection.Forward);
                if (tpc == TextPointerContext.Text)
                {
                    root.AddText(pos.GetTextInRun(LogicalDirection.Forward));
                }
                else if (tpc == TextPointerContext.EmbeddedElement)
                {
                    root.AddChild(pos.GetAdjacentElement(LogicalDirection.Forward));
                }
                else if (tpc == TextPointerContext.ElementStart)
                {
                    object obj = pos.GetAdjacentElement(LogicalDirection.Forward);
                    if (obj != null)
                    {
                        root.AddChild(obj);
                        pos.MoveToNextContextPosition(LogicalDirection.Forward);
                        pos.MoveToElementEdge(ElementEdge.BeforeEnd);
                    }
                }

                pos.MoveToNextContextPosition(LogicalDirection.Forward);
            }
            return(root);
        }
Ejemplo n.º 24
0
            //------------------------------------------------------
            //
            //  Private Methods
            //
            //------------------------------------------------------

            #region Private Methods

            private void AddMultipleCompositionLines(ITextPointer start, ITextPointer end)
            {
                // Initalize the start/end line pointer
                ITextPointer startLinePointer = start;
                ITextPointer endLinePointer   = startLinePointer;

                // Get all composition lines that includes the start/end pointer
                while (endLinePointer.CompareTo(end) < 0)
                {
                    TextSegment textSegment = _textView.GetLineRange(endLinePointer);

                    if (textSegment.IsNull)
                    {
                        // endLinePointer is not within the TextView's definition of a line.
                        // Skip ahead to text on the next iteration.
                        startLinePointer = endLinePointer;
                    }
                    else
                    {
                        Debug.Assert(start.CompareTo(startLinePointer) <= 0, "The start pointer is positioned after the composition start line pointer!");

                        if (startLinePointer.CompareTo(textSegment.Start) < 0)
                        {
                            // Update the start line pointer
                            startLinePointer = textSegment.Start;
                        }

                        if (endLinePointer.CompareTo(textSegment.End) < 0)
                        {
                            if (end.CompareTo(textSegment.End) < 0)
                            {
                                // Update the end line pointer
                                endLinePointer = end.CreatePointer();
                            }
                            else
                            {
                                // Update the end line pointer
                                endLinePointer = textSegment.End.CreatePointer(LogicalDirection.Backward);
                            }
                        }
                        else
                        {
                            Debug.Assert(endLinePointer.CompareTo(textSegment.End) == 0, "The end line pointer is positioned after the composition text range end pointer!");
                        }

                        // Get the rectangle for start/end position
                        Rect startRect = _textView.GetRectangleFromTextPosition(startLinePointer);
                        Rect endRect   = _textView.GetRectangleFromTextPosition(endLinePointer);

                        // Add the composition line to be rendered
                        _compositionLines.Add(new CompositionLine(startRect, endRect, _textServicesDisplayAttribute.GetLineColor(startLinePointer)));

                        startLinePointer = textSegment.End.CreatePointer(LogicalDirection.Forward);
                    }

                    // Move the start pointer to the next text line. startLinePointer must be a pointer to start
                    // text.
                    while ((startLinePointer.GetPointerContext(LogicalDirection.Forward) != TextPointerContext.None) &&
                           (startLinePointer.GetPointerContext(LogicalDirection.Forward) != TextPointerContext.Text))
                    {
                        startLinePointer.MoveToNextContextPosition(LogicalDirection.Forward);
                    }
                    endLinePointer = startLinePointer;
                }
            }
Ejemplo n.º 25
0
        // Part of plain text converter: called from GetTextInternal when processing ElementEnd for Paragraph elements. 
        // Outputs \n - for regular paragraphs and TableRow ends or \t for TableCell ends.
        private static void PlainConvertParagraphEnd(StringBuilder textBuffer, ITextPointer navigator)
        {
            // Check for a special case for a single paragraph within a TableCell 
            // which must be serialized as "\t" character.
            navigator.MoveToElementEdge(ElementEdge.BeforeStart); 
            bool theParagraphIsTheFirstInCollection = navigator.GetPointerContext(LogicalDirection.Backward) == TextPointerContext.ElementStart; 
            navigator.MoveToNextContextPosition(LogicalDirection.Forward);
            navigator.MoveToElementEdge(ElementEdge.AfterEnd); 
            TextPointerContext symbolType = navigator.GetPointerContext(LogicalDirection.Forward);

            if (theParagraphIsTheFirstInCollection && symbolType == TextPointerContext.ElementEnd &&
                typeof(TableCell).IsAssignableFrom(navigator.ParentType)) 
            {
                // This is an end of a table cell 
 
                navigator.MoveToNextContextPosition(LogicalDirection.Forward);
                symbolType = navigator.GetPointerContext(LogicalDirection.Forward); 
                if (symbolType == TextPointerContext.ElementStart)
                {
                    // Next table cell starts after this one. Use '\t' as a cell separator
                    textBuffer.Append('\t'); 
                }
                else 
                { 
                    // This was the last cell in a row. Use '\r\n' as a line separator
                    textBuffer.Append(Environment.NewLine); 
                }
            }
            else
            { 
                // Ordinary paragraph end
                textBuffer.Append(Environment.NewLine); 
            } 
        }
        // Token: 0x060039BC RID: 14780 RVA: 0x00106178 File Offset: 0x00104378
        private static int SetFindTextAndFindTextPositionMap(ITextPointer startPosition, ITextPointer endPosition, ITextPointer navigator, LogicalDirection direction, bool matchLast, char[] findText, int[] findTextPositionMap)
        {
            Invariant.Assert(startPosition.CompareTo(navigator) <= 0);
            Invariant.Assert(endPosition.CompareTo(navigator) >= 0);
            int num  = 0;
            int num2 = 0;

            if (matchLast && num2 == 0)
            {
                findTextPositionMap[findTextPositionMap.Length - 1] = 0;
            }
            while ((matchLast ? startPosition.CompareTo(navigator) : navigator.CompareTo(endPosition)) < 0)
            {
                switch (navigator.GetPointerContext(direction))
                {
                case TextPointerContext.None:
                case TextPointerContext.ElementStart:
                case TextPointerContext.ElementEnd:
                    if (TextFindEngine.IsAdjacentToFormatElement(navigator, direction))
                    {
                        num++;
                    }
                    else if (!matchLast)
                    {
                        findText[num2]            = '\n';
                        findTextPositionMap[num2] = num2 + num;
                        num2++;
                    }
                    else
                    {
                        num2++;
                        findText[findText.Length - num2]            = '\n';
                        findTextPositionMap[findText.Length - num2] = num2 + num;
                    }
                    navigator.MoveToNextContextPosition(direction);
                    break;

                case TextPointerContext.Text:
                {
                    int num3 = navigator.GetTextRunLength(direction);
                    num3 = Math.Min(num3, findText.Length - num2);
                    if (!matchLast)
                    {
                        num3 = Math.Min(num3, navigator.GetOffsetToPosition(endPosition));
                        navigator.GetTextInRun(direction, findText, num2, num3);
                        for (int i = num2; i < num2 + num3; i++)
                        {
                            findTextPositionMap[i] = i + num;
                        }
                    }
                    else
                    {
                        num3 = Math.Min(num3, startPosition.GetOffsetToPosition(navigator));
                        navigator.GetTextInRun(direction, findText, findText.Length - num2 - num3, num3);
                        int num4 = findText.Length - num2 - 1;
                        for (int j = num2; j < num2 + num3; j++)
                        {
                            findTextPositionMap[num4--] = j + num + 1;
                        }
                    }
                    navigator.MoveByOffset(matchLast ? (-num3) : num3);
                    num2 += num3;
                    break;
                }

                case TextPointerContext.EmbeddedElement:
                    if (!matchLast)
                    {
                        findText[num2]            = '';
                        findTextPositionMap[num2] = num2 + num;
                        num2++;
                    }
                    else
                    {
                        num2++;
                        findText[findText.Length - num2]            = '';
                        findTextPositionMap[findText.Length - num2] = num2 + num;
                    }
                    navigator.MoveToNextContextPosition(direction);
                    break;
                }
                if (num2 >= findText.Length)
                {
                    break;
                }
            }
            if (!matchLast)
            {
                if (num2 > 0)
                {
                    findTextPositionMap[num2] = findTextPositionMap[num2 - 1] + 1;
                }
                else
                {
                    findTextPositionMap[0] = 0;
                }
            }
            return(num2);
        }
Ejemplo n.º 27
0
        /// <summary> 
        /// Determine paragraph type at the current TextPointer and
        /// create it. Only ListItem elements are considered. Any other 
        /// content is skipped.
        /// </summary>
        /// <param name="textPointer">
        /// TextPointer at which paragraph is to be created 
        /// </param>
        /// <param name="fEmptyOk"> 
        /// True if empty paragraph is acceptable 
        /// </param>
        /// <returns> 
        /// BaseParagraph that was created
        /// </returns>
        protected override BaseParagraph GetParagraph(ITextPointer textPointer, bool fEmptyOk)
        { 
            Invariant.Assert(textPointer is TextPointer);
 
            BaseParagraph paragraph = null; 

            while (paragraph == null) 
            {
                TextPointerContext runType = textPointer.GetPointerContext(LogicalDirection.Forward);
                if (runType == TextPointerContext.ElementStart)
                { 
                    TextElement element = ((TextPointer)textPointer).GetAdjacentElementFromOuterPosition(LogicalDirection.Forward);
                    if (element is ListItem) 
                    { 
                        //
 



 

 
                        paragraph = new ListItemParagraph(element, StructuralCache); 
                        break;
                    } 
                    else if (element is List)
                    {
                        //
 

 
 

 

                        paragraph = new ListParagraph(element, StructuralCache);
                        break;
                    } 
                    // Skip all elements, which are not valid list item children
                    if (((TextPointer)textPointer).IsFrozen) 
                    { 
                        // Need to clone TextPointer before moving it.
                        textPointer = textPointer.CreatePointer(); 
                    }
                    textPointer.MoveToPosition(element.ElementEnd);
                }
                else if (runType == TextPointerContext.ElementEnd) 
                {
                    // End of list, if the same as Owner of associated element 
                    // Skip content otherwise 
                    if (Element == ((TextPointer)textPointer).Parent)
                    { 
                        break;
                    }
                    if (((TextPointer)textPointer).IsFrozen)
                    { 
                        // Need to clone TextPointer before moving it.
                        textPointer = textPointer.CreatePointer(); 
                    } 
                    textPointer.MoveToNextContextPosition(LogicalDirection.Forward);
                } 
                else
                {
                    // Skip content
                    if (((TextPointer)textPointer).IsFrozen) 
                    {
                        // Need to clone TextPointer before moving it. 
                        textPointer = textPointer.CreatePointer(); 
                    }
                    textPointer.MoveToNextContextPosition(LogicalDirection.Forward); 
                }
            }

            if (paragraph != null) 
            {
                StructuralCache.CurrentFormatContext.DependentMax = (TextPointer)textPointer; 
            } 

            return paragraph; 
        }
Ejemplo n.º 28
0
        /// <summary>
        /// Determine paragraph type at the current TextPointer and
        /// create it. Only ListItem elements are considered. Any other
        /// content is skipped.
        /// </summary>
        /// <param name="textPointer">
        /// TextPointer at which paragraph is to be created
        /// </param>
        /// <param name="fEmptyOk">
        /// True if empty paragraph is acceptable
        /// </param>
        /// <returns>
        /// BaseParagraph that was created
        /// </returns>
        protected override BaseParagraph GetParagraph(ITextPointer textPointer, bool fEmptyOk)
        {
            Invariant.Assert(textPointer is TextPointer);

            BaseParagraph paragraph = null;

            while (paragraph == null)
            {
                TextPointerContext runType = textPointer.GetPointerContext(LogicalDirection.Forward);
                if (runType == TextPointerContext.ElementStart)
                {
                    TextElement element = ((TextPointer)textPointer).GetAdjacentElementFromOuterPosition(LogicalDirection.Forward);
                    if (element is ListItem)
                    {
                        //      Need to handle visibility collapsed.
                        //Visibility visibility = Retriever.Visibility(treePtr.CPPtr.Element);
                        //if (visibility != Visibility.Collapsed)
                        //{
                        //    para = new
                        //}
                        //else skip the element
                        paragraph = new ListItemParagraph(element, StructuralCache);
                        break;
                    }
                    else if (element is List)
                    {
                        //      Need to handle visibility collapsed.
                        //Visibility visibility = Retriever.Visibility(treePtr.CPPtr.Element);
                        //if (visibility != Visibility.Collapsed)
                        //{
                        //    para = new
                        //}
                        //else skip the element
                        paragraph = new ListParagraph(element, StructuralCache);
                        break;
                    }
                    // Skip all elements, which are not valid list item children
                    if (((TextPointer)textPointer).IsFrozen)
                    {
                        // Need to clone TextPointer before moving it.
                        textPointer = textPointer.CreatePointer();
                    }
                    textPointer.MoveToPosition(element.ElementEnd);
                }
                else if (runType == TextPointerContext.ElementEnd)
                {
                    // End of list, if the same as Owner of associated element
                    // Skip content otherwise
                    if (Element == ((TextPointer)textPointer).Parent)
                    {
                        break;
                    }
                    if (((TextPointer)textPointer).IsFrozen)
                    {
                        // Need to clone TextPointer before moving it.
                        textPointer = textPointer.CreatePointer();
                    }
                    textPointer.MoveToNextContextPosition(LogicalDirection.Forward);
                }
                else
                {
                    // Skip content
                    if (((TextPointer)textPointer).IsFrozen)
                    {
                        // Need to clone TextPointer before moving it.
                        textPointer = textPointer.CreatePointer();
                    }
                    textPointer.MoveToNextContextPosition(LogicalDirection.Forward);
                }
            }

            if (paragraph != null)
            {
                StructuralCache.CurrentFormatContext.DependentMax = (TextPointer)textPointer;
            }

            return(paragraph);
        }
Ejemplo n.º 29
0
        //------------------------------------------------------
        //
        //  Private Methods
        //
        //------------------------------------------------------

        #region Private Methods

        // Worker for MoveToNextFormatNormalizedPosition/MoveToNextInsertionPosition.
        private static bool NormalizePosition(ITextPointer thisNavigator, LogicalDirection direction, bool respectCaretUnitBoundaries)
        {
            Invariant.Assert(!thisNavigator.IsFrozen, "Can't reposition a frozen pointer!");

            int symbolCount = 0;
            int increment;
            LogicalDirection oppositeDirection;
            TextPointerContext directEnterScope;
            TextPointerContext oppositeEnterScope;

            if (direction == LogicalDirection.Forward)
            {
                increment = +1;
                oppositeDirection = LogicalDirection.Backward;
                directEnterScope = TextPointerContext.ElementStart;
                oppositeEnterScope = TextPointerContext.ElementEnd;
            }
            else
            {
                increment = -1;
                oppositeDirection = LogicalDirection.Forward;
                directEnterScope = TextPointerContext.ElementEnd;
                oppositeEnterScope = TextPointerContext.ElementStart;
            }

            // When the pointer appears in between structural tags we need to start
            // from sliding into the deepest possible position without
            // leaving any structural units. We need to do that only
            // if we are not at insertion position already.
            if (!IsAtNormalizedPosition(thisNavigator, respectCaretUnitBoundaries))
            {
                // Go inside an innermost structured element (non-inline)
                while (
                    thisNavigator.GetPointerContext(direction) == directEnterScope &&
                    !typeof(Inline).IsAssignableFrom(thisNavigator.GetElementType(direction)) &&
                    !IsAtNormalizedPosition(thisNavigator, respectCaretUnitBoundaries))
                {
                    thisNavigator.MoveToNextContextPosition(direction);
                    symbolCount += increment;
                }
                while (
                    thisNavigator.GetPointerContext(oppositeDirection) == oppositeEnterScope &&
                    !typeof(Inline).IsAssignableFrom(thisNavigator.GetElementType(oppositeDirection)) &&
                    !IsAtNormalizedPosition(thisNavigator, respectCaretUnitBoundaries))
                {
                    thisNavigator.MoveToNextContextPosition(oppositeDirection);
                    symbolCount -= increment;
                }
            }

            // Get out of a Hyperlink, etc. inner edge.
            symbolCount = LeaveNonMergeableInlineBoundary(thisNavigator, direction, symbolCount);

            // Get out of a compound sequence if any.
            if (respectCaretUnitBoundaries)
            {
                while (!IsAtCaretUnitBoundary(thisNavigator))
                {
                    symbolCount += increment;
                    thisNavigator.MoveByOffset(increment);
                }
            }

            // Here is the core part of this method's logic - skipping all formatting tags in the given direction.
            // Skip character formatting tags if they are present in this direction.
            // Even if an insertion position can be in the middle of this formatting sequence,
            // we want to skip it all and reach the farthest possible insertion position in that direction.
            // Such approach guarantees that repeated calls of this normalization will give the same reauls.
            // In case if there is an inserrtion position in the middle (say, in empty Run),
            // the loop moving in opposite direction below will find it if needed.
            while (TextSchema.IsMergeableInline(thisNavigator.GetElementType(direction)))
            {
                thisNavigator.MoveToNextContextPosition(direction);
                symbolCount += increment;
            }

            if (!IsAtNormalizedPosition(thisNavigator, respectCaretUnitBoundaries))
            {
                // If still not at insertion point, try skipping inline tags in the opposite direction
                // now possibly stopping inside of empty element
                while (!IsAtNormalizedPosition(thisNavigator, respectCaretUnitBoundaries) &&
                    TextSchema.IsMergeableInline(thisNavigator.GetElementType(oppositeDirection)))
                {
                    thisNavigator.MoveToNextContextPosition(oppositeDirection);
                    symbolCount -= increment;
                }

                // If still not at insertion point, then try harder - skipping block tags
                // First in "preferred" direction
                while (!IsAtNormalizedPosition(thisNavigator, respectCaretUnitBoundaries) &&
                    thisNavigator.MoveToNextContextPosition(direction))
                {
                    symbolCount += increment;
                }

                // And finally in apposite direction
                while (!IsAtNormalizedPosition(thisNavigator, respectCaretUnitBoundaries) &&
                    thisNavigator.MoveToNextContextPosition(oppositeDirection))
                {
                    symbolCount -= increment;
                }

                if (!IsAtNormalizedPosition(thisNavigator, respectCaretUnitBoundaries))
                {
                    // When there is no insertion positions in the whole document
                    // we return the position back to its original place.
                    thisNavigator.MoveByOffset(-symbolCount);
                }
            }

            return symbolCount != 0;
        }
Ejemplo n.º 30
0
        /// <summary>
        /// Helper function to move given position to word boundary. TextPointerBase.MoveToNextWordBoundary 
        /// cannot be used directly, because it does not modify LogicalDirection. Because of that, IsAtWordBoundary
        /// for just moved positions may return FALSE.
        /// </summary>
        private static bool MoveToNextWordBoundary(ITextPointer position, LogicalDirection direction)
        {
            int moveCounter = 0;
            ITextPointer startPosition = position.CreatePointer();

            // Move the position in the given direction until word boundary is reached.
            while (position.MoveToNextInsertionPosition(direction))
            {
                moveCounter++;
                if (IsAtWordBoundary(position))
                {
                    break;
                }
                // Need to break the loop for weird case when there is no word break in text content.
                // When the word looks too long, consider end of textRun as a word break.
                if (moveCounter > 128) // 128 was taken as a random number. Probably not big enough though...
                {
                    position.MoveToPosition(startPosition);
                    position.MoveToNextContextPosition(direction);
                    break;
                }
            }

            // Note that we always use Forward direction for word orientation.
            if (moveCounter > 0)
            {
                position.SetLogicalDirection(LogicalDirection.Forward);
            }
            return moveCounter > 0;
        }
Ejemplo n.º 31
0
        internal static bool IsAtNormalizedPosition(ITextPointer position, LogicalDirection direction, bool respectCaretUnitBoundaries)
        {
            if (!IsAtNormalizedPosition(position, respectCaretUnitBoundaries))
            {
                return false;
            }

            // 

            if (position.GetPointerContext(LogicalDirection.Backward) == TextPointerContext.ElementStart &&
                position.GetPointerContext(LogicalDirection.Forward) == TextPointerContext.ElementEnd)
            {
                return true;
            }

            // Check if there is no any formatting tags in the given direction
            if (TextSchema.IsFormattingType(position.GetElementType(direction)))
            {
                position = position.CreatePointer();
                while (TextSchema.IsFormattingType(position.GetElementType(direction)))
                {
                    position.MoveToNextContextPosition(direction);
                }

                if (IsAtNormalizedPosition(position, respectCaretUnitBoundaries))
                {
                    // So there is a possibility to move over formatting tags only
                    // and reach some insertion position. This means
                    // that our position was not normalized in the given direction.
                    return false;
                }
            }

            return true;
        }
Ejemplo n.º 32
0
        /// <summary>
        /// Moves the position to the closes unit boundary.
        /// </summary>
        private bool MoveToUnitBoundary(ITextPointer position, bool isStart, LogicalDirection direction, TextUnit unit)
        {
            bool moved = false;
            ITextView textView;
            switch (unit)
            {
                case TextUnit.Character:
                    if (!TextPointerBase.IsAtInsertionPosition(position))
                    {
                        if (TextPointerBase.MoveToNextInsertionPosition(position, direction))
                        {
                            moved = true;
                        }
                    }
                    break;

                case TextUnit.Word:
                    if (!IsAtWordBoundary(position))
                    {
                        if (MoveToNextWordBoundary(position, direction))
                        {
                            moved = true;
                        }
                    }
                    break;

                case TextUnit.Format:
                    // Formatting changes can be introduced by elements. Hence it is fair to 
                    // assume that formatting boundaries are defined by non-text context.
                    while (position.GetPointerContext(direction) == TextPointerContext.Text)
                    {
                        if (position.MoveToNextContextPosition(direction))
                        {
                            moved = true;
                        }
                    }
                    // Make sure we end with text on the right, so that later ExpandToEnclosingUnit calls
                    // do the right thing.
                    if (moved && direction == LogicalDirection.Forward)
                    {
                        while (true)
                        {
                            TextPointerContext context = position.GetPointerContext(LogicalDirection.Forward);

                            if (context != TextPointerContext.ElementStart && context != TextPointerContext.ElementEnd)
                                break;

                            position.MoveToNextContextPosition(LogicalDirection.Forward);
                        }
                    }
                    break;

                case TextUnit.Line:
                    // Positions are snapped to closest line boundaries. But since line information
                    // is based on the layout, positions are not changed, if:
                    // a) they are not currently in the view, or
                    // b) containing line cannot be found.
                    textView = _textAdaptor.GetUpdatedTextView();
                    if (textView != null && textView.IsValid && textView.Contains(position))
                    {
                        TextSegment lineRange = textView.GetLineRange(position);
                        if (!lineRange.IsNull)
                        {
                            double newSuggestedX;
                            int linesMoved = 0;

                            if (direction == LogicalDirection.Forward)
                            {
                                ITextPointer nextLineStart = null;

                                if (isStart)
                                {
                                    nextLineStart = textView.GetPositionAtNextLine(lineRange.End, Double.NaN, 1, out newSuggestedX, out linesMoved);
                                }

                                if (linesMoved != 0)
                                {
                                    lineRange = textView.GetLineRange(nextLineStart);
                                    nextLineStart = lineRange.Start;
                                }
                                else
                                {
                                    nextLineStart = lineRange.End;
                                }
                                nextLineStart = GetInsertionPosition(nextLineStart, LogicalDirection.Forward);

                                if (position.CompareTo(nextLineStart) != 0)
                                {
                                    position.MoveToPosition(nextLineStart);
                                    position.SetLogicalDirection(isStart ? LogicalDirection.Forward : LogicalDirection.Backward);
                                    moved = true;
                                }
                            }
                            else
                            {
                                ITextPointer previousLineEnd = null;

                                if (!isStart)
                                {
                                    previousLineEnd = textView.GetPositionAtNextLine(lineRange.Start, Double.NaN, -1, out newSuggestedX, out linesMoved);
                                }

                                if (linesMoved != 0)
                                {
                                    lineRange = textView.GetLineRange(previousLineEnd);
                                    previousLineEnd = lineRange.End;
                                }
                                else
                                {
                                    previousLineEnd = lineRange.Start;
                                }
                                previousLineEnd = GetInsertionPosition(previousLineEnd, LogicalDirection.Backward);

                                if (position.CompareTo(previousLineEnd) != 0)
                                {
                                    position.MoveToPosition(previousLineEnd);
                                    position.SetLogicalDirection(isStart ? LogicalDirection.Forward : LogicalDirection.Backward);
                                    moved = true;
                                }
                            }
                        }
                    }
                    break;

                case TextUnit.Paragraph:
                    // Utilize TextRange logic to determine paragraph boundaries.
                    ITextRange textRange = new TextRange(position, position);
                    TextRangeBase.SelectParagraph(textRange, position);

                    if (direction == LogicalDirection.Forward)
                    {
                        ITextPointer nextParagraphStart = textRange.End;

                        if (isStart)
                        {
                            nextParagraphStart = nextParagraphStart.CreatePointer();
                            if (nextParagraphStart.MoveToNextInsertionPosition(LogicalDirection.Forward))
                            {
                                TextRangeBase.SelectParagraph(textRange, nextParagraphStart);
                                nextParagraphStart = textRange.Start;
                            }
                        }

                        if (position.CompareTo(nextParagraphStart) != 0)
                        {
                            position.MoveToPosition(nextParagraphStart);
                            position.SetLogicalDirection(isStart ? LogicalDirection.Forward : LogicalDirection.Backward);
                            moved = true;
                        }
                    }
                    else
                    {
                        ITextPointer previousParagraphEnd = textRange.Start;

                        if (!isStart)
                        {
                            previousParagraphEnd = previousParagraphEnd.CreatePointer();
                            if (previousParagraphEnd.MoveToNextInsertionPosition(LogicalDirection.Backward))
                            {
                                TextRangeBase.SelectParagraph(textRange, previousParagraphEnd);
                                previousParagraphEnd = textRange.End;
                            }
                        }

                        if (position.CompareTo(previousParagraphEnd) != 0)
                        {
                            position.MoveToPosition(previousParagraphEnd);
                            position.SetLogicalDirection(isStart ? LogicalDirection.Forward : LogicalDirection.Backward);
                            moved = true;
                        }
                    }
                    break;

                case TextUnit.Page:
                    // Positions are snapped to nearest page boundaries. But since page information
                    // is based on the layout, positions are not changed, if they are not currently in the view.
                    // We need to consider 2 types of scenarios: single page and multi-page.
                    // In case of multi-page scenario, first need to find a page associated with the position.
                    // If page is found, move the start position to the beginning of the first range of that page
                    // and move the end position to the end of the last range of that page.
                    textView = _textAdaptor.GetUpdatedTextView();
                    if (textView != null && textView.IsValid && textView.Contains(position))
                    {
                        ITextView pageTextView = textView;
                        if (textView is MultiPageTextView)
                        {
                            // This is "multi page" case. Find page associated with the start position.
                            pageTextView = ((MultiPageTextView)textView).GetPageTextViewFromPosition(position);
                        }
                        ReadOnlyCollection<TextSegment> textSegments = pageTextView.TextSegments;

                        if (textSegments != null && textSegments.Count > 0)
                        {
                            //When comparing, we need to take into account if the pointer is not right at 
                            //the end of the page (or beginning) because of normalization
                            
                            if (direction == LogicalDirection.Forward)
                            {
                                while (position.CompareTo(textSegments[textSegments.Count - 1].End) != 0)
                                {
                                    if (position.GetPointerContext(LogicalDirection.Forward) != TextPointerContext.ElementEnd)
                                    {
                                        position.MoveToPosition(textSegments[textSegments.Count - 1].End);
                                        moved = true;
                                        break;
                                    }
                                    Invariant.Assert(position.MoveToNextContextPosition(LogicalDirection.Forward));
                                }
                                MoveToInsertionPosition(position, LogicalDirection.Forward);
                            }
                            else
                            {
                                while (position.CompareTo(textSegments[0].Start) != 0)
                                {
                                    if (position.GetPointerContext(LogicalDirection.Backward) != TextPointerContext.ElementStart)
                                    {
                                        position.MoveToPosition(textSegments[0].Start);
                                        moved = true;
                                        break;
                                    }
                                    Invariant.Assert(position.MoveToNextContextPosition(LogicalDirection.Backward));
                                }
                                MoveToInsertionPosition(position, LogicalDirection.Backward);
                                
                            }
                        }
                    }
                    break;

                case TextUnit.Document:
                    if (direction == LogicalDirection.Forward)
                    {
                        if (position.CompareTo(GetInsertionPosition(position.TextContainer.End, LogicalDirection.Backward)) != 0)
                        {
                            position.MoveToPosition(position.TextContainer.End);
                            moved = true;
                        }
                    }
                    else
                    {
                        if (position.CompareTo(GetInsertionPosition(position.TextContainer.Start, LogicalDirection.Forward)) != 0)
                        {
                            position.MoveToPosition(position.TextContainer.Start);
                            moved = true;
                        }
                    }
                    break;

                default:
                    // Unknown unit
                    break;
            }
            return moved;
        }
Ejemplo n.º 33
0
        // GetText handler for object runs.
        private static bool WalkObjectRun(ITextPointer navigator, ITextPointer limit, char[] text, int cchReq, ref int charsCopied, UnsafeNativeMethods.TS_RUNINFO[] runInfo, int cRunInfoReq, ref int cRunInfoRcv)
        {
            bool hitLimit;

            Invariant.Assert(navigator.GetPointerContext(LogicalDirection.Forward) == TextPointerContext.EmbeddedElement);
            Invariant.Assert(limit == null || navigator.CompareTo(limit) <= 0);

            if (limit != null && navigator.CompareTo(limit) == 0)
            {
                return true;
            }

            hitLimit = false;

            navigator.MoveToNextContextPosition(LogicalDirection.Forward);

            if (cchReq >= 1)
            {
                text[charsCopied] = UnsafeNativeMethods.TS_CHAR_EMBEDDED;
                charsCopied++;
            }

            if (cRunInfoReq > 0)
            {
                // Be sure to merge this text run with the previous run, if they are both text runs.
                // (A good robustness fix would be to make cicero handle this, if we ever get the chance.)
                if (cRunInfoRcv > 0 && runInfo[cRunInfoRcv - 1].type == UnsafeNativeMethods.TsRunType.TS_RT_PLAIN)
                {
                    runInfo[cRunInfoRcv - 1].count++;
                }
                else
                {
                    runInfo[cRunInfoRcv].count = 1;
                    runInfo[cRunInfoRcv].type = UnsafeNativeMethods.TsRunType.TS_RT_PLAIN;
                    cRunInfoRcv++;
                }
            }

            return hitLimit;
        }
Ejemplo n.º 34
0
        //-------------------------------------------------------------------
        //
        //  Internal Methods
        //
        //-------------------------------------------------------------------

        #region Internal Methods

        /// <summary>
        /// Retrieves a collection of AutomationPeers that fall within the range.
        /// Children that overlap with the range but are not entirely enclosed by
        /// it will also be included in the collection.
        /// </summary>
        internal static List <AutomationPeer> GetAutomationPeersFromRange(ITextPointer start, ITextPointer end, ITextPointer ownerContentStart)
        {
            bool                  positionMoved;
            AutomationPeer        peer = null;
            object                element;
            List <AutomationPeer> peers = new List <AutomationPeer>();

            start = start.CreatePointer();

            while (start.CompareTo(end) < 0)
            {
                // Indicate that 'start' position is not moved yet.
                positionMoved = false;

                if (start.GetPointerContext(LogicalDirection.Forward) == TextPointerContext.ElementStart)
                {
                    // Get adjacent element and try to retrive AutomationPeer for it.
                    element = start.GetAdjacentElement(LogicalDirection.Forward);
                    if (element is ContentElement)
                    {
                        peer = ContentElementAutomationPeer.CreatePeerForElement((ContentElement)element);
                        // If AutomationPeer has been retrieved, add it to the collection.
                        // And skip entire element.
                        if (peer != null)
                        {
                            if (ownerContentStart == null || IsImmediateAutomationChild(start, ownerContentStart))
                            {
                                peers.Add(peer);
                            }
                            start.MoveToNextContextPosition(LogicalDirection.Forward);
                            start.MoveToElementEdge(ElementEdge.AfterEnd);
                            positionMoved = true;
                        }
                    }
                }
                else if (start.GetPointerContext(LogicalDirection.Forward) == TextPointerContext.EmbeddedElement)
                {
                    // Get adjacent element and try to retrive AutomationPeer for it.
                    element = start.GetAdjacentElement(LogicalDirection.Forward);
                    if (element is UIElement)
                    {
                        if (ownerContentStart == null || IsImmediateAutomationChild(start, ownerContentStart))
                        {
                            peer = UIElementAutomationPeer.CreatePeerForElement((UIElement)element);
                            // If AutomationPeer has been retrieved, add it to the collection.
                            if (peer != null)
                            {
                                peers.Add(peer);
                            }
                            else
                            {
                                iterate((Visual)element, peers);
                            }
                        }
                    }
                    else if (element is ContentElement)
                    {
                        peer = ContentElementAutomationPeer.CreatePeerForElement((ContentElement)element);
                        // If AutomationPeer has been retrieved, add it to the collection.
                        if (peer != null)
                        {
                            if (ownerContentStart == null || IsImmediateAutomationChild(start, ownerContentStart))
                            {
                                peers.Add(peer);
                            }
                        }
                    }
                }
                // Move to the next content position, if position has not been moved already.
                if (!positionMoved)
                {
                    if (!start.MoveToNextContextPosition(LogicalDirection.Forward))
                    {
                        break;
                    }
                }
            }

            return(peers);
        }
Ejemplo n.º 35
0
        // Normalizes a range:
        //
        // -The start position is advanced over all element edges not visible
        //  to the IMEs.
        // -Start and end positions are moved to insertion positions.
        private void GetNormalizedRange(int startCharOffset, int endCharOffset, out ITextPointer start, out ITextPointer end)
        {
            start = CreatePointerAtCharOffset(startCharOffset, LogicalDirection.Forward);
            end = (startCharOffset == endCharOffset) ? start : CreatePointerAtCharOffset(endCharOffset, LogicalDirection.Backward);

            // Skip over hidden element edges.
            while (start.CompareTo(end) < 0)
            {
                TextPointerContext forwardContext = start.GetPointerContext(LogicalDirection.Forward);

                if (forwardContext == TextPointerContext.ElementStart)
                {
                    TextElement element = start.GetAdjacentElement(LogicalDirection.Forward) as TextElement;

                    if (element == null)
                        break;
                    if (element.IMELeftEdgeCharCount != 0)
                        break;
                }
                else if (forwardContext != TextPointerContext.ElementEnd)
                {
                    break;
                }

                start.MoveToNextContextPosition(LogicalDirection.Forward);
            }

            // Move to insertion positions.
            // If the positions are already adjacent to text, we must respect
            // the IME's decision in regards to exact placement.
            // MoveToInsertionPosition will skip over surrogates and combining
            // marks, but the IME needs fine-grained control over these positions.

            if (start.CompareTo(end) == 0)
            {
                start = start.GetFormatNormalizedPosition(LogicalDirection.Backward);
                end = start;
            }
            else
            {
                start = start.GetFormatNormalizedPosition(LogicalDirection.Backward);
                end = end.GetFormatNormalizedPosition(LogicalDirection.Backward);
            }
        }
Ejemplo n.º 36
0
        /// <summary>
        /// Retrieves the range of a child object.
        /// </summary>
        /// <param name="childElementProvider">The child element.  A provider should check that the
        /// passed element is a child of the text container, and should throw an
        /// InvalidOperationException if it is not.</param>
        /// <returns>A range that spans the child element.</returns>
        ITextRangeProvider ITextProvider.RangeFromChild(IRawElementProviderSimple childElementProvider)
        {
            if (childElementProvider == null)
            {
                throw new ArgumentNullException("childElementProvider");
            }

            // Retrieve DependencyObject from AutomationElement
            DependencyObject childElement;

            if (_textPeer is TextAutomationPeer)
            {
                childElement = ((TextAutomationPeer)_textPeer).ElementFromProvider(childElementProvider);
            }
            else
            {
                childElement = ((ContentTextAutomationPeer)_textPeer).ElementFromProvider(childElementProvider);
            }

            TextRangeAdaptor range = null;

            if (childElement != null)
            {
                ITextPointer rangeStart = null;
                ITextPointer rangeEnd   = null;

                // Retrieve start and end positions for given element.
                // If element is TextElement, retrieve its Element Start and End positions.
                // If element is UIElement hosted by UIContainer (Inlien of Block),
                // retrieve content Start and End positions of the container.
                // Otherwise scan ITextContainer to find a range for given element.
                if (childElement is TextElement)
                {
                    rangeStart = ((TextElement)childElement).ElementStart;
                    rangeEnd   = ((TextElement)childElement).ElementEnd;
                }
                else
                {
                    DependencyObject parent = LogicalTreeHelper.GetParent(childElement);
                    if (parent is InlineUIContainer || parent is BlockUIContainer)
                    {
                        rangeStart = ((TextElement)parent).ContentStart;
                        rangeEnd   = ((TextElement)parent).ContentEnd;
                    }
                    else
                    {
                        ITextPointer position = _textContainer.Start.CreatePointer();
                        while (position.CompareTo(_textContainer.End) < 0)
                        {
                            TextPointerContext context = position.GetPointerContext(LogicalDirection.Forward);
                            if (context == TextPointerContext.ElementStart)
                            {
                                if (childElement == position.GetAdjacentElement(LogicalDirection.Forward))
                                {
                                    rangeStart = position.CreatePointer(LogicalDirection.Forward);
                                    position.MoveToElementEdge(ElementEdge.AfterEnd);
                                    rangeEnd = position.CreatePointer(LogicalDirection.Backward);
                                    break;
                                }
                            }
                            else if (context == TextPointerContext.EmbeddedElement)
                            {
                                if (childElement == position.GetAdjacentElement(LogicalDirection.Forward))
                                {
                                    rangeStart = position.CreatePointer(LogicalDirection.Forward);
                                    position.MoveToNextContextPosition(LogicalDirection.Forward);
                                    rangeEnd = position.CreatePointer(LogicalDirection.Backward);
                                    break;
                                }
                            }
                            position.MoveToNextContextPosition(LogicalDirection.Forward);
                        }
                    }
                }
                // Create range
                if (rangeStart != null && rangeEnd != null)
                {
                    range = new TextRangeAdaptor(this, rangeStart, rangeEnd, _textPeer);
                }
            }
            if (range == null)
            {
                throw new InvalidOperationException(SR.Get(SRID.TextProvider_InvalidChildElement));
            }
            return(range);
        }
Ejemplo n.º 37
0
        /// <summary>
        /// Set the find text content from reading the text on the current text position.
        /// </summary>
        /// <returns>
        /// Returns the number of characters actually loaded into the findText array.
        /// </returns>
        private static int SetFindTextAndFindTextPositionMap(
            ITextPointer startPosition,
            ITextPointer endPosition,
            ITextPointer navigator,
            LogicalDirection direction,
            bool matchLast,
            char[] findText,
            int[] findTextPositionMap)
        {
            Invariant.Assert(startPosition.CompareTo(navigator) <= 0);
            Invariant.Assert(endPosition.CompareTo(navigator) >= 0);

            int runCount;
            int inlineCount    = 0;
            int findTextLength = 0;

            // Set the first offset which is zero on TextBufferSize + 1 location of
            // the text position map in case of the backward searching
            if (matchLast && findTextLength == 0)
            {
                findTextPositionMap[findTextPositionMap.Length - 1] = 0;
            }

            while ((matchLast ? startPosition.CompareTo(navigator) : navigator.CompareTo(endPosition)) < 0)
            {
                switch (navigator.GetPointerContext(direction))
                {
                case TextPointerContext.Text:
                    runCount = navigator.GetTextRunLength(direction);
                    runCount = Math.Min(runCount, findText.Length - findTextLength);

                    if (!matchLast)
                    {
                        runCount = Math.Min(runCount, navigator.GetOffsetToPosition(endPosition));
                        navigator.GetTextInRun(direction, findText, findTextLength, runCount);

                        for (int i = findTextLength; i < findTextLength + runCount; i++)
                        {
                            findTextPositionMap[i] = i + inlineCount;
                        }
                    }
                    else
                    {
                        runCount = Math.Min(runCount, startPosition.GetOffsetToPosition(navigator));
                        navigator.GetTextInRun(
                            direction,
                            findText,
                            findText.Length - findTextLength - runCount,
                            runCount);

                        // Set the text offest for the amount of runCount from the last index
                        // of text position map
                        int mapIndex = findText.Length - findTextLength - 1;
                        for (int i = findTextLength; i < findTextLength + runCount; i++)
                        {
                            findTextPositionMap[mapIndex--] = i + inlineCount + 1;
                        }
                    }

                    // Move the navigator position for the amount of runCount
                    navigator.MoveByOffset(matchLast ? -runCount : runCount);
                    findTextLength += runCount;
                    break;

                case TextPointerContext.None:
                case TextPointerContext.ElementStart:
                case TextPointerContext.ElementEnd:
                    if (IsAdjacentToFormatElement(navigator, direction))
                    {
                        // Filter out formatting tags since find text content is plain.
                        inlineCount++;
                    }
                    else
                    {
                        if (!matchLast)
                        {
                            // Stick in a line break to account for the block element.
                            findText[findTextLength]            = '\n';
                            findTextPositionMap[findTextLength] = findTextLength + inlineCount;
                            findTextLength++;
                        }
                        else
                        {
                            // Increse the find text length first since adding text and map reversely
                            findTextLength++;

                            // Stick in a line break to account for the block element and
                            // add text offset on the last index of text position map
                            findText[findText.Length - findTextLength]            = '\n';
                            findTextPositionMap[findText.Length - findTextLength] = findTextLength + inlineCount;
                        }
                    }

                    navigator.MoveToNextContextPosition(direction);
                    break;

                case TextPointerContext.EmbeddedElement:
                    if (!matchLast)
                    {
                        findText[findTextLength]            = '\xf8ff'; // Unicode private use.
                        findTextPositionMap[findTextLength] = findTextLength + inlineCount;
                        findTextLength++;
                    }
                    else
                    {
                        // Increse the find text length first since adding text and map reversely
                        findTextLength++;

                        // Set the private unicode value and text offset
                        findText[findText.Length - findTextLength]            = '\xf8ff';
                        findTextPositionMap[findText.Length - findTextLength] = findTextLength + inlineCount;
                    }

                    navigator.MoveToNextContextPosition(direction);
                    break;
                }

                if (findTextLength >= findText.Length)
                {
                    break;
                }
            }

            // Complete the adding the find text position to the position map for only the forward finding.
            // The backward finding(matchLast) is already added initially as the zero offset at the end of
            // text position map.
            if (!matchLast)
            {
                if (findTextLength > 0)
                {
                    findTextPositionMap[findTextLength] = findTextPositionMap[findTextLength - 1] + 1;
                }
                else
                {
                    findTextPositionMap[0] = 0;
                }
            }

            return(findTextLength);
        }
Ejemplo n.º 38
0
        // Moves the navigator in the given direction over all characters,
        // embedded objects and formatting tags. 
        //

        private static void SkipParagraphContent(ITextPointer navigator, LogicalDirection direction)
        { 
            TextPointerContext nextContext = navigator.GetPointerContext(direction);
 
            while (true) 
            {
                if (nextContext == TextPointerContext.None // 
                    || //
                    // Entering non-inline content
                    (nextContext == TextPointerContext.ElementStart && direction == LogicalDirection.Forward || //
                    nextContext == TextPointerContext.ElementEnd && direction == LogicalDirection.Backward) && // 
                    !typeof(Inline).IsAssignableFrom(navigator.GetElementType(direction)) //
                    || 
                    // Exiting non-inline content 
                    (nextContext == TextPointerContext.ElementEnd && direction == LogicalDirection.Forward || //
                    nextContext == TextPointerContext.ElementStart && direction == LogicalDirection.Backward) && // 
                    !typeof(Inline).IsAssignableFrom(navigator.ParentType))
                {
                    // End of paragraph content reached. Stop here.
                    break; 
                }
 
                //Need to bail out if MoveToNextContentPosition fails 
                if (!navigator.MoveToNextContextPosition(direction))
                { 
                    break;
                }
                nextContext = navigator.GetPointerContext(direction);
            } 
        }
Ejemplo n.º 39
0
        /// <summary>
        /// Re-positions the given position by an integral number of text units, but it does
        /// not guarantee that position is snapped to TextUnit boundary.
        /// This method assumes that input position is already snapped to appropriate TextUnit boundary.
        /// </summary>
        /// <param name="position">The position to move</param>
        /// <param name="unit">Text units to step by</param>
        /// <param name="count">Number of units to step over. Also specifies the direction of moving: 
        /// forward if positive, backward otherwise</param>
        /// <returns>The actual number of units the position was moved over</returns>
        private int MovePositionByUnits(ITextPointer position, TextUnit unit, int count)
        {
            ITextView textView;
            int moved = 0;
            int absCount = (count == int.MinValue) ? int.MaxValue : Math.Abs(count);
            LogicalDirection direction = (count > 0) ? LogicalDirection.Forward : LogicalDirection.Backward;

            // This method assumes that position is already snapped to appropriate TextUnit.

            switch (unit)
            {
                case TextUnit.Character:
                    while (moved < absCount)
                    {
                        if (!TextPointerBase.MoveToNextInsertionPosition(position, direction))
                        {
                            break;
                        }
                        moved++;
                    }
                    break;

                case TextUnit.Word:
                    while (moved < absCount)
                    {
                        if (!MoveToNextWordBoundary(position, direction))
                        {
                            break;
                        }
                        moved++;
                    }
                    break;

                case TextUnit.Format:
                    // Formatting changes can be introduced by elements. Hence it is fair to 
                    // assume that formatting boundaries are defined by non-text context.
                    while (moved < absCount)
                    {
                        ITextPointer positionOrig = position.CreatePointer();

                        // First skip all text in given direction.
                        while (position.GetPointerContext(direction) == TextPointerContext.Text)
                        {
                            if (!position.MoveToNextContextPosition(direction))
                            {
                                break;
                            }
                        }
                        // Move to next context
                        if (!position.MoveToNextContextPosition(direction))
                        {
                            break;
                        }
                        // Skip all formatting elements and position the pointer next to text.
                        while (position.GetPointerContext(direction) != TextPointerContext.Text)
                        {
                            if (!position.MoveToNextContextPosition(direction))
                            {
                                break;
                            }
                        }
                        // If moving backwards, position the pointer at the beginning of formatting range.
                        if (direction == LogicalDirection.Backward)
                        {
                            while (position.GetPointerContext(LogicalDirection.Backward) == TextPointerContext.Text)
                            {
                                if (!position.MoveToNextContextPosition(LogicalDirection.Backward))
                                {
                                    break;
                                }
                            }
                        }
                        if (position.GetPointerContext(direction) != TextPointerContext.None)
                        {
                            moved++;
                        }
                        else
                        {
                            position.MoveToPosition(positionOrig);
                            break;
                        }
                    }

                    // Adjust logical direction to point to the following text (forward or backward movement).
                    // If we don't do this, we'll normalize in the wrong direction and get stuck in a loop
                    // if caller tries to advance again.
                    position.SetLogicalDirection(LogicalDirection.Forward);

                    break;

                case TextUnit.Line:
                    // Position is snapped to nearest line boundary. But since line information
                    // is based on the layout, position is not changed, if:
                    // a) it is not currently in the view, or
                    // b) containing line cannot be found.
                    textView = _textAdaptor.GetUpdatedTextView();
                    if (textView != null && textView.IsValid && textView.Contains(position))
                    {
                        // ITextPointer.MoveToLineBoundary can't handle Table row end positions.
                        // Mimic TextEditor's caret navigation code and move into the preceding
                        // TableCell.
                        if (TextPointerBase.IsAtRowEnd(position))
                        {
                            position.MoveToNextInsertionPosition(LogicalDirection.Backward);
                        }

                        moved = position.MoveToLineBoundary(count);
                        
                        MoveToInsertionPosition(position, LogicalDirection.Forward);

                        if (moved < 0)
                        {
                            moved = -moved; // Will be reversed below.
                        }
                    }
                    break; 

                case TextUnit.Paragraph:
                    // Utilize TextRange logic to determine paragraph boundaries.
                    ITextRange paragraphRange = new TextRange(position, position);
                    paragraphRange.SelectParagraph(position);
                    while (moved < absCount)
                    {
                        position.MoveToPosition(direction == LogicalDirection.Forward ? paragraphRange.End : paragraphRange.Start);
                        if (!position.MoveToNextInsertionPosition(direction))
                        {
                            break;
                        }
                        moved++;
                        paragraphRange.SelectParagraph(position);
                        position.MoveToPosition(paragraphRange.Start); // Position it always at the beginning of the paragraph.
                    }
                    break;

                case TextUnit.Page:
                    // But since page information is based on the layout, position is not changed, if:
                    // a) it is not currently in the view, or
                    // b) containing page cannot be found.
                    // Page movement is possible only in multi-page scenario.
                    textView = _textAdaptor.GetUpdatedTextView();
                    if (textView != null && textView.IsValid && textView.Contains(position))
                    {
                        if (textView is MultiPageTextView)
                        {
                            // Get embedded page ITextView for given position.
                            ITextView pageTextView = ((MultiPageTextView)textView).GetPageTextViewFromPosition(position);
                            ReadOnlyCollection<TextSegment> textSegments = pageTextView.TextSegments;
                            while (moved < absCount)
                            {
                                if (textSegments == null || textSegments.Count == 0)
                                {
                                    break;
                                }
                                // Move the position to appropriate edge.
                                if (direction == LogicalDirection.Backward)
                                {
                                    position.MoveToPosition(textSegments[0].Start);
                                    MoveToInsertionPosition(position, LogicalDirection.Backward);
                                }
                                else
                                {
                                    position.MoveToPosition(textSegments[textSegments.Count - 1].End);
                                    MoveToInsertionPosition(position, LogicalDirection.Forward);
                                }
                                // Try to move the position to the next page.
                                ITextPointer positionTemp = position.CreatePointer();
                                if (!positionTemp.MoveToNextInsertionPosition(direction))
                                {
                                    break;
                                }
                                else
                                {
                                    // MoveToNextInsertionPosition may return 'true' and move the position
                                    // in oposite direction.
                                    if (direction == LogicalDirection.Forward)
                                    {
                                        if (positionTemp.CompareTo(position) <= 0)
                                        {
                                            break;
                                        }
                                    }
                                    else
                                    {
                                        if (positionTemp.CompareTo(position) >= 0)
                                        {
                                            break;
                                        }
                                    }
                                }
                                // Get embedded page ITextView for given position.
                                if (!textView.Contains(positionTemp))
                                {
                                    break;
                                }
                                pageTextView = ((MultiPageTextView)textView).GetPageTextViewFromPosition(positionTemp);
                                textSegments = pageTextView.TextSegments;
                                moved++;
                            }
                        }
                    }
                    break;

                case TextUnit.Document:
                    // This method assumes that position is already snapped to appropriate TextUnit.
                    break;
            }

            return (direction == LogicalDirection.Forward) ? moved : -moved;
        }
Ejemplo n.º 40
0
        /// <summary> 
        /// Set the find text content from reading the text on the current text position. 
        /// </summary>
        /// <returns> 
        /// Returns the number of characters actually loaded into the findText array.
        /// </returns>
        private static int SetFindTextAndFindTextPositionMap(
            ITextPointer startPosition, 
            ITextPointer endPosition,
            ITextPointer navigator, 
            LogicalDirection direction, 
            bool matchLast,
            char[] findText, 
            int[] findTextPositionMap)
        {
            Invariant.Assert(startPosition.CompareTo(navigator) <= 0);
            Invariant.Assert(endPosition.CompareTo(navigator) >= 0); 

            int runCount; 
            int inlineCount = 0; 
            int findTextLength = 0;
 
            // Set the first offset which is zero on TextBufferSize + 1 location of
            // the text position map in case of the backward searching
            if (matchLast && findTextLength == 0)
            { 
                findTextPositionMap[findTextPositionMap.Length - 1] = 0;
            } 
 
            while ((matchLast ? startPosition.CompareTo(navigator) : navigator.CompareTo(endPosition)) < 0)
            { 

                switch (navigator.GetPointerContext(direction))
                {
                    case TextPointerContext.Text: 
                        runCount = navigator.GetTextRunLength(direction);
                        runCount = Math.Min(runCount, findText.Length - findTextLength); 
 
                        if (!matchLast)
                        { 
                            runCount = Math.Min(runCount, navigator.GetOffsetToPosition(endPosition));
                            navigator.GetTextInRun(direction, findText, findTextLength, runCount);

                            for (int i = findTextLength; i < findTextLength + runCount; i++) 
                            {
                                findTextPositionMap[i] = i + inlineCount; 
                            } 
                        }
                        else 
                        {
                            runCount = Math.Min(runCount, startPosition.GetOffsetToPosition(navigator));
                            navigator.GetTextInRun(
                                direction, 
                                findText,
                                findText.Length - findTextLength - runCount, 
                                runCount); 

                            // Set the text offest for the amount of runCount from the last index 
                            // of text position map
                            int mapIndex = findText.Length - findTextLength - 1;
                            for (int i = findTextLength; i < findTextLength + runCount; i++)
                            { 
                                findTextPositionMap[mapIndex--] = i + inlineCount + 1;
                            } 
                        } 

                        // Move the navigator position for the amount of runCount 
                        navigator.MoveByOffset(matchLast ? - runCount : runCount);
                        findTextLength += runCount;
                        break;
 
                    case TextPointerContext.None:
                    case TextPointerContext.ElementStart: 
                    case TextPointerContext.ElementEnd: 
                        if (IsAdjacentToFormatElement(navigator, direction))
                        { 
                            // Filter out formatting tags since find text content is plain.
                            inlineCount++;
                        }
                        else 
                        {
                            if (!matchLast) 
                            { 
                                // Stick in a line break to account for the block element.
                                findText[findTextLength] = '\n'; 
                                findTextPositionMap[findTextLength] = findTextLength + inlineCount;
                                findTextLength++;
                            }
                            else 
                            {
                                // Increse the find text length first since adding text and map reversely 
                                findTextLength++; 

                                // Stick in a line break to account for the block element and 
                                // add text offset on the last index of text position map
                                findText[findText.Length - findTextLength] = '\n';
                                findTextPositionMap[findText.Length - findTextLength] = findTextLength + inlineCount;
                            } 
                        }
 
                        navigator.MoveToNextContextPosition(direction); 
                        break;
 
                    case TextPointerContext.EmbeddedElement:
                        if (!matchLast)
                        {
                            findText[findTextLength] = '\xf8ff'; // Unicode private use. 
                            findTextPositionMap[findTextLength] = findTextLength + inlineCount;
                            findTextLength++; 
                        } 
                        else
                        { 
                            // Increse the find text length first since adding text and map reversely
                            findTextLength++;

                            // Set the private unicode value and text offset 
                            findText[findText.Length - findTextLength] = '\xf8ff';
                            findTextPositionMap[findText.Length - findTextLength] = findTextLength + inlineCount; 
                        } 

                        navigator.MoveToNextContextPosition(direction); 
                        break;
                }

                if (findTextLength >= findText.Length) 
                {
                    break; 
                } 
            }
 
            // Complete the adding the find text position to the position map for only the forward finding.
            // The backward finding(matchLast) is already added initially as the zero offset at the end of
            // text position map.
            if (!matchLast) 
            {
                if (findTextLength > 0) 
                { 
                    findTextPositionMap[findTextLength] = findTextPositionMap[findTextLength - 1] + 1;
                } 
                else
                {
                    findTextPositionMap[0] = 0;
                } 
            }
 
            return findTextLength; 
        }