Esempio n. 1
0
        /*
         * Code used to trim text segments for alternative display of sticky note anchors
         *
         * /// <summary>
         * /// ctor that initializes the TextSegments array by cloning and trimming the input segment Array
         * /// </summary>
         * /// <param name="segments">input segment</param>
         * /// <remarks>This is used to convert a TextRange into TextAnchor.
         * /// Input segments must be ordered and non overlapping</remarks>
         * internal TextAnchor(IList<TextSegment> segments)
         * {
         *  if (segments == null)
         *      return;
         *
         *  ITextPointer lastPointer = null;
         *  for (int i = 0; i < segments.Count; i++)
         *  {
         *      Invariant.Assert((lastPointer == null) || (lastPointer.CompareTo(segments[i].Start) <= 0), "overlapped segments found");
         *      TextSegment newSegment = TextAnchor.Trim(segments[i]);
         *      if (newSegment.IsNull)
         *          continue;
         *
         *      _segments.Add(newSegment);
         *      lastPointer = newSegment.End;
         *  }
         * }
         */

        #endregion Constructors

        //------------------------------------------------------
        //
        //  Public Methods
        //
        //------------------------------------------------------

        #region Public Methods

        /// <summary>
        /// Determines if the text pointer is contained by one of the
        /// anchor's TextSegment.s
        /// </summary>
        /// <param name="textPointer">text pointer to test</param>
        internal bool Contains(ITextPointer textPointer)
        {
            if (textPointer == null)
            {
                throw new ArgumentNullException("textPointer");
            }

            if (textPointer.TextContainer != this.Start.TextContainer)
            {
                throw new ArgumentException(SR.Get(SRID.NotInAssociatedTree, "textPointer"));
            }

            // Correct position normalization on range boundary so that
            // our test would not depend on what side of formatting tags
            // pointer is located.
            if (textPointer.CompareTo(this.Start) < 0)
            {
                textPointer = textPointer.GetInsertionPosition(LogicalDirection.Forward);
            }
            else if (textPointer.CompareTo(this.End) > 0)
            {
                textPointer = textPointer.GetInsertionPosition(LogicalDirection.Backward);
            }

            // Check if at least one segment contains this position.
            for (int i = 0; i < _segments.Count; i++)
            {
                if (_segments[i].Contains(textPointer))
                {
                    return(true);
                }
            }

            return(false);
        }
Esempio n. 2
0
 // Token: 0x06006761 RID: 26465 RVA: 0x001CE628 File Offset: 0x001CC828
 private void GetAffectedPages(ITextPointer start, ITextPointer end, out int pageStart, out int pageCount)
 {
     for (pageStart = 0; pageStart < this._breakRecords.Count; pageStart++)
     {
         Invariant.Assert(this._breakRecords[pageStart] != null, "Invalid BreakRecordTable entry.");
         TextPointer dependentMax = this._breakRecords[pageStart].DependentMax;
         if (dependentMax != null && start.CompareTo(dependentMax) <= 0)
         {
             break;
         }
         ReadOnlyCollection <TextSegment> textSegments = this._breakRecords[pageStart].TextSegments;
         if (textSegments == null)
         {
             break;
         }
         bool flag = false;
         foreach (TextSegment textSegment in textSegments)
         {
             if (start.CompareTo(textSegment.End) <= 0)
             {
                 flag = true;
                 break;
             }
         }
         if (flag)
         {
             break;
         }
     }
     pageCount = this._breakRecords.Count - pageStart;
 }
Esempio n. 3
0
 // Token: 0x0600625B RID: 25179 RVA: 0x001B9470 File Offset: 0x001B7670
 private static TextSegment CreateNormalizedSegment(ITextPointer start, ITextPointer end)
 {
     if (start.CompareTo(end) == 0)
     {
         if (!TextPointerBase.IsAtInsertionPosition(start, start.LogicalDirection))
         {
             start = start.GetInsertionPosition(start.LogicalDirection);
             end   = start;
         }
     }
     else
     {
         if (!TextPointerBase.IsAtInsertionPosition(start, start.LogicalDirection))
         {
             start = start.GetInsertionPosition(LogicalDirection.Forward);
         }
         if (!TextPointerBase.IsAtInsertionPosition(end, start.LogicalDirection))
         {
             end = end.GetInsertionPosition(LogicalDirection.Backward);
         }
         if (start.CompareTo(end) >= 0)
         {
             if (start.LogicalDirection == LogicalDirection.Backward)
             {
                 start = end.GetFrozenPointer(LogicalDirection.Backward);
             }
             end = start;
         }
     }
     return(new TextSegment(start, end));
 }
Esempio n. 4
0
 // Token: 0x0600624A RID: 25162 RVA: 0x001B8AC4 File Offset: 0x001B6CC4
 internal bool Contains(ITextPointer textPointer)
 {
     if (textPointer == null)
     {
         throw new ArgumentNullException("textPointer");
     }
     if (textPointer.TextContainer != this.Start.TextContainer)
     {
         throw new ArgumentException(SR.Get("NotInAssociatedTree", new object[]
         {
             "textPointer"
         }));
     }
     if (textPointer.CompareTo(this.Start) < 0)
     {
         textPointer = textPointer.GetInsertionPosition(LogicalDirection.Forward);
     }
     else if (textPointer.CompareTo(this.End) > 0)
     {
         textPointer = textPointer.GetInsertionPosition(LogicalDirection.Backward);
     }
     for (int i = 0; i < this._segments.Count; i++)
     {
         if (this._segments[i].Contains(textPointer))
         {
             return(true);
         }
     }
     return(false);
 }
Esempio n. 5
0
        // Token: 0x06002BD3 RID: 11219 RVA: 0x000C7B28 File Offset: 0x000C5D28
        private void _OnHighlightChanged(object sender, HighlightChangedEventArgs args)
        {
            int i = 0;
            DocumentSequenceTextPointer documentSequenceTextPointer = null;
            ChildDocumentBlock          childDocumentBlock          = null;
            List <TextSegment>          list = new List <TextSegment>(4);

            while (i < args.Ranges.Count)
            {
                TextSegment textSegment = (TextSegment)args.Ranges[i];
                DocumentSequenceTextPointer documentSequenceTextPointer2 = (DocumentSequenceTextPointer)textSegment.End;
                if (documentSequenceTextPointer == null)
                {
                    documentSequenceTextPointer = (DocumentSequenceTextPointer)textSegment.Start;
                }
                ChildDocumentBlock childDocumentBlock2 = childDocumentBlock;
                childDocumentBlock = documentSequenceTextPointer.ChildBlock;
                if (childDocumentBlock2 != null && childDocumentBlock != childDocumentBlock2 && !(childDocumentBlock2.ChildContainer is NullTextContainer) && list.Count != 0)
                {
                    childDocumentBlock2.ChildHighlightLayer.RaiseHighlightChangedEvent(new ReadOnlyCollection <TextSegment>(list));
                    list.Clear();
                }
                ITextPointer childPointer = documentSequenceTextPointer.ChildPointer;
                if (documentSequenceTextPointer2.ChildBlock != childDocumentBlock)
                {
                    ITextPointer textPointer = documentSequenceTextPointer.ChildPointer.TextContainer.End;
                    if (childPointer.CompareTo(textPointer) != 0)
                    {
                        list.Add(new TextSegment(childPointer, textPointer));
                    }
                    if (!(childDocumentBlock.ChildContainer is NullTextContainer) && list.Count != 0)
                    {
                        childDocumentBlock.ChildHighlightLayer.RaiseHighlightChangedEvent(new ReadOnlyCollection <TextSegment>(list));
                    }
                    childDocumentBlock          = childDocumentBlock.NextBlock;
                    documentSequenceTextPointer = new DocumentSequenceTextPointer(childDocumentBlock, childDocumentBlock.ChildContainer.Start);
                    list.Clear();
                }
                else
                {
                    ITextPointer textPointer = documentSequenceTextPointer2.ChildPointer;
                    if (childPointer.CompareTo(textPointer) != 0)
                    {
                        list.Add(new TextSegment(childPointer, textPointer));
                    }
                    i++;
                    documentSequenceTextPointer = null;
                }
            }
            if (list.Count > 0 && childDocumentBlock != null && !(childDocumentBlock.ChildContainer is NullTextContainer))
            {
                childDocumentBlock.ChildHighlightLayer.RaiseHighlightChangedEvent(new ReadOnlyCollection <TextSegment>(list));
            }
        }
        // Token: 0x060039B3 RID: 14771 RVA: 0x00105B0C File Offset: 0x00103D0C
        internal static TextRange InternalFind(ITextPointer startPosition, ITextPointer endPosition, string findPattern, CultureInfo cultureInfo, bool matchCase, bool matchWholeWord, bool matchLast, bool matchDiacritics, bool matchKashida, bool matchAlefHamza)
        {
            Invariant.Assert(startPosition.CompareTo(endPosition) <= 0);
            ITextPointer     textPointer;
            LogicalDirection direction;

            if (matchLast)
            {
                textPointer = endPosition;
                direction   = LogicalDirection.Backward;
            }
            else
            {
                textPointer = startPosition;
                direction   = LogicalDirection.Forward;
            }
            int num = Math.Max(64, findPattern.Length * 2 * 2);

            textPointer = textPointer.CreatePointer();
            while ((matchLast ? startPosition.CompareTo(textPointer) : textPointer.CompareTo(endPosition)) < 0)
            {
                ITextPointer textPointer2 = textPointer.CreatePointer();
                char[]       array        = new char[num];
                int[]        array2       = new int[num + 1];
                int          num2         = TextFindEngine.SetFindTextAndFindTextPositionMap(startPosition, endPosition, textPointer, direction, matchLast, array, array2);
                if (!matchDiacritics || num2 >= findPattern.Length)
                {
                    int  num3 = matchLast ? (array.Length - num2) : 0;
                    bool hasPreceedingSeparatorChar = false;
                    bool hasFollowingSeparatorChar  = false;
                    if (matchWholeWord)
                    {
                        TextFindEngine.GetContextualInformation(textPointer2, matchLast ? (-array2[array2.Length - num2 - 1]) : array2[num2], out hasPreceedingSeparatorChar, out hasFollowingSeparatorChar);
                    }
                    string textString = new string(array, num3, num2);
                    int    num5;
                    int    num4 = TextFindEngine.FindMatchIndexFromFindContent(textString, findPattern, cultureInfo, matchCase, matchWholeWord, matchLast, matchDiacritics, matchKashida, matchAlefHamza, hasPreceedingSeparatorChar, hasFollowingSeparatorChar, out num5);
                    if (num4 != -1)
                    {
                        ITextPointer textPointer3 = textPointer2.CreatePointer();
                        textPointer3.MoveByOffset(matchLast ? (-array2[num3 + num4]) : array2[num4]);
                        ITextPointer textPointer4 = textPointer2.CreatePointer();
                        textPointer4.MoveByOffset(matchLast ? (-array2[num3 + num4 + num5]) : array2[num4 + num5]);
                        return(new TextRange(textPointer3, textPointer4));
                    }
                    if (num2 > findPattern.Length)
                    {
                        textPointer = textPointer2.CreatePointer();
                        textPointer.MoveByOffset(matchLast ? (-array2[array.Length - num2 + findPattern.Length]) : array2[num2 - findPattern.Length]);
                    }
                }
            }
            return(null);
        }
