Exemplo n.º 1
0
        /// <summary>
        /// Retrieves an oriented text position matching position advanced by
        /// a number of lines from its initial position.
        /// </summary>
        /// <param name="position">
        /// Initial text position of an object/character.
        /// </param>
        /// <param name="suggestedX">
        /// The suggested X offset, in pixels, of text position on the destination
        /// line. If suggestedX is set to Double.NaN it will be ignored, otherwise
        /// the method will try to find a position on the destination line closest
        /// to suggestedX.
        /// </param>
        /// <param name="count">
        /// Number of lines to advance. Negative means move backwards.
        /// </param>
        /// <param name="newSuggestedX">
        /// newSuggestedX is the offset at the position moved (useful when moving
        /// between columns or pages).
        /// </param>
        /// <param name="linesMoved">
        /// linesMoved indicates the number of lines moved, which may be less
        /// than count if there is no more content.
        /// </param>
        /// <returns>
        /// A TextPointer and its orientation matching suggestedX on the
        /// destination line.
        /// </returns>
        /// <exception cref="System.InvalidOperationException">
        /// Throws InvalidOperationException if IsValid is false.
        /// If IsValid returns false, Validate method must be called before
        /// calling this method.
        /// </exception>
        internal override ITextPointer GetPositionAtNextLine(ITextPointer position, double suggestedX, int count, out double newSuggestedX, out int linesMoved)
        {
            newSuggestedX = suggestedX;
            linesMoved    = count;

            DocumentsTrace.FixedDocumentSequence.TextOM.Trace(string.Format("GetPositionAtNextLine {0} {1} {2} {3} ", position, position.LogicalDirection, suggestedX, count));
            DocumentSequenceTextPointer newTp   = null;
            LogicalDirection            newEdge = LogicalDirection.Forward;
            DocumentSequenceTextPointer tp      = null;

            if (position != null)
            {
                tp = _docPage.FixedDocumentSequence.TextContainer.VerifyPosition(position);
            }

            // Note we do not handle cross page navigation
            if (tp != null)
            {
                if (ChildTextView != null)
                {
                    if (ChildTextView.TextContainer == tp.ChildBlock.ChildContainer)
                    {
                        ITextPointer childOTP = ChildTextView.GetPositionAtNextLine(tp.ChildPointer.CreatePointer(position.LogicalDirection), suggestedX, count, out newSuggestedX, out linesMoved);
                        if (childOTP != null)
                        {
                            newTp   = new DocumentSequenceTextPointer(ChildBlock, childOTP);
                            newEdge = childOTP.LogicalDirection;
                        }
                    }
                }
            }
            return(DocumentSequenceTextPointer.CreatePointer(newTp, newEdge));
        }
Exemplo n.º 2
0
        /// <summary>
        /// Retrieves the height and offset, in pixels, of the edge of
        /// the object/character represented by position.
        /// </summary>
        /// <param name="position">
        /// Position of an object/character.
        /// </param>
        /// <param name="transform">
        /// Transform to be applied to returned rect
        /// </param>
        /// <returns>
        /// The height, in pixels, of the edge of the object/character
        /// represented by position.
        /// </returns>
        /// <exception cref="System.InvalidOperationException">
        /// Throws InvalidOperationException if IsValid is false.
        /// If IsValid returns false, Validate method must be called before
        /// calling this method.
        /// </exception>
        /// <remarks>
        /// Rect.Width is always 0.
        ///
        /// If the document is empty, then this method returns the expected
        /// height of a character, if placed at the specified position.
        /// </remarks>
        internal override Rect GetRawRectangleFromTextPosition(ITextPointer position, out Transform transform)
        {
            DocumentsTrace.FixedDocumentSequence.TextOM.Trace(string.Format("GetRawRectangleFromTextPosition {0} {1}", position, position.LogicalDirection));
            DocumentSequenceTextPointer tp = null;

            // Initialize transform to identity
            transform = Transform.Identity;

            if (position != null)
            {
                tp = _docPage.FixedDocumentSequence.TextContainer.VerifyPosition(position);
            }

            if (tp != null)
            {
                if (ChildTextView != null)
                {
                    if (ChildTextView.TextContainer == tp.ChildBlock.ChildContainer)
                    {
                        return(ChildTextView.GetRawRectangleFromTextPosition(tp.ChildPointer.CreatePointer(position.LogicalDirection), out transform));
                    }
                }
            }
            return(Rect.Empty);
        }
Exemplo n.º 3
0
        //  Intelligent compare routine that understands block gap
        //  Since there it is assumed that there is an invisible Gap
        //  object between adjancent two blocks, there is no position
        //  overlap.
        private static int xGapAwareCompareTo(DocumentSequenceTextPointer thisTp, DocumentSequenceTextPointer tp)
        {
            Debug.Assert(tp != null);
            if ((object)thisTp == (object)tp)
            {
                return(0);
            }

            ChildDocumentBlock thisBlock = thisTp.ChildBlock;
            ChildDocumentBlock tpBlock   = tp.ChildBlock;

            int comp = thisTp.AggregatedContainer.GetChildBlockDistance(thisBlock, tpBlock);

            if (comp == 0)
            {
                Debug.Assert(thisTp.ChildBlock.ChildContainer == tp.ChildBlock.ChildContainer);
                return(thisTp.ChildPointer.CompareTo(tp.ChildPointer));
            }
            else if (comp < 0)
            {
                // thisBlock is after tpBlock
                return(xUnseparated(tp, thisTp) ? 0 : 1);
            }
            else
            {
                // thisBlock is before tpBlock
                return(xUnseparated(thisTp, tp) ? 0 : -1);
            }
        }
Exemplo n.º 4
0
        // Token: 0x06002B79 RID: 11129 RVA: 0x000C66D0 File Offset: 0x000C48D0
        internal int GetPageNumber(ContentPosition contentPosition)
        {
            if (contentPosition == null)
            {
                throw new ArgumentNullException("contentPosition");
            }
            DynamicDocumentPaginator dynamicDocumentPaginator = null;
            ContentPosition          contentPosition2         = null;

            if (contentPosition is DocumentSequenceTextPointer)
            {
                DocumentSequenceTextPointer documentSequenceTextPointer = (DocumentSequenceTextPointer)contentPosition;
                dynamicDocumentPaginator = this.GetPaginator(documentSequenceTextPointer.ChildBlock.DocRef);
                contentPosition2         = (documentSequenceTextPointer.ChildPointer as ContentPosition);
            }
            if (contentPosition2 == null)
            {
                throw new ArgumentException(SR.Get("IDPInvalidContentPosition"));
            }
            int pageNumber = dynamicDocumentPaginator.GetPageNumber(contentPosition2);
            int result;

            this._SynthesizeGlobalPageNumber(dynamicDocumentPaginator, pageNumber, out result);
            return(result);
        }
Exemplo n.º 5
0
        // Token: 0x06002E74 RID: 11892 RVA: 0x000D2774 File Offset: 0x000D0974
        private static void _GetFirstPageSearchPointers(ITextPointer start, ITextPointer end, int pageNumber, bool matchLast, out ITextPointer firstSearchPageStart, out ITextPointer firstSearchPageEnd)
        {
            if (matchLast)
            {
                DocumentSequenceTextPointer documentSequenceTextPointer = end as DocumentSequenceTextPointer;
                if (documentSequenceTextPointer != null)
                {
                    FlowPosition pageStartFlowPosition = ((FixedTextContainer)documentSequenceTextPointer.ChildBlock.ChildContainer).FixedTextBuilder.GetPageStartFlowPosition(pageNumber);
                    firstSearchPageStart = new DocumentSequenceTextPointer(documentSequenceTextPointer.ChildBlock, new FixedTextPointer(false, LogicalDirection.Forward, pageStartFlowPosition));
                }
                else
                {
                    FixedTextPointer fixedTextPointer = end as FixedTextPointer;
                    firstSearchPageStart = new FixedTextPointer(false, LogicalDirection.Forward, fixedTextPointer.FixedTextContainer.FixedTextBuilder.GetPageStartFlowPosition(pageNumber));
                }
                firstSearchPageEnd = end;
                return;
            }
            DocumentSequenceTextPointer documentSequenceTextPointer2 = start as DocumentSequenceTextPointer;

            if (documentSequenceTextPointer2 != null)
            {
                FlowPosition pageEndFlowPosition = ((FixedTextContainer)documentSequenceTextPointer2.ChildBlock.ChildContainer).FixedTextBuilder.GetPageEndFlowPosition(pageNumber);
                firstSearchPageEnd = new DocumentSequenceTextPointer(documentSequenceTextPointer2.ChildBlock, new FixedTextPointer(false, LogicalDirection.Backward, pageEndFlowPosition));
            }
            else
            {
                FixedTextPointer fixedTextPointer2 = start as FixedTextPointer;
                firstSearchPageEnd = new FixedTextPointer(false, LogicalDirection.Backward, fixedTextPointer2.FixedTextContainer.FixedTextBuilder.GetPageEndFlowPosition(pageNumber));
            }
            firstSearchPageStart = start;
        }
