// Token: 0x06002EE2 RID: 12002 RVA: 0x000D3AB0 File Offset: 0x000D1CB0
        internal override bool IsAtCaretUnitBoundary(ITextPointer position)
        {
            FixedTextPointer ftp = this.Container.VerifyPosition(position);
            FixedPosition    fixedPosition;

            if (this._GetFixedPosition(ftp, out fixedPosition))
            {
                DependencyObject element = this.FixedPage.GetElement(fixedPosition.Node);
                if (element is Glyphs)
                {
                    Glyphs glyphs = (Glyphs)element;
                    int    num    = (glyphs.UnicodeString == null) ? 0 : glyphs.UnicodeString.Length;
                    if (fixedPosition.Offset == num)
                    {
                        return(true);
                    }
                    GlyphRun measurementGlyphRun = glyphs.MeasurementGlyphRun;
                    return(measurementGlyphRun.CaretStops == null || measurementGlyphRun.CaretStops[fixedPosition.Offset]);
                }
                else if (element is Image || element is Path)
                {
                    return(true);
                }
            }
            return(false);
        }
 // Token: 0x06002D1C RID: 11548 RVA: 0x000CB9FB File Offset: 0x000C9BFB
 internal FixedElement(FixedElement.ElementType type, FixedTextPointer start, FixedTextPointer end, int pageIndex)
 {
     this._type      = type;
     this._start     = start;
     this._end       = end;
     this._pageIndex = pageIndex;
 }
        // Token: 0x06002EE3 RID: 12003 RVA: 0x000D3B5C File Offset: 0x000D1D5C
        internal override ITextPointer GetNextCaretUnitPosition(ITextPointer position, LogicalDirection direction)
        {
            FixedTextPointer ftp = this.Container.VerifyPosition(position);
            FixedPosition    fixedPosition;

            if (this._GetFixedPosition(ftp, out fixedPosition))
            {
                DependencyObject element = this.FixedPage.GetElement(fixedPosition.Node);
                if (element is Glyphs)
                {
                    Glyphs       glyphs       = (Glyphs)element;
                    GlyphRun     glyphRun     = glyphs.ToGlyphRun();
                    int          num          = (glyphRun.Characters == null) ? 0 : glyphRun.Characters.Count;
                    CharacterHit characterHit = (fixedPosition.Offset == num) ? new CharacterHit(fixedPosition.Offset - 1, 1) : new CharacterHit(fixedPosition.Offset, 0);
                    CharacterHit obj          = (direction == LogicalDirection.Forward) ? glyphRun.GetNextCaretCharacterHit(characterHit) : glyphRun.GetPreviousCaretCharacterHit(characterHit);
                    if (!characterHit.Equals(obj))
                    {
                        LogicalDirection edge = LogicalDirection.Forward;
                        if (obj.TrailingLength > 0)
                        {
                            edge = LogicalDirection.Backward;
                        }
                        int offset = obj.FirstCharacterIndex + obj.TrailingLength;
                        return(this._CreateTextPointer(new FixedPosition(fixedPosition.Node, offset), edge));
                    }
                }
            }
            ITextPointer textPointer = position.CreatePointer();

            textPointer.MoveToNextInsertionPosition(direction);
            return(textPointer);
        }
Esempio n. 4
0
        //Find the first valid insertion position after or before the boundary node
        private bool _GetFirstFixedPosition(FixedTextPointer ftp, out FixedPosition fixedP)
        {
            LogicalDirection dir = LogicalDirection.Forward;

            if (ftp.FlowPosition.FlowNode.Fp != 0)
            {
                //End boundary
                dir = LogicalDirection.Backward;
            }
            FlowPosition flowP = (FlowPosition)ftp.FlowPosition.Clone();

            //Get the first node that comes before or after the boundary node(probably a start or end node)
            flowP.Move(dir);

            FixedTextPointer nav = new FixedTextPointer(true, dir, flowP);

            if (flowP.IsStart || flowP.IsEnd)
            {
                ((ITextPointer)nav).MoveToNextInsertionPosition(dir);
            }
            if (this.Container.GetPageNumber(nav) == this.PageIndex)
            {
                return(Container.FixedTextBuilder.GetFixedPosition(nav.FlowPosition, dir, out fixedP));
            }
            else
            {
                //This position is on another page.
                fixedP = new FixedPosition(this.Container.FixedTextBuilder.FixedFlowMap.FixedStartEdge, 0);
                return(false);
            }
        }
Esempio n. 5
0
        internal int GetPageNumber(ITextPointer textPointer)
        {
            FixedTextPointer fixedTextPointer = textPointer as FixedTextPointer;
            int pageNumber = int.MaxValue;

            if (fixedTextPointer != null)
            {
                if (fixedTextPointer.CompareTo(((ITextContainer)this).Start) == 0)
                {
                    pageNumber = 0;
                }
                else if (fixedTextPointer.CompareTo(((ITextContainer)this).End) == 0)
                {
                    pageNumber = this.FixedDocument.PageCount - 1;
                }
                else
                {
                    FlowNode flowNode;
                    int      flowOffset;

                    fixedTextPointer.FlowPosition.GetFlowNode(fixedTextPointer.LogicalDirection, out flowNode, out flowOffset);

                    FixedElement fixedElement = flowNode.Cookie as FixedElement;

                    if (flowNode.Type == FlowNodeType.Boundary)
                    {
                        if (flowNode.Fp > 0)
                        {
                            //Document end boundary node
                            pageNumber = this.FixedDocument.PageCount - 1;
                        }
                        else
                        {
                            //Document start boundary node
                            pageNumber = 0;
                        }
                    }
                    else if (flowNode.Type == FlowNodeType.Virtual || flowNode.Type == FlowNodeType.Noop)
                    {
                        pageNumber = (int)flowNode.Cookie;
                    }
                    else if (fixedElement != null)
                    {
                        pageNumber = (int)fixedElement.PageIndex;
                    }
                    else
                    {
                        FixedPosition fixPos;
                        bool          res = FixedTextBuilder.GetFixedPosition(fixedTextPointer.FlowPosition, fixedTextPointer.LogicalDirection, out fixPos);
                        Debug.Assert(res);
                        if (res)
                        {
                            pageNumber = fixPos.Page;
                        }
                    }
                }
            }

            return(pageNumber);
        }
