/// <summary>
        /// Gets start and end offset for a text segment but clamps those values to the start and end 
        /// of a given element.  This way if a large text range is being resolved on a node that only contains
        /// a portion of the text range (such as a paragraph) the result only includes the content in that node.
        /// </summary>
        private void GetTextSegmentValues(TextSegment segment, ITextPointer elementStart, ITextPointer elementEnd, out int startOffset, out int endOffset)
        {
            startOffset = 0;
            endOffset = 0;

            if (elementStart.CompareTo(segment.Start) >= 0)
            {
                // segment starts before the start of the element
                startOffset = 0;
            }
            else
            {
                startOffset = elementStart.GetOffsetToPosition(segment.Start);
            }

            if (elementEnd.CompareTo(segment.End) >= 0)
            {
                endOffset = elementStart.GetOffsetToPosition(segment.End);
            }
            else
            {
                // segment ends after the end of the element
                endOffset = elementStart.GetOffsetToPosition(elementEnd);
            }
        }
Ejemplo n.º 2
0
        /// <summary>
        /// Returns a TextSegment that spans the line on which position is located. 
        /// </summary> 
        /// <param name="paragraph">Paragraph to search</param>
        /// <param name="position">Any oriented text position on the line.</param> 
        private TextSegment GetLineRangeFromPosition(ParagraphResult paragraph, ITextPointer position)
        {
            TextSegment lineRange = TextSegment.Null;
 
            // Each paragraph type is handled differently:
            // a) ContainerParagraph - process nested paragraphs. 
            // b) TextParagraph - find line index of a line containing input text position 
            //    and then return its range.
            // c) TableParagraph - process nested paragraphs. 
            if (paragraph is ContainerParagraphResult)
            {
                // a) ContainerParagraph - process nested paragraphs.
                ReadOnlyCollection<ParagraphResult> nestedParagraphs = ((ContainerParagraphResult)paragraph).Paragraphs; 
                // Paragraphs collection may be null in case of empty List.
                Invariant.Assert(nestedParagraphs != null, "Paragraph collection is null."); 
                if (nestedParagraphs.Count > 0) 
                {
                    lineRange = GetLineRangeFromPosition(nestedParagraphs, _emptyParagraphCollection, position); 
                }
            }
            else if (paragraph is TextParagraphResult)
            { 
                // b) TextParagraph - find line index of a line containing input text position
                //    and then return its range. 
                ReadOnlyCollection<LineResult> lines = ((TextParagraphResult)paragraph).Lines; 
                Invariant.Assert(lines != null, "Lines collection is null");
                if (!((TextParagraphResult)paragraph).HasTextContent) 
                {
                    // Paragraph has no lines.
                    //
 

                    lineRange = new TextSegment(((TextParagraphResult)paragraph).EndPosition, ((TextParagraphResult)paragraph).EndPosition, true); 
                } 
                else
                { 
                    // Get index of the line that contains position.
                    int lineIndex = TextParagraphView.GetLineFromPosition(lines, position);
                    Invariant.Assert(lineIndex >= 0 && lineIndex < lines.Count, "Line not found.");
                    lineRange = new TextSegment(lines[lineIndex].StartPosition, lines[lineIndex].GetContentEndPosition(), true); 
                }
            } 
            else if (paragraph is TableParagraphResult) 
            {
                // c) TableParagraph - process nested paragraphs. 
                ReadOnlyCollection<ParagraphResult> nestedParagraphs = ((TableParagraphResult)paragraph).GetParagraphsFromPosition(position);
                // Paragraphs collection may be null in case of empty List.
                Invariant.Assert(nestedParagraphs != null, "Paragraph collection is null.");
                if (nestedParagraphs.Count > 0) 
                {
                    lineRange = GetLineRangeFromPosition(nestedParagraphs, _emptyParagraphCollection, position); 
                } 
            }
            else if (paragraph is SubpageParagraphResult) 
            {
                SubpageParagraphResult subpageParagraphResult = (SubpageParagraphResult)paragraph;
                ReadOnlyCollection<ColumnResult> columns = subpageParagraphResult.Columns;
                ReadOnlyCollection<ParagraphResult> nestedFloatingElements = subpageParagraphResult.FloatingElements; 
                Invariant.Assert(columns != null, "Column collection is null.");
                Invariant.Assert(nestedFloatingElements != null, "Paragraph collection is null."); 
                if (columns.Count > 0 || nestedFloatingElements.Count > 0) 
                {
                    lineRange = GetLineRangeFromPosition(columns, nestedFloatingElements, position); 
                }
            }
            else if (paragraph is FigureParagraphResult)
            { 
                FigureParagraphResult figureParagraphResult = (FigureParagraphResult)paragraph;
                ReadOnlyCollection<ColumnResult> columns = figureParagraphResult.Columns; 
                ReadOnlyCollection<ParagraphResult> nestedFloatingElements = figureParagraphResult.FloatingElements; 
                Invariant.Assert(columns != null, "Column collection is null.");
                Invariant.Assert(nestedFloatingElements != null, "Paragraph collection is null."); 
                if (columns.Count > 0 || nestedFloatingElements.Count > 0)
                {
                    lineRange = GetLineRangeFromPosition(columns, nestedFloatingElements, position);
                } 
            }
            else if (paragraph is FloaterParagraphResult) 
            { 
                FloaterParagraphResult floaterParagraphResult = (FloaterParagraphResult)paragraph;
                ReadOnlyCollection<ColumnResult> columns = floaterParagraphResult.Columns; 
                ReadOnlyCollection<ParagraphResult> nestedFloatingElements = floaterParagraphResult.FloatingElements;
                Invariant.Assert(columns != null, "Column collection is null.");
                Invariant.Assert(nestedFloatingElements != null, "Paragraph collection is null.");
                if (columns.Count > 0 || nestedFloatingElements.Count > 0) 
                {
                    lineRange = GetLineRangeFromPosition(columns, nestedFloatingElements, position); 
                } 
            }
            else if (paragraph is UIElementParagraphResult) 
            {
                // UIElement paragraph result - return content range between BlockUIContainer.ContentStart and ContentEnd
                BlockUIContainer blockUIContainer = paragraph.Element as BlockUIContainer;
                if (blockUIContainer != null) 
                {
                    lineRange = new TextSegment(blockUIContainer.ContentStart.CreatePointer(LogicalDirection.Forward), blockUIContainer.ContentEnd.CreatePointer(LogicalDirection.Backward)); 
                } 
            }
            return lineRange; 
        }