Exemplo n.º 6
0
        /// <summary>
        /// Returns a TextSegment that spans the line on which position is located.
        /// </summary>
        /// <param name="position">
        /// Any oriented text position on the line.
        /// </param>
        /// <returns>
        /// TextSegment that spans the line on which position is located.
        /// </returns>
        /// <exception cref="System.InvalidOperationException">
        /// Throws InvalidOperationException if IsValid is false.
        /// If IsValid returns false, Validate method must be called before
        /// calling this method.
        /// </exception>
        internal override TextSegment GetLineRange(ITextPointer position)
        {
            DocumentsTrace.FixedDocumentSequence.TextOM.Trace(string.Format("GetLineRange {0} {1}", position, position.LogicalDirection));
            DocumentSequenceTextPointer tpStart = null;
            DocumentSequenceTextPointer tpEnd   = null;
            DocumentSequenceTextPointer tpLine  = null;

            if (position != null)
            {
                if (ChildTextView != null)
                {
                    tpLine = _docPage.FixedDocumentSequence.TextContainer.VerifyPosition(position);

                    if (ChildTextView.TextContainer == tpLine.ChildBlock.ChildContainer)
                    {
                        TextSegment childTR = ChildTextView.GetLineRange(tpLine.ChildPointer.CreatePointer(position.LogicalDirection));
                        if (!childTR.IsNull)
                        {
                            tpStart = new DocumentSequenceTextPointer(ChildBlock, childTR.Start);
                            tpEnd   = new DocumentSequenceTextPointer(ChildBlock, childTR.End);
                            return(new TextSegment(tpStart, tpEnd, true));
                        }
                    }
                }
            }
            return(TextSegment.Null);
        }
Exemplo n.º 7
0
        // Token: 0x06002C1C RID: 11292 RVA: 0x000C8430 File Offset: 0x000C6630
        private static int xGapAwareCompareTo(DocumentSequenceTextPointer thisTp, DocumentSequenceTextPointer tp)
        {
            if (thisTp == tp)
            {
                return(0);
            }
            ChildDocumentBlock childBlock  = thisTp.ChildBlock;
            ChildDocumentBlock childBlock2 = tp.ChildBlock;
            int childBlockDistance         = thisTp.AggregatedContainer.GetChildBlockDistance(childBlock, childBlock2);

            if (childBlockDistance == 0)
            {
                return(thisTp.ChildPointer.CompareTo(tp.ChildPointer));
            }
            if (childBlockDistance < 0)
            {
                if (!DocumentSequenceTextPointer.xUnseparated(tp, thisTp))
                {
                    return(1);
                }
                return(0);
            }
            else
            {
                if (!DocumentSequenceTextPointer.xUnseparated(thisTp, tp))
                {
                    return(-1);
                }
                return(0);
            }
        }
Exemplo n.º 8
0
        // Token: 0x06002C0D RID: 11277 RVA: 0x000C81A4 File Offset: 0x000C63A4
        public static Type GetElementType(DocumentSequenceTextPointer thisTp, LogicalDirection direction)
        {
            ValidationHelper.VerifyDirection(direction, "direction");
            DocumentSequenceTextPointer documentSequenceTextPointer = DocumentSequenceTextPointer.xGetClingDSTP(thisTp, direction);

            return(documentSequenceTextPointer.ChildPointer.GetElementType(direction));
        }
Exemplo n.º 9
0
        // Token: 0x06002C19 RID: 11289 RVA: 0x000C8360 File Offset: 0x000C6560
        private static DocumentSequenceTextPointer xGetClingDSTP(DocumentSequenceTextPointer thisTp, LogicalDirection direction)
        {
            TextPointerContext pointerContext = thisTp.ChildPointer.GetPointerContext(direction);

            if (pointerContext != TextPointerContext.None)
            {
                return(thisTp);
            }
            ChildDocumentBlock childDocumentBlock = thisTp.ChildBlock;
            ITextPointer       textPointer        = thisTp.ChildPointer;

            if (direction == LogicalDirection.Forward)
            {
                while (pointerContext == TextPointerContext.None)
                {
                    if (childDocumentBlock.IsTail)
                    {
                        break;
                    }
                    childDocumentBlock = childDocumentBlock.NextBlock;
                    textPointer        = childDocumentBlock.ChildContainer.Start;
                    pointerContext     = textPointer.GetPointerContext(direction);
                }
            }
            else
            {
                while (pointerContext == TextPointerContext.None && !childDocumentBlock.IsHead)
                {
                    childDocumentBlock = childDocumentBlock.PreviousBlock;
                    textPointer        = childDocumentBlock.ChildContainer.End;
                    pointerContext     = textPointer.GetPointerContext(direction);
                }
            }
            return(new DocumentSequenceTextPointer(childDocumentBlock, textPointer));
        }
Exemplo n.º 10
0
            // Token: 0x0600847C RID: 33916 RVA: 0x002483B0 File Offset: 0x002465B0
            private StaticTextPointer GetStaticPositionInChildContainer(StaticTextPointer textPosition, LogicalDirection direction, StaticTextPointer originalPosition)
            {
                StaticTextPointer result = StaticTextPointer.Null;

                if (!textPosition.IsNull)
                {
                    DocumentSequenceTextPointer documentSequenceTextPointer = textPosition.CreateDynamicTextPointer(LogicalDirection.Forward) as DocumentSequenceTextPointer;
                    ITextPointer textPointer = documentSequenceTextPointer.ChildPointer;
                    if (textPointer.TextContainer != originalPosition.TextContainer)
                    {
                        if (this.IsContentHighlighted(originalPosition, direction))
                        {
                            textPointer = ((direction == LogicalDirection.Forward) ? originalPosition.TextContainer.End : originalPosition.TextContainer.Start);
                            result      = textPointer.CreateStaticPointer();
                        }
                        else
                        {
                            result = StaticTextPointer.Null;
                        }
                    }
                    else
                    {
                        result = textPointer.CreateStaticPointer();
                    }
                }
                return(result);
            }
Exemplo n.º 11
0
 // Token: 0x06002BD1 RID: 11217 RVA: 0x000C7918 File Offset: 0x000C5B18
 private void AddChange(ITextPointer startPosition, int symbolCount, PrecursorTextChangeType precursorTextChange)
 {
     Invariant.Assert(!this._isReadOnly, "Illegal to modify DocumentSequenceTextContainer inside Change event scope!");
     ((ITextContainer)this).BeginChange();
     try
     {
         if (this.Changing != null)
         {
             this.Changing(this, EventArgs.Empty);
         }
         if (this._changes == null)
         {
             this._changes = new TextContainerChangedEventArgs();
         }
         this._changes.AddChange(precursorTextChange, DocumentSequenceTextPointer.GetOffsetToPosition(this._start, startPosition), symbolCount, false);
         if (this.Change != null)
         {
             Invariant.Assert(precursorTextChange == PrecursorTextChangeType.ContentAdded || precursorTextChange == PrecursorTextChangeType.ContentRemoved);
             TextChangeType textChange = (precursorTextChange == PrecursorTextChangeType.ContentAdded) ? TextChangeType.ContentAdded : TextChangeType.ContentRemoved;
             this._isReadOnly = true;
             try
             {
                 this.Change(this, new TextContainerChangeEventArgs(startPosition, symbolCount, -1, textChange));
             }
             finally
             {
                 this._isReadOnly = false;
             }
         }
     }
     finally
     {
         ((ITextContainer)this).EndChange();
     }
 }
Exemplo n.º 12
0
        // ======================================================
        // Static part of a class

        // <summary>
        // DocumentSequenceTextPointer is a static  class that is provided all the
        // common functions of ITextPointer/ITextNavigaor for DocumentSequence.
        // Since we don't have multiple inheritance, this is a way to share code between
        // DocumentSequenceTextPointer and DocumentSequenceTextPointer.
        // </summary>

        //------------------------------------------------------
        //
        //  Public Methods
        //
        //------------------------------------------------------
        #region TextPointer Methods
        /// <summary>
        /// <see cref="ITextPointer.CompareTo(ITextPointer)"/>
        /// </summary>
        public static int CompareTo(DocumentSequenceTextPointer thisTp, ITextPointer position)
        {
            DocumentSequenceTextPointer tp = thisTp.AggregatedContainer.VerifyPosition(position);

            // Now do compare
            return(xGapAwareCompareTo(thisTp, tp));
        }
Exemplo n.º 13
0
        /// <summary>
        /// <see cref="ITextPointer.GetTextInRun(LogicalDirection,char[],int,int)"/>
        /// </summary>
        /// <remarks>Only reutrn uninterrupted runs of text</remarks>
        public static int GetTextInRun(DocumentSequenceTextPointer thisTp, LogicalDirection direction, char[] textBuffer, int startIndex, int count)
        {
            ValidationHelper.VerifyDirection(direction, "direction");

            if (textBuffer == null)
            {
                throw new ArgumentNullException("textBuffer");
            }
            if (startIndex < 0)
            {
                throw new ArgumentException(SR.Get(SRID.NegativeValue, "startIndex"));
            }
            if (startIndex > textBuffer.Length)
            {
                throw new ArgumentException(SR.Get(SRID.StartIndexExceedsBufferSize, startIndex, textBuffer.Length));
            }
            if (count < 0)
            {
                throw new ArgumentException(SR.Get(SRID.NegativeValue, "count"));
            }
            if (count > textBuffer.Length - startIndex)
            {
                throw new ArgumentException(SR.Get(SRID.MaxLengthExceedsBufferSize, count, textBuffer.Length, startIndex));
            }

            return(thisTp.ChildPointer.GetTextInRun(direction, textBuffer, startIndex, count));
        }