Esempio n. 6
0
        /// <summary>
        /// Determines if a position is located between two caret units.
        /// </summary>
        /// <param name="position">
        /// Position to test.
        /// </param>
        /// <returns>
        /// Returns true if the specified position precedes or follows
        /// the first or last code point of a caret unit, respectively.
        /// </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>
        /// In the context of this method, "caret unit" refers to a group
        /// of one or more Unicode code points that map to a single rendered
        /// glyph.
        /// </remarks>
        internal override bool IsAtCaretUnitBoundary(ITextPointer position)
        {
            FixedTextPointer ftp = Container.VerifyPosition(position);
            FixedPosition    fixedp;

            if (_GetFixedPosition(ftp, out fixedp))
            {
                DependencyObject element = this.FixedPage.GetElement(fixedp.Node);
                if (element is Glyphs)
                {
                    Glyphs g = (Glyphs)element;
                    int    characterCount = (g.UnicodeString == null ? 0 : g.UnicodeString.Length);
                    if (fixedp.Offset == characterCount)
                    {   //end of line -- allow caret
                        return(true);
                    }
                    else
                    {
                        GlyphRun run = g.MeasurementGlyphRun;
                        return(run.CaretStops == null || run.CaretStops[fixedp.Offset]);
                    }
                }
                else if (element is Image || element is Path)
                {   //support caret before and after image
                    return(true);
                }
                else
                {
                    // No text position should be on any other type of element
                    Debug.Assert(false);
                }
            }

            return(false);
        }
Esempio n. 7
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;
        }
Esempio n. 8
0
        /// <summary>
        /// <see cref="TextViewBase.GetTightBoundingGeometryFromTextPositions"/>
        /// </summary>
        internal override Geometry GetTightBoundingGeometryFromTextPositions(ITextPointer startPosition, ITextPointer endPosition)
        {
            PathGeometry boundingGeometry = new PathGeometry();

            Debug.Assert(startPosition != null && this.Contains(startPosition));
            Debug.Assert(endPosition != null && this.Contains(endPosition));
            Dictionary <FixedPage, ArrayList> highlights = new Dictionary <FixedPage, ArrayList>();
            FixedTextPointer startftp = this.Container.VerifyPosition(startPosition);
            FixedTextPointer endftp   = this.Container.VerifyPosition(endPosition);

            this.Container.GetMultiHighlights(startftp, endftp, highlights, FixedHighlightType.TextSelection, null, null);

            ArrayList highlightList;

            highlights.TryGetValue(this.FixedPage, out highlightList);

            if (highlightList != null)
            {
                foreach (FixedHighlight fh in highlightList)
                {
                    if (fh.HighlightType == FixedHighlightType.None)
                    {
                        continue;
                    }

                    Rect backgroundRect = fh.ComputeDesignRect();

                    if (backgroundRect == Rect.Empty)
                    {
                        continue;
                    }

                    GeneralTransform transform = fh.Element.TransformToAncestor(this.FixedPage);

                    Transform t = transform.AffineTransform;
                    if (t == null)
                    {
                        t = Transform.Identity;
                    }

                    Glyphs g = fh.Glyphs;

                    if (fh.Element.Clip != null)
                    {
                        Rect clipRect = fh.Element.Clip.Bounds;
                        backgroundRect.Intersect(clipRect);
                    }

                    Geometry thisGeometry = new RectangleGeometry(backgroundRect);
                    thisGeometry.Transform = t;

                    backgroundRect = transform.TransformBounds(backgroundRect);

                    boundingGeometry.AddGeometry(thisGeometry);
                }
            }

            return(boundingGeometry);
        }
Esempio n. 9
0
        /// <summary>
        /// <see cref="ITextPointer.MoveToPosition"/>
        /// </summary>
        void ITextPointer.MoveToPosition(ITextPointer position)
        {
            FixedTextPointer ftp = this.FixedTextContainer.VerifyPosition(position);

            Debug.Assert(!_isFrozen, "Can't reposition a frozen pointer!");

            _flowPosition.MoveTo(ftp.FlowPosition);
        }
        // Token: 0x06002EB5 RID: 11957 RVA: 0x000D3098 File Offset: 0x000D1298
        bool ITextPointer.HasEqualScope(ITextPointer position)
        {
            FixedTextPointer fixedTextPointer = this.FixedTextContainer.VerifyPosition(position);
            FixedElement     scopingElement   = this._flowPosition.GetScopingElement();
            FixedElement     scopingElement2  = fixedTextPointer.FlowPosition.GetScopingElement();

            return(scopingElement == scopingElement2);
        }
Esempio n. 11
0
        /// <summary>
        /// Determines whenever TextView contains specified position.
        /// </summary>
        /// <param name="position">
        /// A position to test.
        /// </param>
        /// <returns>
        /// True if TextView contains specified text position.
        /// Otherwise returns false.
        /// </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 bool Contains(ITextPointer position)
        {
            FixedTextPointer tp = Container.VerifyPosition(position);

            return((tp.CompareTo(this.Start) > 0 && tp.CompareTo(this.End) < 0) ||
                   (tp.CompareTo(this.Start) == 0 && (tp.LogicalDirection == LogicalDirection.Forward || this.IsContainerStart)) ||
                   (tp.CompareTo(this.End) == 0 && (tp.LogicalDirection == LogicalDirection.Backward || this.IsContainerEnd))
                   );
        }