Ejemplo n.º 3
0
        // Part of ExtendSelectionByMouse method:
        // Identifies words on selection ends.
        private void IdentifyWordsOnSelectionEnds(ITextPointer anchorPosition, ITextPointer cursorPosition, bool forceWordSelection, out TextSegment anchorWordRange, out TextSegment cursorWordRange)
        {
            if (forceWordSelection)
            {
                anchorWordRange = TextPointerBase.GetWordRange(anchorPosition);
                cursorWordRange = TextPointerBase.GetWordRange(cursorPosition, cursorPosition.LogicalDirection);
            }
            else
            {
                // Define whether word adjustment is allowed. Pressing Shift+Control prevents from auto-word expansion.
                bool disableWordExpansion = _textEditor.AutoWordSelection == false || ((Keyboard.Modifiers & ModifierKeys.Shift) != 0 && (Keyboard.Modifiers & ModifierKeys.Control) != 0);

                if (disableWordExpansion)
                {
                    anchorWordRange = new TextSegment(anchorPosition, anchorPosition);
                    cursorWordRange = new TextSegment(cursorPosition, cursorPosition);
                }
                else
                {
                    // Autoword expansion heuristics
                    // -----------------------------

                    // Word autoword heuristics:
                    // a) After active end returned to selected area, autoword expansion on active end is disabled
                    // b) After active end returned to the very first word, expansion on anchor word is disabled either
                    //    We do this though only if selection has crossed initial word boundary at least once.
                    // c) After active end crosses new word, autoword expansion of active end is enabled again

                    // Calculate a word range for anchor position
                    anchorWordRange = TextPointerBase.GetWordRange(anchorPosition);

                    // Check if we re-entering selection or moving outside
                    // and set autoexpansion flags accordingly
                    if (_previousCursorPosition != null &&
                        (anchorPosition.CompareTo(cursorPosition) < 0 && cursorPosition.CompareTo(_previousCursorPosition) < 0 ||
                        _previousCursorPosition.CompareTo(cursorPosition) < 0 && cursorPosition.CompareTo(anchorPosition) < 0))
                    {
                        // Re-entering selection.

                        // Store position of reentering
                        _reenterPosition = cursorPosition.CreatePointer();

                        // When re-entering reaches initial word, disable word expansion on anchor end either
                        if (_anchorWordRangeHasBeenCrossedOnce && anchorWordRange.Contains(cursorPosition))
                        {
                            _allowWordExpansionOnAnchorEnd = false;
                        }
                    }
                    else
                    {
                        // Extending the selection.

                        // Check if we are crossing a boundary of last reentered word to re-enable word expansion on moving end
                        if (_reenterPosition != null)
                        {
                            TextSegment lastReenteredWordRange = TextPointerBase.GetWordRange(_reenterPosition);
                            if (!lastReenteredWordRange.Contains(cursorPosition))
                            {
                                _reenterPosition = null;
                            }
                        }
                    }

                    // Identify expanded range on both ends
                    // 

                    if (anchorWordRange.Contains(cursorPosition) ||
                        anchorWordRange.Contains(cursorPosition.GetInsertionPosition(LogicalDirection.Forward)) ||
                        anchorWordRange.Contains(cursorPosition.GetInsertionPosition(LogicalDirection.Backward)))
                    {
                        // Selection does not cross word boundary, so shrink selection to exact anchor/cursor positions
                        anchorWordRange = new TextSegment(anchorPosition, anchorPosition);
                        cursorWordRange = new TextSegment(cursorPosition, cursorPosition);
                    }
                    else
                    {
                        // Selection crosses word boundary.
                        _anchorWordRangeHasBeenCrossedOnce = true;

                        if (!_allowWordExpansionOnAnchorEnd || //
                            TextPointerBase.IsAtWordBoundary(anchorPosition, /*insideWordDirection:*/LogicalDirection.Forward))
                        {
                            // We collapse anchorPosition in two cases:
                            // If we have been re-entering the initial word before -
                            // then we treat it as an indicator that user wants exact position on anchor end
                            // or
                            // if selection starts exactly on word boundary -
                            // then we should not include the following word (when selection extends backward).
                            //
                            // So in the both cases we collapse anchorWordRange to exact _anchorPosition
                            anchorWordRange = new TextSegment(anchorPosition, anchorPosition);
                        }

                        if (TextPointerBase.IsAfterLastParagraph(cursorPosition) ||
                            TextPointerBase.IsAtWordBoundary(cursorPosition, /*insideWordDirection:*/LogicalDirection.Forward))
                        {
                            cursorWordRange = new TextSegment(cursorPosition, cursorPosition);
                        }
                        else
                        {
                            if (_reenterPosition == null)
                            {
                                // We are not in re-entering mode; expand moving end to word boundary
                                cursorWordRange = TextPointerBase.GetWordRange(cursorPosition, cursorPosition.LogicalDirection);
                            }
                            else
                            {
                                // We are in re-entering mode; use exact moving end position
                                cursorWordRange = new TextSegment(cursorPosition, cursorPosition);
                            }
                        }
                    }
                }
            }
        }