Exemplo n.º 14
0
        /// <summary>
        /// <see cref="DynamicDocumentPaginator.GetPageNumber"/>
        /// </summary>
        internal int GetPageNumber(ContentPosition contentPosition)
        {
            if (contentPosition == null)
            {
                throw new ArgumentNullException("contentPosition");
            }

            // ContentPosition may be only created by DynamicDocumentPaginator.GetObjectPosition or
            // DynamicDocumentPaginator.GetPagePosition.
            // Because of that we are expecting one of 2 types here.
            DynamicDocumentPaginator childPaginator       = null;
            ContentPosition          childContentPosition = null;

            if (contentPosition is DocumentSequenceTextPointer)
            {
                DocumentSequenceTextPointer dsTextPointer = (DocumentSequenceTextPointer)contentPosition;

                #pragma warning suppress 6506 // dsTextPointer is obviously not null
                childPaginator       = GetPaginator(dsTextPointer.ChildBlock.DocRef);
                childContentPosition = dsTextPointer.ChildPointer as ContentPosition;
            }

            if (childContentPosition == null)
            {
                throw new ArgumentException(SR.Get(SRID.IDPInvalidContentPosition));
            }

            int childPageNumber = childPaginator.GetPageNumber(childContentPosition);
            int pageNumber;
            _SynthesizeGlobalPageNumber(childPaginator, childPageNumber, out pageNumber);
            return(pageNumber);
        }
Exemplo n.º 15
0
 // Token: 0x06002C11 RID: 11281 RVA: 0x000C8278 File Offset: 0x000C6478
 public static object ReadLocalValue(DocumentSequenceTextPointer thisTp, DependencyProperty property)
 {
     if (property == null)
     {
         throw new ArgumentNullException("property");
     }
     return(thisTp.ChildPointer.ReadLocalValue(property));
 }
Exemplo n.º 16
0
 internal static string ToString(DocumentSequenceTextPointer thisTp)
 {
     return((thisTp is DocumentSequenceTextPointer ? "DSTP" : "DSTN")
            + " Id=" + thisTp.DebugId
            + " B=" + thisTp.ChildBlock.DebugId
            + " G=" + thisTp.ChildPointer.LogicalDirection
            );
 }
        // Token: 0x06002C2A RID: 11306 RVA: 0x000C8A64 File Offset: 0x000C6C64
        internal override bool Contains(ITextPointer position)
        {
            DocumentSequenceTextPointer documentSequenceTextPointer = null;

            if (position != null)
            {
                documentSequenceTextPointer = this._docPage.FixedDocumentSequence.TextContainer.VerifyPosition(position);
            }
            return(documentSequenceTextPointer != null && this.ChildTextView != null && this.ChildTextView.TextContainer == documentSequenceTextPointer.ChildBlock.ChildContainer && this.ChildTextView.Contains(documentSequenceTextPointer.ChildPointer.CreatePointer(position.LogicalDirection)));
        }
Exemplo n.º 18
0
        //------------------------------------------------------
        //
        //  Public Properties
        //
        //------------------------------------------------------


        //------------------------------------------------------
        //
        //  Public Events
        //
        //------------------------------------------------------


        //------------------------------------------------------
        //
        //  Internal Methods
        //
        //------------------------------------------------------

        #region Internal Methods


        // Internal Method, input parameter contains TP that is not synced to generation
        internal static bool iScan(DocumentSequenceTextPointer thisTp, LogicalDirection direction)
        {
            bool moved = thisTp.ChildPointer.MoveToNextContextPosition(direction);

            if (!moved)
            {
                moved = xGapAwareScan(thisTp, (direction == LogicalDirection.Forward ? 1 : -1));
            }
            return(moved);
        }
Exemplo n.º 19
0
        // Token: 0x06002C0F RID: 11279 RVA: 0x000C81E0 File Offset: 0x000C63E0
        public static bool HasEqualScope(DocumentSequenceTextPointer thisTp, ITextPointer position)
        {
            DocumentSequenceTextPointer documentSequenceTextPointer = thisTp.AggregatedContainer.VerifyPosition(position);

            if (thisTp.ChildPointer.TextContainer == documentSequenceTextPointer.ChildPointer.TextContainer)
            {
                return(thisTp.ChildPointer.HasEqualScope(documentSequenceTextPointer.ChildPointer));
            }
            return(thisTp.ChildPointer.ParentType == typeof(FixedDocument) && documentSequenceTextPointer.ChildPointer.ParentType == typeof(FixedDocument));
        }
Exemplo n.º 20
0
        // Token: 0x06002C17 RID: 11287 RVA: 0x000C8328 File Offset: 0x000C6528
        internal static bool iScan(DocumentSequenceTextPointer thisTp, LogicalDirection direction)
        {
            bool flag = thisTp.ChildPointer.MoveToNextContextPosition(direction);

            if (!flag)
            {
                flag = DocumentSequenceTextPointer.xGapAwareScan(thisTp, (direction == LogicalDirection.Forward) ? 1 : -1);
            }
            return(flag);
        }
Exemplo n.º 21
0
        // Token: 0x06002C16 RID: 11286 RVA: 0x000C82D4 File Offset: 0x000C64D4
        public static ITextPointer CreatePointer(DocumentSequenceTextPointer thisTp, int distance, LogicalDirection gravity)
        {
            ValidationHelper.VerifyDirection(gravity, "gravity");
            DocumentSequenceTextPointer documentSequenceTextPointer = new DocumentSequenceTextPointer(thisTp.ChildBlock, thisTp.ChildPointer.CreatePointer(gravity));

            if (distance != 0 && !DocumentSequenceTextPointer.xGapAwareScan(documentSequenceTextPointer, distance))
            {
                throw new ArgumentException(SR.Get("BadDistance"), "distance");
            }
            return(documentSequenceTextPointer);
        }
Exemplo n.º 22
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));
            }
        }
Exemplo n.º 23
0
        /// <summary>
        /// <see cref="ITextPointer.HasEqualScope"/>
        /// </summary>
        public static bool HasEqualScope(DocumentSequenceTextPointer thisTp, ITextPointer position)
        {
            DocumentSequenceTextPointer tp = thisTp.AggregatedContainer.VerifyPosition(position);

            if (thisTp.ChildPointer.TextContainer == tp.ChildPointer.TextContainer)
            {
                return(thisTp.ChildPointer.HasEqualScope(tp.ChildPointer));
            }
            // The TextOM speced behavior is if both scopes are null, return true.
            return(thisTp.ChildPointer.ParentType == typeof(FixedDocument) && tp.ChildPointer.ParentType == typeof(FixedDocument));
        }
Exemplo n.º 24
0
 // Token: 0x06002BFB RID: 11259 RVA: 0x000C7F0A File Offset: 0x000C610A
 int ITextPointer.MoveByOffset(int offset)
 {
     if (this._isFrozen)
     {
         throw new InvalidOperationException(SR.Get("TextPositionIsFrozen"));
     }
     if (DocumentSequenceTextPointer.iScan(this, offset))
     {
         return(offset);
     }
     return(0);
 }
        // Token: 0x06002C25 RID: 11301 RVA: 0x000C88C0 File Offset: 0x000C6AC0
        internal override bool IsAtCaretUnitBoundary(ITextPointer position)
        {
            Invariant.Assert(position != null);
            if (position == null)
            {
                throw new ArgumentNullException("position");
            }
            Invariant.Assert(this.ChildTextView != null);
            DocumentSequenceTextPointer documentSequenceTextPointer = this.DocumentSequenceTextContainer.VerifyPosition(position);

            return(this.ChildTextView.IsAtCaretUnitBoundary(documentSequenceTextPointer.ChildPointer));
        }
        // Token: 0x06002C26 RID: 11302 RVA: 0x000C8910 File Offset: 0x000C6B10
        internal override ITextPointer GetNextCaretUnitPosition(ITextPointer position, LogicalDirection direction)
        {
            Invariant.Assert(position != null);
            if (position == null)
            {
                throw new ArgumentNullException("position");
            }
            Invariant.Assert(this.ChildTextView != null);
            DocumentSequenceTextPointer documentSequenceTextPointer = this.DocumentSequenceTextContainer.VerifyPosition(position);

            return(this.ChildTextView.GetNextCaretUnitPosition(documentSequenceTextPointer.ChildPointer, direction));
        }