Esempio n. 7
0
        /// <summary>
        /// Retrieves indices of affected pages by specified content range.
        /// </summary>
        /// <param name="start">Content change start position.</param>
        /// <param name="end">Content change end position.</param>
        /// <param name="pageStart">The first affected page.</param>
        /// <param name="pageCount">Number of affected pages.</param>
        private void GetAffectedPages(ITextPointer start, ITextPointer end, out int pageStart, out int pageCount)
        {
            bool affects;
            ReadOnlyCollection <TextSegment> textSegments;
            TextPointer dependentMax;

            // Find the first affected page.
            pageStart = 0;
            while (pageStart < _breakRecords.Count)
            {
                Invariant.Assert(_breakRecords[pageStart] != null, "Invalid BreakRecordTable entry.");

                // If the start position is before last position affecting the output break record,
                // this page is affected.
                dependentMax = _breakRecords[pageStart].DependentMax;
                if (dependentMax != null)
                {
                    if (start.CompareTo(dependentMax) <= 0)
                    {
                        break;
                    }
                }

                textSegments = _breakRecords[pageStart].TextSegments;
                if (textSegments != null)
                {
                    affects = false;
                    foreach (TextSegment textSegment in textSegments)
                    {
                        if (start.CompareTo(textSegment.End) <= 0)
                        {
                            affects = true;
                            break;
                        }
                    }
                    if (affects)
                    {
                        break;
                    }
                }
                else
                {
                    // There is no information about this page, so assume that it is
                    // affected.
                    break;
                }
                ++pageStart;
            }
            // Find the last affected page
            // For now assume that all following pages are affected.
            pageCount = _breakRecords.Count - pageStart;
        }
 // Token: 0x06003C07 RID: 15367 RVA: 0x0011500C File Offset: 0x0011320C
 internal TextSegment(ITextPointer startPosition, ITextPointer endPosition, bool preserveLogicalDirection)
 {
     ValidationHelper.VerifyPositionPair(startPosition, endPosition);
     if (startPosition.CompareTo(endPosition) == 0)
     {
         this._start = startPosition.GetFrozenPointer(startPosition.LogicalDirection);
         this._end   = this._start;
         return;
     }
     Invariant.Assert(startPosition.CompareTo(endPosition) < 0);
     this._start = startPosition.GetFrozenPointer(preserveLogicalDirection ? startPosition.LogicalDirection : LogicalDirection.Backward);
     this._end   = endPosition.GetFrozenPointer(preserveLogicalDirection ? endPosition.LogicalDirection : LogicalDirection.Forward);
 }
 // Token: 0x06005B55 RID: 23381 RVA: 0x0019C11A File Offset: 0x0019A31A
 internal SpellingError(Speller speller, ITextPointer start, ITextPointer end)
 {
     Invariant.Assert(start.CompareTo(end) < 0);
     this._speller = speller;
     this._start   = start.GetFrozenPointer(LogicalDirection.Forward);
     this._end     = end.GetFrozenPointer(LogicalDirection.Backward);
 }
Esempio n. 10
0
        // Token: 0x06007C33 RID: 31795 RVA: 0x0022EB24 File Offset: 0x0022CD24
        public static IList <DependencyObject> GetSelectedNodes(object selection)
        {
            if (selection == null)
            {
                throw new ArgumentNullException("selection");
            }
            ITextPointer        textPointer = null;
            ITextPointer        position    = null;
            IList <TextSegment> list;

            TextSelectionHelper.CheckSelection(selection, out textPointer, out position, out list);
            IList <DependencyObject> list2 = new List <DependencyObject>();

            if (textPointer.CompareTo(position) == 0)
            {
                list2.Add(((TextPointer)textPointer).Parent);
                return(list2);
            }
            TextPointer textPointer2 = (TextPointer)textPointer.CreatePointer();

            while (((ITextPointer)textPointer2).CompareTo(position) < 0)
            {
                DependencyObject parent = textPointer2.Parent;
                if (!list2.Contains(parent))
                {
                    list2.Add(parent);
                }
                textPointer2.MoveToNextContextPosition(LogicalDirection.Forward);
            }
            return(list2);
        }
Esempio n. 11
0
        // Token: 0x06007C39 RID: 31801 RVA: 0x0022EDE4 File Offset: 0x0022CFE4
        public static Rect GetAnchorRectangle(ITextPointer pointer)
        {
            if (pointer == null)
            {
                throw new ArgumentNullException("pointer");
            }
            bool      flag = false;
            ITextView documentPageTextView = TextSelectionHelper.GetDocumentPageTextView(pointer);

            if (pointer.CompareTo(pointer.TextContainer.End) == 0)
            {
                Point point = new Point(double.MaxValue, double.MaxValue);
                pointer = documentPageTextView.GetTextPositionFromPoint(point, true);
                flag    = true;
            }
            if (documentPageTextView != null && documentPageTextView.IsValid && TextDocumentView.Contains(pointer, documentPageTextView.TextSegments))
            {
                Rect rectangleFromTextPosition = documentPageTextView.GetRectangleFromTextPosition(pointer);
                if (flag && rectangleFromTextPosition != Rect.Empty)
                {
                    rectangleFromTextPosition.X += rectangleFromTextPosition.Height / 2.0;
                }
                return(rectangleFromTextPosition);
            }
            return(Rect.Empty);
        }
Esempio n. 12
0
        /// <summary>
        /// Is AutometionPeer represented by 'elementStart' is immediate child of AutomationPeer
        /// represented by 'ownerContentStart'.
        /// </summary>
        internal static bool IsImmediateAutomationChild(ITextPointer elementStart, ITextPointer ownerContentStart)
        {
            Invariant.Assert(elementStart.CompareTo(ownerContentStart) >= 0);
            bool immediateChild = true;
            // Walk element tree up looking for AutomationPeers.
            ITextPointer position = elementStart.CreatePointer();

            while (typeof(TextElement).IsAssignableFrom(position.ParentType))
            {
                position.MoveToElementEdge(ElementEdge.BeforeStart);
                if (position.CompareTo(ownerContentStart) <= 0)
                {
                    break;
                }
                AutomationPeer peer    = null;
                object         element = position.GetAdjacentElement(LogicalDirection.Forward);
                if (element is UIElement)
                {
                    peer = UIElementAutomationPeer.CreatePeerForElement((UIElement)element);
                }
                else if (element is ContentElement)
                {
                    peer = ContentElementAutomationPeer.CreatePeerForElement((ContentElement)element);
                }
                if (peer != null)
                {
                    immediateChild = false;
                    break;
                }
            }
            return(immediateChild);
        }
            // Constructor.
            internal TextSelectionHighlightChangedEventArgs(ITextPointer invalidRangeLeftStart, ITextPointer invalidRangeLeftEnd,
                                                            ITextPointer invalidRangeRightStart, ITextPointer invalidRangeRightEnd)
            {
                List <TextSegment> rangeArray;

                Invariant.Assert(invalidRangeLeftStart != invalidRangeLeftEnd || invalidRangeRightStart != invalidRangeRightEnd, "Unexpected empty range!");

                if (invalidRangeLeftStart.CompareTo(invalidRangeLeftEnd) == 0)
                {
                    rangeArray = new List <TextSegment>(1);
                    rangeArray.Add(new TextSegment(invalidRangeRightStart, invalidRangeRightEnd));
                }
                else if (invalidRangeRightStart.CompareTo(invalidRangeRightEnd) == 0)
                {
                    rangeArray = new List <TextSegment>(1);
                    rangeArray.Add(new TextSegment(invalidRangeLeftStart, invalidRangeLeftEnd));
                }
                else
                {
                    rangeArray = new List <TextSegment>(2);
                    rangeArray.Add(new TextSegment(invalidRangeLeftStart, invalidRangeLeftEnd));
                    rangeArray.Add(new TextSegment(invalidRangeRightStart, invalidRangeRightEnd));
                }

                _ranges = new ReadOnlyCollection <TextSegment>(rangeArray);
            }
