//----------------------------------------------------- // // ITextRange Methods // //----------------------------------------------------- #region ITextRange Methods //...................................................... // // Selection Building // //...................................................... /// <summary> /// </summary> // internal static bool Contains(ITextRange thisRange, ITextPointer textPointer) { NormalizeRange(thisRange); if (textPointer == null) { throw new ArgumentNullException("textPointer"); } if (textPointer.TextContainer != thisRange.Start.TextContainer) { throw new ArgumentException(SR.Get(SRID.NotInAssociatedTree), "textPointer"); } // Correct position normalization on range boundary so that // our test would not depend on what side of formatting tags // pointer is located. if (textPointer.CompareTo(thisRange.Start) < 0) { textPointer = textPointer.GetFormatNormalizedPosition(LogicalDirection.Forward); } else if (textPointer.CompareTo(thisRange.End) > 0) { textPointer = textPointer.GetFormatNormalizedPosition(LogicalDirection.Backward); } // Check if at least one segment contains this position. for (int i = 0; i < thisRange._TextSegments.Count; i++) { if (thisRange._TextSegments[i].Contains(textPointer)) { return true; } } return false; }
// Normalizes a range: // // -The start position is advanced over all element edges not visible // to the IMEs. // -Start and end positions are moved to insertion positions. private void GetNormalizedRange(int startCharOffset, int endCharOffset, out ITextPointer start, out ITextPointer end) { start = CreatePointerAtCharOffset(startCharOffset, LogicalDirection.Forward); end = (startCharOffset == endCharOffset) ? start : CreatePointerAtCharOffset(endCharOffset, LogicalDirection.Backward); // Skip over hidden element edges. while (start.CompareTo(end) < 0) { TextPointerContext forwardContext = start.GetPointerContext(LogicalDirection.Forward); if (forwardContext == TextPointerContext.ElementStart) { TextElement element = start.GetAdjacentElement(LogicalDirection.Forward) as TextElement; if (element == null) break; if (element.IMELeftEdgeCharCount != 0) break; } else if (forwardContext != TextPointerContext.ElementEnd) { break; } start.MoveToNextContextPosition(LogicalDirection.Forward); } // Move to insertion positions. // If the positions are already adjacent to text, we must respect // the IME's decision in regards to exact placement. // MoveToInsertionPosition will skip over surrogates and combining // marks, but the IME needs fine-grained control over these positions. if (start.CompareTo(end) == 0) { start = start.GetFormatNormalizedPosition(LogicalDirection.Backward); end = start; } else { start = start.GetFormatNormalizedPosition(LogicalDirection.Backward); end = end.GetFormatNormalizedPosition(LogicalDirection.Backward); } }
private static ITextPointer GetNormalizedPosition(ITextRange thisRange, ITextPointer position, LogicalDirection direction) { ITextPointer normalizedPosition; if (thisRange.IgnoreTextUnitBoundaries) { normalizedPosition = position.GetFormatNormalizedPosition(direction); } else { normalizedPosition = position.GetInsertionPosition(direction); } return normalizedPosition; }