/// <summary>
        /// Retrieves the visible ranges of text.
        /// </summary>
        /// <returns>The ranges of text that are visible, or possibly an empty array if there is
        /// no visible text whatsoever.  Text in the range may still be obscured by an overlapping
        /// window.  Also, portions
        /// of the range at the beginning, in the middle, or at the end may not be visible
        /// because they are scrolled off to the side.
        /// Providers should ensure they return at most a range from the beginning of the first
        /// line with portions visible through the end of the last line with portions visible.</returns>
        ITextRangeProvider[] ITextProvider.GetVisibleRanges()
        {
            ITextRangeProvider[] ranges   = null;
            ITextView            textView = GetUpdatedTextView();

            if (textView != null)
            {
                List <TextSegment> visibleTextSegments = new List <TextSegment>();

                // Get visible portion of the document.
                //



                if (textView is MultiPageTextView)
                {
                    // For MultiPageTextView assume that all current pages are entirely visible.
                    visibleTextSegments.AddRange(textView.TextSegments);
                }
                else
                {
                    // For all others TextViews get visible rectangle and hittest TopLeft and
                    // BottomRight points to retrieve visible range.
                    // Find out the bounds of the area visible through all nested scroll areas
                    Rect visibleRect = GetVisibleRectangle(textView);
                    if (!visibleRect.IsEmpty)
                    {
                        ITextPointer visibleStart = textView.GetTextPositionFromPoint(visibleRect.TopLeft, true);
                        ITextPointer visibleEnd   = textView.GetTextPositionFromPoint(visibleRect.BottomRight, true);
                        visibleTextSegments.Add(new TextSegment(visibleStart, visibleEnd, true));
                    }
                }

                // Create collection of TextRangeProviders for visible ranges.
                if (visibleTextSegments.Count > 0)
                {
                    ranges = new ITextRangeProvider[visibleTextSegments.Count];
                    for (int i = 0; i < visibleTextSegments.Count; i++)
                    {
                        ranges[i] = new TextRangeAdaptor(this, visibleTextSegments[i].Start, visibleTextSegments[i].End, _textPeer);
                    }
                }
            }
            // If no text is visible in the control, return the degenerate text range
            // (empty range) at the beginning of the document.
            if (ranges == null)
            {
                ranges = new ITextRangeProvider[] { new TextRangeAdaptor(this, _textContainer.Start, _textContainer.Start, _textPeer) };
            }
            return(ranges);
        }
Beispiel #2
0
        // Token: 0x060065D2 RID: 26066 RVA: 0x001C8A94 File Offset: 0x001C6C94
        ITextRangeProvider ITextProvider.RangeFromPoint(Point location)
        {
            TextRangeAdaptor textRangeAdaptor = null;
            ITextView        updatedTextView  = this.GetUpdatedTextView();

            if (updatedTextView != null)
            {
                location = this.ScreenToClient(location, updatedTextView.RenderScope);
                ITextPointer textPositionFromPoint = updatedTextView.GetTextPositionFromPoint(location, true);
                if (textPositionFromPoint != null)
                {
                    textRangeAdaptor = new TextRangeAdaptor(this, textPositionFromPoint, textPositionFromPoint, this._textPeer);
                }
            }
            if (textRangeAdaptor == null)
            {
                throw new ArgumentException(SR.Get("TextProvider_InvalidPoint"));
            }
            return(textRangeAdaptor);
        }