Esempio n. 14
0
        /// <summary>
        ///  Gets the rectangle for this ITextPointer
        /// </summary>
        /// <param name="pointer">the pointer to examine</param>
        /// <returns>
        /// The anchor point of the selection;
        /// If there is no valid AnchorPoint returns Point(Double.NaN, Double.NaN).
        /// </returns>
        /// <exception cref="ArgumentNullException">pointer is null</exception>
        public static Rect GetAnchorRectangle(ITextPointer pointer)
        {
            if (pointer == null)
            {
                throw new ArgumentNullException("pointer");
            }
            bool extension = false;

            ITextView textView = GetDocumentPageTextView(pointer);

            if (pointer.CompareTo(pointer.TextContainer.End) == 0)
            {
                //we can not get rectangle for the end of the TextContainer
                //so get the last symbol
                Point endPoint = new Point(Double.MaxValue, Double.MaxValue);
                pointer = textView.GetTextPositionFromPoint(endPoint, true);
                //we need to move the resulting rectangle at half space because
                //the geometry calculating function does the same
                extension = true;
            }
            if (textView != null && textView.IsValid && TextDocumentView.Contains(pointer, textView.TextSegments))
            {
                Rect rect = textView.GetRectangleFromTextPosition(pointer);
                if (extension && rect != Rect.Empty)
                {
                    rect.X += rect.Height / 2.0;
                }
                return(rect);
            }

            return(Rect.Empty);
        }
 // Token: 0x06003EEE RID: 16110 RVA: 0x0011F2FC File Offset: 0x0011D4FC
 internal static void VerifyPositionPair(ITextPointer startPosition, ITextPointer endPosition)
 {
     if (startPosition == null)
     {
         throw new ArgumentNullException("startPosition");
     }
     if (endPosition == null)
     {
         throw new ArgumentNullException("endPosition");
     }
     if (startPosition.TextContainer != endPosition.TextContainer)
     {
         throw new ArgumentException(SR.Get("InDifferentTextContainers", new object[]
         {
             "startPosition",
             "endPosition"
         }));
     }
     if (startPosition.CompareTo(endPosition) > 0)
     {
         throw new ArgumentException(SR.Get("BadTextPositionOrder", new object[]
         {
             "startPosition",
             "endPosition"
         }));
     }
 }
Esempio n. 16
0
        // Token: 0x0600676F RID: 26479 RVA: 0x001CECD4 File Offset: 0x001CCED4
        internal Geometry GetTightBoundingGeometryFromTextPositions(ITextPointer startPosition, ITextPointer endPosition, Rect visibleRect)
        {
            Geometry geometry = null;

            if (endPosition.CompareTo(this.Cell.StaticElementEnd) >= 0)
            {
                geometry = new RectangleGeometry(this._rect.FromTextDpi());
            }
            else
            {
                SubpageParagraphResult            subpageParagraphResult = (SubpageParagraphResult)this.CreateParagraphResult();
                ReadOnlyCollection <ColumnResult> columns = subpageParagraphResult.Columns;
                Transform transform = new TranslateTransform(-TextDpi.FromTextDpi(base.ContentRect.u), -TextDpi.FromTextDpi(base.ContentRect.v));
                visibleRect = transform.TransformBounds(visibleRect);
                geometry    = TextDocumentView.GetTightBoundingGeometryFromTextPositionsHelper(columns[0].Paragraphs, subpageParagraphResult.FloatingElements, startPosition, endPosition, 0.0, visibleRect);
                if (geometry != null)
                {
                    Rect viewport = new Rect(0.0, 0.0, TextDpi.FromTextDpi(base.ContentRect.du), TextDpi.FromTextDpi(base.ContentRect.dv));
                    CaretElement.ClipGeometryByViewport(ref geometry, viewport);
                    transform = new TranslateTransform(TextDpi.FromTextDpi(base.ContentRect.u), TextDpi.FromTextDpi(base.ContentRect.v));
                    CaretElement.AddTransformToGeometry(geometry, transform);
                }
            }
            return(geometry);
        }
Esempio n. 17
0
        // Token: 0x06007245 RID: 29253 RVA: 0x0020AA54 File Offset: 0x00208C54
        internal static List <AutomationPeer> GetAutomationPeersFromRange(ITextPointer start, ITextPointer end, ITextPointer ownerContentStart)
        {
            List <AutomationPeer> list = new List <AutomationPeer>();

            start = start.CreatePointer();
            while (start.CompareTo(end) < 0)
            {
                bool flag = false;
                if (start.GetPointerContext(LogicalDirection.Forward) == TextPointerContext.ElementStart)
                {
                    object adjacentElement = start.GetAdjacentElement(LogicalDirection.Forward);
                    if (adjacentElement is ContentElement)
                    {
                        AutomationPeer automationPeer = ContentElementAutomationPeer.CreatePeerForElement((ContentElement)adjacentElement);
                        if (automationPeer != null)
                        {
                            if (ownerContentStart == null || TextContainerHelper.IsImmediateAutomationChild(start, ownerContentStart))
                            {
                                list.Add(automationPeer);
                            }
                            start.MoveToNextContextPosition(LogicalDirection.Forward);
                            start.MoveToElementEdge(ElementEdge.AfterEnd);
                            flag = true;
                        }
                    }
                }
                else if (start.GetPointerContext(LogicalDirection.Forward) == TextPointerContext.EmbeddedElement)
                {
                    object adjacentElement = start.GetAdjacentElement(LogicalDirection.Forward);
                    if (adjacentElement is UIElement)
                    {
                        if (ownerContentStart == null || TextContainerHelper.IsImmediateAutomationChild(start, ownerContentStart))
                        {
                            AutomationPeer automationPeer = UIElementAutomationPeer.CreatePeerForElement((UIElement)adjacentElement);
                            if (automationPeer != null)
                            {
                                list.Add(automationPeer);
                            }
                            else
                            {
                                TextContainerHelper.iterate((Visual)adjacentElement, list);
                            }
                        }
                    }
                    else if (adjacentElement is ContentElement)
                    {
                        AutomationPeer automationPeer = ContentElementAutomationPeer.CreatePeerForElement((ContentElement)adjacentElement);
                        if (automationPeer != null && (ownerContentStart == null || TextContainerHelper.IsImmediateAutomationChild(start, ownerContentStart)))
                        {
                            list.Add(automationPeer);
                        }
                    }
                }
                if (!flag && !start.MoveToNextContextPosition(LogicalDirection.Forward))
                {
                    break;
                }
            }
            return(list);
        }
Esempio n. 18
0
        // Token: 0x06007246 RID: 29254 RVA: 0x0020AB60 File Offset: 0x00208D60
        internal static bool IsImmediateAutomationChild(ITextPointer elementStart, ITextPointer ownerContentStart)
        {
            Invariant.Assert(elementStart.CompareTo(ownerContentStart) >= 0);
            bool         result      = true;
            ITextPointer textPointer = elementStart.CreatePointer();

            while (typeof(TextElement).IsAssignableFrom(textPointer.ParentType))
            {
                textPointer.MoveToElementEdge(ElementEdge.BeforeStart);
                if (textPointer.CompareTo(ownerContentStart) <= 0)
                {
                    break;
                }
                AutomationPeer automationPeer  = null;
                object         adjacentElement = textPointer.GetAdjacentElement(LogicalDirection.Forward);
                if (adjacentElement is UIElement)
                {
                    automationPeer = UIElementAutomationPeer.CreatePeerForElement((UIElement)adjacentElement);
                }
                else if (adjacentElement is ContentElement)
                {
                    automationPeer = ContentElementAutomationPeer.CreatePeerForElement((ContentElement)adjacentElement);
                }
                if (automationPeer != null)
                {
                    result = false;
                    break;
                }
            }
            return(result);
        }
Esempio n. 19
0
        /// <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);
            }
        }
Esempio n. 20
0
            // Token: 0x060085BD RID: 34237 RVA: 0x0024AA08 File Offset: 0x00248C08
            private ITextPointer GetDropPosition(Visual target, Point point)
            {
                Invariant.Assert(target != null);
                Invariant.Assert(this._textEditor.TextView.IsValid);
                if (target != this._textEditor.TextView.RenderScope && target != null && this._textEditor.TextView.RenderScope.IsAncestorOf(target))
                {
                    GeneralTransform generalTransform = target.TransformToAncestor(this._textEditor.TextView.RenderScope);
                    generalTransform.TryTransform(point, out point);
                }
                ITextPointer textPointer = this.TextView.GetTextPositionFromPoint(point, true);

                if (textPointer != null)
                {
                    textPointer = textPointer.GetInsertionPosition(textPointer.LogicalDirection);
                    if (this._textEditor.AcceptsRichContent)
                    {
                        TextSegment normalizedLineRange = TextEditorSelection.GetNormalizedLineRange(this.TextView, textPointer);
                        if (!normalizedLineRange.IsNull && textPointer.CompareTo(normalizedLineRange.End) < 0 && !TextPointerBase.IsAtWordBoundary(textPointer, LogicalDirection.Forward) && this._dragSourceTextRange != null && TextPointerBase.IsAtWordBoundary(this._dragSourceTextRange.Start, LogicalDirection.Forward) && TextPointerBase.IsAtWordBoundary(this._dragSourceTextRange.End, LogicalDirection.Forward))
                        {
                            TextSegment wordRange        = TextPointerBase.GetWordRange(textPointer);
                            string      textInternal     = TextRangeBase.GetTextInternal(wordRange.Start, wordRange.End);
                            int         offsetToPosition = wordRange.Start.GetOffsetToPosition(textPointer);
                            textPointer = ((offsetToPosition < textInternal.Length / 2) ? wordRange.Start : wordRange.End);
                        }
                    }
                }
                return(textPointer);
            }