Esempio n. 12
0
        /// <summary>
        /// <see cref="ITextPointer.HasEqualScope"/>
        /// </summary>
        bool ITextPointer.HasEqualScope(ITextPointer position)
        {
            FixedTextPointer ftp = this.FixedTextContainer.VerifyPosition(position);

            FixedElement thisFE = _flowPosition.GetScopingElement();
            FixedElement thatFE = ftp.FlowPosition.GetScopingElement();

            // We retun true even if both scoping elements are the
            // container element.
            return(thisFE == thatFE);
        }
Esempio n. 13
0
        // Token: 0x06002EA0 RID: 11936 RVA: 0x000D2AD4 File Offset: 0x000D0CD4
        internal int GetPageNumber(ITextPointer textPointer)
        {
            FixedTextPointer fixedTextPointer = textPointer as FixedTextPointer;
            int result = int.MaxValue;

            if (fixedTextPointer != null)
            {
                if (fixedTextPointer.CompareTo(((ITextContainer)this).Start) == 0)
                {
                    result = 0;
                }
                else if (fixedTextPointer.CompareTo(((ITextContainer)this).End) == 0)
                {
                    result = this.FixedDocument.PageCount - 1;
                }
                else
                {
                    FlowNode flowNode;
                    int      num;
                    fixedTextPointer.FlowPosition.GetFlowNode(fixedTextPointer.LogicalDirection, out flowNode, out num);
                    FixedElement fixedElement = flowNode.Cookie as FixedElement;
                    if (flowNode.Type == FlowNodeType.Boundary)
                    {
                        if (flowNode.Fp > 0)
                        {
                            result = this.FixedDocument.PageCount - 1;
                        }
                        else
                        {
                            result = 0;
                        }
                    }
                    else if (flowNode.Type == FlowNodeType.Virtual || flowNode.Type == FlowNodeType.Noop)
                    {
                        result = (int)flowNode.Cookie;
                    }
                    else if (fixedElement != null)
                    {
                        result = fixedElement.PageIndex;
                    }
                    else
                    {
                        FixedPosition fixedPosition2;
                        bool          fixedPosition = this.FixedTextBuilder.GetFixedPosition(fixedTextPointer.FlowPosition, fixedTextPointer.LogicalDirection, out fixedPosition2);
                        if (fixedPosition)
                        {
                            result = fixedPosition2.Page;
                        }
                    }
                }
            }
            return(result);
        }
Esempio n. 14
0
        //--------------------------------------------------------------------
        // FlowPosition --> FixedPosition
        //---------------------------------------------------------------------

        // Helper function to overcome the limitation in FixedTextBuilder.GetFixedPosition
        // Making sure we are asking a position that is either a Run or an EmbeddedElement.
        private bool _GetFixedPosition(FixedTextPointer ftp, out FixedPosition fixedp)
        {
            LogicalDirection   textdir    = ftp.LogicalDirection;
            TextPointerContext symbolType = ((ITextPointer)ftp).GetPointerContext(textdir);

            if (ftp.FlowPosition.IsBoundary || symbolType == TextPointerContext.None)
            {
                return(_GetFirstFixedPosition(ftp, out fixedp));
            }

            if (symbolType == TextPointerContext.ElementStart || symbolType == TextPointerContext.ElementEnd)
            {
                //Try to find the first valid insertion position if exists
                switch (symbolType)
                {
                case TextPointerContext.ElementStart:
                    textdir = LogicalDirection.Forward;
                    break;

                case TextPointerContext.ElementEnd:
                    textdir = LogicalDirection.Backward;
                    break;
                }

                FixedTextPointer nav = new FixedTextPointer(true, textdir, (FlowPosition)ftp.FlowPosition.Clone());

                _SkipFormattingTags(nav);

                symbolType = ((ITextPointer)nav).GetPointerContext(textdir);
                if (symbolType != TextPointerContext.Text && symbolType != TextPointerContext.EmbeddedElement)
                {
                    //Try moving to the next insertion position
                    if (((ITextPointer)nav).MoveToNextInsertionPosition(textdir) &&
                        this.Container.GetPageNumber(nav) == this.PageIndex)
                    {
                        return(Container.FixedTextBuilder.GetFixedPosition(nav.FlowPosition, textdir, out fixedp));
                    }
                    else
                    {
                        fixedp = new FixedPosition(this.Container.FixedTextBuilder.FixedFlowMap.FixedStartEdge, 0);
                        return(false);
                    }
                }
                else
                {
                    ftp = nav;
                }
            }

            Debug.Assert(symbolType == TextPointerContext.Text || symbolType == TextPointerContext.EmbeddedElement);
            return(Container.FixedTextBuilder.GetFixedPosition(ftp.FlowPosition, textdir, out fixedp));
        }
Esempio n. 15
0
        //--------------------------------------------------------------------
        //
        // Private Methods
        //
        //---------------------------------------------------------------------

        #region Private Methods

        //--------------------------------------------------------------------
        // Initilization
        //---------------------------------------------------------------------
        private void _CreateEmptyContainer()
        {
            // new text builder with map
            _fixedTextBuilder = new FixedTextBuilder(this);

            // create initial TextPointer and container element
            _start = new  FixedTextPointer(false, LogicalDirection.Backward, new FlowPosition(this, this.FixedTextBuilder.FixedFlowMap.FlowStartEdge, 1));
            _end   = new FixedTextPointer(false, LogicalDirection.Forward, new FlowPosition(this, this.FixedTextBuilder.FixedFlowMap.FlowEndEdge, 0));

            _containerElement = new FixedElement(FixedElement.ElementType.Container, _start, _end, int.MaxValue);
            _start.FlowPosition.AttachElement(_containerElement);
            _end.FlowPosition.AttachElement(_containerElement);
        }