Beispiel #3
0
        /// <summary>
        /// Finds the degenerate range nearest to a screen coordinate.
        /// </summary>
        /// <param name="location">The location in screen coordinates.
        /// The provider should check that the coordinates are within the client
        /// area of the provider, and should throw an InvalidOperation exception
        /// if they are not.</param>
        /// <returns>A degenerate range nearest the specified location.</returns>
        ITextRangeProvider ITextProvider.RangeFromPoint(Point location)
        {
            TextRangeAdaptor range    = null;
            ITextView        textView = GetUpdatedTextView();

            if (textView != null)
            {
                // Convert the screen point to the element space coordinates.
                location = ScreenToClient(location, textView.RenderScope);
                ITextPointer position = textView.GetTextPositionFromPoint(location, true);
                if (position != null)
                {
                    range = new TextRangeAdaptor(this, position, position, _textPeer);
                }
            }
            if (range == null)
            {
                throw new ArgumentException(SR.Get(SRID.TextProvider_InvalidPoint));
            }
            return(range);
        }
Beispiel #4
0
        // Token: 0x060065D0 RID: 26064 RVA: 0x001C8810 File Offset: 0x001C6A10
        ITextRangeProvider[] ITextProvider.GetVisibleRanges()
        {
            ITextRangeProvider[] array           = null;
            ITextView            updatedTextView = this.GetUpdatedTextView();

            if (updatedTextView != null)
            {
                List <TextSegment> list = new List <TextSegment>();
                if (updatedTextView is MultiPageTextView)
                {
                    list.AddRange(updatedTextView.TextSegments);
                }
                else
                {
                    Rect visibleRectangle = this.GetVisibleRectangle(updatedTextView);
                    if (!visibleRectangle.IsEmpty)
                    {
                        ITextPointer textPositionFromPoint  = updatedTextView.GetTextPositionFromPoint(visibleRectangle.TopLeft, true);
                        ITextPointer textPositionFromPoint2 = updatedTextView.GetTextPositionFromPoint(visibleRectangle.BottomRight, true);
                        list.Add(new TextSegment(textPositionFromPoint, textPositionFromPoint2, true));
                    }
                }
                if (list.Count > 0)
                {
                    array = new ITextRangeProvider[list.Count];
                    for (int i = 0; i < list.Count; i++)
                    {
                        array[i] = new TextRangeAdaptor(this, list[i].Start, list[i].End, this._textPeer);
                    }
                }
            }
            if (array == null)
            {
                array = new ITextRangeProvider[]
                {
                    new TextRangeAdaptor(this, this._textContainer.Start, this._textContainer.Start, this._textPeer)
                };
            }
            return(array);
        }