Exemplo n.º 27
0
        //--------------------------------------------------------------------
        // ContentChange
        //---------------------------------------------------------------------
        private void _OnContentChanged(object sender, NotifyCollectionChangedEventArgs args)
        {
#if DEBUG
            this._generation++;
#endif

            if (args.Action == NotifyCollectionChangedAction.Add)
            {
                if (args.NewItems.Count != 1)
                {
                    throw new NotSupportedException(SR.Get(SRID.RangeActionsNotSupported));
                }
                else
                {
                    object item          = args.NewItems[0];
                    int    startingIndex = args.NewStartingIndex;

                    if (startingIndex != _parent.References.Count - 1)
                    {
                        throw new NotSupportedException(SR.Get(SRID.UnexpectedCollectionChangeAction, args.Action));
                    }

                    ChildDocumentBlock newBlock = new ChildDocumentBlock(this, (DocumentReference)item);

                    ChildDocumentBlock insertAfter = _doclistTail.PreviousBlock;
                    insertAfter.InsertNextBlock(newBlock);
                    DocumentSequenceTextPointer changeStart =
                        new DocumentSequenceTextPointer(insertAfter, insertAfter.End);

                    //Update end pointer
                    _end = new DocumentSequenceTextPointer(newBlock, newBlock.ChildContainer.End);

                    if (newBlock.NextBlock == _doclistTail && newBlock.PreviousBlock == _doclistHead)
                    {
                        //Update start pointer for the first block
                        _start = new DocumentSequenceTextPointer(newBlock, newBlock.ChildContainer.Start);
                    }


                    // Record Change Notifications
                    ITextContainer container   = newBlock.ChildContainer;
                    int            symbolCount = 1; // takes too long to calculate for large documents, and no one will use this info

                    // this does not affect state, only fires event handlers
                    AddChange(changeStart, symbolCount, PrecursorTextChangeType.ContentAdded);
                }
            }
            else
            {
                throw new NotSupportedException(SR.Get(SRID.UnexpectedCollectionChangeAction, args.Action));
            }
        }
 // Token: 0x06002C23 RID: 11299 RVA: 0x000C87B4 File Offset: 0x000C69B4
 internal override Geometry GetTightBoundingGeometryFromTextPositions(ITextPointer startPosition, ITextPointer endPosition)
 {
     if (startPosition != null && endPosition != null && this.ChildTextView != null)
     {
         DocumentSequenceTextPointer documentSequenceTextPointer  = this._docPage.FixedDocumentSequence.TextContainer.VerifyPosition(startPosition);
         DocumentSequenceTextPointer documentSequenceTextPointer2 = this._docPage.FixedDocumentSequence.TextContainer.VerifyPosition(endPosition);
         if (documentSequenceTextPointer != null && documentSequenceTextPointer2 != null)
         {
             return(this.ChildTextView.GetTightBoundingGeometryFromTextPositions(documentSequenceTextPointer.ChildPointer, documentSequenceTextPointer2.ChildPointer));
         }
     }
     return(new PathGeometry());
 }
Exemplo n.º 29
0
        /// <summary>
        /// Finds the previous position at the edge of a caret after backspacing.
        /// </summary>
        /// <param name="position">
        /// Initial text position of an object/character.
        /// </param>
        /// <returns>
        /// The previous caret unit break position after backspacing.
        /// </returns>
        /// <exception cref="System.InvalidOperationException">
        /// Throws InvalidOperationException if IsValid is false.
        /// If IsValid returns false, Validate method must be called before
        /// calling this method.
        /// </exception>
        internal override ITextPointer GetBackspaceCaretUnitPosition(ITextPointer position)
        {
            Invariant.Assert(position != null);
            if (position == null)
            {
                throw new ArgumentNullException("position");
            }

            //Verify the position and propagate the call to the child text view
            Invariant.Assert(ChildTextView != null);
            DocumentSequenceTextPointer ftp = this.DocumentSequenceTextContainer.VerifyPosition(position);

            return(this.ChildTextView.GetBackspaceCaretUnitPosition(ftp.ChildPointer));
        }
