Пример #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);
        }
        // Token: 0x06002EFA RID: 12026 RVA: 0x000D47DC File Offset: 0x000D29DC
        private void _SkipFormattingTags(ITextPointer textPointer)
        {
            LogicalDirection logicalDirection = textPointer.LogicalDirection;
            int offset = (logicalDirection == LogicalDirection.Forward) ? 1 : -1;

            while (TextSchema.IsFormattingType(textPointer.GetElementType(logicalDirection)))
            {
                textPointer.MoveByOffset(offset);
            }
        }
        // Token: 0x060039B3 RID: 14771 RVA: 0x00105B0C File Offset: 0x00103D0C
        internal static TextRange InternalFind(ITextPointer startPosition, ITextPointer endPosition, string findPattern, CultureInfo cultureInfo, bool matchCase, bool matchWholeWord, bool matchLast, bool matchDiacritics, bool matchKashida, bool matchAlefHamza)
        {
            Invariant.Assert(startPosition.CompareTo(endPosition) <= 0);
            ITextPointer     textPointer;
            LogicalDirection direction;

            if (matchLast)
            {
                textPointer = endPosition;
                direction   = LogicalDirection.Backward;
            }
            else
            {
                textPointer = startPosition;
                direction   = LogicalDirection.Forward;
            }
            int num = Math.Max(64, findPattern.Length * 2 * 2);

            textPointer = textPointer.CreatePointer();
            while ((matchLast ? startPosition.CompareTo(textPointer) : textPointer.CompareTo(endPosition)) < 0)
            {
                ITextPointer textPointer2 = textPointer.CreatePointer();
                char[]       array        = new char[num];
                int[]        array2       = new int[num + 1];
                int          num2         = TextFindEngine.SetFindTextAndFindTextPositionMap(startPosition, endPosition, textPointer, direction, matchLast, array, array2);
                if (!matchDiacritics || num2 >= findPattern.Length)
                {
                    int  num3 = matchLast ? (array.Length - num2) : 0;
                    bool hasPreceedingSeparatorChar = false;
                    bool hasFollowingSeparatorChar  = false;
                    if (matchWholeWord)
                    {
                        TextFindEngine.GetContextualInformation(textPointer2, matchLast ? (-array2[array2.Length - num2 - 1]) : array2[num2], out hasPreceedingSeparatorChar, out hasFollowingSeparatorChar);
                    }
                    string textString = new string(array, num3, num2);
                    int    num5;
                    int    num4 = TextFindEngine.FindMatchIndexFromFindContent(textString, findPattern, cultureInfo, matchCase, matchWholeWord, matchLast, matchDiacritics, matchKashida, matchAlefHamza, hasPreceedingSeparatorChar, hasFollowingSeparatorChar, out num5);
                    if (num4 != -1)
                    {
                        ITextPointer textPointer3 = textPointer2.CreatePointer();
                        textPointer3.MoveByOffset(matchLast ? (-array2[num3 + num4]) : array2[num4]);
                        ITextPointer textPointer4 = textPointer2.CreatePointer();
                        textPointer4.MoveByOffset(matchLast ? (-array2[num3 + num4 + num5]) : array2[num4 + num5]);
                        return(new TextRange(textPointer3, textPointer4));
                    }
                    if (num2 > findPattern.Length)
                    {
                        textPointer = textPointer2.CreatePointer();
                        textPointer.MoveByOffset(matchLast ? (-array2[array.Length - num2 + findPattern.Length]) : array2[num2 - findPattern.Length]);
                    }
                }
            }
            return(null);
        }
Пример #4
0
        private void _SkipFormattingTags(ITextPointer textPointer)
        {
            Debug.Assert(!textPointer.IsFrozen, "Can't reposition a frozen pointer!");

            LogicalDirection dir = textPointer.LogicalDirection;
            int increment        = (dir == LogicalDirection.Forward ? +1 : -1);

            while (TextSchema.IsFormattingType(textPointer.GetElementType(dir)))
            {
                textPointer.MoveByOffset(increment);
            }
        }