Esempio n. 16
0
        // Token: 0x06002EA9 RID: 11945 RVA: 0x000D2E8C File Offset: 0x000D108C
        private bool _GetFixedNodesForFlowRange(ITextPointer start, ITextPointer end, out FixedSOMElement[] elements, out int startIndex, out int endIndex)
        {
            elements   = null;
            startIndex = 0;
            endIndex   = 0;
            if (start.CompareTo(end) == 0)
            {
                return(false);
            }
            FixedTextPointer fixedTextPointer  = (FixedTextPointer)start;
            FixedTextPointer fixedTextPointer2 = (FixedTextPointer)end;

            return(this.FixedTextBuilder.GetFixedNodesForFlowRange(fixedTextPointer.FlowPosition, fixedTextPointer2.FlowPosition, out elements, out startIndex, out endIndex));
        }
        // Token: 0x06002CBF RID: 11455 RVA: 0x000C9CB4 File Offset: 0x000C7EB4
        internal int GetPageNumber(ContentPosition contentPosition)
        {
            if (contentPosition == null)
            {
                throw new ArgumentNullException("contentPosition");
            }
            FixedTextPointer fixedTextPointer = contentPosition as FixedTextPointer;

            if (fixedTextPointer == null)
            {
                throw new ArgumentException(SR.Get("IDPInvalidContentPosition"));
            }
            return(fixedTextPointer.FixedTextContainer.GetPageNumber(fixedTextPointer));
        }
        //------------------------------------------------------
        //
        //  Constructors
        //
        //------------------------------------------------------
        #region Constructors
        // Ctor always set mutable flag to false
        internal FixedElement(ElementType type, FixedTextPointer start, FixedTextPointer end, int pageIndex)
        {
            _type = type;
#if DEBUG
            if (_type == ElementType.Object) // is EmbeddedObject
            {
                Debug.Assert((object)_start == (object)_end);
            }
            _children = new List <FixedElement>();
#endif
            _start     = start;
            _end       = end;
            _pageIndex = pageIndex;
        }
Esempio n. 19
0
        // Token: 0x06002EA8 RID: 11944 RVA: 0x000D2E3C File Offset: 0x000D103C
        internal void OnNewFlowElement(FixedElement parentElement, FixedElement.ElementType elementType, FlowPosition pStart, FlowPosition pEnd, object source, int pageIndex)
        {
            FixedTextPointer start        = new FixedTextPointer(false, LogicalDirection.Backward, pStart);
            FixedTextPointer end          = new FixedTextPointer(false, LogicalDirection.Forward, pEnd);
            FixedElement     fixedElement = new FixedElement(elementType, start, end, pageIndex);

            if (source != null)
            {
                fixedElement.Object = source;
            }
            parentElement.Append(fixedElement);
            pStart.AttachElement(fixedElement);
            pEnd.AttachElement(fixedElement);
        }
        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;
            }
        }
Esempio n. 21
0
        internal void OnNewFlowElement(FixedElement parentElement, FixedElement.ElementType elementType, FlowPosition pStart, FlowPosition pEnd, Object source, int pageIndex)
        {
            FixedTextPointer eStart = new FixedTextPointer(false, LogicalDirection.Backward, pStart);
            FixedTextPointer eEnd   = new FixedTextPointer(false, LogicalDirection.Forward, pEnd);
            FixedElement     e      = new FixedElement(elementType, eStart, eEnd, pageIndex);

            if (source != null)
            {
                e.Object = source;
            }
            // hook up logical tree
            parentElement.Append(e);

            // attach element to flownode for faster lookup later.
            pStart.AttachElement(e);
            pEnd.AttachElement(e);
        }
Esempio n. 22
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: 0x06002EE0 RID: 12000 RVA: 0x000D382C File Offset: 0x000D1A2C
        internal override Geometry GetTightBoundingGeometryFromTextPositions(ITextPointer startPosition, ITextPointer endPosition)
        {
            PathGeometry pathGeometry = new PathGeometry();
            Dictionary <FixedPage, ArrayList> dictionary = new Dictionary <FixedPage, ArrayList>();
            FixedTextPointer start = this.Container.VerifyPosition(startPosition);
            FixedTextPointer end   = this.Container.VerifyPosition(endPosition);

            this.Container.GetMultiHighlights(start, end, dictionary, FixedHighlightType.TextSelection, null, null);
            ArrayList arrayList;

            dictionary.TryGetValue(this.FixedPage, out arrayList);
            if (arrayList != null)
            {
                foreach (object obj in arrayList)
                {
                    FixedHighlight fixedHighlight = (FixedHighlight)obj;
                    if (fixedHighlight.HighlightType != FixedHighlightType.None)
                    {
                        Rect rect = fixedHighlight.ComputeDesignRect();
                        if (!(rect == Rect.Empty))
                        {
                            GeneralTransform generalTransform = fixedHighlight.Element.TransformToAncestor(this.FixedPage);
                            Transform        transform        = generalTransform.AffineTransform;
                            if (transform == null)
                            {
                                transform = Transform.Identity;
                            }
                            Glyphs glyphs = fixedHighlight.Glyphs;
                            if (fixedHighlight.Element.Clip != null)
                            {
                                Rect bounds = fixedHighlight.Element.Clip.Bounds;
                                rect.Intersect(bounds);
                            }
                            Geometry geometry = new RectangleGeometry(rect);
                            geometry.Transform = transform;
                            rect = generalTransform.TransformBounds(rect);
                            pathGeometry.AddGeometry(geometry);
                        }
                    }
                }
            }
            return(pathGeometry);
        }
