// Worker for GetText, accepts any ITextPointer.
        internal static string GetTextInRun(ITextPointer position, LogicalDirection direction)
        {
            char[] text;
            int textLength;
            int getTextLength;

            textLength = position.GetTextRunLength(direction);
            text = new char[textLength];

            getTextLength = position.GetTextInRun(direction, text, 0, textLength);
            Invariant.Assert(getTextLength == textLength, "textLengths returned from GetTextRunLength and GetTextInRun are innconsistent");

            return new string(text);
        }
        // Token: 0x06004132 RID: 16690 RVA: 0x0012A184 File Offset: 0x00128384
        public override TextSpan <CultureSpecificCharacterBufferRange> GetPrecedingText(int dcp)
        {
            CharacterBufferRange empty   = CharacterBufferRange.Empty;
            CultureInfo          culture = null;

            if (dcp > 0)
            {
                ITextPointer textPointer = this._owner.Host.TextContainer.CreatePointerAtOffset(dcp, LogicalDirection.Backward);
                int          num         = Math.Min(128, textPointer.GetTextRunLength(LogicalDirection.Backward));
                char[]       array       = new char[num];
                textPointer.GetTextInRun(LogicalDirection.Backward, array, 0, num);
                empty   = new CharacterBufferRange(array, 0, num);
                culture = DynamicPropertyReader.GetCultureInfo((Control)this._owner.Host);
            }
            return(new TextSpan <CultureSpecificCharacterBufferRange>(empty.Length, new CultureSpecificCharacterBufferRange(culture, empty)));
        }
Beispiel #3
0
        /// <summary>
        /// Get text immediately before specified text source position.
        /// </summary>
        public override TextSpan <CultureSpecificCharacterBufferRange> GetPrecedingText(int dcp)
        {
            CharacterBufferRange precedingText = CharacterBufferRange.Empty;
            CultureInfo          culture       = null;

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

                // Return text in run. If it is at start of TextContainer this will return an empty string.
                // Typically the caller requires just the preceding character.  Worst case is the entire
                // preceding sentence, which we approximate with a 128 char limit.
                int     runLength = Math.Min(128, position.GetTextRunLength(LogicalDirection.Backward));
                char [] text      = new char[runLength];
                position.GetTextInRun(LogicalDirection.Backward, text, 0, runLength);

                precedingText = new CharacterBufferRange(text, 0, runLength);
                culture       = DynamicPropertyReader.GetCultureInfo((Control)_owner.Host);
            }

            return(new TextSpan <CultureSpecificCharacterBufferRange>(
                       precedingText.Length, new CultureSpecificCharacterBufferRange(culture, precedingText)));
        }
        // 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);
        }
Beispiel #5
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);
        }
Beispiel #6
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);
        }
Beispiel #7
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;
        }
Beispiel #8
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); 
 } 
        // 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);
        }
Beispiel #10
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; 
        }