Exemplo n.º 30
0
        // Token: 0x06002BFC RID: 11260 RVA: 0x000C7F30 File Offset: 0x000C6130
        void ITextPointer.MoveToPosition(ITextPointer position)
        {
            DocumentSequenceTextPointer documentSequenceTextPointer = this.AggregatedContainer.VerifyPosition(position);
            LogicalDirection            logicalDirection            = this.ChildPointer.LogicalDirection;

            this.ChildBlock = documentSequenceTextPointer.ChildBlock;
            if (this.ChildPointer.TextContainer == documentSequenceTextPointer.ChildPointer.TextContainer)
            {
                this.ChildPointer.MoveToPosition(documentSequenceTextPointer.ChildPointer);
                return;
            }
            this.ChildPointer = documentSequenceTextPointer.ChildPointer.CreatePointer();
            this.ChildPointer.SetLogicalDirection(logicalDirection);
        }
 // Internal Method, input parameter contains TP that is not synced to generation
 internal static bool iScan(DocumentSequenceTextPointer thisTp, int distance)
 {
     return xGapAwareScan(thisTp, distance);
 }
        /// <summary>
        /// <see cref="ITextPointer.GetTextInRun(LogicalDirection,char[],int,int)"/>
        /// </summary>
        /// <remarks>Only reutrn uninterrupted runs of text</remarks>
        public static int GetTextInRun(DocumentSequenceTextPointer thisTp, LogicalDirection direction, char[] textBuffer, int startIndex, int count)
        {
            ValidationHelper.VerifyDirection(direction, "direction");

            if (textBuffer == null)
            {
                throw new ArgumentNullException("textBuffer");
            }
            if (startIndex < 0)
            {
                throw new ArgumentException(SR.Get(SRID.NegativeValue, "startIndex"));
            }
            if (startIndex > textBuffer.Length)
            {
                throw new ArgumentException(SR.Get(SRID.StartIndexExceedsBufferSize, startIndex, textBuffer.Length));
            }
            if (count < 0)
            {
                throw new ArgumentException(SR.Get(SRID.NegativeValue, "count"));
            }
            if (count > textBuffer.Length - startIndex)
            {
                throw new ArgumentException(SR.Get(SRID.MaxLengthExceedsBufferSize, count, textBuffer.Length, startIndex));
            }

            return thisTp.ChildPointer.GetTextInRun(direction, textBuffer, startIndex, count);
        }
 /// <summary>
 /// <see cref="ITextPointer.GetElementType"/>
 /// </summary>
 public static Type GetElementType(DocumentSequenceTextPointer thisTp)
 {
     return thisTp.ChildPointer.ParentType;
 }
 /// <summary>
 /// <see cref="ITextPointer.GetLocalValueEnumerator"/>
 /// </summary>
 /// <remarks>Returns an empty enumerator if there is no scoping element</remarks>
 public static LocalValueEnumerator GetLocalValueEnumerator(DocumentSequenceTextPointer thisTp)
 {
     return thisTp.ChildPointer.GetLocalValueEnumerator();
 }
 public static ITextPointer CreatePointer(DocumentSequenceTextPointer thisTp, LogicalDirection gravity)
 {
     return CreatePointer(thisTp, 0, gravity);
 }
        /// <summary>
        /// <see cref="ITextPointer.GetOffsetToPosition"/>
        /// </summary>
        public static int GetOffsetToPosition(DocumentSequenceTextPointer thisTp, ITextPointer position)
        {
            DocumentSequenceTextPointer tp = thisTp.AggregatedContainer.VerifyPosition(position);

            int comp = xGapAwareCompareTo(thisTp, tp);
            if (comp == 0)
            {
                return 0;
            }
            else if (comp <= 0)
            {
                return xGapAwareGetDistance(thisTp, tp);
            }
            else
            {
                return -1 * xGapAwareGetDistance(tp, thisTp);
            }
        }
        /// <summary>
        /// <see cref="ITextPointer.CreatePointer(int,LogicalDirection)"/>
        /// </summary>
        public static ITextPointer CreatePointer(DocumentSequenceTextPointer thisTp, int distance, LogicalDirection gravity)
        {
            ValidationHelper.VerifyDirection(gravity, "gravity");

            // Special case for common case of distance == 0
            // to avoid calculating child container size, which
            // could be expansive especially in case where child
            // container requires virtualization.
            DocumentSequenceTextPointer newTp = new DocumentSequenceTextPointer(thisTp.ChildBlock, thisTp.ChildPointer.CreatePointer(gravity));
            if (distance != 0)
            {
                if (!xGapAwareScan(newTp, distance))
                {
                    throw new ArgumentException(SR.Get(SRID.BadDistance), "distance");
                }
            }
            return newTp;
        }
        //-----------------------------------------------------------------------
        // Trusted Methods -- all positions are in valid blocks
        //
        // Each ChildDocumentBlock pair is separated by a gap (DocumentBreak),
        // which is surfaced as an embedded object. Besides the Head and Tail block,
        // each block is enclosed by two gap objects, one at each end of the
        // TextContainer (Before TextContainer.Start and After TextContainer.End)
        //-----------------------------------------------------------------------


        private static TextPointerContext xGapAwareGetSymbolType(DocumentSequenceTextPointer thisTp, LogicalDirection direction)
        {
            DocumentSequenceTextPointer tp = xGetClingDSTP(thisTp, direction);
            return tp.ChildPointer.GetPointerContext(direction);
        }
        //------------------------------------------------------
        //
        //  Internal Methods
        //
        //------------------------------------------------------

        #region Internal Methods

        /// <summary>
        /// Retrieves a position matching a point.
        /// </summary>
        /// <param name="point">
        /// Point in pixel coordinates to test.
        /// </param>
        /// <param name="snapToText">
        /// If true, this method must always return a positioned text position 
        /// (the closest position as calculated by the control's heuristics). 
        /// If false, this method should return null position, if the test 
        /// point does not fall within any character bounding box.
        /// </param>
        /// <returns>
        /// A text position and its orientation matching or closest to the point.
        /// </returns>
        /// <exception cref="System.InvalidOperationException">
        /// Throws InvalidOperationException if IsValid is false.
        /// If IsValid returns false, Validate method must be called before 
        /// calling this method.
        /// </exception>
        internal override ITextPointer GetTextPositionFromPoint(Point point, bool snapToText)
        {
            DocumentsTrace.FixedDocumentSequence.TextOM.Trace(string.Format("GetTextPositionFromPoint {0}-{1}", point, snapToText));
            DocumentSequenceTextPointer tp = null;
            LogicalDirection edge = LogicalDirection.Forward;

            if (ChildTextView != null)
            {
                ITextPointer childOTP = ChildTextView.GetTextPositionFromPoint(point, snapToText);
                if (childOTP != null)
                {
                    tp = new DocumentSequenceTextPointer(ChildBlock, childOTP);
                    edge = childOTP.LogicalDirection;
                }
            }

            // When snapToText is true, ChildTextView.GetTextPositionFromPoint will guranttee to
            // return a non-null position. 
            // In current code, ChildTextView can't be null. 
            return tp == null ? null : DocumentSequenceTextPointer.CreatePointer(tp, edge);
        }
        /// <summary>
        /// Returns a TextSegment that spans the line on which position is located.
        /// </summary>
        /// <param name="position">
        /// Any oriented text position on the line.
        /// </param>
        /// <returns>
        /// TextSegment that spans the line on which position is located.
        /// </returns>
        /// <exception cref="System.InvalidOperationException">
        /// Throws InvalidOperationException if IsValid is false.
        /// If IsValid returns false, Validate method must be called before 
        /// calling this method.
        /// </exception>
        internal override TextSegment GetLineRange(ITextPointer position)
        {
            DocumentsTrace.FixedDocumentSequence.TextOM.Trace(string.Format("GetLineRange {0} {1}", position, position.LogicalDirection));
            DocumentSequenceTextPointer tpStart = null;
            DocumentSequenceTextPointer tpEnd   = null;
            DocumentSequenceTextPointer tpLine = null;

            if (position != null)
            {
                if (ChildTextView != null)
                {
                    tpLine = _docPage.FixedDocumentSequence.TextContainer.VerifyPosition(position);

                    if (ChildTextView.TextContainer == tpLine.ChildBlock.ChildContainer)
                    {
                        TextSegment childTR = ChildTextView.GetLineRange(tpLine.ChildPointer.CreatePointer(position.LogicalDirection));
                        if (!childTR.IsNull)
                        {
                            tpStart = new DocumentSequenceTextPointer(ChildBlock, childTR.Start);
                            tpEnd = new DocumentSequenceTextPointer(ChildBlock, childTR.End);
                            return new TextSegment(tpStart, tpEnd, true);
                        }
                    }
                }
            }
            return TextSegment.Null;
        }
        /// <summary>
        /// Retrieves an oriented text position matching position advanced by 
        /// a number of lines from its initial position.
        /// </summary>
        /// <param name="position">
        /// Initial text position of an object/character.
        /// </param>
        /// <param name="suggestedX">
        /// The suggested X offset, in pixels, of text position on the destination 
        /// line. If suggestedX is set to Double.NaN it will be ignored, otherwise 
        /// the method will try to find a position on the destination line closest 
        /// to suggestedX.
        /// </param>
        /// <param name="count">
        /// Number of lines to advance. Negative means move backwards.
        /// </param>
        /// <param name="newSuggestedX">
        /// newSuggestedX is the offset at the position moved (useful when moving 
        /// between columns or pages).
        /// </param>
        /// <param name="linesMoved">
        /// linesMoved indicates the number of lines moved, which may be less 
        /// than count if there is no more content.
        /// </param>
        /// <returns>
        /// A TextPointer and its orientation matching suggestedX on the 
        /// destination line.
        /// </returns>
        /// <exception cref="System.InvalidOperationException">
        /// Throws InvalidOperationException if IsValid is false.
        /// If IsValid returns false, Validate method must be called before 
        /// calling this method.
        /// </exception>
        internal override ITextPointer GetPositionAtNextLine(ITextPointer position, double suggestedX, int count, out double newSuggestedX, out int linesMoved)
        {
            newSuggestedX = suggestedX;
            linesMoved = count;

            DocumentsTrace.FixedDocumentSequence.TextOM.Trace(string.Format("GetPositionAtNextLine {0} {1} {2} {3} ", position, position.LogicalDirection, suggestedX, count));
            DocumentSequenceTextPointer newTp  = null;
            LogicalDirection newEdge = LogicalDirection.Forward;
            DocumentSequenceTextPointer tp = null;
            if (position != null)
            {
                tp = _docPage.FixedDocumentSequence.TextContainer.VerifyPosition(position);
            }

            // Note we do not handle cross page navigation
            if (tp != null)
            {
                if (ChildTextView != null)
                {
                    if (ChildTextView.TextContainer == tp.ChildBlock.ChildContainer)
                    {
                        ITextPointer childOTP = ChildTextView.GetPositionAtNextLine(tp.ChildPointer.CreatePointer(position.LogicalDirection), suggestedX, count, out newSuggestedX, out linesMoved);
                        if (childOTP != null)
                        {
                            newTp = new DocumentSequenceTextPointer(ChildBlock, childOTP);
                            newEdge = childOTP.LogicalDirection;
                        }
                    }
                }
            }
            return DocumentSequenceTextPointer.CreatePointer(newTp, newEdge);
        }
        /// <summary>
        /// <see cref="ITextPointer.GetAdjacentElement"/>
        /// </summary>
        /// <remarks>Return null if the embedded object does not exist</remarks>
        public static object GetAdjacentElement(DocumentSequenceTextPointer thisTp, LogicalDirection direction)
        {
            ValidationHelper.VerifyDirection(direction, "direction");

            return xGapAwareGetEmbeddedElement(thisTp, direction);
        }
        /// <summary>
        /// <see cref="ITextPointer.GetElementType"/>
        /// </summary>
        /// <remarks>Return null if no TextElement in the direction</remarks>
        public static Type GetElementType(DocumentSequenceTextPointer thisTp, LogicalDirection direction)
        {
            ValidationHelper.VerifyDirection(direction, "direction");

            DocumentSequenceTextPointer tp = xGetClingDSTP(thisTp, direction);

            return tp.ChildPointer.GetElementType(direction);
        }
        /// <summary>
        /// <see cref="ITextPointer.GetTextRunLength"/>
        /// </summary>
        /// <remarks>Return 0 if non-text run</remarks>
        public static int GetTextRunLength(DocumentSequenceTextPointer thisTp, LogicalDirection direction)
        {
            ValidationHelper.VerifyDirection(direction, "direction");

            return thisTp.ChildPointer.GetTextRunLength(direction);
        }
        //------------------------------------------------------
        //
        //  Public Properties
        //
        //------------------------------------------------------


        //------------------------------------------------------
        //
        //  Public Events
        //
        //------------------------------------------------------


        //------------------------------------------------------
        //
        //  Internal Methods
        //
        //------------------------------------------------------

        #region Internal Methods


        // Internal Method, input parameter contains TP that is not synced to generation
        internal static bool iScan(DocumentSequenceTextPointer thisTp, LogicalDirection direction)
        {
            bool moved = thisTp.ChildPointer.MoveToNextContextPosition(direction);
            if (!moved)
            {
                moved = xGapAwareScan(thisTp, (direction == LogicalDirection.Forward ? 1 : -1));
            }
            return moved;
        }
        /// <summary>
        /// <see cref="ITextPointer.ReadLocalValue"/>
        /// </summary>
        /// <remarks>Throws InvalidOperationException if there is no scoping element</remarks>
        public static object ReadLocalValue(DocumentSequenceTextPointer thisTp, DependencyProperty property)
        {
            if (property == null)
            {
                throw new ArgumentNullException("property");
            }

            return thisTp.ChildPointer.ReadLocalValue(property);
        }
        /// <summary>
        /// <see cref="ITextPointer.GetPointerContext"/>
        /// </summary>
        public static TextPointerContext GetPointerContext(DocumentSequenceTextPointer thisTp, LogicalDirection direction)
        {
            ValidationHelper.VerifyDirection(direction, "direction");

            return xGapAwareGetSymbolType(thisTp, direction);
        }
        //------------------------------------------------------------------- 
        // Highlight compositing 
        //----------------------------------------------------------------------
 
        private void _OnHighlightChanged(object sender, HighlightChangedEventArgs args)
        {
            Debug.Assert(sender != null);
            Debug.Assert(args != null); 
            Debug.Assert(args.Ranges != null);
#if DEBUG 
            { 
                Highlights highlights = this.Highlights;
                StaticTextPointer highlightTransitionPosition; 
                StaticTextPointer highlightRangeStart;
                object selected;

                DocumentsTrace.FixedDocumentSequence.Highlights.Trace("===BeginNewHighlightRange==="); 
                highlightTransitionPosition = ((ITextContainer)this).CreateStaticPointerAtOffset(0);
                while (true) 
                { 
                    // Move to the next highlight start.
                    if (!highlights.IsContentHighlighted(highlightTransitionPosition, LogicalDirection.Forward)) 
                    {
                        highlightTransitionPosition = highlights.GetNextHighlightChangePosition(highlightTransitionPosition, LogicalDirection.Forward);

                        // No more highlights? 
                        if (highlightTransitionPosition.IsNull)
                            break; 
                    } 

                    // highlightTransitionPosition is at the start of a new highlight run. 
                    selected = highlights.GetHighlightValue(highlightTransitionPosition, LogicalDirection.Forward, typeof(TextSelection));

                    // Save the start position and find the end.
                    highlightRangeStart = highlightTransitionPosition; 
                    highlightTransitionPosition = highlights.GetNextHighlightChangePosition(highlightTransitionPosition, LogicalDirection.Forward);
                    Invariant.Assert(!highlightTransitionPosition.IsNull, "Highlight start not followed by highlight end!"); 
 
                    // Store the highlight.
                    if (selected != DependencyProperty.UnsetValue) 
                    {
                        DocumentsTrace.FixedDocumentSequence.Highlights.Trace(string.Format("HightlightRange {0}-{1}", highlightRangeStart.ToString(), highlightTransitionPosition.ToString()));
                        if (highlightRangeStart.GetPointerContext(LogicalDirection.Forward) != TextPointerContext.Text)
                        { 
                            DocumentsTrace.FixedDocumentSequence.Highlights.Trace("<HighlightNotOnText>");
                        } 
                        else 
                        {
                            char[] sb = new char[256]; 
                            TextPointerBase.GetTextWithLimit(highlightRangeStart.CreateDynamicTextPointer(LogicalDirection.Forward), LogicalDirection.Forward, sb, 0, 256, highlightTransitionPosition.CreateDynamicTextPointer(LogicalDirection.Forward));
                            DocumentsTrace.FixedDocumentSequence.TextOM.Trace(string.Format("HightlightContent [{0}]", new String(sb)));
                        }
                    } 
                }
                DocumentsTrace.FixedDocumentSequence.TextOM.Trace("===EndNewHighlightRange==="); 
            } 
#endif
            Debug.Assert(args.Ranges.Count > 0 && ((TextSegment)args.Ranges[0]).Start.CompareTo(((TextSegment)args.Ranges[0]).End) < 0); 


            // For each change range we received, we need to figure out
            // affected child TextContainer, and notify it with appropriate 
            // ranges that are in the child's address space.
            // 
            // We only fire one highlight change notification for any child 
            // TextContainer even if there is multiple change ranges fall
            // into the same child TextContainer. 
            //
            // We scan the ranges and the child TextContainer in the same loop,
            // moving forward two scanning pointers and at boundary of each
            // TextContainer, we fire a change notification. 
            //
            int idxScan = 0; 
            DocumentSequenceTextPointer  tsScan  = null; 
            ChildDocumentBlock cdbScan =  null;
            List<TextSegment>  rangeArray = new List<TextSegment>(4); 
            while (idxScan < args.Ranges.Count)
            {
                TextSegment ts = (TextSegment)args.Ranges[idxScan];
                DocumentSequenceTextPointer tsEnd   = (DocumentSequenceTextPointer)ts.End; 
                ITextPointer tpChildStart, tpChildEnd;
                ChildDocumentBlock lastBlock; 
 
                // If tsScan == null, we were done with previous range,
                // so we are going to set tsScan to begining of this range. 
                // Otherwise the previous range was split so we will simply
                // start from what was left over from previous loop.
                if (tsScan == null)
                { 
                    tsScan = (DocumentSequenceTextPointer)ts.Start;
                } 
                lastBlock = cdbScan; 
                cdbScan = tsScan.ChildBlock;
 
                if (lastBlock != null && cdbScan != lastBlock && !(lastBlock.ChildContainer is NullTextContainer) && rangeArray.Count != 0)
                {
                    // This range is in a different block, so take care of old blocks first
                    lastBlock.ChildHighlightLayer.RaiseHighlightChangedEvent(new ReadOnlyCollection<TextSegment>(rangeArray)); 
                    rangeArray.Clear();
                } 
 
                tpChildStart = tsScan.ChildPointer;
 
                if (tsEnd.ChildBlock != cdbScan)
                {
                    // If this range crosses blocks, we are done with current block
                    tpChildEnd = tsScan.ChildPointer.TextContainer.End; 
                    if (tpChildStart.CompareTo(tpChildEnd) != 0)
                    { 
                        rangeArray.Add(new TextSegment(tpChildStart, tpChildEnd)); 
                    }
                    // Notify child container 
                    if (!(cdbScan.ChildContainer is NullTextContainer) && rangeArray.Count != 0)
                    {
                        cdbScan.ChildHighlightLayer.RaiseHighlightChangedEvent(new ReadOnlyCollection<TextSegment>(rangeArray));
                    } 

                    // Move on to next block; 
                    cdbScan = cdbScan.NextBlock; 
                    tsScan  = new DocumentSequenceTextPointer(cdbScan, cdbScan.ChildContainer.Start);
                    rangeArray.Clear(); 
                }
                else
                {
                    // Otherwise we need to go on to see if there is more ranges 
                    // fall withing the same block. Simply add this change range
                    tpChildEnd = tsEnd.ChildPointer; 
                    if (tpChildStart.CompareTo(tpChildEnd) != 0) 
                    {
                        rangeArray.Add(new TextSegment(tpChildStart, tpChildEnd)); 
                    }

                    // Move on to next range
                    idxScan++; 
                    tsScan = null;
                } 
            } 

            // Fire change notification for the last child block. 
            if (rangeArray.Count > 0 && (!(cdbScan == null || cdbScan.ChildContainer is NullTextContainer)))
            {
                cdbScan.ChildHighlightLayer.RaiseHighlightChangedEvent(new ReadOnlyCollection<TextSegment>(rangeArray));
            } 
        }
        // ======================================================
        // Static part of a class

        // <summary>
        // DocumentSequenceTextPointer is a static  class that is provided all the
        // common functions of ITextPointer/ITextNavigaor for DocumentSequence.
        // Since we don't have multiple inheritance, this is a way to share code between
        // DocumentSequenceTextPointer and DocumentSequenceTextPointer.
        // </summary>

        //------------------------------------------------------
        //
        //  Public Methods
         //
        //------------------------------------------------------
        #region TextPointer Methods
        /// <summary>
        /// <see cref="ITextPointer.CompareTo(ITextPointer)"/>
        /// </summary>
        public static int CompareTo(DocumentSequenceTextPointer thisTp, ITextPointer position)
        {
            DocumentSequenceTextPointer tp = thisTp.AggregatedContainer.VerifyPosition(position);

            // Now do compare
            return xGapAwareCompareTo(thisTp, tp);
        }
        //------------------------------------------------------
        //
        //  Internal Property
        //
        //------------------------------------------------------

        //------------------------------------------------------
        //
        //  Private Methods
        //
        //------------------------------------------------------

        #region Private Methods
        private static DocumentSequenceTextPointer xGetClingDSTP(DocumentSequenceTextPointer thisTp, LogicalDirection direction)
        {
            TextPointerContext context = thisTp.ChildPointer.GetPointerContext(direction);

            if (context != TextPointerContext.None)
            {
                return thisTp;
            }

            ChildDocumentBlock block = thisTp.ChildBlock;
            ITextPointer pointer = thisTp.ChildPointer;

            if (direction == LogicalDirection.Forward)
            {
                while (context == TextPointerContext.None && !block.IsTail)
                {
                    // get next block
                    block = block.NextBlock;
                    // get start
                    pointer = block.ChildContainer.Start;
                    context = pointer.GetPointerContext(direction);
                }
            }
            else
            {
                Debug.Assert(direction == LogicalDirection.Backward);
                while (context == TextPointerContext.None && !block.IsHead)
                {
                    // get next block
                    block = block.PreviousBlock;
                    // get start
                    pointer = block.ChildContainer.End;
                    context = pointer.GetPointerContext(direction);
                }
            }

            return new DocumentSequenceTextPointer(block, pointer);
        }
 public static ITextPointer CreatePointer(DocumentSequenceTextPointer thisTp, int distance)
 {
     return CreatePointer(thisTp, distance, thisTp.ChildPointer.LogicalDirection);
 }
 internal static string ToString(DocumentSequenceTextPointer thisTp)
 {
     return  (thisTp is DocumentSequenceTextPointer ? "DSTP" : "DSTN")
             + " Id=" + thisTp.DebugId
             + " B=" + thisTp.ChildBlock.DebugId
             + " G=" + thisTp.ChildPointer.LogicalDirection
             ;
 }
        //-------------------------------------------------------------------
        // 
        // Private Methods
        // 
        //---------------------------------------------------------------------- 

        #region Private Methods 

        //-------------------------------------------------------------------
        // Initilization
        //--------------------------------------------------------------------- 
        private void _Initialize()
        { 
            Debug.Assert(_parent != null); 

            // Create Start Block/Container/Position 
            _doclistHead = new ChildDocumentBlock(this, new NullTextContainer());

            // Create End Block/Container/Position
            _doclistTail = new ChildDocumentBlock(this, new NullTextContainer()); 

            // Link Start and End container together 
            _doclistHead.InsertNextBlock(_doclistTail); 

            // Now initialize the child doc block list 
            ChildDocumentBlock currentBlock = _doclistHead;
            foreach (DocumentReference docRef in _parent.References)
            {
                currentBlock.InsertNextBlock(new ChildDocumentBlock(this, docRef)); 
                currentBlock = currentBlock.NextBlock;
            } 
 
            //if we have at least one document, start and end pointers should be set to valid child blocks not to the placeholders
            if (_parent.References.Count != 0) 
            {
                _start = new DocumentSequenceTextPointer(_doclistHead.NextBlock,  _doclistHead.NextBlock.ChildContainer.Start);
                _end = new DocumentSequenceTextPointer(_doclistTail.PreviousBlock, _doclistTail.PreviousBlock.ChildContainer.End);
            } 
            else
            { 
                _start = new DocumentSequenceTextPointer(_doclistHead,  _doclistHead.ChildContainer.Start); 
                _end = new DocumentSequenceTextPointer(_doclistTail, _doclistTail.ChildContainer.End);
            } 

            // Listen to collection changes
            _parent.References.CollectionChanged += new NotifyCollectionChangedEventHandler(_OnContentChanged);
 
            // Listen to Highlights changes so that it can notify sub-TextContainer
            this.Highlights.Changed += new HighlightChangedEventHandler(_OnHighlightChanged); 
        } 