Esempio n. 21
0
        // Token: 0x060035AF RID: 13743 RVA: 0x000F3B94 File Offset: 0x000F1D94
        private void MarkRange(ITextPointer start, ITextPointer end, SpellerStatusTable.RunType runType)
        {
            if (start.CompareTo(end) == 0)
            {
                return;
            }
            Invariant.Assert(runType == SpellerStatusTable.RunType.Clean || runType == SpellerStatusTable.RunType.Dirty);
            int num  = this.FindIndex(start.CreateStaticPointer(), LogicalDirection.Forward);
            int num2 = this.FindIndex(end.CreateStaticPointer(), LogicalDirection.Backward);

            Invariant.Assert(num >= 0);
            Invariant.Assert(num2 >= 0);
            if (num + 1 < num2)
            {
                for (int i = num + 1; i < num2; i++)
                {
                    this.NotifyHighlightLayerBeforeRunChange(i);
                }
                this._runList.RemoveRange(num + 1, num2 - num - 1);
                num2 = num + 1;
            }
            if (num == num2)
            {
                this.AddRun(num, start, end, runType);
                return;
            }
            Invariant.Assert(num == num2 - 1);
            this.AddRun(num, start, end, runType);
            num2 = this.FindIndex(end.CreateStaticPointer(), LogicalDirection.Backward);
            Invariant.Assert(num2 >= 0);
            this.AddRun(num2, start, end, runType);
        }
Esempio n. 22
0
        // Token: 0x060038DB RID: 14555 RVA: 0x00100F94 File Offset: 0x000FF194
        private static ITextPointer GetNextTextPosition(ITextPointer position, ITextPointer limit, LogicalDirection direction, out char character)
        {
            bool flag = false;

            character = '\0';
            while (position != null && !flag && (limit == null || position.CompareTo(limit) < 0))
            {
                switch (position.GetPointerContext(direction))
                {
                case TextPointerContext.Text:
                {
                    char[] array = new char[1];
                    position.GetTextInRun(direction, array, 0, 1);
                    character = array[0];
                    flag      = true;
                    continue;
                }

                case TextPointerContext.ElementStart:
                case TextPointerContext.ElementEnd:
                    if (TextSchema.IsFormattingType(position.GetElementType(direction)))
                    {
                        position = position.CreatePointer(1);
                        continue;
                    }
                    position = null;
                    continue;
                }
                position = null;
            }
            return(position);
        }
Esempio n. 23
0
        // Token: 0x060038D8 RID: 14552 RVA: 0x00100E4C File Offset: 0x000FF04C
        private static bool IsErrorAtNonMergeableInlineEdge(SpellingError spellingError, out ITextPointer textStart, out ITextPointer textEnd)
        {
            bool result = false;

            textStart = spellingError.Start.CreatePointer(LogicalDirection.Backward);
            while (textStart.CompareTo(spellingError.End) < 0 && textStart.GetPointerContext(LogicalDirection.Forward) != TextPointerContext.Text)
            {
                textStart.MoveToNextContextPosition(LogicalDirection.Forward);
            }
            textEnd = spellingError.End.CreatePointer();
            while (textEnd.CompareTo(spellingError.Start) > 0 && textEnd.GetPointerContext(LogicalDirection.Backward) != TextPointerContext.Text)
            {
                textEnd.MoveToNextContextPosition(LogicalDirection.Backward);
            }
            if (textStart.GetPointerContext(LogicalDirection.Forward) != TextPointerContext.Text || textStart.CompareTo(spellingError.End) == 0)
            {
                return(false);
            }
            Invariant.Assert(textEnd.GetPointerContext(LogicalDirection.Backward) == TextPointerContext.Text && textEnd.CompareTo(spellingError.Start) != 0);
            if ((TextPointerBase.IsAtNonMergeableInlineStart(textStart) || TextPointerBase.IsAtNonMergeableInlineEnd(textEnd)) && typeof(Run).IsAssignableFrom(textStart.ParentType) && textStart.HasEqualScope(textEnd))
            {
                result = true;
            }
            return(result);
        }
        // Returns the next non-white space character in the forward direction
        // from position, or null if no such position exists.
        // The return value will equal position if position is immediately followed
        // by a non-whitespace char.
        //
        // This method expects that limit is never null.  The scan will halt if
        // limit is encountered.
        private static ITextPointer GetNextNonWhiteSpacePosition(ITextPointer position, ITextPointer limit)
        {
            char character;

            Invariant.Assert(limit != null);

            while (true)
            {
                if (position.CompareTo(limit) == 0)
                {
                    position = null;
                    break;
                }

                position = GetNextTextPosition(position, limit, LogicalDirection.Forward, out character);

                if (position == null)
                {
                    break;
                }

                if (!Char.IsWhiteSpace(character))
                {
                    break;
                }

                position = position.CreatePointer(+1);
            }
            ;

            return(position);
        }
Esempio n. 25
0
        // convert a range given by TextPointers to a UIA TextRange
        // (helper method for raising ActiveTextPositionChanged event)
        internal ITextRangeProvider TextRangeFromTextPointers(ITextPointer rangeStart, ITextPointer rangeEnd)
        {
            // special case for the entire range
            if (rangeStart == null && rangeEnd == null)
            {
                return(null);
            }

            // map null into the appropriate endpoint
            rangeStart = rangeStart ?? _textContainer.Start;
            rangeEnd   = rangeEnd ?? _textContainer.End;

            // if either pointer belongs to the wrong tree, return null (meaning "entire range")
            if (rangeStart.TextContainer != _textContainer || rangeEnd.TextContainer != _textContainer)
            {
                return(null);
            }

            // swap the pointers, if necessary
            if (rangeStart.CompareTo(rangeEnd) > 0)
            {
                ITextPointer temp = rangeStart;
                rangeStart = rangeEnd;
                rangeEnd   = rangeStart;
            }

            // return the resulting range, wrapped so that it's ready for use by UIA
            ITextRangeProvider textRange = new TextRangeAdaptor(this, rangeStart, rangeEnd, _textPeer);

            return(TextRangeProviderWrapper.WrapArgument(textRange, _textPeer));
        }
Esempio n. 26
0
 // Token: 0x060035B0 RID: 13744 RVA: 0x000F3C68 File Offset: 0x000F1E68
 private void AddRun(int index, ITextPointer start, ITextPointer end, SpellerStatusTable.RunType runType)
 {
     Invariant.Assert(runType == SpellerStatusTable.RunType.Clean || runType == SpellerStatusTable.RunType.Dirty);
     Invariant.Assert(start.CompareTo(end) < 0);
     SpellerStatusTable.RunType runType2 = (runType == SpellerStatusTable.RunType.Clean) ? SpellerStatusTable.RunType.Dirty : SpellerStatusTable.RunType.Clean;
     SpellerStatusTable.Run     run      = this.GetRun(index);
     if (run.RunType == runType)
     {
         this.TryToMergeRunWithNeighbors(index);
         return;
     }
     if (run.RunType != runType2)
     {
         run.RunType = runType;
         ITextPointer position = run.Position;
         ITextPointer runEndPositionDynamic = this.GetRunEndPositionDynamic(index);
         this.TryToMergeRunWithNeighbors(index);
         this._highlightLayer.FireChangedEvent(position, runEndPositionDynamic);
         return;
     }
     if (run.Position.CompareTo(start) >= 0)
     {
         if (this.GetRunEndPosition(index).CompareTo(end) <= 0)
         {
             run.RunType = runType;
             this.TryToMergeRunWithNeighbors(index);
             return;
         }
         if (index > 0 && this.GetRun(index - 1).RunType == runType)
         {
             run.Position = end;
             return;
         }
         run.RunType = runType;
         SpellerStatusTable.Run value = new SpellerStatusTable.Run(end, runType2);
         this._runList.Insert(index + 1, value);
         return;
     }
     else
     {
         SpellerStatusTable.Run value;
         if (this.GetRunEndPosition(index).CompareTo(end) > 0)
         {
             value = new SpellerStatusTable.Run(start, runType);
             this._runList.Insert(index + 1, value);
             value = new SpellerStatusTable.Run(end, runType2);
             this._runList.Insert(index + 2, value);
             return;
         }
         if (index < this._runList.Count - 1 && this.GetRun(index + 1).RunType == runType)
         {
             this.GetRun(index + 1).Position = start;
             return;
         }
         value = new SpellerStatusTable.Run(start, runType);
         this._runList.Insert(index + 1, value);
         return;
     }
 }
Esempio n. 27
0
        //-----------------------------------------------------
        //
        //  Constructors 
        //
        //----------------------------------------------------- 
 
        #region Constructors
 
        // Creates a new instance.
        internal SpellingError(Speller speller, ITextPointer start, ITextPointer end)
        {
            Invariant.Assert(start.CompareTo(end) < 0); 

            _speller = speller; 
            _start = start.GetFrozenPointer(LogicalDirection.Forward); 
            _end = end.GetFrozenPointer(LogicalDirection.Backward);
        } 