Beispiel #5
0
        //-------------------------------------------------------------------
        //
        //  Internal Methods
        //
        //-------------------------------------------------------------------

        #region Internal Methods

        /// <summary>
        /// Retrieves the bounding rectangles for the text lines of a given range.
        /// </summary>
        /// <param name="start">Start of range to measure</param>
        /// <param name="end">End of range to measure</param>
        /// <param name="clipToView">Specifies whether the caller wants the full bounds (false) or the bounds of visible portions
        /// of the viewable line only ('true')</param>
        /// <param name="transformToScreen">Requests the results in screen coordinates</param>
        /// <returns>An array of bounding rectangles for each line or portion of a line within the client area of the text provider.
        /// No bounding rectangles will be returned for lines that are empty or scrolled out of view.  Note that even though a
        /// bounding rectangle is returned the corresponding text may not be visible due to overlapping windows.
        /// This will not return null, but may return an empty array.</returns>
        internal Rect[] GetBoundingRectangles(ITextPointer start, ITextPointer end, bool clipToView, bool transformToScreen)
        {
            ITextView textView = GetUpdatedTextView();

            if (textView == null)
            {
                return(new Rect[0]);
            }

            // If start/end positions are not in the visible range, move them to the first/last visible positions.
            ReadOnlyCollection <TextSegment> textSegments = textView.TextSegments;

            if (textSegments.Count > 0)
            {
                if (!textView.Contains(start) && start.CompareTo(textSegments[0].Start) < 0)
                {
                    start = textSegments[0].Start.CreatePointer();;
                }
                if (!textView.Contains(end) && end.CompareTo(textSegments[textSegments.Count - 1].End) > 0)
                {
                    end = textSegments[textSegments.Count - 1].End.CreatePointer();
                }
            }
            if (!textView.Contains(start) || !textView.Contains(end))
            {
                return(new Rect[0]);
            }

            TextRangeAdaptor.MoveToInsertionPosition(start, LogicalDirection.Forward);
            TextRangeAdaptor.MoveToInsertionPosition(end, LogicalDirection.Backward);

            Rect visibleRect = Rect.Empty;

            if (clipToView)
            {
                visibleRect = GetVisibleRectangle(textView);
                // If clipping into view and visible rect is empty, return.
                if (visibleRect.IsEmpty)
                {
                    return(new Rect[0]);
                }
            }

            List <Rect>  rectangles = new List <Rect>();
            ITextPointer position   = start.CreatePointer();

            while (position.CompareTo(end) < 0)
            {
                TextSegment lineRange = textView.GetLineRange(position);
                if (!lineRange.IsNull)
                {
                    // Since range is limited to just one line, GetTightBoundingGeometry will return tight bounding
                    // rectangle for given range. It will also work correctly with bidi text.
                    ITextPointer first    = (lineRange.Start.CompareTo(start) <= 0) ? start : lineRange.Start;
                    ITextPointer last     = (lineRange.End.CompareTo(end) >= 0) ? end : lineRange.End;
                    Rect         lineRect = Rect.Empty;
                    Geometry     geometry = textView.GetTightBoundingGeometryFromTextPositions(first, last);
                    if (geometry != null)
                    {
                        lineRect = geometry.Bounds;
                        if (clipToView)
                        {
                            lineRect.Intersect(visibleRect);
                        }
                        if (!lineRect.IsEmpty)
                        {
                            if (transformToScreen)
                            {
                                lineRect = new Rect(ClientToScreen(lineRect.TopLeft, textView.RenderScope), ClientToScreen(lineRect.BottomRight, textView.RenderScope));
                            }
                            rectangles.Add(lineRect);
                        }
                    }
                }
                if (position.MoveToLineBoundary(1) == 0)
                {
                    position = end;
                }
            }
            return(rectangles.ToArray());
        }
Beispiel #6
0
        /// <summary>
        /// Retrieves the range of a child object.
        /// </summary>
        /// <param name="childElementProvider">The child element.  A provider should check that the
        /// passed element is a child of the text container, and should throw an
        /// InvalidOperationException if it is not.</param>
        /// <returns>A range that spans the child element.</returns>
        ITextRangeProvider ITextProvider.RangeFromChild(IRawElementProviderSimple childElementProvider)
        {
            if (childElementProvider == null)
            {
                throw new ArgumentNullException("childElementProvider");
            }

            // Retrieve DependencyObject from AutomationElement
            DependencyObject childElement;

            if (_textPeer is TextAutomationPeer)
            {
                childElement = ((TextAutomationPeer)_textPeer).ElementFromProvider(childElementProvider);
            }
            else
            {
                childElement = ((ContentTextAutomationPeer)_textPeer).ElementFromProvider(childElementProvider);
            }

            TextRangeAdaptor range = null;

            if (childElement != null)
            {
                ITextPointer rangeStart = null;
                ITextPointer rangeEnd   = null;

                // Retrieve start and end positions for given element.
                // If element is TextElement, retrieve its Element Start and End positions.
                // If element is UIElement hosted by UIContainer (Inlien of Block),
                // retrieve content Start and End positions of the container.
                // Otherwise scan ITextContainer to find a range for given element.
                if (childElement is TextElement)
                {
                    rangeStart = ((TextElement)childElement).ElementStart;
                    rangeEnd   = ((TextElement)childElement).ElementEnd;
                }
                else
                {
                    DependencyObject parent = LogicalTreeHelper.GetParent(childElement);
                    if (parent is InlineUIContainer || parent is BlockUIContainer)
                    {
                        rangeStart = ((TextElement)parent).ContentStart;
                        rangeEnd   = ((TextElement)parent).ContentEnd;
                    }
                    else
                    {
                        ITextPointer position = _textContainer.Start.CreatePointer();
                        while (position.CompareTo(_textContainer.End) < 0)
                        {
                            TextPointerContext context = position.GetPointerContext(LogicalDirection.Forward);
                            if (context == TextPointerContext.ElementStart)
                            {
                                if (childElement == position.GetAdjacentElement(LogicalDirection.Forward))
                                {
                                    rangeStart = position.CreatePointer(LogicalDirection.Forward);
                                    position.MoveToElementEdge(ElementEdge.AfterEnd);
                                    rangeEnd = position.CreatePointer(LogicalDirection.Backward);
                                    break;
                                }
                            }
                            else if (context == TextPointerContext.EmbeddedElement)
                            {
                                if (childElement == position.GetAdjacentElement(LogicalDirection.Forward))
                                {
                                    rangeStart = position.CreatePointer(LogicalDirection.Forward);
                                    position.MoveToNextContextPosition(LogicalDirection.Forward);
                                    rangeEnd = position.CreatePointer(LogicalDirection.Backward);
                                    break;
                                }
                            }
                            position.MoveToNextContextPosition(LogicalDirection.Forward);
                        }
                    }
                }
                // Create range
                if (rangeStart != null && rangeEnd != null)
                {
                    range = new TextRangeAdaptor(this, rangeStart, rangeEnd, _textPeer);
                }
            }
            if (range == null)
            {
                throw new InvalidOperationException(SR.Get(SRID.TextProvider_InvalidChildElement));
            }
            return(range);
        }