Пример #5
0
        // Token: 0x06006B2C RID: 27436 RVA: 0x001EF318 File Offset: 0x001ED518
        internal int GetLastDcpAttachedObjectBeforeLine(int dcpFirst)
        {
            ITextPointer textPointerFromCP = TextContainerHelper.GetTextPointerFromCP(base.StructuralCache.TextContainer, base.ParagraphStartCharacterPosition + dcpFirst, LogicalDirection.Forward);
            ITextPointer contentStart      = TextContainerHelper.GetContentStart(base.StructuralCache.TextContainer, base.Element);

            while (textPointerFromCP.GetPointerContext(LogicalDirection.Forward) == TextPointerContext.ElementStart)
            {
                TextElement adjacentElementFromOuterPosition = ((TextPointer)textPointerFromCP).GetAdjacentElementFromOuterPosition(LogicalDirection.Forward);
                if (!(adjacentElementFromOuterPosition is Figure) && !(adjacentElementFromOuterPosition is Floater))
                {
                    break;
                }
                textPointerFromCP.MoveByOffset(adjacentElementFromOuterPosition.SymbolCount);
            }
            return(contentStart.GetOffsetToPosition(textPointerFromCP));
        }
Пример #6
0
        /// <summary>
        /// Get text immediately before specified text source position. Return CharacterBufferRange
        /// containing this text.
        /// </summary>
        /// <param name="dcp">
        /// dcp of position relative to start of line
        /// </param>
        internal override TextSpan <CultureSpecificCharacterBufferRange> GetPrecedingText(int dcp)
        {
            // Parameter validation
            Invariant.Assert(dcp >= 0);

            int nonTextLength = 0;
            CharacterBufferRange precedingText = CharacterBufferRange.Empty;
            CultureInfo          culture       = null;

            if (dcp > 0)
            {
                // Create TextPointer at dcp, and pointer at paragraph start to compare
                ITextPointer startPosition = TextContainerHelper.GetTextPointerFromCP(_paraClient.Paragraph.StructuralCache.TextContainer, _cpPara, LogicalDirection.Forward);
                ITextPointer position      = TextContainerHelper.GetTextPointerFromCP(_paraClient.Paragraph.StructuralCache.TextContainer, _cpPara + dcp, LogicalDirection.Forward);

                // Move backward until we find a position at the end of a text run, or reach start of TextContainer
                while (position.GetPointerContext(LogicalDirection.Backward) != TextPointerContext.Text &&
                       position.CompareTo(startPosition) != 0)
                {
                    position.MoveByOffset(-1);
                    nonTextLength++;
                }


                // Return text in run. If it is at start of TextContainer this will return an empty string
                string precedingTextString = position.GetTextInRun(LogicalDirection.Backward);
                precedingText = new CharacterBufferRange(precedingTextString, 0, precedingTextString.Length);


                StaticTextPointer pointer = position.CreateStaticPointer();
                DependencyObject  element = (pointer.Parent != null) ? pointer.Parent : _paraClient.Paragraph.Element;
                culture = DynamicPropertyReader.GetCultureInfo(element);
            }

            return(new TextSpan <CultureSpecificCharacterBufferRange>(
                       nonTextLength + precedingText.Length,
                       new CultureSpecificCharacterBufferRange(culture, precedingText)
                       ));
        }
        // Token: 0x06006600 RID: 26112 RVA: 0x001CAB08 File Offset: 0x001C8D08
        public override TextSpan <CultureSpecificCharacterBufferRange> GetPrecedingText(int dcp)
        {
            int num = 0;
            CharacterBufferRange empty   = CharacterBufferRange.Empty;
            CultureInfo          culture = null;

            if (dcp > 0)
            {
                ITextPointer textPointer = this._owner.TextContainer.CreatePointerAtOffset(dcp, LogicalDirection.Backward);
                while (textPointer.GetPointerContext(LogicalDirection.Backward) != TextPointerContext.Text && textPointer.CompareTo(this._owner.TextContainer.Start) != 0)
                {
                    textPointer.MoveByOffset(-1);
                    num++;
                }
                string textInRun = textPointer.GetTextInRun(LogicalDirection.Backward);
                empty = new CharacterBufferRange(textInRun, 0, textInRun.Length);
                StaticTextPointer staticTextPointer = textPointer.CreateStaticPointer();
                DependencyObject  element           = (staticTextPointer.Parent != null) ? staticTextPointer.Parent : this._owner;
                culture = DynamicPropertyReader.GetCultureInfo(element);
            }
            return(new TextSpan <CultureSpecificCharacterBufferRange>(num + empty.Length, new CultureSpecificCharacterBufferRange(culture, empty)));
        }
