// Token: 0x060038DB RID: 14555 RVA: 0x00100F94 File Offset: 0x000FF194 private static ITextPointer GetNextTextPosition(ITextPointer position, ITextPointer limit, LogicalDirection direction, out char character) { bool flag = false; character = '\0'; while (position != null && !flag && (limit == null || position.CompareTo(limit) < 0)) { switch (position.GetPointerContext(direction)) { case TextPointerContext.Text: { char[] array = new char[1]; position.GetTextInRun(direction, array, 0, 1); character = array[0]; flag = true; continue; } case TextPointerContext.ElementStart: case TextPointerContext.ElementEnd: if (TextSchema.IsFormattingType(position.GetElementType(direction))) { position = position.CreatePointer(1); continue; } position = null; continue; } position = null; } return(position); }
// 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))); }
// Returns the position preceeding the next text character in a specified // direction, or null if no such position exists. // The scan will halt if limit is encounted; limit may be null. private static ITextPointer GetNextTextPosition(ITextPointer position, ITextPointer limit, LogicalDirection direction, out char character) { bool foundText = false; character = (char)0; while (position != null && !foundText && (limit == null || position.CompareTo(limit) < 0)) { switch (position.GetPointerContext(direction)) { case TextPointerContext.Text: char[] buffer = new char[1]; position.GetTextInRun(direction, buffer, 0, 1); character = buffer[0]; foundText = true; break; case TextPointerContext.ElementStart: case TextPointerContext.ElementEnd: if (TextSchema.IsFormattingType(position.GetElementType(direction))) { position = position.CreatePointer(+1); } else { position = null; } break; case TextPointerContext.EmbeddedElement: case TextPointerContext.None: default: position = null; break; } } return(position); }
// Like GetText, excepts also accepts a limit parameter -- no text is returned past // this second position. // limit may be null, in which case it is ignored. internal static int GetTextWithLimit(ITextPointer thisPointer, LogicalDirection direction, char[] textBuffer, int startIndex, int count, ITextPointer limit) { int charsCopied; if (limit == null) { // No limit, just call GetText. charsCopied = thisPointer.GetTextInRun(direction, textBuffer, startIndex, count); } else if (direction == LogicalDirection.Forward && limit.CompareTo(thisPointer) <= 0) { // Limit completely blocks the read. charsCopied = 0; } else if (direction == LogicalDirection.Backward && limit.CompareTo(thisPointer) >= 0) { // Limit completely blocks the read. charsCopied = 0; } else { int maxCount; // Get an upper bound on the amount of text to copy. // Since GetText always stops on non-text boundaries, it's // ok if the count too high, it will get truncated anyways. if (direction == LogicalDirection.Forward) { maxCount = Math.Min(count, thisPointer.GetOffsetToPosition(limit)); } else { maxCount = Math.Min(count, limit.GetOffsetToPosition(thisPointer)); } maxCount = Math.Min(count, maxCount); charsCopied = thisPointer.GetTextInRun(direction, textBuffer, startIndex, maxCount); } return charsCopied; }
/// <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))); }
/// <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))); }
// 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))); }
// ------------------------------------------------------------------ // 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) )); }
/// <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); }
/// <summary> /// </summary> void ITextSelection.SetCaretToPosition(ITextPointer caretPosition, LogicalDirection direction, bool allowStopAtLineEnd, bool allowStopNearSpace) { // We need a pointer with appropriate direction, // becasue it will be used in textRangeBase.Select method for // pointer normalization. caretPosition = caretPosition.CreatePointer(direction); // Normalize the position in its logical direction - to get to text content over there. caretPosition.MoveToInsertionPosition(direction); // We need a pointer with the reverse direction to confirm // the line wrapping position. So we can ensure Bidi caret navigation. // Bidi can have the different caret position by setting the // logical direction, so we have to only set the logical direction // as the forward for the real line wrapping position. ITextPointer reversePosition = caretPosition.CreatePointer(direction == LogicalDirection.Forward ? LogicalDirection.Backward : LogicalDirection.Forward); // Check line wrapping condition if (!allowStopAtLineEnd && ((TextPointerBase.IsAtLineWrappingPosition(caretPosition, this.TextView) && TextPointerBase.IsAtLineWrappingPosition(reversePosition, this.TextView)) || TextPointerBase.IsNextToPlainLineBreak(caretPosition, LogicalDirection.Backward) || TextSchema.IsBreak(caretPosition.GetElementType(LogicalDirection.Backward)))) { // Caret is at wrapping position, and we are not allowed to stay at end of line, // so we choose forward direction to appear in the begiinning of a second line caretPosition.SetLogicalDirection(LogicalDirection.Forward); } else { if (caretPosition.GetPointerContext(LogicalDirection.Backward) == TextPointerContext.Text && caretPosition.GetPointerContext(LogicalDirection.Forward) == TextPointerContext.Text) { // This is statistically most typical case. No "smartness" needed // to choose standard Forward orientation for the caret. // NOTE: By using caretPosition's direction we solve BiDi caret orientation case: // The orietnation reflects a direction from where caret has been moved // or orientation where mouse clicked. So we will stick with appropriate // character. // Nothing to do. The caretPosition is good to go. } else if (!allowStopNearSpace) { // There are some tags around, and we are not allowed to choose a side near to space. // So we need to perform some content analysis. char[] charBuffer = new char[1]; if (caretPosition.GetPointerContext(direction) == TextPointerContext.Text && caretPosition.GetTextInRun(direction, charBuffer, 0, 1) == 1 && Char.IsWhiteSpace(charBuffer[0])) { LogicalDirection oppositeDirection = direction == LogicalDirection.Forward ? LogicalDirection.Backward : LogicalDirection.Forward; // Check formatting switch condition at this position FlowDirection initialFlowDirection = (FlowDirection)caretPosition.GetValue(FrameworkElement.FlowDirectionProperty); bool moved = caretPosition.MoveToInsertionPosition(oppositeDirection); if (moved && initialFlowDirection == (FlowDirection)caretPosition.GetValue(FrameworkElement.FlowDirectionProperty) && (caretPosition.GetPointerContext(oppositeDirection) != TextPointerContext.Text || caretPosition.GetTextInRun(oppositeDirection, charBuffer, 0, 1) != 1 || !Char.IsWhiteSpace(charBuffer[0]))) { // In the opposite direction we have a non-space // character. So we choose that direction direction = oppositeDirection; caretPosition.SetLogicalDirection(direction); } } } } // Now that orientation of a caretPosition is identified, // build an empty selection at this position TextRangeBase.BeginChange(this); try { TextRangeBase.Select(this, caretPosition, caretPosition); // Note how Select method works for the case of empty range: // It creates a single instance TextPointer normalized and oriented // in a direction taken from caretPosition: ITextSelection thisSelection = this; Invariant.Assert(thisSelection.Start.LogicalDirection == caretPosition.LogicalDirection); // orientation must be as passed Invariant.Assert(this.IsEmpty); //Invariant.Assert((object)thisSelection.Start == (object)thisSelection.End); // it must be the same instance of TextPointer //Invariant.Assert(TextPointerBase.IsAtInsertionPosition(thisSelection.Start, caretPosition.LogicalDirection)); // normalization must be done in the same diredction as orientation // Clear active positions when selection is empty SetActivePositions(null, null); } finally { TextRangeBase.EndChange(this); } }
// Token: 0x06002D1F RID: 11551 RVA: 0x000CBAC0 File Offset: 0x000C9CC0 internal object BuildObjectTree() { FixedElement.ElementType type = this._type; IAddChild addChild; if (type != FixedElement.ElementType.Paragraph) { switch (type) { case FixedElement.ElementType.Table: addChild = new Table(); goto IL_C7; case FixedElement.ElementType.TableRowGroup: addChild = new TableRowGroup(); goto IL_C7; case FixedElement.ElementType.TableRow: addChild = new TableRow(); goto IL_C7; case FixedElement.ElementType.TableCell: addChild = new TableCell(); goto IL_C7; case FixedElement.ElementType.Hyperlink: { Hyperlink hyperlink = new Hyperlink(); hyperlink.NavigateUri = (base.GetValue(FixedElement.NavigateUriProperty) as Uri); hyperlink.RequestNavigate += this.ClickHyperlink; AutomationProperties.SetHelpText(hyperlink, (string)base.GetValue(FixedElement.HelpTextProperty)); AutomationProperties.SetName(hyperlink, (string)base.GetValue(FixedElement.NameProperty)); addChild = hyperlink; goto IL_C7; } } addChild = null; } else { addChild = new Paragraph(); } IL_C7: ITextPointer textPointer = ((ITextPointer)this._start).CreatePointer(); while (textPointer.CompareTo(this._end) < 0) { TextPointerContext pointerContext = textPointer.GetPointerContext(LogicalDirection.Forward); if (pointerContext == TextPointerContext.Text) { addChild.AddText(textPointer.GetTextInRun(LogicalDirection.Forward)); } else if (pointerContext == TextPointerContext.EmbeddedElement) { addChild.AddChild(textPointer.GetAdjacentElement(LogicalDirection.Forward)); } else if (pointerContext == TextPointerContext.ElementStart) { object adjacentElement = textPointer.GetAdjacentElement(LogicalDirection.Forward); if (adjacentElement != null) { addChild.AddChild(adjacentElement); textPointer.MoveToNextContextPosition(LogicalDirection.Forward); textPointer.MoveToElementEdge(ElementEdge.BeforeEnd); } } textPointer.MoveToNextContextPosition(LogicalDirection.Forward); } return(addChild); }
// <summary> // Checks if there is a Environment.NewLine symbol immediately // next to the position. Used only for plain text scenarios. // RichText case will always return false. // </summary> internal static bool IsNextToPlainLineBreak(ITextPointer thisPosition, LogicalDirection direction) { char[] textBuffer = new char[2]; int actualCount = thisPosition.GetTextInRun(direction, textBuffer, /*startIndex:*/0, /*count:*/2); return (actualCount == 1 && IsCharUnicodeNewLine(textBuffer[0])) || (actualCount == 2 && ( (direction == LogicalDirection.Backward && IsCharUnicodeNewLine(textBuffer[1])) || (direction == LogicalDirection.Forward && IsCharUnicodeNewLine(textBuffer[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; }
// Returns true if the position is inside of a pair of surrogate characters // or inside of Newline sequence "\r\n". // Such position is not valid position for caret stopping or for text insertion. private static bool IsInsideCompoundSequence(ITextPointer position) { // OK, so we're surrounded by text runs (possibly empty), try getting a character // in each direction -- it's OK to position the caret if there's no characters // before or after it Char[] neighborhood = new char[2]; if (position.GetTextInRun(LogicalDirection.Backward, neighborhood, 0, 1) == 1 && position.GetTextInRun(LogicalDirection.Forward, neighborhood, 1, 1) == 1) { if (Char.IsSurrogatePair(neighborhood[0], neighborhood[1]) || neighborhood[0] == '\r' && neighborhood[1] == '\n') { return true; } // Check for combining marks. // // See Unicode 3.1, Section 3.5 (Combination), D13 and D14 for // strict definitions of "combining character" and "base character". // // The CLR source for StringInfo is also informative. // // In brief: we're looking for a character followed by a // combining mark. // UnicodeCategory category1 = Char.GetUnicodeCategory(neighborhood[1]); if (category1 == UnicodeCategory.SpacingCombiningMark || category1 == UnicodeCategory.NonSpacingMark || category1 == UnicodeCategory.EnclosingMark) { UnicodeCategory category0 = Char.GetUnicodeCategory(neighborhood[0]); if (category0 != UnicodeCategory.Control && category0 != UnicodeCategory.Format && category0 != UnicodeCategory.OtherNotAssigned) { return true; } } } return false; }
internal object BuildObjectTree() { IAddChild root; switch (_type) { case ElementType.Table: root = new Table(); break; case ElementType.TableRowGroup: root = new TableRowGroup(); break; case ElementType.TableRow: root = new TableRow(); break; case ElementType.TableCell: root = new TableCell(); break; case ElementType.Paragraph: root = new Paragraph(); break; case ElementType.Hyperlink: Hyperlink link = new Hyperlink(); link.NavigateUri = GetValue(NavigateUriProperty) as Uri; link.RequestNavigate += new RequestNavigateEventHandler(ClickHyperlink); AutomationProperties.SetHelpText(link, (String)this.GetValue(HelpTextProperty)); AutomationProperties.SetName(link, (String)this.GetValue(NameProperty)); root = link; break; default: Debug.Assert(false); root = null; break; } ITextPointer pos = ((ITextPointer)_start).CreatePointer(); while (pos.CompareTo((ITextPointer)_end) < 0) { TextPointerContext tpc = pos.GetPointerContext(LogicalDirection.Forward); if (tpc == TextPointerContext.Text) { root.AddText(pos.GetTextInRun(LogicalDirection.Forward)); } else if (tpc == TextPointerContext.EmbeddedElement) { root.AddChild(pos.GetAdjacentElement(LogicalDirection.Forward)); } else if (tpc == TextPointerContext.ElementStart) { object obj = pos.GetAdjacentElement(LogicalDirection.Forward); if (obj != null) { root.AddChild(obj); pos.MoveToNextContextPosition(LogicalDirection.Forward); pos.MoveToElementEdge(ElementEdge.BeforeEnd); } } pos.MoveToNextContextPosition(LogicalDirection.Forward); } return(root); }
// 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); }
// Returns the position preceeding the next text character in a specified // direction, or null if no such position exists. // The scan will halt if limit is encounted; limit may be null. private static ITextPointer GetNextTextPosition(ITextPointer position, ITextPointer limit, LogicalDirection direction, out char character) { bool foundText = false; character = (char)0; while (position != null && !foundText && (limit == null || position.CompareTo(limit) < 0)) { switch (position.GetPointerContext(direction)) { case TextPointerContext.Text: char[] buffer = new char[1]; position.GetTextInRun(direction, buffer, 0, 1); character = buffer[0]; foundText = true; break; case TextPointerContext.ElementStart: case TextPointerContext.ElementEnd: if (TextSchema.IsFormattingType(position.GetElementType(direction))) { position = position.CreatePointer(+1); } else { position = null; } break; case TextPointerContext.EmbeddedElement: case TextPointerContext.None: default: position = null; break; } } return position; }