Beispiel #7
0
        // Token: 0x060065C4 RID: 26052 RVA: 0x001C8254 File Offset: 0x001C6454
        internal Rect[] GetBoundingRectangles(ITextPointer start, ITextPointer end, bool clipToView, bool transformToScreen)
        {
            ITextView updatedTextView = this.GetUpdatedTextView();

            if (updatedTextView == null)
            {
                return(new Rect[0]);
            }
            ReadOnlyCollection <TextSegment> textSegments = updatedTextView.TextSegments;

            if (textSegments.Count > 0)
            {
                if (!updatedTextView.Contains(start) && start.CompareTo(textSegments[0].Start) < 0)
                {
                    start = textSegments[0].Start.CreatePointer();
                }
                if (!updatedTextView.Contains(end) && end.CompareTo(textSegments[textSegments.Count - 1].End) > 0)
                {
                    end = textSegments[textSegments.Count - 1].End.CreatePointer();
                }
            }
            if (!updatedTextView.Contains(start) || !updatedTextView.Contains(end))
            {
                return(new Rect[0]);
            }
            TextRangeAdaptor.MoveToInsertionPosition(start, LogicalDirection.Forward);
            TextRangeAdaptor.MoveToInsertionPosition(end, LogicalDirection.Backward);
            Rect rect = Rect.Empty;

            if (clipToView)
            {
                rect = this.GetVisibleRectangle(updatedTextView);
                if (rect.IsEmpty)
                {
                    return(new Rect[0]);
                }
            }
            List <Rect>  list        = new List <Rect>();
            ITextPointer textPointer = start.CreatePointer();

            while (textPointer.CompareTo(end) < 0)
            {
                TextSegment lineRange = updatedTextView.GetLineRange(textPointer);
                if (!lineRange.IsNull)
                {
                    ITextPointer startPosition = (lineRange.Start.CompareTo(start) <= 0) ? start : lineRange.Start;
                    ITextPointer endPosition   = (lineRange.End.CompareTo(end) >= 0) ? end : lineRange.End;
                    Rect         item          = Rect.Empty;
                    Geometry     tightBoundingGeometryFromTextPositions = updatedTextView.GetTightBoundingGeometryFromTextPositions(startPosition, endPosition);
                    if (tightBoundingGeometryFromTextPositions != null)
                    {
                        item = tightBoundingGeometryFromTextPositions.Bounds;
                        if (clipToView)
                        {
                            item.Intersect(rect);
                        }
                        if (!item.IsEmpty)
                        {
                            if (transformToScreen)
                            {
                                item = new Rect(this.ClientToScreen(item.TopLeft, updatedTextView.RenderScope), this.ClientToScreen(item.BottomRight, updatedTextView.RenderScope));
                            }
                            list.Add(item);
                        }
                    }
                }
                if (textPointer.MoveToLineBoundary(1) == 0)
                {
                    textPointer = end;
                }
            }
            return(list.ToArray());
        }