Пример #8
0
        // Token: 0x06006864 RID: 26724 RVA: 0x001D6C0C File Offset: 0x001D4E0C
        internal override TextSpan <CultureSpecificCharacterBufferRange> GetPrecedingText(int dcp)
        {
            Invariant.Assert(dcp >= 0);
            int num = 0;
            CharacterBufferRange empty   = CharacterBufferRange.Empty;
            CultureInfo          culture = null;

            if (dcp > 0)
            {
                ITextPointer textPointerFromCP  = TextContainerHelper.GetTextPointerFromCP(this._paraClient.Paragraph.StructuralCache.TextContainer, this._cpPara, LogicalDirection.Forward);
                ITextPointer textPointerFromCP2 = TextContainerHelper.GetTextPointerFromCP(this._paraClient.Paragraph.StructuralCache.TextContainer, this._cpPara + dcp, LogicalDirection.Forward);
                while (textPointerFromCP2.GetPointerContext(LogicalDirection.Backward) != TextPointerContext.Text && textPointerFromCP2.CompareTo(textPointerFromCP) != 0)
                {
                    textPointerFromCP2.MoveByOffset(-1);
                    num++;
                }
                string textInRun = textPointerFromCP2.GetTextInRun(LogicalDirection.Backward);
                empty = new CharacterBufferRange(textInRun, 0, textInRun.Length);
                StaticTextPointer staticTextPointer = textPointerFromCP2.CreateStaticPointer();
                DependencyObject  element           = (staticTextPointer.Parent != null) ? staticTextPointer.Parent : this._paraClient.Paragraph.Element;
                culture = DynamicPropertyReader.GetCultureInfo(element);
            }
            return(new TextSpan <CultureSpecificCharacterBufferRange>(num + empty.Length, new CultureSpecificCharacterBufferRange(culture, empty)));
        }
Пример #9
0
        // ------------------------------------------------------------------
        // Get text immediately before specified text source position.
        // ------------------------------------------------------------------
        public override TextSpan <CultureSpecificCharacterBufferRange> GetPrecedingText(int dcp)
        {
            // Parameter validation
            Debug.Assert(dcp >= 0);

            int nonTextLength = 0;
            CharacterBufferRange precedingText = CharacterBufferRange.Empty;
            CultureInfo          culture       = null;

            if (dcp > 0)
            {
                // Create TextPointer at dcp
                ITextPointer position = _owner.TextContainer.CreatePointerAtOffset(dcp, LogicalDirection.Backward);

                // Move backward until we find a position at the end of a text run, or reach start of TextContainer
                while (position.GetPointerContext(LogicalDirection.Backward) != TextPointerContext.Text &&
                       position.CompareTo(_owner.TextContainer.Start) != 0)
                {
                    position.MoveByOffset(-1);
                    nonTextLength++;
                }

                // Return text in run. If it is at start of TextContainer this will return an empty string
                string precedingTextString = position.GetTextInRun(LogicalDirection.Backward);
                precedingText = new CharacterBufferRange(precedingTextString, 0, precedingTextString.Length);

                StaticTextPointer pointer = position.CreateStaticPointer();
                DependencyObject  element = (pointer.Parent != null) ? pointer.Parent : _owner;
                culture = DynamicPropertyReader.GetCultureInfo(element);
            }

            return(new TextSpan <CultureSpecificCharacterBufferRange>(
                       nonTextLength + precedingText.Length,
                       new CultureSpecificCharacterBufferRange(culture, precedingText)
                       ));
        }
