Ejemplo n.º 1
0
        // 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);
        }
Ejemplo n.º 2
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;
        }
        /// <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;
        }
Ejemplo n.º 6
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; 
        }
Ejemplo n.º 7
0
        /// <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;
        }
Ejemplo n.º 8
0
        /// <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;
        }
Ejemplo n.º 9
0
        /// <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;
        }
Ejemplo n.º 10
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);
        }