Esempio n. 28
0
        //--------------------------------------------------------------------
        // TextContainer Element
        //---------------------------------------------------------------------

        // given a TextPointer range, find out all fixed position included in this range and
        // offset into the begin and end fixed element
        private bool _GetFixedNodesForFlowRange(ITextPointer start, ITextPointer end, out FixedSOMElement[] elements, out int startIndex, out int endIndex)
        {
            Debug.Assert(start.CompareTo(end) <= 0);
            elements   = null;
            startIndex = 0;
            endIndex   = 0;

            if (start.CompareTo(end) == 0)
            {
                return(false);
            }

            FixedTextPointer pStart = (FixedTextPointer)start;
            FixedTextPointer pEnd   = (FixedTextPointer)end;

            return(this.FixedTextBuilder.GetFixedNodesForFlowRange(pStart.FlowPosition, pEnd.FlowPosition, out elements, out startIndex, out endIndex));
        } //endofGetFixedNodes
 // Token: 0x060084BE RID: 33982 RVA: 0x00249888 File Offset: 0x00247A88
 internal SpellerHighlightChangedEventArgs(ITextPointer start, ITextPointer end)
 {
     Invariant.Assert(start.CompareTo(end) < 0, "Bogus start/end combination!");
     this._ranges = new ReadOnlyCollection <TextSegment>(new List <TextSegment>(1)
     {
         new TextSegment(start, end)
     });
 }
 // Token: 0x06006B6F RID: 27503 RVA: 0x001F0B08 File Offset: 0x001EED08
 internal Geometry GetTightBoundingGeometryFromTextPositions(ITextPointer startPosition, ITextPointer endPosition)
 {
     if (startPosition.CompareTo(((BlockUIContainer)base.Paragraph.Element).ContentEnd) < 0 && endPosition.CompareTo(((BlockUIContainer)base.Paragraph.Element).ContentStart) > 0)
     {
         return(new RectangleGeometry(this._rect.FromTextDpi()));
     }
     return(null);
 }
Esempio n. 31
0
        /// <summary>
        /// Constructor.
        /// </summary>
        /// <param name="startPosition">
        /// Position preceeding the TextSegment's content.
        /// </param>
        /// <param name="endPosition">
        /// Position following the TextSegment's content.
        /// </param>
        /// <param name="preserveLogicalDirection">
        /// Whether preserves LogicalDirection of start and end positions.
        /// </param>
        internal TextSegment(ITextPointer startPosition, ITextPointer endPosition, bool preserveLogicalDirection)
        {
            ValidationHelper.VerifyPositionPair(startPosition, endPosition);

            if (startPosition.CompareTo(endPosition) == 0)
            {
                // To preserve segment emptiness
                // we use the same instance of a pointer
                // for both segment ends.
                _start = startPosition.GetFrozenPointer(startPosition.LogicalDirection);
                _end = _start;
            }
            else
            {
                Invariant.Assert(startPosition.CompareTo(endPosition) < 0);
                _start = startPosition.GetFrozenPointer(preserveLogicalDirection ? startPosition.LogicalDirection : LogicalDirection.Backward);
                _end = endPosition.GetFrozenPointer(preserveLogicalDirection ? endPosition.LogicalDirection : LogicalDirection.Forward);
            }
        }
        // Token: 0x0600717A RID: 29050 RVA: 0x00207344 File Offset: 0x00205544
        internal override bool Contains(ITextPointer position, bool strict)
        {
            bool flag = base.Contains(position, strict);

            if (!flag && strict)
            {
                flag = (position.CompareTo(base.EndPosition) == 0);
            }
            return(flag);
        }
Esempio n. 33
0
        //----------------------------------------------------- 
        //
        // ITextRange Methods
        //
        //----------------------------------------------------- 

        #region ITextRange Methods 
 
        //......................................................
        // 
        // Selection Building
        //
        //......................................................
 
        /// <summary>
        /// </summary> 
        // 
        internal static bool Contains(ITextRange thisRange, ITextPointer textPointer)
        { 
            NormalizeRange(thisRange);

            if (textPointer == null)
            { 
                throw new ArgumentNullException("textPointer");
            } 
 
            if (textPointer.TextContainer != thisRange.Start.TextContainer)
            { 
                throw new ArgumentException(SR.Get(SRID.NotInAssociatedTree), "textPointer");
            }

            // Correct position normalization on range boundary so that 
            // our test would not depend on what side of formatting tags
            // pointer is located. 
            if (textPointer.CompareTo(thisRange.Start) < 0) 
            {
                textPointer = textPointer.GetFormatNormalizedPosition(LogicalDirection.Forward); 
            }
            else if (textPointer.CompareTo(thisRange.End) > 0)
            {
                textPointer = textPointer.GetFormatNormalizedPosition(LogicalDirection.Backward); 
            }
 
            // Check if at least one segment contains this position. 
            for (int i = 0; i < thisRange._TextSegments.Count; i++)
            { 
                if (thisRange._TextSegments[i].Contains(textPointer))
                {
                    return true;
                } 
            }
 
            return false; 
        }
Esempio n. 34
0
 // Verifies two positions are safe to use as a logical text span.
 //
 // Throws ArgumentNullException if startPosition == null || endPosition == null
 //        ArgumentException if startPosition.TextContainer != endPosition.TextContainer or
 //                             startPosition > endPosition
 internal static void VerifyPositionPair(ITextPointer startPosition, ITextPointer endPosition)
 {
     if (startPosition == null)
     {
         throw new ArgumentNullException("startPosition");
     }
     if (endPosition == null)
     {
         throw new ArgumentNullException("endPosition");
     }
     if (startPosition.TextContainer != endPosition.TextContainer)
     {
         throw new ArgumentException(SR.Get(SRID.InDifferentTextContainers, "startPosition", "endPosition"));
     }
     if (startPosition.CompareTo(endPosition) > 0)
     {
         throw new ArgumentException(SR.Get(SRID.BadTextPositionOrder, "startPosition", "endPosition"));
     }
 }
Esempio n. 35
0
        // Deletes a specified run of content.
        //
        // On exit,
        //   symbolsRemoved <== count of symbols actually removed.
        //   removeStartIndex <== offset of first symbol affected by the edit.
        //
        // removeStartIndex is always <= endPosition.Offset, but it does not necessarily
        // match the position of the logically removed content.  In some rare cases
        // a scoping element may be removed, meaning we have two or more runs of
        // removed content, and removeStartIndex + symbolsRemoved < the offset of
        // the last position affected by the operation.
        private void RemoveContent(ITextPointer startPosition, ITextPointer endPosition, out int symbolsRemoved, out int removeStartIndex)
        {
            symbolsRemoved = 0;
            removeStartIndex = startPosition.Offset;

            if (startPosition.CompareTo(endPosition) == 0)
                return;

            TextContainer container = (TextContainer)startPosition.TextContainer;

            symbolsRemoved = container.SymbolCount;

            if (startPosition is TextPointer)
            {
                _minSymbolsRemovedIndex = Int32.MaxValue;
            }

            startPosition.DeleteContentToPosition(endPosition);

            if (startPosition is TextPointer)
            {
                removeStartIndex = _minSymbolsRemovedIndex;
            }

            symbolsRemoved = symbolsRemoved - container.SymbolCount;
        }
        /// <summary>
        /// Checks if line wrapping is happening at this position
        /// </summary>
        internal static bool IsAtLineWrappingPosition(ITextPointer position, ITextView textView)
        {
            Invariant.Assert(position != null, "null check: position");

            if (!position.HasValidLayout)
            {
                return false;
            }

            Invariant.Assert(textView != null, "textView cannot be null because the position has valid layout");
            TextSegment lineSegment = textView.GetLineRange(position);

            if (lineSegment.IsNull)
            {
                return false;
            }

            bool isAtLineWrappingPosition = position.LogicalDirection == LogicalDirection.Forward 
                ? position.CompareTo(lineSegment.Start) == 0 
                : position.CompareTo(lineSegment.End) == 0;

            return isAtLineWrappingPosition;
        }
Esempio n. 37
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;
                }
            }
Esempio n. 38
0
        // Extends the selection to the mouse cursor position.
        void ITextSelection.ExtendSelectionByMouse(ITextPointer cursorPosition, bool forceWordSelection, bool forceParagraphSelection)
        {
            ITextSelection thisSelection = (ITextSelection)this;

            // Check whether the cursor has been actually moved - compare with the previous position
            if (forceParagraphSelection || _previousCursorPosition != null && cursorPosition.CompareTo(_previousCursorPosition) == 0)
            {
                // Mouse was not actually moved. Ignore the event.
                return;
            }

            thisSelection.BeginChange();
            try
            {
                if (!BeginMouseSelectionProcess(cursorPosition))
                {
                    return;
                }

                // Get anchor position
                ITextPointer anchorPosition = ((ITextSelection)this).AnchorPosition;

                // Identify words on selection ends
                TextSegment anchorWordRange;
                TextSegment cursorWordRange;
                IdentifyWordsOnSelectionEnds(anchorPosition, cursorPosition, forceWordSelection, out anchorWordRange, out cursorWordRange);

                // Calculate selection boundary positions
                ITextPointer startPosition;
                ITextPointer movingPosition;
                if (anchorWordRange.Start.CompareTo(cursorWordRange.Start) <= 0)
                {
                    startPosition = anchorWordRange.Start.GetFrozenPointer(LogicalDirection.Forward);
                    movingPosition = cursorWordRange.End.GetFrozenPointer(LogicalDirection.Backward); ;
                }
                else
                {
                    startPosition = anchorWordRange.End.GetFrozenPointer(LogicalDirection.Backward);
                    movingPosition = cursorWordRange.Start.GetFrozenPointer(LogicalDirection.Forward); ;
                }

                // Note that we use includeCellAtMovingPosition=true because we want that hit-tested table cell
                // be included into selection no matter whether it's empty or not.
                TextRangeBase.Select(this, startPosition, movingPosition, /*includeCellAtMovingPosition:*/true);
                SetActivePositions(anchorPosition, movingPosition);

                // Store previous cursor position - for the next extension event
                _previousCursorPosition = cursorPosition.CreatePointer();

                Invariant.Assert(thisSelection.Contains(thisSelection.AnchorPosition));
            }
            finally
            {
                thisSelection.EndChange();
            }
        }