Пример #10
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);
        }
Пример #11
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);
        }
Пример #12
0
        //---------------------------------------------------------------------
        //
        // Private methods
        //
        //---------------------------------------------------------------------

        #region Private Methods

        // Find the text with the specified find options.
        internal static TextRange InternalFind(
            ITextPointer startPosition,
            ITextPointer endPosition,
            string findPattern,
            CultureInfo cultureInfo,
            bool matchCase,
            bool matchWholeWord,
            bool matchLast,
            bool matchDiacritics,
            bool matchKashida,
            bool matchAlefHamza)
        {
            Invariant.Assert(startPosition.CompareTo(endPosition) <= 0);

            ITextPointer     navigator;
            LogicalDirection direction;

            char[] findText;
            int[]  findTextPositionMap;
            int    findTextLength;

            if (matchLast)
            {
                navigator = endPosition;
                direction = LogicalDirection.Backward;
            }
            else
            {
                navigator = startPosition;
                direction = LogicalDirection.Forward;
            }

            // Set the text block size to read the find text content.
            // The block size must be bigger than the double of find pattern size
            // so that we can find matches intersected by neighboring blocks.
            // We need an additional x2 fudge factor to account for the matchDiacritics
            // option -- the findPattern may lack diacritics that will be ignored in
            // the text.
            int textBlockLength = Math.Max(TextBlockLength, findPattern.Length * 2 * 2);

            navigator = navigator.CreatePointer();

            while ((matchLast ? startPosition.CompareTo(navigator) : navigator.CompareTo(endPosition)) < 0)
            {
                ITextPointer startFindTextPosition = navigator.CreatePointer();

                findText            = new char[textBlockLength];
                findTextPositionMap = new int[textBlockLength + 1];

                // Set the find text content from reading text of the current text position.
                // Set the find text position map as well to track of the text pointer of the text content.
                findTextLength = SetFindTextAndFindTextPositionMap(
                    startPosition,
                    endPosition,
                    navigator,
                    direction,
                    matchLast,
                    findText,
                    findTextPositionMap);

                if (!matchDiacritics || findTextLength >= findPattern.Length)
                {
                    int textStartIndex = matchLast ? findText.Length - findTextLength : 0;

                    // Track whether or not the text array findText is bounded by
                    // separator chars.  We only look at these values when matchWholeWord
                    // is true.
                    bool hasPreceedingSeparatorChar = false;
                    bool hasFollowingSeparatorChar  = false;

                    if (matchWholeWord)
                    {
                        GetContextualInformation(startFindTextPosition, matchLast ? -findTextPositionMap[findTextPositionMap.Length - findTextLength - 1] : findTextPositionMap[findTextLength],
                                                 out hasPreceedingSeparatorChar, out hasFollowingSeparatorChar);
                    }

                    string textString = new string(findText, textStartIndex, findTextLength);
                    int    matchLength;

                    // Now find text the matched index for the find pattern from the find text content
                    int matchIndex = FindMatchIndexFromFindContent(
                        textString,
                        findPattern,
                        cultureInfo,
                        matchCase,
                        matchWholeWord,
                        matchLast,
                        matchDiacritics,
                        matchKashida,
                        matchAlefHamza,
                        hasPreceedingSeparatorChar,
                        hasFollowingSeparatorChar,
                        out matchLength);

                    if (matchIndex != -1)
                    {
                        // Found the find pattern string from the find text content!
                        // Return the text range for the matched find text position.

                        ITextPointer startMatchPosition = startFindTextPosition.CreatePointer();
                        startMatchPosition.MoveByOffset(matchLast ? -findTextPositionMap[textStartIndex + matchIndex] : findTextPositionMap[matchIndex]);

                        ITextPointer endMatchPosition = startFindTextPosition.CreatePointer();
                        endMatchPosition.MoveByOffset(matchLast ? -findTextPositionMap[textStartIndex + matchIndex + matchLength] : findTextPositionMap[matchIndex + matchLength]);

                        return(new TextRange(startMatchPosition, endMatchPosition));
                    }

                    // Move the text position for the size of finding pattern string not to miss
                    // the matching text that is located on the boundary of the find text block.
                    // Move back the position to N(findTextLength) - findPattern.Length
                    if (findTextLength > findPattern.Length)
                    {
                        // Need to set new pointer to jump the correct place of backing offset of the findPattern length
                        navigator = startFindTextPosition.CreatePointer();
                        navigator.MoveByOffset(matchLast ? -findTextPositionMap[findText.Length - findTextLength + findPattern.Length] : findTextPositionMap[findTextLength - findPattern.Length]);
                    }
                }
            }

            return(null);
        }