Exemplo n.º 54
0
        //Searches for the specified pattern and updates start *or* end pointers depending on search direction
        //At the end of the operation, start or end should be pointing to the beginning/end of the page 
        //of occurance of pattern respectively
        internal static TextRange Find  ( ITextPointer start,
                                           ITextPointer end,
                                           string findPattern, 
                                           CultureInfo cultureInfo,
                                           bool matchCase, 
                                           bool matchWholeWord, 
                                           bool matchLast,
                                           bool matchDiacritics, 
                                           bool matchKashida,
                                           bool matchAlefHamza)
        {
            Debug.Assert(start != null); 
            Debug.Assert(end != null);
            Debug.Assert( ((start is DocumentSequenceTextPointer) && (end is DocumentSequenceTextPointer)) || 
                          ((start is FixedTextPointer) && (end is FixedTextPointer)) ); 
            Debug.Assert(findPattern != null);
 
            if (findPattern.Length == 0)
            {
                return null;
            } 

            IDocumentPaginatorSource paginatorSource = start.TextContainer.Parent as IDocumentPaginatorSource; 
            DynamicDocumentPaginator paginator = paginatorSource.DocumentPaginator as DynamicDocumentPaginator; 
            Debug.Assert(paginator != null);
 
            int pageNumber = -1;
            int endPageNumber = -1;

            if (matchLast) 
            {
                endPageNumber = paginator.GetPageNumber( (ContentPosition) start); 
                pageNumber = paginator.GetPageNumber( (ContentPosition) end); 
            }
            else 
            {
                endPageNumber = paginator.GetPageNumber( (ContentPosition) end);
                pageNumber = paginator.GetPageNumber( (ContentPosition) start);
            } 

            TextRange result = null; 
 
            CompareInfo compareInfo = cultureInfo.CompareInfo;
            bool replaceAlefWithAlefHamza = false; 
            CompareOptions compareOptions = _InitializeSearch(cultureInfo, matchCase, matchAlefHamza, matchDiacritics, ref findPattern, out replaceAlefWithAlefHamza);

            //Translate the page number
            int translatedPageNumber = pageNumber; 
            //If this is a DocumentSequence, we need to pass translated page number to the below call
            FixedDocumentSequence documentSequence = paginatorSource as FixedDocumentSequence; 
            DynamicDocumentPaginator childPaginator = null; 

            if (documentSequence != null) 
            {
                documentSequence.TranslatePageNumber(pageNumber, out childPaginator, out translatedPageNumber);
            }
 
            if (pageNumber - endPageNumber != 0)
            { 
                ITextPointer firstSearchPageStart = null; 
                ITextPointer firstSearchPageEnd = null;
 
                _GetFirstPageSearchPointers(start, end, translatedPageNumber, matchLast, out firstSearchPageStart, out firstSearchPageEnd);

                Debug.Assert(firstSearchPageStart != null);
                Debug.Assert(firstSearchPageEnd != null); 

                //Need to search the first page using TextFindEngine to start exactly from the requested search location to avoid false positives 
                result = TextFindEngine.InternalFind( firstSearchPageStart, 
                                                      firstSearchPageEnd,
                                                      findPattern, 
                                                      cultureInfo,
                                                      matchCase,
                                                      matchWholeWord,
                                                      matchLast, 
                                                      matchDiacritics,
                                                      matchKashida, 
                                                      matchAlefHamza); 
                if (result == null)
                { 
                    //Start from the next page and check all pages until the end
                    pageNumber = matchLast ? pageNumber-1 : pageNumber+1;
                    int increment = matchLast ? -1 : 1;
                    for (; matchLast ? pageNumber >= endPageNumber : pageNumber <= endPageNumber; pageNumber+=increment) 
                    {
                        FixedDocument fixedDoc = null; 
 
                        translatedPageNumber = pageNumber;
                        childPaginator = null; 
                        if (documentSequence != null)
                        {
                            documentSequence.TranslatePageNumber(pageNumber, out childPaginator, out translatedPageNumber);
                            fixedDoc = (FixedDocument) childPaginator.Source; 
                        }
                        else 
                        { 
                            fixedDoc = paginatorSource as FixedDocument;
                        } 

                        Debug.Assert(fixedDoc != null);

                        String pageString = _GetPageString(fixedDoc, translatedPageNumber, replaceAlefWithAlefHamza); 

                        if (pageString == null) 
                        { 
                            //This is not a page-per-stream
                            //Default back to slow search 
                           return TextFindEngine.InternalFind( start,
                                                      end,
                                                      findPattern,
                                                      cultureInfo, 
                                                      matchCase,
                                                      matchWholeWord, 
                                                      matchLast, 
                                                      matchDiacritics,
                                                      matchKashida, 
                                                      matchAlefHamza);
                        }

                        if ( _FoundOnPage(pageString, findPattern, cultureInfo, compareOptions) ) 
                        {
                            //Update end or start pointer depending on search direction 
                            if (documentSequence != null) 
                            {
                                ChildDocumentBlock childBlock = documentSequence.TextContainer.FindChildBlock(fixedDoc.DocumentReference); 
                                if (matchLast)
                                {
                                    end = new DocumentSequenceTextPointer(childBlock, new FixedTextPointer(false, LogicalDirection.Backward, fixedDoc.FixedContainer.FixedTextBuilder.GetPageEndFlowPosition(translatedPageNumber)));
                                    start = new DocumentSequenceTextPointer(childBlock, new FixedTextPointer(false, LogicalDirection.Forward, fixedDoc.FixedContainer.FixedTextBuilder.GetPageStartFlowPosition(translatedPageNumber))); 
                                }
                                else 
                                { 
                                    start = new DocumentSequenceTextPointer(childBlock, new FixedTextPointer(false, LogicalDirection.Forward, fixedDoc.FixedContainer.FixedTextBuilder.GetPageStartFlowPosition(translatedPageNumber)));
                                    end = new DocumentSequenceTextPointer(childBlock, new FixedTextPointer(false, LogicalDirection.Backward, fixedDoc.FixedContainer.FixedTextBuilder.GetPageEndFlowPosition(translatedPageNumber))); 
                                }
                            }
                            else
                            { 
                                //We are working on a FixedDocument
                                FixedTextBuilder textBuilder = ((FixedDocument)(paginatorSource)).FixedContainer.FixedTextBuilder; 
                                if (matchLast) 
                                {
                                    end = new FixedTextPointer(false, LogicalDirection.Backward, textBuilder.GetPageEndFlowPosition(pageNumber)); 
                                    start = new FixedTextPointer(false, LogicalDirection.Forward, textBuilder.GetPageStartFlowPosition(pageNumber));
                                }
                                else
                                { 
                                    start = new FixedTextPointer(false, LogicalDirection.Forward, textBuilder.GetPageStartFlowPosition(pageNumber));
                                    end = new FixedTextPointer(false, LogicalDirection.Backward, textBuilder.GetPageEndFlowPosition(pageNumber)); 
                                } 
                            }
                            result =  TextFindEngine.InternalFind( start, 
                                                  end,
                                                  findPattern,
                                                  cultureInfo,
                                                  matchCase, 
                                                  matchWholeWord,
                                                  matchLast, 
                                                  matchDiacritics, 
                                                  matchKashida,
                                                  matchAlefHamza); 

                            //If the result is null, this means we had a false positive
                            if (result != null)
                            { 
                                return result;
                            } 
                        } 
                    }
                } 
            }

            else
            { 
                //Make sure fast search result and slow search result are consistent
                FixedDocument fixedDoc = childPaginator != null ? childPaginator.Source as FixedDocument : paginatorSource as FixedDocument; 
                String pageString = _GetPageString(fixedDoc, translatedPageNumber, replaceAlefWithAlefHamza); 
                if (pageString == null ||
                    _FoundOnPage(pageString, findPattern, cultureInfo, compareOptions)) 
                {
                    //The search is only limited to the current page
                    result = TextFindEngine.InternalFind( start,
                                                      end, 
                                                      findPattern,
                                                      cultureInfo, 
                                                      matchCase, 
                                                      matchWholeWord,
                                                      matchLast, 
                                                      matchDiacritics,
                                                      matchKashida,
                                                      matchAlefHamza);
                } 
            }
 
            return result; 

        } 
        //-------------------------------------------------------------------
        // ContentChange 
        //----------------------------------------------------------------------
        private void _OnContentChanged(object sender, NotifyCollectionChangedEventArgs args) 
        { 
#if DEBUG
            this._generation++; 
#endif

            if (args.Action == NotifyCollectionChangedAction.Add)
            { 
                if (args.NewItems.Count != 1)
                { 
                    throw new NotSupportedException(SR.Get(SRID.RangeActionsNotSupported)); 
                }
                else 
                {
                        object item = args.NewItems[0];
                        int startingIndex = args.NewStartingIndex;
 
                        if (startingIndex != _parent.References.Count - 1)
                        { 
                            throw new NotSupportedException(SR.Get(SRID.UnexpectedCollectionChangeAction, args.Action)); 
                        }
 
                        ChildDocumentBlock newBlock = new ChildDocumentBlock(this, (DocumentReference)item);

                        ChildDocumentBlock insertAfter = _doclistTail.PreviousBlock;
                        insertAfter.InsertNextBlock(newBlock); 
                        DocumentSequenceTextPointer changeStart =
                            new DocumentSequenceTextPointer(insertAfter, insertAfter.End); 
 
                        //Update end pointer
                        _end = new DocumentSequenceTextPointer(newBlock, newBlock.ChildContainer.End); 

                        if (newBlock.NextBlock == _doclistTail && newBlock.PreviousBlock == _doclistHead)
                        {
                            //Update start pointer for the first block 
                            _start = new DocumentSequenceTextPointer(newBlock,  newBlock.ChildContainer.Start);
 
                        } 

 
                        // Record Change Notifications
                        ITextContainer container = newBlock.ChildContainer;
                        int symbolCount = 1; // takes too long to calculate for large documents, and no one will use this info
 
                        // this does not affect state, only fires event handlers
                        AddChange(changeStart, symbolCount, PrecursorTextChangeType.ContentAdded); 
                  } 
            }
            else 
            {
                throw new NotSupportedException(SR.Get(SRID.UnexpectedCollectionChangeAction, args.Action));
            }
        } 
        /// <summary>
        /// <see cref="ITextPointer.HasEqualScope"/>
        /// </summary>
        public static bool HasEqualScope(DocumentSequenceTextPointer thisTp, ITextPointer position)
        {
            DocumentSequenceTextPointer tp = thisTp.AggregatedContainer.VerifyPosition(position);

            if (thisTp.ChildPointer.TextContainer == tp.ChildPointer.TextContainer)
            {
                return thisTp.ChildPointer.HasEqualScope(tp.ChildPointer);
            }
            // The TextOM speced behavior is if both scopes are null, return true.
            return thisTp.ChildPointer.ParentType == typeof(FixedDocument) && tp.ChildPointer.ParentType == typeof(FixedDocument);
        }
 private static object xGapAwareGetEmbeddedElement(DocumentSequenceTextPointer thisTp, LogicalDirection direction)
 {
     DocumentSequenceTextPointer tp = xGetClingDSTP(thisTp, direction);
     return tp.ChildPointer.GetAdjacentElement(direction);
 }
        private static bool xUnseparated(DocumentSequenceTextPointer tp1, DocumentSequenceTextPointer tp2)
        {
            // tp1 is before tp2, check both are at edge of documents
            //check nothing of any length between them
            if (tp1.ChildPointer.GetPointerContext(LogicalDirection.Forward) != TextPointerContext.None ||
                tp2.ChildPointer.GetPointerContext(LogicalDirection.Backward) != TextPointerContext.None)
            {
                return false;
            }

            ChildDocumentBlock block = tp1.ChildBlock.NextBlock;

            while (block != tp2.ChildBlock)
            {
                if (block.ChildContainer.Start.GetPointerContext(LogicalDirection.Forward) != TextPointerContext.None)
                {
                    return false;
                }

                block = block.NextBlock;
            }

            return true;
        }