Esempio n. 24
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)
        {
#if DEBUG
            DocumentsTrace.FixedTextOM.TextView.Trace(string.Format("GetLineRange {0}, {1}", (FixedTextPointer)position, position.LogicalDirection));
#endif
            FixedTextPointer ftp = Container.VerifyPosition(position);
            FixedPosition    fixedp;
            if (!_GetFixedPosition(ftp, out fixedp))
            {
                return(new TextSegment(position, position, true));
            }

            int         count      = 0;
            FixedNode[] fixedNodes = Container.FixedTextBuilder.GetNextLine(fixedp.Node, true, ref count);

            if (fixedNodes == null)
            {
                // This will happen in the case of images
                fixedNodes = new FixedNode[] { fixedp.Node };
            }

            FixedNode        lastNode = fixedNodes[fixedNodes.Length - 1];
            DependencyObject element  = FixedPage.GetElement(lastNode);

            int lastIndex = 1;
            if (element is Glyphs)
            {
                lastIndex = ((Glyphs)element).UnicodeString.Length;
            }

            ITextPointer begin = _CreateTextPointer(new FixedPosition(fixedNodes[0], 0), LogicalDirection.Forward);
            ITextPointer end   = _CreateTextPointer(new FixedPosition(lastNode, lastIndex), LogicalDirection.Backward);

            if (begin.CompareTo(end) > 0)
            {
                ITextPointer temp = begin;
                begin = end;
                end   = temp;
            }

            return(new TextSegment(begin, end, true));
        }
        // Token: 0x06002EF6 RID: 12022 RVA: 0x000D45B4 File Offset: 0x000D27B4
        private bool _GetFixedPosition(FixedTextPointer ftp, out FixedPosition fixedp)
        {
            LogicalDirection   logicalDirection = ftp.LogicalDirection;
            TextPointerContext pointerContext   = ((ITextPointer)ftp).GetPointerContext(logicalDirection);

            if (ftp.FlowPosition.IsBoundary || pointerContext == TextPointerContext.None)
            {
                return(this._GetFirstFixedPosition(ftp, out fixedp));
            }
            if (pointerContext == TextPointerContext.ElementStart || pointerContext == TextPointerContext.ElementEnd)
            {
                if (pointerContext != TextPointerContext.ElementStart)
                {
                    if (pointerContext == TextPointerContext.ElementEnd)
                    {
                        logicalDirection = LogicalDirection.Backward;
                    }
                }
                else
                {
                    logicalDirection = LogicalDirection.Forward;
                }
                FixedTextPointer fixedTextPointer = new FixedTextPointer(true, logicalDirection, (FlowPosition)ftp.FlowPosition.Clone());
                this._SkipFormattingTags(fixedTextPointer);
                pointerContext = ((ITextPointer)fixedTextPointer).GetPointerContext(logicalDirection);
                if (pointerContext != TextPointerContext.Text && pointerContext != TextPointerContext.EmbeddedElement)
                {
                    if (((ITextPointer)fixedTextPointer).MoveToNextInsertionPosition(logicalDirection) && this.Container.GetPageNumber(fixedTextPointer) == this.PageIndex)
                    {
                        return(this.Container.FixedTextBuilder.GetFixedPosition(fixedTextPointer.FlowPosition, logicalDirection, out fixedp));
                    }
                    fixedp = new FixedPosition(this.Container.FixedTextBuilder.FixedFlowMap.FixedStartEdge, 0);
                    return(false);
                }
                else
                {
                    ftp = fixedTextPointer;
                }
            }
            return(this.Container.FixedTextBuilder.GetFixedPosition(ftp.FlowPosition, logicalDirection, out fixedp));
        }
Esempio n. 26
0
        /// <summary>
        /// Finds the next position at the edge of a caret unit in
        /// specified direction.
        /// </summary>
        /// <param name="position">
        /// Initial text position of an object/character.
        /// </param>
        /// <param name="direction">
        /// If Forward, this method returns the "caret unit" position following
        /// the initial position.
        /// If Backward, this method returns the caret unit" position preceding
        /// the initial position.
        /// </param>
        /// <returns>
        /// The next caret unit break position in specified direction.
        /// </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>
        /// In the context of this method, "caret unit" refers to a group of one
        /// or more Unicode code points that map to a single rendered glyph.
        ///
        /// If position is located between two caret units, this method returns
        /// a new position located at the opposite edge of the caret unit in
        /// the indicated direction.
        /// If position is located within a group of Unicode code points that map
        /// to a single caret unit, this method returns a new position at
        /// the indicated edge of the containing caret unit.
        /// If position is located at the beginning of end of content -- there is
        /// no content in the indicated direction -- then this method returns
        /// a position located at the same location as initial position.
        /// </remarks>
        internal override ITextPointer GetNextCaretUnitPosition(ITextPointer position, LogicalDirection direction)
        {
            FixedTextPointer ftp = Container.VerifyPosition(position);
            FixedPosition    fixedp;

            if (_GetFixedPosition(ftp, out fixedp))
            {
                DependencyObject element = this.FixedPage.GetElement(fixedp.Node);
                if (element is Glyphs)
                {
                    Glyphs   g   = (Glyphs)element;
                    GlyphRun run = g.ToGlyphRun();

                    int          characterCount = (run.Characters == null) ? 0 : run.Characters.Count;
                    CharacterHit start          = (fixedp.Offset == characterCount) ?
                                                  new CharacterHit(fixedp.Offset - 1, 1) :
                                                  new CharacterHit(fixedp.Offset, 0);
                    CharacterHit next = (direction == LogicalDirection.Forward) ?
                                        run.GetNextCaretCharacterHit(start) :
                                        run.GetPreviousCaretCharacterHit(start);

                    if (!start.Equals(next))
                    {
                        LogicalDirection edge = LogicalDirection.Forward;
                        if (next.TrailingLength > 0)
                        {
                            edge = LogicalDirection.Backward;
                        }

                        int index = next.FirstCharacterIndex + next.TrailingLength;

                        return(_CreateTextPointer(new FixedPosition(fixedp.Node, index), edge));
                    }
                }
            }
            //default behavior is to simply move textpointer
            ITextPointer pointer = position.CreatePointer();

            pointer.MoveToNextInsertionPosition(direction);
            return(pointer);
        }