Пример #13
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);
        }
Пример #14
0
        // GetText handler for Blocks and TableCell to add '\n' or TS_CHAR_REGION.
        private static bool WalkRegionBoundary(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.ElementStart || navigator.GetPointerContext(LogicalDirection.Forward) == TextPointerContext.ElementEnd);
            Invariant.Assert(limit == null || navigator.CompareTo(limit) <= 0);

            // If the caller passed in a non-null limit, we don't do anything and just return true.
            // we've passed it.
            if (limit != null)
            {
                if (navigator.CompareTo(limit) >= 0)
                {
                    return true;
                }
            }

            hitLimit = false;

            if (cchReq > 0)
            {
                // Add one TS_CHAR_REGION (TableCell) or '\n' (everything else) char.
                char ch = (navigator.GetAdjacentElement(LogicalDirection.Forward) is TableCell) ? UnsafeNativeMethods.TS_CHAR_REGION : '\n';
                text[charsCopied] = ch;
                navigator.MoveByOffset(1);
                charsCopied += 1;
                hitLimit = (text.Length == charsCopied) || (limit != null && navigator.CompareTo(limit) == 0);
            }
            else
            {
                // Caller doesn't want text, just run info.
                // Advance the navigator.
                // Add one TS_CHAR_REGION char.
                navigator.MoveByOffset(1);
            }

            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 += 1;
                }
                else
                {
                    runInfo[cRunInfoRcv].count = 1;
                    runInfo[cRunInfoRcv].type = UnsafeNativeMethods.TsRunType.TS_RT_PLAIN;
                    cRunInfoRcv++;
                }
            }

            return hitLimit;
        }