Exemplo n.º 59
0
        private static void _GetFirstPageSearchPointers ( ITextPointer start, 
                                                                   ITextPointer end, 
                                                                   int pageNumber,
                                                                   bool matchLast, 
                                                                   out ITextPointer firstSearchPageStart,
                                                                   out ITextPointer firstSearchPageEnd)
        {
            if (matchLast) 
            {
                //The page in question is the last page 
                //Need to search between the start of the last page and the end pointer 
                DocumentSequenceTextPointer endAsDSTP = end as DocumentSequenceTextPointer;
                if (endAsDSTP != null) 
                {
                    FlowPosition pageStartFlowPosition = ((FixedTextContainer)(endAsDSTP.ChildBlock.ChildContainer)).FixedTextBuilder.GetPageStartFlowPosition(pageNumber);
                    firstSearchPageStart = new DocumentSequenceTextPointer(endAsDSTP.ChildBlock,
                                                                           new FixedTextPointer(false, LogicalDirection.Forward,pageStartFlowPosition)); 
                }
                else 
                { 
                    FixedTextPointer endAsFTP = end as FixedTextPointer;
                    Debug.Assert(endAsFTP != null); 
                    firstSearchPageStart = new FixedTextPointer(false, LogicalDirection.Forward, endAsFTP.FixedTextContainer.FixedTextBuilder.GetPageStartFlowPosition(pageNumber));
                }

                firstSearchPageEnd = end; 
            }
            else 
            { 
                //The page in question is the first page
                //Need to search between the start pointer and the end of the first page 
                DocumentSequenceTextPointer startAsDSTP = start as DocumentSequenceTextPointer;
                if (startAsDSTP != null)
                {
                    FlowPosition pageEndFlowPosition = ((FixedTextContainer)startAsDSTP.ChildBlock.ChildContainer).FixedTextBuilder.GetPageEndFlowPosition(pageNumber); 
                    firstSearchPageEnd = new DocumentSequenceTextPointer( startAsDSTP.ChildBlock,
                                                                          new FixedTextPointer(false, LogicalDirection.Backward, pageEndFlowPosition)); 
                } 
                else
                { 
                    FixedTextPointer startAsFTP = start as FixedTextPointer;
                    Debug.Assert(startAsFTP != null);
                    firstSearchPageEnd = new FixedTextPointer(false, LogicalDirection.Backward, startAsFTP.FixedTextContainer.FixedTextBuilder.GetPageEndFlowPosition(pageNumber));
                } 
                firstSearchPageStart = start;
            } 
 
        }
        //  Intelligent compare routine that understands block gap
        //  Since there it is assumed that there is an invisible Gap
        //  object between adjancent two blocks, there is no position
        //  overlap.
        private static int xGapAwareCompareTo(DocumentSequenceTextPointer thisTp, DocumentSequenceTextPointer tp)
        {
            Debug.Assert(tp != null);
            if ((object)thisTp == (object)tp)
            {
                return 0;
            }

            ChildDocumentBlock thisBlock = thisTp.ChildBlock;
            ChildDocumentBlock tpBlock = tp.ChildBlock;

            int comp = thisTp.AggregatedContainer.GetChildBlockDistance(thisBlock, tpBlock);
            if (comp == 0)
            {
                Debug.Assert(thisTp.ChildBlock.ChildContainer == tp.ChildBlock.ChildContainer);
                return thisTp.ChildPointer.CompareTo(tp.ChildPointer);
            }
            else if (comp < 0)
            {
                // thisBlock is after tpBlock
                return xUnseparated(tp, thisTp) ? 0 : 1;
            }
            else
            {
                // thisBlock is before tpBlock
                return xUnseparated(thisTp, tp) ? 0 : -1;
            }
        }