Esempio n. 27
0
        //--------------------------------------------------------------------
        //
        // Internal Methods
        //
        //---------------------------------------------------------------------

        #region Internal Methods

        //--------------------------------------------------------------------
        // Utility Method
        //---------------------------------------------------------------------
        internal FixedTextPointer VerifyPosition(ITextPointer position)
        {
            if (position == null)
            {
                throw new ArgumentNullException("position");
            }

            if (position.TextContainer != this)
            {
                throw new ArgumentException(SR.Get(SRID.NotInAssociatedContainer, "position"));
            }

            FixedTextPointer ftp = position as FixedTextPointer;

            if (ftp == null)
            {
                throw new ArgumentException(SR.Get(SRID.BadFixedTextPosition, "position"));
            }

            return(ftp);
        }
        // Token: 0x06002EE5 RID: 12005 RVA: 0x000D3C68 File Offset: 0x000D1E68
        internal override TextSegment GetLineRange(ITextPointer position)
        {
            FixedTextPointer ftp = this.Container.VerifyPosition(position);
            FixedPosition    fixedPosition;

            if (!this._GetFixedPosition(ftp, out fixedPosition))
            {
                return(new TextSegment(position, position, true));
            }
            int num = 0;

            FixedNode[] array = this.Container.FixedTextBuilder.GetNextLine(fixedPosition.Node, true, ref num);
            if (array == null)
            {
                array = new FixedNode[]
                {
                    fixedPosition.Node
                };
            }
            FixedNode        fixedNode = array[array.Length - 1];
            DependencyObject element   = this.FixedPage.GetElement(fixedNode);
            int offset = 1;

            if (element is Glyphs)
            {
                offset = ((Glyphs)element).UnicodeString.Length;
            }
            ITextPointer textPointer  = this._CreateTextPointer(new FixedPosition(array[0], 0), LogicalDirection.Forward);
            ITextPointer textPointer2 = this._CreateTextPointer(new FixedPosition(fixedNode, offset), LogicalDirection.Backward);

            if (textPointer.CompareTo(textPointer2) > 0)
            {
                ITextPointer textPointer3 = textPointer;
                textPointer  = textPointer2;
                textPointer2 = textPointer3;
            }
            return(new TextSegment(textPointer, textPointer2, true));
        }
        // Token: 0x06002EF7 RID: 12023 RVA: 0x000D46A8 File Offset: 0x000D28A8
        private bool _GetFirstFixedPosition(FixedTextPointer ftp, out FixedPosition fixedP)
        {
            LogicalDirection logicalDirection = LogicalDirection.Forward;

            if (ftp.FlowPosition.FlowNode.Fp != 0)
            {
                logicalDirection = LogicalDirection.Backward;
            }
            FlowPosition flowPosition = (FlowPosition)ftp.FlowPosition.Clone();

            flowPosition.Move(logicalDirection);
            FixedTextPointer fixedTextPointer = new FixedTextPointer(true, logicalDirection, flowPosition);

            if (flowPosition.IsStart || flowPosition.IsEnd)
            {
                ((ITextPointer)fixedTextPointer).MoveToNextInsertionPosition(logicalDirection);
            }
            if (this.Container.GetPageNumber(fixedTextPointer) == this.PageIndex)
            {
                return(this.Container.FixedTextBuilder.GetFixedPosition(fixedTextPointer.FlowPosition, logicalDirection, out fixedP));
            }
            fixedP = new FixedPosition(this.Container.FixedTextBuilder.FixedFlowMap.FixedStartEdge, 0);
            return(false);
        }
Esempio n. 30
0
        // Token: 0x06002E9F RID: 11935 RVA: 0x000D2A68 File Offset: 0x000D0C68
        internal FixedTextPointer VerifyPosition(ITextPointer position)
        {
            if (position == null)
            {
                throw new ArgumentNullException("position");
            }
            if (position.TextContainer != this)
            {
                throw new ArgumentException(SR.Get("NotInAssociatedContainer", new object[]
                {
                    "position"
                }));
            }
            FixedTextPointer fixedTextPointer = position as FixedTextPointer;

            if (fixedTextPointer == null)
            {
                throw new ArgumentException(SR.Get("BadFixedTextPosition", new object[]
                {
                    "position"
                }));
            }
            return(fixedTextPointer);
        }
Esempio n. 31
0
        //--------------------------------------------------------------------
        //
        // Private Methods
        //
        //---------------------------------------------------------------------

        #region Private Methods

        //--------------------------------------------------------------------
        // Initilization
        //---------------------------------------------------------------------
        private void _CreateEmptyContainer()
        {
            // new text builder with map
            _fixedTextBuilder = new FixedTextBuilder(this);

            // create initial TextPointer and container element
            _start = new  FixedTextPointer(false, LogicalDirection.Backward, new FlowPosition(this, this.FixedTextBuilder.FixedFlowMap.FlowStartEdge, 1));
            _end = new FixedTextPointer(false, LogicalDirection.Forward, new FlowPosition(this, this.FixedTextBuilder.FixedFlowMap.FlowEndEdge, 0));

            _containerElement = new FixedElement(FixedElement.ElementType.Container, _start, _end, int.MaxValue);
            _start.FlowPosition.AttachElement(_containerElement);
            _end.FlowPosition.AttachElement(_containerElement);

        }
        //--------------------------------------------------------------------
        // FlowPosition --> FixedPosition
        //---------------------------------------------------------------------

        // Helper function to overcome the limitation in FixedTextBuilder.GetFixedPosition 
        // Making sure we are asking a position that is either a Run or an EmbeddedElement. 
        private bool _GetFixedPosition(FixedTextPointer ftp, out FixedPosition fixedp)
        {
            LogicalDirection textdir = ftp.LogicalDirection;
            TextPointerContext symbolType = ((ITextPointer)ftp).GetPointerContext(textdir);

            if (ftp.FlowPosition.IsBoundary || symbolType == TextPointerContext.None)
            {
                return _GetFirstFixedPosition(ftp, out fixedp);
            }

            if (symbolType == TextPointerContext.ElementStart || symbolType == TextPointerContext.ElementEnd)
            {
                //Try to find the first valid insertion position if exists
                switch (symbolType)
                {
                case TextPointerContext.ElementStart:
                    textdir = LogicalDirection.Forward;
                    break;
                case TextPointerContext.ElementEnd:
                    textdir = LogicalDirection.Backward;
                    break;
                }

                FixedTextPointer nav = new FixedTextPointer(true, textdir, (FlowPosition)ftp.FlowPosition.Clone());

                _SkipFormattingTags(nav);

                symbolType = ((ITextPointer)nav).GetPointerContext(textdir);
                if (symbolType != TextPointerContext.Text && symbolType != TextPointerContext.EmbeddedElement)
                {
                    //Try moving to the next insertion position
                    if (((ITextPointer)nav).MoveToNextInsertionPosition(textdir) &&
                        this.Container.GetPageNumber(nav) == this.PageIndex)
                    {
                        return Container.FixedTextBuilder.GetFixedPosition(nav.FlowPosition, textdir, out fixedp);
                    }
                    else
                    {
                        fixedp = new FixedPosition(this.Container.FixedTextBuilder.FixedFlowMap.FixedStartEdge, 0);
                        return false;
                    }
                }
                else
                {
                    ftp = nav;
                }
            }

            Debug.Assert(symbolType == TextPointerContext.Text || symbolType == TextPointerContext.EmbeddedElement);
            return Container.FixedTextBuilder.GetFixedPosition(ftp.FlowPosition, textdir, out fixedp);
        }
        /// <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 = 0;