Пример #15
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;
        }
        /// <summary>
        /// Advances this TextNavigator by a count number of characters.
        /// </summary>
        /// <param name="thisNavigator">ITextPointer to advance.</param>
        /// <param name="direction">
        /// A direction in which to search a next characters.
        /// </param>
        /// <returns>
        /// True if the navigator is advanced, false if the end of document is
        /// encountered and the navigator is not repositioned.
        /// </returns>
        /// <remarks>
        /// A "character" in this context is a sequence of one or several text
        /// symbols: one or more Unicode code points may be a character, every
        /// embedded object is a character, a sequence of closing block tags
        /// followed by opening block tags may also be a unit. Formatting tags
        /// do not contribute in any unit.
        /// </remarks>
        internal static bool MoveToNextInsertionPosition(ITextPointer thisNavigator, LogicalDirection direction)
        {
            Invariant.Assert(!thisNavigator.IsFrozen, "Can't reposition a frozen pointer!");

            bool moved = true;

            int increment = direction == LogicalDirection.Forward ? +1 : -1;

            ITextPointer initialPosition = thisNavigator.CreatePointer();

            if (!IsAtInsertionPosition(thisNavigator))
            {
                // If the TextPointer is not currently at an insertion position,
                // move the TextPointer to the next insertion position in
                // the indicated direction, just like the MoveToInsertionPosition method.

                if (!MoveToInsertionPosition(thisNavigator, direction))
                {
                    // No insertion position in all content. MoveToInsertionPosition() guarantees that navigator is moved back to initial position.
                    moved = false;
                    goto Exit;
                }

                if ((direction == LogicalDirection.Forward && initialPosition.CompareTo(thisNavigator) < 0) ||
                    (direction == LogicalDirection.Backward && thisNavigator.CompareTo(initialPosition) < 0))
                {
                    // We have found an insertion position in requested direction.
                    goto Exit;
                }
            }

            // Start with skipping character formatting tags in this direction
            while (TextSchema.IsFormattingType(thisNavigator.GetElementType(direction)))
            {
                thisNavigator.MoveByOffset(increment);
            }

            do
            {
                if (thisNavigator.GetPointerContext(direction) != TextPointerContext.None)
                {
                    thisNavigator.MoveByOffset(increment);
                }
                else
                {
                    // No insertion position in this direction; Move back
                    thisNavigator.MoveToPosition(initialPosition);
                    moved = false;
                    goto Exit;
                }
            }
            while (!IsAtInsertionPosition(thisNavigator));

            // We must leave position normalized in backward direction
            if (direction == LogicalDirection.Backward)
            {
                // For this we must skip character formatting tags if we have any
                while (TextSchema.IsFormattingType(thisNavigator.GetElementType(direction)))
                {
                    thisNavigator.MoveByOffset(increment);
                }

                // However if it is block start we should back off
                TextPointerContext context = thisNavigator.GetPointerContext(direction);
                if (context == TextPointerContext.ElementStart || context == TextPointerContext.None)
                {
                    increment = -increment;
                    while (TextSchema.IsFormattingType(thisNavigator.GetElementType(LogicalDirection.Forward))
                           && !IsAtInsertionPosition(thisNavigator))
                    {
                        thisNavigator.MoveByOffset(increment);
                    }
                }
            }

        Exit:
            if (moved)
            {
                if (direction == LogicalDirection.Forward)
                {
                    Invariant.Assert(thisNavigator.CompareTo(initialPosition) > 0, "thisNavigator is expected to be moved from initialPosition - 1");
                }
                else
                {
                    Invariant.Assert(thisNavigator.CompareTo(initialPosition) < 0, "thisNavigator is expected to be moved from initialPosition - 2");
                }
            }
            else
            {
                Invariant.Assert(thisNavigator.CompareTo(initialPosition) == 0, "thisNavigator must stay at initial position");
            }
            return moved;
        }
        //------------------------------------------------------
        //
        //  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;
        }
Пример #18
0
 private void _SkipFormattingTags(ITextPointer textPointer)
 {
     Debug.Assert(!textPointer.IsFrozen, "Can't reposition a frozen pointer!");
     
     LogicalDirection dir = textPointer.LogicalDirection;
     int increment = (dir == LogicalDirection.Forward ? +1 : -1);
     while (TextSchema.IsFormattingType( textPointer.GetElementType(dir)) )
     {
         textPointer.MoveByOffset(increment);
     }
 }
Пример #19
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; 
        }
        // 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);
        }
Пример #21
0
        //
        // Move the TextPointer by offset in char count.
        //
        private static ITextPointer MoveToNextCharPos(ITextPointer position, int offset)
        {
            bool done = false;
            if (offset < 0)
            {
                while ((offset < 0) && !done)
                {
                    switch (position.GetPointerContext(LogicalDirection.Backward))
                    {
                        case TextPointerContext.Text:
                            offset++;
                            break;
                        case TextPointerContext.None:
                            done = true;
                            break;
                    }
                    position.MoveByOffset(-1);
                }
            }
            else if (offset > 0)
            {
                while ((offset > 0) && !done)
                {
                    switch (position.GetPointerContext(LogicalDirection.Forward))
                    {
                        case TextPointerContext.Text:
                            offset--;
                            break;
                        case TextPointerContext.None:
                            done = true;
                            break;
                    }
                    position.MoveByOffset(1);
                }
            }

            return position;
        }