Ejemplo n.º 4
0
            //----------------------------------------------------- 
            //
            //  Private methods
            //
            //----------------------------------------------------- 

            #region Private methods 
 
            /// <summary>
            /// Calculates geometry for ine TextSegment 
            /// </summary>
            /// <param name="geometry">GeometryGroup to add the geometry</param>
            /// <param name="segment">TextSegment</param>
            /// <param name="parentView">TextView to which geometry has to be transformed</param> 
            private void GetSegmentGeometry(GeometryGroup geometry, TextSegment segment, ITextView parentView)
            { 
                List<ITextView> textViews = TextSelectionHelper.GetDocumentPageTextViews(segment); 
                Debug.Assert(textViews != null, "geometry text view not found");
 
                foreach (ITextView view in textViews)
                {
                    Geometry viewGeometry = GetPageGeometry(segment, view, parentView);
                    if (viewGeometry != null) 
                        geometry.Children.Add(viewGeometry);
                } 
 
            }
Ejemplo n.º 5
0
            /// <summary>
            /// Get a geometry for a particular page and transforms it to the parent page
            /// </summary>
            /// <param name="segment">the TextSegment for which geometry we are looking</param> 
            /// <param name="view">the page view</param>
            /// <param name="parentView">the parent page view</param> 
            /// <returns></returns> 
            private Geometry GetPageGeometry(TextSegment segment, ITextView view, ITextView parentView)
            { 
                Debug.Assert((view != null) && (parentView != null), "null text view");
                //in the initial layout update the TextViews might be invalid. This is OK
                //since there will be a second pass
                if (!view.IsValid || !parentView.IsValid) 
                    return null;
 
                //Debug.Assert((view.RenderScope != null) && (parentView.RenderScope != null), "null text view render scope"); 
                if ((view.RenderScope == null) || (parentView.RenderScope == null))
                    return null; 

                Geometry pageGeometry = null;
                pageGeometry = view.GetTightBoundingGeometryFromTextPositions(segment.Start, segment.End);
 
                if (pageGeometry != null)
                { 
                    if (parentView != null) 
                    {
                        Transform additionalTransform = (Transform)view.RenderScope.TransformToVisual(parentView.RenderScope); 
                        if (pageGeometry.Transform != null)
                        {
                            //we need to create geometry group in this case
                            TransformGroup group = new TransformGroup(); 
                            group.Children.Add(pageGeometry.Transform);
                            group.Children.Add(additionalTransform); 
                            pageGeometry.Transform = group; 
                        }
                        else 
                        {
                            //now set the transformation
                            pageGeometry.Transform = additionalTransform;
                        } 
                    }
                } 
 
                return pageGeometry;
            } 