Esempio n. 39
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);
                            }
                        }
                    }
                }
            }
        }
Esempio n. 40
0
        /// <summary> 
        /// <see cref="TextViewBase.GetTightBoundingGeometryFromTextPositions"/>
        /// </summary>
        internal override Geometry GetTightBoundingGeometryFromTextPositions(ITextPointer startPosition, ITextPointer endPosition)
        { 
            //  verify that layout information is valid. Cannot continue if not valid.
            if (!IsValid) 
            { 
                throw new InvalidOperationException(SR.Get(SRID.TextViewInvalidLayout));
            } 

            Geometry geometry = null;

            for (int i = 0, count = _pageTextViews.Count; i < count; ++i) 
            {
                ReadOnlyCollection<TextSegment> textSegments = _pageTextViews[i].TextSegments; 
 
                for (int segmentIndex = 0; segmentIndex < textSegments.Count; segmentIndex++)
                { 
                    TextSegment textSegment = textSegments[segmentIndex];

                    ITextPointer startPositionInTextSegment = startPosition.CompareTo(textSegment.Start) > 0 ? startPosition : textSegment.Start;
                    ITextPointer endPositionInTextSegment = endPosition.CompareTo(textSegment.End) < 0 ? endPosition : textSegment.End; 

                    if (startPositionInTextSegment.CompareTo(endPositionInTextSegment) >= 0) 
                    { 
                        continue;
                    } 

                    Geometry pageGeometry = _pageTextViews[i].GetTightBoundingGeometryFromTextPositions(startPositionInTextSegment, endPositionInTextSegment);
                    if (pageGeometry != null)
                    { 
                        Transform transform = _pageTextViews[i].RenderScope.TransformToAncestor(_renderScope).AffineTransform;
                        CaretElement.AddTransformToGeometry(pageGeometry, transform); 
 
                        CaretElement.AddGeometry(ref geometry, pageGeometry);
                    } 
                }
            }

            return (geometry); 
        }
Esempio n. 41
0
        // Uses the current selection state to match an ITextPointer to one of the possible
        // moving position edges.
        private MovingEdge ConvertToMovingEdge(ITextPointer anchorPosition, ITextPointer movingPosition)
        {
            ITextSelection thisSelection = this;
            MovingEdge movingEdge;

            if (thisSelection.IsEmpty)
            {
                // Empty selections have no moving edge.
                movingEdge = MovingEdge.None;
            }
            else if (thisSelection.TextSegments.Count < 2)
            {
                // Simple text selections move opposite their anchor positions.
                movingEdge = (anchorPosition.CompareTo(movingPosition) <= 0) ? MovingEdge.End : MovingEdge.Start;
            }
            else
            {
                // Table selection.  Look for an exact match.
                if (movingPosition.CompareTo(thisSelection.Start) == 0)
                {
                    movingEdge = MovingEdge.Start;
                }
                else if (movingPosition.CompareTo(thisSelection.End) == 0)
                {
                    movingEdge = MovingEdge.End;
                }
                else if (movingPosition.CompareTo(thisSelection.TextSegments[0].End) == 0)
                {
                    movingEdge = MovingEdge.StartInner;
                }
                else if (movingPosition.CompareTo(thisSelection.TextSegments[thisSelection.TextSegments.Count-1].Start) == 0)
                {
                    movingEdge = MovingEdge.EndInner;
                }
                else
                {
                    movingEdge = (anchorPosition.CompareTo(movingPosition) <= 0) ? MovingEdge.End : MovingEdge.Start;
                }
            }

            return movingEdge;
        }
Esempio n. 42
0
        //--------------------------------------------------------------------
        // TextContainer Element
        //---------------------------------------------------------------------

        // given a TextPointer range, find out all fixed position included in this range and
        // offset into the begin and end fixed element
        private bool _GetFixedNodesForFlowRange(ITextPointer start, ITextPointer end, out FixedSOMElement[] elements, out int startIndex, out int endIndex)
        {
            Debug.Assert(start.CompareTo(end) <= 0);
            elements  = null;
            startIndex = 0;
            endIndex = 0;

            if (start.CompareTo(end) == 0)
            {
                return false;
            }

            FixedTextPointer pStart    = (FixedTextPointer)start;
            FixedTextPointer pEnd      = (FixedTextPointer)end;

            return this.FixedTextBuilder.GetFixedNodesForFlowRange(pStart.FlowPosition, pEnd.FlowPosition, out elements, out startIndex, out endIndex);
        } //endofGetFixedNodes
Esempio n. 43
0
        internal Geometry GetTightBoundingGeometryFromTextPositions(ITextPointer startPosition, ITextPointer endPosition, Rect visibleRect)
        {
            Debug.Assert(   TableParagraph.Table != null
                        &&  CalculatedColumns != null  );

            Geometry geometry = null;

            PTS.FSTABLEROWDESCRIPTION[] arrayTableRowDesc;
            PTS.FSKUPDATE fskupdTable;
            PTS.FSRECT rectTable;

            if (QueryTableDetails(out arrayTableRowDesc, out fskupdTable, out rectTable))
            {
                bool passedEndPosition = false;

                for (int iR = 0; iR < arrayTableRowDesc.Length && !passedEndPosition; ++iR)
                {
                    PTS.FSKUPDATE[] arrayUpdate;
                    IntPtr[] arrayFsCell;
                    PTS.FSTABLEKCELLMERGE[] arrayTableCellMerge;

                    QueryRowDetails(
                        arrayTableRowDesc[iR].pfstablerow,
                        out arrayFsCell,
                        out arrayUpdate,
                        out arrayTableCellMerge);

                    for (int iC = 0; iC < arrayFsCell.Length; ++iC)
                    {
                        if (arrayFsCell[iC] == IntPtr.Zero)
                        {
                            //  paginated case - cell may be null
                            continue;
                        }

                        CellParaClient cpc = (CellParaClient)(PtsContext.HandleToObject(arrayFsCell[iC]));

                        if (endPosition.CompareTo(cpc.Cell.ContentStart) <= 0)
                        {
                            //  remember that at least one cell in this row starts after the range's end.
                            //  in this case it is safe to break after this whole row is processed.
                            //  Note: can not break right away because cells in arrayFsCell come not
                            //  necessarily in backing store (cp) order.
                            passedEndPosition = true;
                        }
                        else
                        {
                            if (startPosition.CompareTo(cpc.Cell.ContentEnd) <= 0)
                            {
                                Geometry cellGeometry = cpc.GetTightBoundingGeometryFromTextPositions(startPosition, endPosition, visibleRect);
                                CaretElement.AddGeometry(ref geometry, cellGeometry);
                            }
                        }
                    }
                }
            }

            if (geometry != null)
            {
                geometry = Geometry.Combine(geometry, Visual.Clip, GeometryCombineMode.Intersect, null);
            }
            return geometry;
        }
        // Marks a text run as clean or dirty.
        private void MarkRange(ITextPointer start, ITextPointer end, RunType runType)
        {
            if (start.CompareTo(end) == 0)
            {
                return;
            }

            int startIndex;
            int endIndex;

            Invariant.Assert(runType == RunType.Clean || runType == RunType.Dirty);

            startIndex = FindIndex(start.CreateStaticPointer(), LogicalDirection.Forward);
            endIndex = FindIndex(end.CreateStaticPointer(), LogicalDirection.Backward);

            // We don't expect start/end to ever point off the edge of the document.
            Invariant.Assert(startIndex >= 0);
            Invariant.Assert(endIndex >= 0);

            // Remove wholly covered runs.
            if (startIndex + 1 < endIndex)
            {
                // Tell the HighlightLayer about any error runs that are going away.
                for (int i = startIndex + 1; i < endIndex; i++)
                {
                    NotifyHighlightLayerBeforeRunChange(i);
                }

                _runList.RemoveRange(startIndex + 1, endIndex - startIndex - 1);
                endIndex = startIndex + 1;
            }

            // Merge the bordering edge runs.

            if (startIndex == endIndex)
            {
                // We're contained in a single run.
                AddRun(startIndex, start, end, runType);
            }
            else
            {
                // We cover two runs.
                Invariant.Assert(startIndex == endIndex - 1);

                // Handle the first run.
                AddRun(startIndex, start, end, runType);

                // Recalc endIndex, since it may have changed in the merge.
                endIndex = FindIndex(end.CreateStaticPointer(), LogicalDirection.Backward);
                Invariant.Assert(endIndex >= 0);
                // Handle the second run.
                AddRun(endIndex, start, end, runType);
            }
        }
        // Like GetText, excepts also accepts a limit parameter -- no text is returned past
        // this second position.
        // limit may be null, in which case it is ignored.
        internal static int GetTextWithLimit(ITextPointer thisPointer, LogicalDirection direction, char[] textBuffer, int startIndex, int count, ITextPointer limit)
        {
            int charsCopied;

            if (limit == null)
            {
                // No limit, just call GetText.
                charsCopied = thisPointer.GetTextInRun(direction, textBuffer, startIndex, count);
            }
            else if (direction == LogicalDirection.Forward && limit.CompareTo(thisPointer) <= 0)
            {
                // Limit completely blocks the read.
                charsCopied = 0;
            }
            else if (direction == LogicalDirection.Backward && limit.CompareTo(thisPointer) >= 0)
            {
                // Limit completely blocks the read.
                charsCopied = 0;
            }
            else
            {
                int maxCount;

                // Get an upper bound on the amount of text to copy.
                // Since GetText always stops on non-text boundaries, it's
                // ok if the count too high, it will get truncated anyways.
                if (direction == LogicalDirection.Forward)
                {
                    maxCount = Math.Min(count, thisPointer.GetOffsetToPosition(limit));
                }
                else
                {
                    maxCount = Math.Min(count, limit.GetOffsetToPosition(thisPointer));
                }
                maxCount = Math.Min(count, maxCount);

                charsCopied = thisPointer.GetTextInRun(direction, textBuffer, startIndex, maxCount);
            }

            return charsCopied;
        }
