// Token: 0x060068B0 RID: 26800 RVA: 0x001D8BE4 File Offset: 0x001D6DE4 protected override BaseParagraph GetParagraph(ITextPointer textPointer, bool fEmptyOk) { Invariant.Assert(textPointer is TextPointer); BaseParagraph baseParagraph = null; while (baseParagraph == null) { TextPointerContext pointerContext = textPointer.GetPointerContext(LogicalDirection.Forward); if (pointerContext == TextPointerContext.ElementStart) { TextElement adjacentElementFromOuterPosition = ((TextPointer)textPointer).GetAdjacentElementFromOuterPosition(LogicalDirection.Forward); if (adjacentElementFromOuterPosition is ListItem) { baseParagraph = new ListItemParagraph(adjacentElementFromOuterPosition, base.StructuralCache); break; } if (adjacentElementFromOuterPosition is List) { baseParagraph = new ListParagraph(adjacentElementFromOuterPosition, base.StructuralCache); break; } if (((TextPointer)textPointer).IsFrozen) { textPointer = textPointer.CreatePointer(); } textPointer.MoveToPosition(adjacentElementFromOuterPosition.ElementEnd); } else if (pointerContext == TextPointerContext.ElementEnd) { if (base.Element == ((TextPointer)textPointer).Parent) { break; } if (((TextPointer)textPointer).IsFrozen) { textPointer = textPointer.CreatePointer(); } textPointer.MoveToNextContextPosition(LogicalDirection.Forward); } else { if (((TextPointer)textPointer).IsFrozen) { textPointer = textPointer.CreatePointer(); } textPointer.MoveToNextContextPosition(LogicalDirection.Forward); } } if (baseParagraph != null) { base.StructuralCache.CurrentFormatContext.DependentMax = (TextPointer)textPointer; } return(baseParagraph); }
// 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; }
// <see cref="System.Windows.Documents.TextPointer.MoveToLineBoundary"/> internal static int MoveToLineBoundary(ITextPointer thisPointer, ITextView textView, int count, bool respectNonMeargeableInlineStart) { ITextPointer position; double newSuggestedX; Invariant.Assert(!thisPointer.IsFrozen, "Can't reposition a frozen pointer!"); Invariant.Assert(textView != null, "Null TextView!"); // Did you check ITextPointer.HasValidLayout? position = textView.GetPositionAtNextLine(thisPointer, Double.NaN, count, out newSuggestedX, out count); if (!position.IsAtInsertionPosition) { if (!respectNonMeargeableInlineStart || (!IsAtNonMergeableInlineStart(position) && !IsAtNonMergeableInlineEnd(position))) { position.MoveToInsertionPosition(position.LogicalDirection); } } if (IsAtRowEnd(position)) { // We will find outselves at a row end when we have incomplete // markup like // // <TableCell></TableCell> <!-- No inner Run! --> // // In that case the end-of-row is the entire line. thisPointer.MoveToPosition(position); thisPointer.SetLogicalDirection(position.LogicalDirection); } else { TextSegment lineRange = textView.GetLineRange(position); if (!lineRange.IsNull) { thisPointer.MoveToPosition(lineRange.Start); thisPointer.SetLogicalDirection(lineRange.Start.LogicalDirection); } else if (count > 0) { // It is possible to get a non-zero return value from ITextView.GetPositionAtNextLine // when moving into a BlockUIContainer. The container is the "next line" but does // not contain any lines itself -- GetLineRange will return null. thisPointer.MoveToPosition(position); thisPointer.SetLogicalDirection(position.LogicalDirection); } } return count; }
/// <summary> /// Moves the navigator in the given direction to a position of the next /// word boundary. /// </summary> /// <param name="thisNavigator">ITextPointer to advance.</param> /// <param name="movingDirection"> /// Direction to move. /// </param> /// <returns></returns> // internal static bool MoveToNextWordBoundary(ITextPointer thisNavigator, LogicalDirection movingDirection) { int moveCounter = 0; Invariant.Assert(!thisNavigator.IsFrozen, "Can't reposition a frozen pointer!"); ITextPointer startPosition = thisNavigator.CreatePointer(); while (thisNavigator.MoveToNextInsertionPosition(movingDirection)) { moveCounter++; // Need to break the loop for weird case when there is no word break in text content. // When the word looks too long, consider end of textRun as a word break. // if (moveCounter > 64) // 64 was taken as a random number. Probably not big enough though... { thisNavigator.MoveToPosition(startPosition); thisNavigator.MoveToNextContextPosition(movingDirection); break; } if (IsAtWordBoundary(thisNavigator, /*insideWordDirection:*/LogicalDirection.Forward)) { // Note that we always use Forward direction for word orientation. break; } } return moveCounter > 0; }
/// <summary> /// Determine paragraph type at the current TextPointer and /// create it. Only ListItem elements are considered. Any other /// content is skipped. /// </summary> /// <param name="textPointer"> /// TextPointer at which paragraph is to be created /// </param> /// <param name="fEmptyOk"> /// True if empty paragraph is acceptable /// </param> /// <returns> /// BaseParagraph that was created /// </returns> protected override BaseParagraph GetParagraph(ITextPointer textPointer, bool fEmptyOk) { Invariant.Assert(textPointer is TextPointer); BaseParagraph paragraph = null; while (paragraph == null) { TextPointerContext runType = textPointer.GetPointerContext(LogicalDirection.Forward); if (runType == TextPointerContext.ElementStart) { TextElement element = ((TextPointer)textPointer).GetAdjacentElementFromOuterPosition(LogicalDirection.Forward); if (element is ListItem) { // paragraph = new ListItemParagraph(element, StructuralCache); break; } else if (element is List) { // paragraph = new ListParagraph(element, StructuralCache); break; } // Skip all elements, which are not valid list item children if (((TextPointer)textPointer).IsFrozen) { // Need to clone TextPointer before moving it. textPointer = textPointer.CreatePointer(); } textPointer.MoveToPosition(element.ElementEnd); } else if (runType == TextPointerContext.ElementEnd) { // End of list, if the same as Owner of associated element // Skip content otherwise if (Element == ((TextPointer)textPointer).Parent) { break; } if (((TextPointer)textPointer).IsFrozen) { // Need to clone TextPointer before moving it. textPointer = textPointer.CreatePointer(); } textPointer.MoveToNextContextPosition(LogicalDirection.Forward); } else { // Skip content if (((TextPointer)textPointer).IsFrozen) { // Need to clone TextPointer before moving it. textPointer = textPointer.CreatePointer(); } textPointer.MoveToNextContextPosition(LogicalDirection.Forward); } } if (paragraph != null) { StructuralCache.CurrentFormatContext.DependentMax = (TextPointer)textPointer; } return paragraph; }
/// <summary> /// Re-positions the given position by an integral number of text units, but it does /// not guarantee that position is snapped to TextUnit boundary. /// This method assumes that input position is already snapped to appropriate TextUnit boundary. /// </summary> /// <param name="position">The position to move</param> /// <param name="unit">Text units to step by</param> /// <param name="count">Number of units to step over. Also specifies the direction of moving: /// forward if positive, backward otherwise</param> /// <returns>The actual number of units the position was moved over</returns> private int MovePositionByUnits(ITextPointer position, TextUnit unit, int count) { ITextView textView; int moved = 0; int absCount = (count == int.MinValue) ? int.MaxValue : Math.Abs(count); LogicalDirection direction = (count > 0) ? LogicalDirection.Forward : LogicalDirection.Backward; // This method assumes that position is already snapped to appropriate TextUnit. switch (unit) { case TextUnit.Character: while (moved < absCount) { if (!TextPointerBase.MoveToNextInsertionPosition(position, direction)) { break; } moved++; } break; case TextUnit.Word: while (moved < absCount) { if (!MoveToNextWordBoundary(position, direction)) { break; } moved++; } break; case TextUnit.Format: // Formatting changes can be introduced by elements. Hence it is fair to // assume that formatting boundaries are defined by non-text context. while (moved < absCount) { ITextPointer positionOrig = position.CreatePointer(); // First skip all text in given direction. while (position.GetPointerContext(direction) == TextPointerContext.Text) { if (!position.MoveToNextContextPosition(direction)) { break; } } // Move to next context if (!position.MoveToNextContextPosition(direction)) { break; } // Skip all formatting elements and position the pointer next to text. while (position.GetPointerContext(direction) != TextPointerContext.Text) { if (!position.MoveToNextContextPosition(direction)) { break; } } // If moving backwards, position the pointer at the beginning of formatting range. if (direction == LogicalDirection.Backward) { while (position.GetPointerContext(LogicalDirection.Backward) == TextPointerContext.Text) { if (!position.MoveToNextContextPosition(LogicalDirection.Backward)) { break; } } } if (position.GetPointerContext(direction) != TextPointerContext.None) { moved++; } else { position.MoveToPosition(positionOrig); break; } } // Adjust logical direction to point to the following text (forward or backward movement). // If we don't do this, we'll normalize in the wrong direction and get stuck in a loop // if caller tries to advance again. position.SetLogicalDirection(LogicalDirection.Forward); break; case TextUnit.Line: // Position is snapped to nearest line boundary. But since line information // is based on the layout, position is not changed, if: // a) it is not currently in the view, or // b) containing line cannot be found. textView = _textAdaptor.GetUpdatedTextView(); if (textView != null && textView.IsValid && textView.Contains(position)) { // ITextPointer.MoveToLineBoundary can't handle Table row end positions. // Mimic TextEditor's caret navigation code and move into the preceding // TableCell. if (TextPointerBase.IsAtRowEnd(position)) { position.MoveToNextInsertionPosition(LogicalDirection.Backward); } moved = position.MoveToLineBoundary(count); MoveToInsertionPosition(position, LogicalDirection.Forward); if (moved < 0) { moved = -moved; // Will be reversed below. } } break; case TextUnit.Paragraph: // Utilize TextRange logic to determine paragraph boundaries. ITextRange paragraphRange = new TextRange(position, position); paragraphRange.SelectParagraph(position); while (moved < absCount) { position.MoveToPosition(direction == LogicalDirection.Forward ? paragraphRange.End : paragraphRange.Start); if (!position.MoveToNextInsertionPosition(direction)) { break; } moved++; paragraphRange.SelectParagraph(position); position.MoveToPosition(paragraphRange.Start); // Position it always at the beginning of the paragraph. } break; case TextUnit.Page: // But since page information is based on the layout, position is not changed, if: // a) it is not currently in the view, or // b) containing page cannot be found. // Page movement is possible only in multi-page scenario. textView = _textAdaptor.GetUpdatedTextView(); if (textView != null && textView.IsValid && textView.Contains(position)) { if (textView is MultiPageTextView) { // Get embedded page ITextView for given position. ITextView pageTextView = ((MultiPageTextView)textView).GetPageTextViewFromPosition(position); ReadOnlyCollection<TextSegment> textSegments = pageTextView.TextSegments; while (moved < absCount) { if (textSegments == null || textSegments.Count == 0) { break; } // Move the position to appropriate edge. if (direction == LogicalDirection.Backward) { position.MoveToPosition(textSegments[0].Start); MoveToInsertionPosition(position, LogicalDirection.Backward); } else { position.MoveToPosition(textSegments[textSegments.Count - 1].End); MoveToInsertionPosition(position, LogicalDirection.Forward); } // Try to move the position to the next page. ITextPointer positionTemp = position.CreatePointer(); if (!positionTemp.MoveToNextInsertionPosition(direction)) { break; } else { // MoveToNextInsertionPosition may return 'true' and move the position // in oposite direction. if (direction == LogicalDirection.Forward) { if (positionTemp.CompareTo(position) <= 0) { break; } } else { if (positionTemp.CompareTo(position) >= 0) { break; } } } // Get embedded page ITextView for given position. if (!textView.Contains(positionTemp)) { break; } pageTextView = ((MultiPageTextView)textView).GetPageTextViewFromPosition(positionTemp); textSegments = pageTextView.TextSegments; moved++; } } } break; case TextUnit.Document: // This method assumes that position is already snapped to appropriate TextUnit. break; } return (direction == LogicalDirection.Forward) ? moved : -moved; }
/// <summary> /// Moves the position to the closes unit boundary. /// </summary> private bool MoveToUnitBoundary(ITextPointer position, bool isStart, LogicalDirection direction, TextUnit unit) { bool moved = false; ITextView textView; switch (unit) { case TextUnit.Character: if (!TextPointerBase.IsAtInsertionPosition(position)) { if (TextPointerBase.MoveToNextInsertionPosition(position, direction)) { moved = true; } } break; case TextUnit.Word: if (!IsAtWordBoundary(position)) { if (MoveToNextWordBoundary(position, direction)) { moved = true; } } break; case TextUnit.Format: // Formatting changes can be introduced by elements. Hence it is fair to // assume that formatting boundaries are defined by non-text context. while (position.GetPointerContext(direction) == TextPointerContext.Text) { if (position.MoveToNextContextPosition(direction)) { moved = true; } } // Make sure we end with text on the right, so that later ExpandToEnclosingUnit calls // do the right thing. if (moved && direction == LogicalDirection.Forward) { while (true) { TextPointerContext context = position.GetPointerContext(LogicalDirection.Forward); if (context != TextPointerContext.ElementStart && context != TextPointerContext.ElementEnd) break; position.MoveToNextContextPosition(LogicalDirection.Forward); } } break; case TextUnit.Line: // Positions are snapped to closest line boundaries. But since line information // is based on the layout, positions are not changed, if: // a) they are not currently in the view, or // b) containing line cannot be found. textView = _textAdaptor.GetUpdatedTextView(); if (textView != null && textView.IsValid && textView.Contains(position)) { TextSegment lineRange = textView.GetLineRange(position); if (!lineRange.IsNull) { double newSuggestedX; int linesMoved = 0; if (direction == LogicalDirection.Forward) { ITextPointer nextLineStart = null; if (isStart) { nextLineStart = textView.GetPositionAtNextLine(lineRange.End, Double.NaN, 1, out newSuggestedX, out linesMoved); } if (linesMoved != 0) { lineRange = textView.GetLineRange(nextLineStart); nextLineStart = lineRange.Start; } else { nextLineStart = lineRange.End; } nextLineStart = GetInsertionPosition(nextLineStart, LogicalDirection.Forward); if (position.CompareTo(nextLineStart) != 0) { position.MoveToPosition(nextLineStart); position.SetLogicalDirection(isStart ? LogicalDirection.Forward : LogicalDirection.Backward); moved = true; } } else { ITextPointer previousLineEnd = null; if (!isStart) { previousLineEnd = textView.GetPositionAtNextLine(lineRange.Start, Double.NaN, -1, out newSuggestedX, out linesMoved); } if (linesMoved != 0) { lineRange = textView.GetLineRange(previousLineEnd); previousLineEnd = lineRange.End; } else { previousLineEnd = lineRange.Start; } previousLineEnd = GetInsertionPosition(previousLineEnd, LogicalDirection.Backward); if (position.CompareTo(previousLineEnd) != 0) { position.MoveToPosition(previousLineEnd); position.SetLogicalDirection(isStart ? LogicalDirection.Forward : LogicalDirection.Backward); moved = true; } } } } break; case TextUnit.Paragraph: // Utilize TextRange logic to determine paragraph boundaries. ITextRange textRange = new TextRange(position, position); TextRangeBase.SelectParagraph(textRange, position); if (direction == LogicalDirection.Forward) { ITextPointer nextParagraphStart = textRange.End; if (isStart) { nextParagraphStart = nextParagraphStart.CreatePointer(); if (nextParagraphStart.MoveToNextInsertionPosition(LogicalDirection.Forward)) { TextRangeBase.SelectParagraph(textRange, nextParagraphStart); nextParagraphStart = textRange.Start; } } if (position.CompareTo(nextParagraphStart) != 0) { position.MoveToPosition(nextParagraphStart); position.SetLogicalDirection(isStart ? LogicalDirection.Forward : LogicalDirection.Backward); moved = true; } } else { ITextPointer previousParagraphEnd = textRange.Start; if (!isStart) { previousParagraphEnd = previousParagraphEnd.CreatePointer(); if (previousParagraphEnd.MoveToNextInsertionPosition(LogicalDirection.Backward)) { TextRangeBase.SelectParagraph(textRange, previousParagraphEnd); previousParagraphEnd = textRange.End; } } if (position.CompareTo(previousParagraphEnd) != 0) { position.MoveToPosition(previousParagraphEnd); position.SetLogicalDirection(isStart ? LogicalDirection.Forward : LogicalDirection.Backward); moved = true; } } break; case TextUnit.Page: // Positions are snapped to nearest page boundaries. But since page information // is based on the layout, positions are not changed, if they are not currently in the view. // We need to consider 2 types of scenarios: single page and multi-page. // In case of multi-page scenario, first need to find a page associated with the position. // If page is found, move the start position to the beginning of the first range of that page // and move the end position to the end of the last range of that page. textView = _textAdaptor.GetUpdatedTextView(); if (textView != null && textView.IsValid && textView.Contains(position)) { ITextView pageTextView = textView; if (textView is MultiPageTextView) { // This is "multi page" case. Find page associated with the start position. pageTextView = ((MultiPageTextView)textView).GetPageTextViewFromPosition(position); } ReadOnlyCollection<TextSegment> textSegments = pageTextView.TextSegments; if (textSegments != null && textSegments.Count > 0) { //When comparing, we need to take into account if the pointer is not right at //the end of the page (or beginning) because of normalization if (direction == LogicalDirection.Forward) { while (position.CompareTo(textSegments[textSegments.Count - 1].End) != 0) { if (position.GetPointerContext(LogicalDirection.Forward) != TextPointerContext.ElementEnd) { position.MoveToPosition(textSegments[textSegments.Count - 1].End); moved = true; break; } Invariant.Assert(position.MoveToNextContextPosition(LogicalDirection.Forward)); } MoveToInsertionPosition(position, LogicalDirection.Forward); } else { while (position.CompareTo(textSegments[0].Start) != 0) { if (position.GetPointerContext(LogicalDirection.Backward) != TextPointerContext.ElementStart) { position.MoveToPosition(textSegments[0].Start); moved = true; break; } Invariant.Assert(position.MoveToNextContextPosition(LogicalDirection.Backward)); } MoveToInsertionPosition(position, LogicalDirection.Backward); } } } break; case TextUnit.Document: if (direction == LogicalDirection.Forward) { if (position.CompareTo(GetInsertionPosition(position.TextContainer.End, LogicalDirection.Backward)) != 0) { position.MoveToPosition(position.TextContainer.End); moved = true; } } else { if (position.CompareTo(GetInsertionPosition(position.TextContainer.Start, LogicalDirection.Forward)) != 0) { position.MoveToPosition(position.TextContainer.Start); moved = true; } } break; default: // Unknown unit break; } return moved; }
/// <summary> /// Helper function to move given position to word boundary. TextPointerBase.MoveToNextWordBoundary /// cannot be used directly, because it does not modify LogicalDirection. Because of that, IsAtWordBoundary /// for just moved positions may return FALSE. /// </summary> private static bool MoveToNextWordBoundary(ITextPointer position, LogicalDirection direction) { int moveCounter = 0; ITextPointer startPosition = position.CreatePointer(); // Move the position in the given direction until word boundary is reached. while (position.MoveToNextInsertionPosition(direction)) { moveCounter++; if (IsAtWordBoundary(position)) { break; } // Need to break the loop for weird case when there is no word break in text content. // When the word looks too long, consider end of textRun as a word break. if (moveCounter > 128) // 128 was taken as a random number. Probably not big enough though... { position.MoveToPosition(startPosition); position.MoveToNextContextPosition(direction); break; } } // Note that we always use Forward direction for word orientation. if (moveCounter > 0) { position.SetLogicalDirection(LogicalDirection.Forward); } return moveCounter > 0; }
/// <summary> /// Determine paragraph type at the current TextPointer and /// create it. Only ListItem elements are considered. Any other /// content is skipped. /// </summary> /// <param name="textPointer"> /// TextPointer at which paragraph is to be created /// </param> /// <param name="fEmptyOk"> /// True if empty paragraph is acceptable /// </param> /// <returns> /// BaseParagraph that was created /// </returns> protected override BaseParagraph GetParagraph(ITextPointer textPointer, bool fEmptyOk) { Invariant.Assert(textPointer is TextPointer); BaseParagraph paragraph = null; while (paragraph == null) { TextPointerContext runType = textPointer.GetPointerContext(LogicalDirection.Forward); if (runType == TextPointerContext.ElementStart) { TextElement element = ((TextPointer)textPointer).GetAdjacentElementFromOuterPosition(LogicalDirection.Forward); if (element is ListItem) { // Need to handle visibility collapsed. //Visibility visibility = Retriever.Visibility(treePtr.CPPtr.Element); //if (visibility != Visibility.Collapsed) //{ // para = new //} //else skip the element paragraph = new ListItemParagraph(element, StructuralCache); break; } else if (element is List) { // Need to handle visibility collapsed. //Visibility visibility = Retriever.Visibility(treePtr.CPPtr.Element); //if (visibility != Visibility.Collapsed) //{ // para = new //} //else skip the element paragraph = new ListParagraph(element, StructuralCache); break; } // Skip all elements, which are not valid list item children if (((TextPointer)textPointer).IsFrozen) { // Need to clone TextPointer before moving it. textPointer = textPointer.CreatePointer(); } textPointer.MoveToPosition(element.ElementEnd); } else if (runType == TextPointerContext.ElementEnd) { // End of list, if the same as Owner of associated element // Skip content otherwise if (Element == ((TextPointer)textPointer).Parent) { break; } if (((TextPointer)textPointer).IsFrozen) { // Need to clone TextPointer before moving it. textPointer = textPointer.CreatePointer(); } textPointer.MoveToNextContextPosition(LogicalDirection.Forward); } else { // Skip content if (((TextPointer)textPointer).IsFrozen) { // Need to clone TextPointer before moving it. textPointer = textPointer.CreatePointer(); } textPointer.MoveToNextContextPosition(LogicalDirection.Forward); } } if (paragraph != null) { StructuralCache.CurrentFormatContext.DependentMax = (TextPointer)textPointer; } return(paragraph); }