Ejemplo n.º 6
0
            // Constructor.
            internal AnnotationHighlightChangedEventArgs(ITextPointer start, ITextPointer end) 
            { 
                TextSegment[] rangeArray = new TextSegment[] { new TextSegment(start, end) };
 
                _ranges = new ReadOnlyCollection<TextSegment>(rangeArray);
            }
Ejemplo n.º 7
0
            /// <summary> 
            /// Creates a new HighlightSegment with a list of owners
            /// </summary>
            /// <param name="start">start segment position</param>
            /// <param name="end">end segment position</param> 
            /// <param name="owners">owners list</param>
            private void Init(ITextPointer start, ITextPointer end, IList<IHighlightRange> owners) 
            { 
                Debug.Assert(start != null, "start pointer is null");
                Debug.Assert(end != null, "end pointer is null"); 
                Debug.Assert(owners != null, "null owners list");
                Debug.Assert(owners.Count > 0, "empty owners list");
                for (int i = 0; i < owners.Count; i++)
                    Debug.Assert(owners[i] != null, "null owner"); 

                _segment = new TextSegment(start, end); 
                IsHitTestVisible = false; 
                object textContainer = start.TextContainer;
                _isFixedContainer = textContainer is FixedTextContainer || textContainer is DocumentSequenceTextContainer; 

                //check for tables, figures and floaters and extract the content
                GetContent();
            } 
        // Returns a normalized line range from TextView for a given position.
        // Note: In current contract, line range returned by TextView.GetLineRange() is not guaranteed to be normalized.
        // This helper does appropriate correction and returns a normalized line range.
        internal static TextSegment GetNormalizedLineRange(ITextView textView, ITextPointer position)
        {
            TextSegment lineRange = textView.GetLineRange(position);
            if (lineRange.IsNull)
            {
                if (!typeof(BlockUIContainer).IsAssignableFrom(position.ParentType))
                {
                    return lineRange;
                }

                ITextPointer lineStart = position.CreatePointer(LogicalDirection.Forward);
                lineStart.MoveToElementEdge(ElementEdge.AfterStart);
                ITextPointer lineEnd = position.CreatePointer(LogicalDirection.Backward);
                lineEnd.MoveToElementEdge(ElementEdge.BeforeEnd);
                lineRange = new TextSegment(lineStart, lineEnd);
                return lineRange;
            }

            // Normalize line range
            ITextRange textRange = new TextRange(lineRange.Start, lineRange.End);
            return new TextSegment(textRange.Start, textRange.End);
        }
