// 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))); }
/// <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); }
/// <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: 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); }
// 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; }
// 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); }
/// <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; }