Beispiel #8
0
        // Token: 0x060065D1 RID: 26065 RVA: 0x001C8918 File Offset: 0x001C6B18
        ITextRangeProvider ITextProvider.RangeFromChild(IRawElementProviderSimple childElementProvider)
        {
            if (childElementProvider == null)
            {
                throw new ArgumentNullException("childElementProvider");
            }
            DependencyObject dependencyObject;

            if (this._textPeer is TextAutomationPeer)
            {
                dependencyObject = ((TextAutomationPeer)this._textPeer).ElementFromProvider(childElementProvider);
            }
            else
            {
                dependencyObject = ((ContentTextAutomationPeer)this._textPeer).ElementFromProvider(childElementProvider);
            }
            TextRangeAdaptor textRangeAdaptor = null;

            if (dependencyObject != null)
            {
                ITextPointer textPointer  = null;
                ITextPointer textPointer2 = null;
                if (dependencyObject is TextElement)
                {
                    textPointer  = ((TextElement)dependencyObject).ElementStart;
                    textPointer2 = ((TextElement)dependencyObject).ElementEnd;
                }
                else
                {
                    DependencyObject parent = LogicalTreeHelper.GetParent(dependencyObject);
                    if (parent is InlineUIContainer || parent is BlockUIContainer)
                    {
                        textPointer  = ((TextElement)parent).ContentStart;
                        textPointer2 = ((TextElement)parent).ContentEnd;
                    }
                    else
                    {
                        ITextPointer textPointer3 = this._textContainer.Start.CreatePointer();
                        while (textPointer3.CompareTo(this._textContainer.End) < 0)
                        {
                            TextPointerContext pointerContext = textPointer3.GetPointerContext(LogicalDirection.Forward);
                            if (pointerContext == TextPointerContext.ElementStart)
                            {
                                if (dependencyObject == textPointer3.GetAdjacentElement(LogicalDirection.Forward))
                                {
                                    textPointer = textPointer3.CreatePointer(LogicalDirection.Forward);
                                    textPointer3.MoveToElementEdge(ElementEdge.AfterEnd);
                                    textPointer2 = textPointer3.CreatePointer(LogicalDirection.Backward);
                                    break;
                                }
                            }
                            else if (pointerContext == TextPointerContext.EmbeddedElement && dependencyObject == textPointer3.GetAdjacentElement(LogicalDirection.Forward))
                            {
                                textPointer = textPointer3.CreatePointer(LogicalDirection.Forward);
                                textPointer3.MoveToNextContextPosition(LogicalDirection.Forward);
                                textPointer2 = textPointer3.CreatePointer(LogicalDirection.Backward);
                                break;
                            }
                            textPointer3.MoveToNextContextPosition(LogicalDirection.Forward);
                        }
                    }
                }
                if (textPointer != null && textPointer2 != null)
                {
                    textRangeAdaptor = new TextRangeAdaptor(this, textPointer, textPointer2, this._textPeer);
                }
            }
            if (textRangeAdaptor == null)
            {
                throw new InvalidOperationException(SR.Get("TextProvider_InvalidChildElement"));
            }
            return(textRangeAdaptor);
        }