Ejemplo n.º 9
0
        //-----------------------------------------------------
        // 
        //  Private Methods 
        //
        //----------------------------------------------------- 

        #region Private Methods

        /// <summary> 
        /// Checks if the input range overlaps existing segments and splits them if needed
        /// </summary> 
        /// <param name="highlightRange">range data</param> 
        /// <param name="invalidateStart">start pointer of the invalid area</param>
        /// <param name="invalidateEnd">end pointer of the invalid area</param> 
        /// <remarks>This method requires ordered nonoverlaped input segments. Otherwise it will assert.</remarks>
        private void ProcessOverlapingSegments(IHighlightRange highlightRange, out ITextPointer invalidateStart, out ITextPointer invalidateEnd)
        {
            Debug.Assert(highlightRange != null, " null highlight range"); 
            ReadOnlyCollection<TextSegment> rangeSegments = highlightRange.Range.TextSegments;
            Debug.Assert((rangeSegments != null) && (rangeSegments.Count > 0), "invalid rangeSegments"); 
 

            invalidateStart = null; 
            invalidateEnd = null;
            int ind = 0;
            IEnumerator<TextSegment> rangeEnumerator = rangeSegments.GetEnumerator();
            TextSegment rangeSegment = rangeEnumerator.MoveNext() ? rangeEnumerator.Current : TextSegment.Null; 
            while ((ind < _segments.Count) && (!rangeSegment.IsNull))
            { 
                HighlightSegment highlightSegment = _segments[ind]; 
                Debug.Assert(highlightSegment != null, "null highlight segment");
 
                if (highlightSegment.Segment.Start.CompareTo(rangeSegment.Start) <= 0)
                {
                    if (highlightSegment.Segment.End.CompareTo(rangeSegment.Start) > 0)
                    { 
                        //split highlightSegment
                        //the split method is smart enough to take care of edge cases - point on start/end of the 
                        //segment, points outside the segment etc 
                        IList<HighlightSegment> res = highlightSegment.Split(rangeSegment.Start, rangeSegment.End, highlightRange);
 
                        //if the result does not contain the original segment we need to clear the owners
                        if (!res.Contains(highlightSegment))
                            highlightSegment.ClearOwners();
 
                        _segments.Remove(highlightSegment);
                        _segments.InsertRange(ind, res); 
                        ind = ind + res.Count - 1; 

                        //check if we need to move to next range segment 
                        if (rangeSegment.End.CompareTo(highlightSegment.Segment.End) <= 0)
                        {
                            //get next one
                            bool next = rangeEnumerator.MoveNext(); 
                            Debug.Assert(rangeEnumerator.Current.IsNull || !next ||
                                         (rangeSegment.End.CompareTo(rangeEnumerator.Current.Start) <= 0), 
                                         "overlapped range segments"); 
                            rangeSegment = next ? rangeEnumerator.Current : TextSegment.Null;
                        } 
                        else
                        {
                            //get the piece that is left
                            rangeSegment = new TextSegment(highlightSegment.Segment.End, rangeSegment.End); 
                        }
 
                        //set invalidateStart if needed 
                        if (invalidateStart == null)
                            invalidateStart = highlightSegment.Segment.Start; 

                    }
                    else
                    { 
                        //move to next highlightsegment
                        ind++; 
                    } 
                }
                else 
                {
                    //set invalidateStart if needed
                    if (invalidateStart == null)
                        invalidateStart = rangeSegment.Start; 

                    if (rangeSegment.End.CompareTo(highlightSegment.Segment.Start) > 0) 
                    { 
                        //add the piece before the highlight segment
                        HighlightSegment temp = new HighlightSegment(rangeSegment.Start, highlightSegment.Segment.Start, highlightRange); 
                        _segments.Insert(ind++, temp);

                        //now our current segment is the rest of the range segment
                        rangeSegment = new TextSegment(highlightSegment.Segment.Start, rangeSegment.End); 

                    } 
                    else 
                    {
                        //just insert this range segment - it does not cover any highlight segnments. Increment ind 
                        //so it points to the same highlight segment
                        _segments.Insert(ind++, new HighlightSegment(rangeSegment.Start, rangeSegment.End, highlightRange));
                        //get next range segment
                        rangeSegment = rangeEnumerator.MoveNext() ? rangeEnumerator.Current : TextSegment.Null; 
                    }
 
                } 
            }
 
            //
            if (!rangeSegment.IsNull)
            {
                if (invalidateStart == null) 
                    invalidateStart = rangeSegment.Start;
                _segments.Insert(ind++, new HighlightSegment(rangeSegment.Start, rangeSegment.End, highlightRange)); 
            } 

            //check if there are more rangeSegments 
            while (rangeEnumerator.MoveNext())
            {
                _segments.Insert(ind++, new HighlightSegment(rangeEnumerator.Current.Start, rangeEnumerator.Current.End, highlightRange));
            } 

            //set invalidateEnd 
            if (invalidateStart != null) 
            {
                if (ind == _segments.Count) ind--; 
                invalidateEnd = _segments[ind].Segment.End;
            }
        }
