Exemplo n.º 1
0
        internal Geometry GetTightBoundingGeometryFromTextPositions(ITextPointer startPosition, ITextPointer endPosition, double paragraphTopSpace, Rect visibleRect) 
        {
            Geometry geometry = null;
            Geometry floatAndFigGeometry = null;
 
            int cpStartTextPointer = startPosition.Offset;
            int cpParagraphStart = Paragraph.ParagraphStartCharacterPosition; 
            int dcpStart = Math.Max(cpStartTextPointer, cpParagraphStart) - cpParagraphStart; 

            int cpEndTextPointer = endPosition.Offset; 
            int cpParagraphEnd = Paragraph.ParagraphEndCharacterPosition;
            int dcpEnd = Math.Min(cpEndTextPointer, cpParagraphEnd) - cpParagraphStart;

            //  apply first line top space only if selection starts before or exactly at this paragraph 
            double firstLineTopSpace = (cpStartTextPointer < cpParagraphStart) ? paragraphTopSpace : 0.0;
 
            //  handle end-of-para only if the range extends beyond this paragraph 
            bool handleEndOfPara = cpEndTextPointer > cpParagraphEnd;
 
            //  mirror transform - needed if flow direction changes
            Transform transform = null;

            if (ThisFlowDirection != PageFlowDirection) 
            {
                transform = new MatrixTransform(-1.0, 0.0, 0.0, 1.0, TextDpi.FromTextDpi(2 * _pageContext.PageRect.u + _pageContext.PageRect.du), 0.0); 
 
                //  (and while we are at it) visibleRect should be mirrored too
                visibleRect = transform.TransformBounds(visibleRect); 
            }

            //  query paragraph details
            PTS.FSTEXTDETAILS textDetails; 
            PTS.Validate(PTS.FsQueryTextDetails(PtsContext.Context, _paraHandle.Value, out textDetails));
 
            // There are 3 different types of text paragraphs: 
            // (a) full with simple lines
            // (b) full with composite lines - when figures/floaters are present 
            // (c) cached - when using ParaCache
            if (textDetails.fsktd == PTS.FSKTEXTDETAILS.fsktdFull)
            {
                if (textDetails.u.full.cLines > 0) 
                {
                    if (!PTS.ToBoolean(textDetails.u.full.fLinesComposite)) 
                    { 
                        // (a) full with simple lines
                        geometry = PathGeometryFromDcpRangeSimpleLines(dcpStart, dcpEnd, firstLineTopSpace, handleEndOfPara, ref textDetails.u.full, visibleRect); 
                    }
                    else
                    {
                        // (b) full with composite lines - when figures/floaters are present 
                        geometry = PathGeometryFromDcpRangeCompositeLines(dcpStart, dcpEnd, firstLineTopSpace, handleEndOfPara, ref textDetails.u.full, visibleRect);
                    } 
                } 
                //  build highlight for floaters and figures in this paragraph
                if (textDetails.u.full.cAttachedObjects > 0) 
                {
                    floatAndFigGeometry = PathGeometryFromDcpRangeFloatersAndFigures(cpStartTextPointer, cpEndTextPointer, ref textDetails.u.full);
                }
            } 
            else
            { 
                // (c) cached - when using ParaCache 
                Debug.Assert(textDetails.fsktd == PTS.FSKTEXTDETAILS.fsktdCached);
                Debug.Assert(false, "Should not get here. ParaCache is not currently used."); 
            }

            //  at this point geometry contains only the text content related geometry
            if (geometry != null && transform != null) 
            {
                //  mirror back to page flow direction 
                CaretElement.AddTransformToGeometry(geometry, transform); 
            }
 
            //  rectangles from which floatAndFigGeometry is calculated are already mirrored.
            //  this is why geometry and floatAndFigGeometry are combined after geometry is mirrored above
            if (floatAndFigGeometry != null)
            { 
                CaretElement.AddGeometry(ref geometry, floatAndFigGeometry);
            } 
 
            return (geometry);
        } 
Exemplo n.º 2
0
 /// <summary>
 /// Transforms point to content's coordinate system. 
 /// </summary>
 /// <param name="rect">Rect to which transform is applied.</param> 
 private void TransformToContent(ref Rect rect) 
 {
     // DocumentPage.Visual for printing scenarions needs to be always returned 
     // in LeftToRight FlowDirection. Hence, if the document is RightToLeft,
     // mirroring transform need to be applied to the content of DocumentPage.Visual.
     FlowDirection flowDirection = (FlowDirection)_owner.StructuralCache.PropertyOwner.GetValue(FlowDocument.FlowDirectionProperty);
     if (flowDirection == FlowDirection.RightToLeft) 
     {
         MatrixTransform transform = new MatrixTransform(-1.0, 0.0, 0.0, 1.0, _owner.Size.Width, 0.0); 
         rect = transform.TransformBounds(rect); 
     }
 }