#if DEBUG
            DocumentsTrace.FixedTextOM.TextView.Trace(string.Format("FixedTextView.MoveToLine {0}, {1}, {2}, {3}", (FixedTextPointer)position, position.LogicalDirection, suggestedX, count));
#endif

            FixedPosition fixedp;
            LogicalDirection edge = position.LogicalDirection;
            LogicalDirection scanDir = LogicalDirection.Forward;
            ITextPointer pos = position;

            FixedTextPointer ftp = Container.VerifyPosition(position);
            FixedTextPointer nav = new FixedTextPointer(true, edge, (FlowPosition)ftp.FlowPosition.Clone());

            //Skip any formatting tags
            _SkipFormattingTags(nav);
            bool gotFixedPosition = false;
            if (   count == 0
                || ((gotFixedPosition = _GetFixedPosition(nav, out fixedp))
                && fixedp.Page != this.PageIndex )
                )
            {
                //Invalid text position, so do nothing. PS #963924
                return position;
            }

            if (count < 0)
            {
                count   = -count;
                scanDir = LogicalDirection.Backward;
            }

            if (!gotFixedPosition)
            {
                // move to next insertion position in direction, provided we're in this view
                if (this.Contains(position))
                {
                    nav = new FixedTextPointer(true, scanDir, (FlowPosition)ftp.FlowPosition.Clone());
                    ((ITextPointer)nav).MoveToInsertionPosition(scanDir);
                    ((ITextPointer)nav).MoveToNextInsertionPosition(scanDir);
                    if (this.Contains(nav))
                    {
                        
                        // make sure we haven't changed pages
                        linesMoved = (scanDir == LogicalDirection.Forward) ? 1 : -1;
                        return nav;
                    }
                }
                return position;
            }

            if (DoubleUtil.IsNaN(suggestedX))
            {
                suggestedX = 0;
            }

            while (count > linesMoved)
            {
                if (!_GetNextLineGlyphs(ref fixedp, ref edge, suggestedX, scanDir))
                    break;
                linesMoved++;
            }

            if (linesMoved == 0)
            {
                pos = position.CreatePointer();
                return pos;
            }

            if (scanDir == LogicalDirection.Backward)
            {
                linesMoved = -linesMoved;
            }
            
            pos = _CreateTextPointer(fixedp, edge);
            Debug.Assert(pos != null);

            if (pos.CompareTo(position) == 0)
            {
                linesMoved = 0;
            }
            
            return pos;
        }
Esempio n. 34
0
        //-----------------------------------------------------
        // 
        //  Constructors 
        //
        //----------------------------------------------------- 
        #region Constructors
        // Ctor always set mutable flag to false
        internal FixedElement(ElementType type, FixedTextPointer start, FixedTextPointer end, int pageIndex)
        { 
            _type = type;
#if DEBUG 
            if (_type == ElementType.Object) // is EmbeddedObject 
            {
                Debug.Assert((object)_start == (object)_end); 
            }
            _children = new List<FixedElement>();
#endif
            _start = start; 
            _end = end;
            _pageIndex = pageIndex; 
 
        }
Esempio n. 35
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;
            } 
 
        }