Ejemplo n.º 10
0
        // Helper function used in DeleteContent for clearing TableCell contents 
        private static void ClearTableCells(TextSegment textSegment)
        { 
            TableCell cell = GetTableCellFromPosition((TextPointer)textSegment.Start); 
            TextPointer end = ((TextPointer)textSegment.End).GetNextInsertionPosition(LogicalDirection.Backward);
            while (cell != null) 
            {
                cell.Blocks.Clear();
                cell.Blocks.Add(new Paragraph());
 
                TextPointer cellEnd = cell.ElementEnd;
                if (cellEnd.CompareTo(end) < 0 && 
                    cellEnd.GetPointerContext(LogicalDirection.Forward) == TextPointerContext.ElementStart) 
                {
                    cell = (TableCell)cellEnd.GetAdjacentElement(LogicalDirection.Forward); 
                }
                else
                {
                    cell = null; 
                }
            } 
        } 
Ejemplo n.º 11
0
        /// <summary> 
        /// Gets a list of ITextViews spanned by this text segment
        /// </summary> 
        /// <param name="segment">the text segment</param>
        /// <returns>the TextViews list</returns>
        internal static List<ITextView> GetDocumentPageTextViews(TextSegment segment)
        { 
            List<ITextView> res = null;
            int startPageNumber, endPageNumber; 
 
            //revert the logical direction of the pointers
            ITextPointer start = segment.Start.CreatePointer(LogicalDirection.Forward); 
            ITextPointer end = segment.End.CreatePointer(LogicalDirection.Backward);

            DependencyObject content = start.TextContainer.Parent as DependencyObject;
            if (content != null) 
            {
                FlowDocumentScrollViewer scrollViewer = PathNode.GetParent(content) as FlowDocumentScrollViewer; 
                if (scrollViewer != null) 
                {
                    IServiceProvider provider = scrollViewer.ScrollViewer.Content as IServiceProvider; 
                    Invariant.Assert(provider != null, "FlowDocumentScrollViewer should be an IServiceProvider.");
                    res = new List<ITextView>(1);
                    res.Add(provider.GetService(typeof(ITextView)) as ITextView);
                    return res; 
                }
            } 
 
            IDocumentPaginatorSource idp = GetPointerPage(start, out startPageNumber);
            DynamicDocumentPaginator ddp = idp.DocumentPaginator as DynamicDocumentPaginator; 
            endPageNumber = ddp != null ? ddp.GetPageNumber((ContentPosition)end) : -1;

            if (startPageNumber == -1 || endPageNumber == -1)
            { 
                // If either page couldn't be found, we return an empty list.  This
                // could be caused by a failure in paginating the document. 
                res = new List<ITextView>(0); 
            }
            else if (startPageNumber == endPageNumber) 
            {
                res = ProcessSinglePage(idp, startPageNumber);
            }
            else 
            {
                res = ProcessMultiplePages(idp, startPageNumber, endPageNumber); 
            } 

            return res; 
        }
 // Token: 0x06003C06 RID: 15366 RVA: 0x00115000 File Offset: 0x00113200
 internal TextSegment(ITextPointer startPosition, ITextPointer endPosition)
 {
     this = new TextSegment(startPosition, endPosition, false);
 }