Esempio n. 46
0
        // Opens the composition undo unit if it exists on the top
        // of the stack. Otherwise, create a new composition undo unit
        // and add it to the undo stack.
        private CompositionParentUndoUnit OpenCompositionUndoUnit(ITextPointer compositionStart, ITextPointer compositionEnd)
        {
            UndoManager undoManager = UndoManager.GetUndoManager(this.TextContainer.Parent);

            if (undoManager == null || !undoManager.IsEnabled)
            {
                return null;
            }

            // The start position is where we'll put the caret if this composition is later
            // undone by a user.
            //
            // At this point some IMEs will not have updated the selection to a
            // position within the composition, suggesting that we always want to
            // use selection start.  However, some IMEs will expand the composition backward on input
            // so the composition covers unmodified text.  (E.g.: chinese prc pinyin IME
            // will expand to cover previously finalized text on <space> input.)
            //
            // So we use a hueristic: take the rightmost of the selection start or composition
            // start.
            ITextPointer start;

            if (compositionStart == null)
            {
                Invariant.Assert(compositionEnd == null);

                GetCompositionPositions(out compositionStart, out compositionEnd);
            }

            if (compositionStart != null && compositionStart.CompareTo(this.TextSelection.Start) > 0)
            {
                start = compositionStart;
            }
            else
            {
                start = this.TextSelection.Start;
            }

            CompositionParentUndoUnit unit = new CompositionParentUndoUnit(this.TextSelection, start, start, _nextUndoUnitIsFirstCompositionUnit);
            _nextUndoUnitIsFirstCompositionUnit = false;

            // Add the given composition undo unit to the undo manager and making it
            // as the opened undo unit.
            undoManager.Open(unit);

            return unit;
        }
Esempio n. 47
0
        private void TextPositionsFromITfRange(UnsafeNativeMethods.ITfRange range, out ITextPointer start, out ITextPointer end)
        {
            UnsafeNativeMethods.ITfRangeACP rangeACP;
            int startIndex;
            int length;

            rangeACP = range as UnsafeNativeMethods.ITfRangeACP;
            rangeACP.GetExtent(out startIndex, out length);

            start = CreatePointerAtCharOffset(startIndex, LogicalDirection.Backward);
            end = CreatePointerAtCharOffset(startIndex + length, LogicalDirection.Forward);

            while (start.CompareTo(end) < 0 && start.GetPointerContext(LogicalDirection.Forward) != TextPointerContext.Text)
            {
                start.MoveToNextContextPosition(LogicalDirection.Forward);
            }
        }
Esempio n. 48
0
        // GetText handler for Blocks and TableCell to add '\n' or TS_CHAR_REGION.
        private static bool WalkRegionBoundary(ITextPointer navigator, ITextPointer limit, char[] text, int cchReq, ref int charsCopied, UnsafeNativeMethods.TS_RUNINFO[] runInfo, int cRunInfoReq, ref int cRunInfoRcv)
        {
            bool hitLimit;

            Invariant.Assert(navigator.GetPointerContext(LogicalDirection.Forward) == TextPointerContext.ElementStart || navigator.GetPointerContext(LogicalDirection.Forward) == TextPointerContext.ElementEnd);
            Invariant.Assert(limit == null || navigator.CompareTo(limit) <= 0);

            // If the caller passed in a non-null limit, we don't do anything and just return true.
            // we've passed it.
            if (limit != null)
            {
                if (navigator.CompareTo(limit) >= 0)
                {
                    return true;
                }
            }

            hitLimit = false;

            if (cchReq > 0)
            {
                // Add one TS_CHAR_REGION (TableCell) or '\n' (everything else) char.
                char ch = (navigator.GetAdjacentElement(LogicalDirection.Forward) is TableCell) ? UnsafeNativeMethods.TS_CHAR_REGION : '\n';
                text[charsCopied] = ch;
                navigator.MoveByOffset(1);
                charsCopied += 1;
                hitLimit = (text.Length == charsCopied) || (limit != null && navigator.CompareTo(limit) == 0);
            }
            else
            {
                // Caller doesn't want text, just run info.
                // Advance the navigator.
                // Add one TS_CHAR_REGION char.
                navigator.MoveByOffset(1);
            }

            if (cRunInfoReq > 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 += 1;
                }
                else
                {
                    runInfo[cRunInfoRcv].count = 1;
                    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;
        }
Esempio n. 50
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;
        }
        // Adds a new run into an old one, merging the two.
        private void AddRun(int index, ITextPointer start, ITextPointer end, RunType runType)
        {
            Run run;
            Run newRun;
            RunType oppositeRunType;

            // We don't expect runType.Error, just clean or dirty.
            Invariant.Assert(runType == RunType.Clean || runType == RunType.Dirty);
            // We don't expect empty runs here.
            Invariant.Assert(start.CompareTo(end) < 0);

            oppositeRunType = (runType == RunType.Clean) ? RunType.Dirty : RunType.Clean;
            run = GetRun(index);

            if (run.RunType == runType)
            {
                // Existing run value matches new one.
                TryToMergeRunWithNeighbors(index);
            }
            else if (run.RunType == oppositeRunType)
            {
                // We're merging a new clean run with an old dirty one, or vice versa.

                // Split the run, insert a new run in the middle.
                if (run.Position.CompareTo(start) >= 0)
                {
                    if (GetRunEndPosition(index).CompareTo(end) <= 0)
                    {
                        // We entirely cover this run, just flip the RunType.
                        run.RunType = runType;

                        TryToMergeRunWithNeighbors(index);
                    }
                    else
                    {
                        // We cover the left half.
                        if (index > 0 && GetRun(index - 1).RunType == runType)
                        {
                            // Previous run matches the new value, merge with it.
                            run.Position = end;
                        }
                        else
                        {
                            run.RunType = runType;
                            newRun = new Run(end, oppositeRunType);
                            _runList.Insert(index + 1, newRun);
                        }
                    }
                }
                else if (GetRunEndPosition(index).CompareTo(end) <= 0)
                {
                    // We cover the right half.
                    if (index < _runList.Count - 1 && GetRun(index + 1).RunType == runType)
                    {
                        // Following run matches the new value, merge with it.
                        GetRun(index + 1).Position = start;
                    }
                    else
                    {
                        // Insert new run.
                        newRun = new Run(start, runType);
                        _runList.Insert(index + 1, newRun);
                    }
                }
                else
                {
                    // We're in the middle of the run.
                    // Split the run, adding a new run and a new second
                    // half of the original run.
                    newRun = new Run(start, runType);
                    _runList.Insert(index + 1, newRun);
                    newRun = new Run(end, oppositeRunType);
                    _runList.Insert(index + 2, newRun);
                }
            }
            else
            {
                ITextPointer errorStart;
                ITextPointer errorEnd;

                // We hit an error run, the whole thing becomes dirty/clean.
                run.RunType = runType;

                errorStart = run.Position;
                errorEnd = GetRunEndPositionDynamic(index);

                // This call might remove run...
                TryToMergeRunWithNeighbors(index);

                // Tell the HighlightLayer about this change.
                _highlightLayer.FireChangedEvent(errorStart, errorEnd);
            }
        }