Esempio n. 36
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; 

        } 
        /// <summary>
        /// <see cref="DynamicDocumentPaginator.GetObjectPosition"/>
        /// </summary>
        /// <exception cref="ArgumentNullException">element is NULL.</exception>
        internal ContentPosition GetObjectPosition(Object o)
        {
            if (o == null)
            {
                throw new ArgumentNullException("o");
            }
            
            DependencyObject element = o as DependencyObject;

            if (element == null)
            {
                throw new ArgumentException(SR.Get(SRID.FixedDocumentExpectsDependencyObject));
            }
            DocumentsTrace.FixedFormat.IDF.Trace(string.Format("IDF.GetContentPositionForElement({0})", element));
            // Make sure that the call is in the right context.
//             Dispatcher.VerifyAccess();


            // walk up the logical parent chain to find the containing page
            FixedPage fixedPage = null;
            int pageIndex = -1;
            if (element != this)
            {
                DependencyObject el = element;
                while (el != null)
                {
                    fixedPage = el as FixedPage;

                    if (fixedPage != null)
                    {
                        pageIndex = GetIndexOfPage(fixedPage);
                        if (pageIndex >= 0)
                        {
                            break;
                        }
                        el = fixedPage.Parent;
                    }
                    else
                    {
                        el = LogicalTreeHelper.GetParent(el);
                    }
                }
            }
            else if (this.Pages.Count > 0)
            {
                // if FixedDocument is requested, return ContentPosition for the first page.
                pageIndex = 0;
            }

            // get FixedTextPointer for element or page index
            FixedTextPointer fixedTextPointer = null;
            if (pageIndex >= 0)
            {
                FixedPosition fixedPosition;
                FlowPosition flowPosition=null;
                System.Windows.Shapes.Path p = element as System.Windows.Shapes.Path;
                if (element is Glyphs || element is Image || (p != null &&  p.Fill is ImageBrush))
                {
                    fixedPosition = new FixedPosition(fixedPage.CreateFixedNode(pageIndex, (UIElement)element), 0);
                    flowPosition = FixedContainer.FixedTextBuilder.CreateFlowPosition(fixedPosition);
                }
                if (flowPosition == null)
                {
                    flowPosition = FixedContainer.FixedTextBuilder.GetPageStartFlowPosition(pageIndex);
                }
                fixedTextPointer = new FixedTextPointer(true, LogicalDirection.Forward, flowPosition);
            }

            return (fixedTextPointer != null) ? fixedTextPointer : ContentPosition.Missing;
        }
Esempio n. 38
0
        // Get the highlights, in Glyphs granularity, that covers this range
        internal void GetMultiHighlights(FixedTextPointer start, FixedTextPointer end, Dictionary<FixedPage, ArrayList> highlights, FixedHighlightType t,
            Brush foregroundBrush, Brush backgroundBrush)
        {
            Debug.Assert(highlights != null);
            if (start.CompareTo(end) > 0)
            {
                // make sure start <= end
                FixedTextPointer temp = start;
                start = end;
                end = temp;
            }

            FixedSOMElement[] elements;
            //Start and end indices in selection for first and last FixedSOMElements respectively
            int startIndex = 0;
            int endIndex = 0;
            if (_GetFixedNodesForFlowRange(start, end, out elements, out startIndex, out endIndex))
            {
                for(int i=0; i<elements.Length; i++)
                {
                    FixedSOMElement elem = elements[i];
                    
                    FixedNode fn = elem.FixedNode;
                    // Get the FixedPage if possible
                    FixedPage page = this.FixedDocument.SyncGetPageWithCheck(fn.Page);
                    if (page == null)
                    {
                        continue;
                    }

                    DependencyObject o = page.GetElement(fn);
                    if (o == null)
                    {
                        continue;
                    }

                    int beginOffset = 0;
                    int endOffset;
                    UIElement e;
                    if (o is Image || o is Path)
                    {
                        e = (UIElement)o;
                        endOffset = 1;
                    }
                    else
                    {
                        Glyphs g = o as Glyphs;
                        if (g == null)
                        {
                            continue;
                        }
                        e = (UIElement)o;
                        beginOffset = elem.StartIndex;
                        endOffset = elem.EndIndex;
                    }

                    if (i == 0)
                    {
                        beginOffset = startIndex;
                    }

                    if (i == elements.Length - 1)
                    {
                        endOffset = endIndex;
                    }

                    ArrayList lfs;
                    if (highlights.ContainsKey(page))
                    {
                        lfs = highlights[page];
                    }
                    else
                    {
                        lfs = new ArrayList();
                        highlights.Add(page, lfs);
                    }

                    FixedSOMTextRun textRun = elem as FixedSOMTextRun;
                    if (textRun != null && textRun.IsReversed)
                    {
                        int oldBeginOffset = beginOffset;
                        beginOffset = elem.EndIndex - endOffset;
                        endOffset = elem.EndIndex - oldBeginOffset;
                    }

                    FixedHighlight fh = new FixedHighlight(e, beginOffset, endOffset, t, foregroundBrush, backgroundBrush);
                    lfs.Add(fh);
                }
            }
        }
        //Find the first valid insertion position after or before the boundary node
        private bool _GetFirstFixedPosition(FixedTextPointer ftp, out FixedPosition fixedP)
        {
            LogicalDirection dir = LogicalDirection.Forward;
            if (ftp.FlowPosition.FlowNode.Fp != 0)
            {
                //End boundary
                dir = LogicalDirection.Backward;
            }
            FlowPosition flowP = (FlowPosition) ftp.FlowPosition.Clone();
            //Get the first node that comes before or after the boundary node(probably a start or end node)
            flowP.Move(dir);

            FixedTextPointer nav = new FixedTextPointer(true, dir, flowP);
            if (flowP.IsStart || flowP.IsEnd)
            {
                ((ITextPointer)nav).MoveToNextInsertionPosition(dir);
            }
            if (this.Container.GetPageNumber(nav) == this.PageIndex)
            {
                return Container.FixedTextBuilder.GetFixedPosition(nav.FlowPosition, dir, out fixedP);
            }
            else
            {
                //This position is on another page.
                fixedP = new FixedPosition(this.Container.FixedTextBuilder.FixedFlowMap.FixedStartEdge, 0);
                return false;
            }
        }
Esempio n. 40
0
        internal void OnNewFlowElement(FixedElement parentElement, FixedElement.ElementType elementType, FlowPosition pStart, FlowPosition pEnd, Object source, int pageIndex)
        {
            FixedTextPointer eStart = new FixedTextPointer(false, LogicalDirection.Backward, pStart);
            FixedTextPointer eEnd = new FixedTextPointer(false, LogicalDirection.Forward, pEnd);
            FixedElement e = new FixedElement(elementType, eStart, eEnd, pageIndex);
            if (source != null)
            {
                e.Object = source;
            }
            // hook up logical tree
            parentElement.Append(e);

            // attach element to flownode for faster lookup later.
            pStart.AttachElement(e);
            pEnd.AttachElement(e);
        }