Ejemplo n.º 13
0
            //------------------------------------------------------
            //
            //  Private Methods
            //
            //------------------------------------------------------

            #region Private Methods

            private void AddMultipleCompositionLines(ITextPointer start, ITextPointer end)
            {
                // Initalize the start/end line pointer
                ITextPointer startLinePointer = start;
                ITextPointer endLinePointer   = startLinePointer;

                // Get all composition lines that includes the start/end pointer
                while (endLinePointer.CompareTo(end) < 0)
                {
                    TextSegment textSegment = _textView.GetLineRange(endLinePointer);

                    if (textSegment.IsNull)
                    {
                        // endLinePointer is not within the TextView's definition of a line.
                        // Skip ahead to text on the next iteration.
                        startLinePointer = endLinePointer;
                    }
                    else
                    {
                        Debug.Assert(start.CompareTo(startLinePointer) <= 0, "The start pointer is positioned after the composition start line pointer!");

                        if (startLinePointer.CompareTo(textSegment.Start) < 0)
                        {
                            // Update the start line pointer
                            startLinePointer = textSegment.Start;
                        }

                        if (endLinePointer.CompareTo(textSegment.End) < 0)
                        {
                            if (end.CompareTo(textSegment.End) < 0)
                            {
                                // Update the end line pointer
                                endLinePointer = end.CreatePointer();
                            }
                            else
                            {
                                // Update the end line pointer
                                endLinePointer = textSegment.End.CreatePointer(LogicalDirection.Backward);
                            }
                        }
                        else
                        {
                            Debug.Assert(endLinePointer.CompareTo(textSegment.End) == 0, "The end line pointer is positioned after the composition text range end pointer!");
                        }

                        // Get the rectangle for start/end position
                        Rect startRect = _textView.GetRectangleFromTextPosition(startLinePointer);
                        Rect endRect   = _textView.GetRectangleFromTextPosition(endLinePointer);

                        // Add the composition line to be rendered
                        _compositionLines.Add(new CompositionLine(startRect, endRect, _textServicesDisplayAttribute.GetLineColor(startLinePointer)));

                        startLinePointer = textSegment.End.CreatePointer(LogicalDirection.Forward);
                    }

                    // Move the start pointer to the next text line. startLinePointer must be a pointer to start
                    // text.
                    while ((startLinePointer.GetPointerContext(LogicalDirection.Forward) != TextPointerContext.None) &&
                           (startLinePointer.GetPointerContext(LogicalDirection.Forward) != TextPointerContext.Text))
                    {
                        startLinePointer.MoveToNextContextPosition(LogicalDirection.Forward);
                    }
                    endLinePointer = startLinePointer;
                }
            }
 // Token: 0x0600860E RID: 34318 RVA: 0x0024B92A File Offset: 0x00249B2A
 public TextRange(TextSegment textSegment)
 {
     this = new WinRTSpellerInterop.TextRange((int)textSegment.StartPosition, (int)textSegment.Length);
 }