Esempio n. 52
0
        // Repositions an ITextRange to comply with limitations on IME input.
        // We cannot modify Table structure, or insert content
        // before or after Tables or BlockUIContainers while maintaing our
        // contract with the cicero interfaces (without major refactoring of
        // our code).
        private static void GetAdjustedSelection(ITextPointer startIn, ITextPointer endIn, out ITextPointer startOut, out ITextPointer endOut)
        {
            startOut = startIn;
            endOut = endIn;

            TextPointer start = startOut as TextPointer;

            // Tables and BlockUIContainers only exist in TextContainers, if
            // we're in some other kind of document no adjustments are needed.
            if (start == null)
            {
                return;
            }

            TextPointer end = (TextPointer)endOut;

            if (startIn.CompareTo(endIn) != 0)
            {
                bool scopingBlockUIContainer = TextPointerBase.IsInBlockUIContainer(start) || TextPointerBase.IsInBlockUIContainer(end);
                TableCell startCell = TextRangeEditTables.GetTableCellFromPosition(start);
                TableCell endCell = TextRangeEditTables.GetTableCellFromPosition(end);
                bool singleScopingTableCell = (startCell != null && startCell == endCell);
                bool scopingTable = TextRangeEditTables.GetTableFromPosition(start) != null || TextRangeEditTables.GetTableFromPosition(end) != null;

                // With a non-empty selection, if neither end of the selection is inside a Table or BlockUIContainer,
                // there's nothing to adjust.
                if (!scopingBlockUIContainer &&
                    (singleScopingTableCell || !scopingTable))
                {
                    return;
                }
            }

            // From this point forward, we know selection will collapse to
            // a single insertion point, so we ignore end.

            if (start.IsAtRowEnd)
            {
                TextPointer previousPosition = start.GetNextInsertionPosition(LogicalDirection.Backward);
                Table currentTable = TextRangeEditTables.GetTableFromPosition(start);
                start = TextRangeEditTables.GetAdjustedRowEndPosition(currentTable, start);

                if (!start.IsAtInsertionPosition)
                {
                    // The document ends with a Table, and position is just past that.
                    // Back up to the previous TableCell proceding.
                    start = previousPosition;
                }
            }
            else if (TextPointerBase.IsInBlockUIContainer(start))
            {
                if (start.GetPointerContext(LogicalDirection.Backward) == TextPointerContext.ElementStart)
                {
                    start = start.GetNextInsertionPosition(LogicalDirection.Backward);
                }
                else
                {
                    start = start.GetNextInsertionPosition(LogicalDirection.Forward);
                }
            }

            while (start != null && TextPointerBase.IsBeforeFirstTable(start))
            {
                // Note that the symmetrical case, AfterLastTable, is handled by
                // the IsAtRowEnd test above.
                start = start.GetNextInsertionPosition(LogicalDirection.Forward);
            }

            // If we have non-canonical format, give up.
            if (start == null || start.IsAtRowEnd || TextPointerBase.IsInBlockUIContainer(start))
            {
                throw new COMException(SR.Get(SRID.TextStore_CompositionRejected), NativeMethods.E_FAIL);
            }

            startOut = start;
            endOut = start;
        }
        /// <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);
            }
        }
Esempio n. 54
0
        // Normalizes a range:
        //
        // -The start position is advanced over all element edges not visible
        //  to the IMEs.
        // -Start and end positions are moved to insertion positions.
        private void GetNormalizedRange(int startCharOffset, int endCharOffset, out ITextPointer start, out ITextPointer end)
        {
            start = CreatePointerAtCharOffset(startCharOffset, LogicalDirection.Forward);
            end = (startCharOffset == endCharOffset) ? start : CreatePointerAtCharOffset(endCharOffset, LogicalDirection.Backward);

            // Skip over hidden element edges.
            while (start.CompareTo(end) < 0)
            {
                TextPointerContext forwardContext = start.GetPointerContext(LogicalDirection.Forward);

                if (forwardContext == TextPointerContext.ElementStart)
                {
                    TextElement element = start.GetAdjacentElement(LogicalDirection.Forward) as TextElement;

                    if (element == null)
                        break;
                    if (element.IMELeftEdgeCharCount != 0)
                        break;
                }
                else if (forwardContext != TextPointerContext.ElementEnd)
                {
                    break;
                }

                start.MoveToNextContextPosition(LogicalDirection.Forward);
            }

            // Move to insertion positions.
            // If the positions are already adjacent to text, we must respect
            // the IME's decision in regards to exact placement.
            // MoveToInsertionPosition will skip over surrogates and combining
            // marks, but the IME needs fine-grained control over these positions.

            if (start.CompareTo(end) == 0)
            {
                start = start.GetFormatNormalizedPosition(LogicalDirection.Backward);
                end = start;
            }
            else
            {
                start = start.GetFormatNormalizedPosition(LogicalDirection.Backward);
                end = end.GetFormatNormalizedPosition(LogicalDirection.Backward);
            }
        }
Esempio n. 55
0
        // GetText handler for object runs.
        private static bool WalkObjectRun(ITextPointer navigator, ITextPointer limit, char[] text, int cchReq, ref int charsCopied, UnsafeNativeMethods.TS_RUNINFO[] runInfo, int cRunInfoReq, ref int cRunInfoRcv)
        {
            bool hitLimit;

            Invariant.Assert(navigator.GetPointerContext(LogicalDirection.Forward) == TextPointerContext.EmbeddedElement);
            Invariant.Assert(limit == null || navigator.CompareTo(limit) <= 0);

            if (limit != null && navigator.CompareTo(limit) == 0)
            {
                return true;
            }

            hitLimit = false;

            navigator.MoveToNextContextPosition(LogicalDirection.Forward);

            if (cchReq >= 1)
            {
                text[charsCopied] = UnsafeNativeMethods.TS_CHAR_EMBEDDED;
                charsCopied++;
            }

            if (cRunInfoReq > 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++;
                }
                else
                {
                    runInfo[cRunInfoRcv].count = 1;
                    runInfo[cRunInfoRcv].type = UnsafeNativeMethods.TsRunType.TS_RT_PLAIN;
                    cRunInfoRcv++;
                }
            }

            return hitLimit;
        }
Esempio n. 56
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();
        }
Esempio n. 57
0
            // Constructor.
            internal TextSelectionHighlightChangedEventArgs(ITextPointer invalidRangeLeftStart, ITextPointer invalidRangeLeftEnd,
                                                            ITextPointer invalidRangeRightStart, ITextPointer invalidRangeRightEnd)
            {
                List<TextSegment> rangeArray;

                Invariant.Assert(invalidRangeLeftStart != invalidRangeLeftEnd || invalidRangeRightStart != invalidRangeRightEnd, "Unexpected empty range!");

                if (invalidRangeLeftStart.CompareTo(invalidRangeLeftEnd) == 0)
                {
                    rangeArray = new List<TextSegment>(1);
                    rangeArray.Add(new TextSegment(invalidRangeRightStart, invalidRangeRightEnd));
                }
                else if (invalidRangeRightStart.CompareTo(invalidRangeRightEnd) == 0)
                {
                    rangeArray = new List<TextSegment>(1);
                    rangeArray.Add(new TextSegment(invalidRangeLeftStart, invalidRangeLeftEnd));
                }
                else
                {
                    rangeArray = new List<TextSegment>(2);
                    rangeArray.Add(new TextSegment(invalidRangeLeftStart, invalidRangeLeftEnd));
                    rangeArray.Add(new TextSegment(invalidRangeRightStart, invalidRangeRightEnd));
                }

                _ranges = new ReadOnlyCollection<TextSegment>(rangeArray);
            }
 /// <summary>
 /// Returns the following TextPointer of a pair.
 /// </summary>
 /// <param name="position1">
 /// TextPointer to compare.
 /// </param>
 /// <param name="position2">
 /// TextPointer to compare.
 /// </param>
 internal static ITextPointer Max(ITextPointer position1, ITextPointer position2)
 {
     return position1.CompareTo(position2) >= 0 ? position1 : position2;
 }
Esempio n. 59
0
        internal CellParaClient GetCellParaClientFromPosition(ITextPointer position)
        {
            Debug.Assert(   TableParagraph.Table != null
                        &&  CalculatedColumns != null  );

            PTS.FSTABLEROWDESCRIPTION[] arrayTableRowDesc;
            PTS.FSKUPDATE fskupdTable;
            PTS.FSRECT rectTable;

            if (QueryTableDetails(out arrayTableRowDesc, out fskupdTable, out rectTable))
            {
                for (int iR = 0; iR < arrayTableRowDesc.Length; ++iR)
                {
                    PTS.FSKUPDATE[] arrayUpdate;
                    IntPtr[] arrayFsCell;
                    PTS.FSTABLEKCELLMERGE[] arrayTableCellMerge;

                    QueryRowDetails(
                        arrayTableRowDesc[iR].pfstablerow,
                        out arrayFsCell,
                        out arrayUpdate,
                        out arrayTableCellMerge);

                    for (int iC = 0; iC < arrayFsCell.Length; ++iC)
                    {
                        if (arrayFsCell[iC] == IntPtr.Zero)
                        {
                            //  paginated case - cell may be null
                            continue;
                        }

                        CellParaClient cpc = (CellParaClient)(PtsContext.HandleToObject(arrayFsCell[iC]));

                        if(position.CompareTo(cpc.Cell.ContentStart) >= 0 && position.CompareTo(cpc.Cell.ContentEnd) <= 0)
                        {
                            return cpc;
                        }
                    }
                }
            }

            return (null);
        }
        private static ITextPointer RestrictWithinBlock(ITextPointer position, ITextPointer limit, LogicalDirection direction)
        {
            Invariant.Assert(!(direction == LogicalDirection.Backward) || position.CompareTo(limit) >= 0, "for backward direction position must be >= than limit");
            Invariant.Assert(!(direction == LogicalDirection.Forward) || position.CompareTo(limit) <= 0, "for forward direcion position must be <= than linit");

            while (direction == LogicalDirection.Backward ? position.CompareTo(limit) > 0 : position.CompareTo(limit) < 0)
            {
                TextPointerContext context = position.GetPointerContext(direction);
                if (context == TextPointerContext.ElementStart || context == TextPointerContext.ElementEnd)
                {
                    Type elementType = position.GetElementType(direction);
                    if (!typeof(Inline).IsAssignableFrom(elementType))
                    {
                        limit = position;
                        break;
                    }
                }
                else if (context == TextPointerContext.EmbeddedElement)
                {
                    limit = position;
                    break;
                }
                position = position.GetNextContextPosition(direction);
            }

            // Return normalized position - in the direction towards a center position.
            return limit.GetInsertionPosition(direction == LogicalDirection.Backward ? LogicalDirection.Forward : LogicalDirection.Backward);
        }