internal override void ValidateVisual(PTS.FSKUPDATE fskupdInherited) 
        { 
            // Floater is always reported as NEW. Override PTS inherited value.
            fskupdInherited = PTS.FSKUPDATE.fskupdNew; 

            // Query subpage details
            PTS.FSSUBPAGEDETAILS subpageDetails;
            PTS.Validate(PTS.FsQuerySubpageDetails(PtsContext.Context, _paraHandle.Value, out subpageDetails)); 

            // Obtain all mbd info 
            MbpInfo mbp = MbpInfo.FromElement(Paragraph.Element); 

            if(ThisFlowDirection != PageFlowDirection) 
            {
                mbp.MirrorBP();
            }
 
            Brush backgroundBrush = (Brush)Paragraph.Element.GetValue(TextElement.BackgroundProperty);
            Visual.DrawBackgroundAndBorder(backgroundBrush, mbp.BorderBrush, mbp.Border, _rect.FromTextDpi(), IsFirstChunk, IsLastChunk); 
 

            ContainerVisual pageContentVisual; 
            ContainerVisual floatingElementsVisual;

            if(_visual.Children.Count != 2)
            { 
                _visual.Children.Clear();
                _visual.Children.Add(new ContainerVisual()); 
                _visual.Children.Add(new ContainerVisual()); 
            }
 
            pageContentVisual = (ContainerVisual)_visual.Children[0];
            floatingElementsVisual = (ContainerVisual)_visual.Children[1];

            // Subpage content may be simple or complex - 
            // depending of set of features used in the content of the subpage.
            // (1) simple subpage (contains only one track) 
            // (2) complex subpage (contains columns) 
            if (PTS.ToBoolean(subpageDetails.fSimple))
            { 
                // (1) simple subpage (contains only one track)
                PTS.FSKUPDATE fskupd = subpageDetails.u.simple.trackdescr.fsupdinf.fskupd;
                if (fskupd == PTS.FSKUPDATE.fskupdInherited)
                { 
                    fskupd = fskupdInherited;
                } 
                VisualCollection visualChildren = pageContentVisual.Children; 
                if (fskupd == PTS.FSKUPDATE.fskupdNew)
                { 
                    visualChildren.Clear();
                    visualChildren.Add(new ContainerVisual());
                }
                // For complex subpage SectionVisual is added. So, when morphing 
                // complex subpage to simple one, remove SectionVisual.
                else if (visualChildren.Count == 1 && !(visualChildren[0] is ContainerVisual)) 
                { 
                    visualChildren.Clear();
                    visualChildren.Add(new ContainerVisual()); 
                }
                Debug.Assert(visualChildren.Count == 1 && visualChildren[0] is ContainerVisual);
                ContainerVisual trackVisual = (ContainerVisual)visualChildren[0];
 
                PtsHelper.UpdateTrackVisuals(PtsContext, trackVisual.Children, fskupdInherited, ref subpageDetails.u.simple.trackdescr);
            } 
            else 
            {
                // (2) complex page (contains columns) 
                // cBasicColumns == 0, means that subpage content is empty
                bool emptySubpage = (subpageDetails.u.complex.cBasicColumns == 0);
                if (!emptySubpage)
                { 
                    // Retrieve description for each column.
                    PTS.FSTRACKDESCRIPTION[] arrayColumnDesc; 
                    PtsHelper.TrackListFromSubpage(PtsContext, _paraHandle.Value, ref subpageDetails, out arrayColumnDesc); 

                    emptySubpage = (arrayColumnDesc.Length == 0); 
                    if (!emptySubpage)
                    {
                        PTS.FSKUPDATE fskupd = fskupdInherited;
                        ErrorHandler.Assert(fskupd != PTS.FSKUPDATE.fskupdShifted, ErrorHandler.UpdateShiftedNotValid); 
                        Debug.Assert(fskupd != PTS.FSKUPDATE.fskupdNoChange);
 
                        // For complex subpage SectionVisual is added. So, when morphing 
                        // simple subpage to complex one, remove ParagraphVisual.
                        VisualCollection visualChildren = pageContentVisual.Children; 
                        if (visualChildren.Count == 0)
                        {
                            visualChildren.Add(new SectionVisual());
                        } 
                        else if (!(visualChildren[0] is SectionVisual))
                        { 
                            visualChildren.Clear(); 
                            visualChildren.Add(new SectionVisual());
                        } 
                        Debug.Assert(visualChildren.Count == 1 && visualChildren[0] is SectionVisual);
                        SectionVisual sectionVisual = (SectionVisual)visualChildren[0];

                        // Draw column rules. 
                        ColumnPropertiesGroup columnProperties = new ColumnPropertiesGroup(Paragraph.Element);
                        sectionVisual.DrawColumnRules(ref arrayColumnDesc, TextDpi.FromTextDpi(subpageDetails.u.complex.fsrc.v), TextDpi.FromTextDpi(subpageDetails.u.complex.fsrc.dv), columnProperties); 
 
                        visualChildren = sectionVisual.Children;
                        if (fskupd == PTS.FSKUPDATE.fskupdNew) 
                        {
                            visualChildren.Clear();
                            for (int index = 0; index < arrayColumnDesc.Length; index++)
                            { 
                                visualChildren.Add(new ContainerVisual());
                            } 
                        } 
                        ErrorHandler.Assert(visualChildren.Count == arrayColumnDesc.Length, ErrorHandler.ColumnVisualCountMismatch);
 
                        for (int index = 0; index < arrayColumnDesc.Length; index++)
                        {
                            ContainerVisual trackVisual = (ContainerVisual)visualChildren[index];
 
                            PtsHelper.UpdateTrackVisuals(PtsContext, trackVisual.Children, fskupdInherited, ref arrayColumnDesc[index]);
                        } 
                    } 
                }
                if (emptySubpage) 
                {
                    // There is no content, remove all existing visuals.
                    _visual.Children.Clear();
                } 
            }
 
            pageContentVisual.Offset = new PTS.FSVECTOR(ContentRect.u, ContentRect.v).FromTextDpi(); 
            floatingElementsVisual.Offset = new PTS.FSVECTOR(ContentRect.u, ContentRect.v).FromTextDpi();
 
            PTS.FSRECT clipRect = new PTS.FSRECT(_paddingRect.u - _contentRect.u, _paddingRect.v - _contentRect.v, _paddingRect.du, _paddingRect.dv);
            PtsHelper.ClipChildrenToRect(_visual, clipRect.FromTextDpi());

            PtsHelper.UpdateFloatingElementVisuals(floatingElementsVisual, _pageContextOfThisPage.FloatingElementList); 
        }
Beispiel #2
0
        internal override List<Rect> GetRectangles(ContentElement e, int start, int length) 
        { 
            List<Rect> rectangles = new List<Rect>();
            Debug.Assert(Paragraph.Element as ContentElement != e); 

            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 ParaChache
            if (textDetails.fsktd == PTS.FSKTEXTDETAILS.fsktdFull) 
            {
                // Check figures and floaters
                if (textDetails.u.full.cAttachedObjects > 0)
                { 
                    PTS.FSATTACHEDOBJECTDESCRIPTION[] arrayAttachedObjectDesc;
                    PtsHelper.AttachedObjectListFromParagraph(PtsContext, _paraHandle.Value, textDetails.u.full.cAttachedObjects, out arrayAttachedObjectDesc); 
 
                    for (int index = 0; index < arrayAttachedObjectDesc.Length; index++)
                    { 
                        PTS.FSATTACHEDOBJECTDESCRIPTION attachedObjectDesc = arrayAttachedObjectDesc[index];

                        BaseParaClient paraClient = PtsContext.HandleToObject(attachedObjectDesc.pfsparaclient) as BaseParaClient;
                        PTS.ValidateHandle(paraClient); 

                        if (start < paraClient.Paragraph.ParagraphEndCharacterPosition) 
                        { 
                            rectangles = paraClient.GetRectangles(e, start, length);
                            Invariant.Assert(rectangles != null); 
                            if (rectangles.Count != 0)
                            {
                                break;
                            } 
                        }
                    } 
                } 

                // If no success with figures and floaters, check in line 
                if (rectangles.Count == 0 && textDetails.u.full.cLines > 0)
                {
                    if (!PTS.ToBoolean(textDetails.u.full.fLinesComposite))
                    { 
                        // (a) full with simple lines
                        rectangles = GetRectanglesInSimpleLines(e, start, length, ref textDetails.u.full); 
                    } 
                    else
                    { 
                        // (b) full with complex lines
                        rectangles = GetRectanglesInCompositeLines(e, start, length, ref textDetails.u.full);
                    }
 
                    // Ensure these are specified in page coordinates.
                    if(rectangles.Count > 0 && ThisFlowDirection != PageFlowDirection) 
                    { 
                        PTS.FSRECT pageRect = _pageContext.PageRect;
 
                        for(int index = 0; index < rectangles.Count; index++)
                        {
                            PTS.FSRECT rectTransform = new PTS.FSRECT(rectangles[index]);
                            PTS.Validate(PTS.FsTransformRectangle(PTS.FlowDirectionToFswdir(ThisFlowDirection), ref pageRect, ref rectTransform, PTS.FlowDirectionToFswdir(PageFlowDirection), out rectTransform)); 
                            rectangles[index] = rectTransform.FromTextDpi();
                        } 
                    } 
                }
 
            }
            else
            {
                // (c) cached - when using ParaChache 
                Debug.Assert(textDetails.fsktd == PTS.FSKTEXTDETAILS.fsktdCached);
                Debug.Assert(false, "Should not get here. ParaCache is not currently used."); 
            } 

            Invariant.Assert(rectangles != null); 
            return rectangles;
        }
Beispiel #3
0
        internal Rect GetRectangleFromTextPosition(ITextPointer position)
        { 
            Rect rect = System.Windows.Rect.Empty;
 
            int cp = Paragraph.StructuralCache.TextContainer.Start.GetOffsetToPosition((TextPointer)position); 
            int dcp = cp - Paragraph.ParagraphStartCharacterPosition;
            int originalDcp = dcp; 
            if (position.LogicalDirection == LogicalDirection.Backward && dcp > 0)
            {
                --dcp;
            } 

            // 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 ParaChache 
            if (textDetails.fsktd == PTS.FSKTEXTDETAILS.fsktdFull)
            { 
                if (textDetails.u.full.cLines > 0) 
                {
                    int vrBaseline = 0; 

                    if (!PTS.ToBoolean(textDetails.u.full.fLinesComposite))
                    {
                        // (a) full with simple lines 
                        RectFromDcpSimpleLines(dcp, originalDcp, position.LogicalDirection, position.GetPointerContext(position.LogicalDirection), ref textDetails.u.full, ref rect, ref vrBaseline);
                    } 
                    else 
                    {
                        // (b) full with composite lines - when figures/floaters are present 
                        RectFromDcpCompositeLines(dcp, originalDcp, position.LogicalDirection, position.GetPointerContext(position.LogicalDirection), ref textDetails.u.full, ref rect, ref vrBaseline);
                    }
                }
            } 
            else
            { 
                // (c) cached - when using ParaChache 
                Debug.Assert(textDetails.fsktd == PTS.FSKTEXTDETAILS.fsktdCached);
                Debug.Assert(false, "Should not get here. ParaCache is not currently used."); 
            }

            // Mirror back to page flow direction
            if(ThisFlowDirection != PageFlowDirection) 
            {
                PTS.FSRECT pageRect = _pageContext.PageRect; 
                PTS.FSRECT rectTransform = new PTS.FSRECT(rect); 
                PTS.Validate(PTS.FsTransformRectangle(PTS.FlowDirectionToFswdir(ThisFlowDirection), ref pageRect, ref rectTransform, PTS.FlowDirectionToFswdir(PageFlowDirection), out rectTransform));
                rect = rectTransform.FromTextDpi(); 
            }

            return rect;
        } 
Beispiel #4
0
        private ReadOnlyCollection<LineResult> LineResultsFromCompositeLines(ref PTS.FSTEXTDETAILSFULL textDetails) 
        {
            ErrorHandler.Assert(!PTS.ToBoolean(textDetails.fDropCapPresent), ErrorHandler.NotSupportedDropCap);

            // Get list of complex composite lines. 
            PTS.FSLINEDESCRIPTIONCOMPOSITE [] arrayLineDesc;
            PtsHelper.LineListCompositeFromTextPara(PtsContext, _paraHandle.Value, ref textDetails, out arrayLineDesc); 
 
            List<LineResult> lines = new List<LineResult>(arrayLineDesc.Length);
 
            // Get lines information
            for (int index = 0; index < arrayLineDesc.Length; index++)
            {
                PTS.FSLINEDESCRIPTIONCOMPOSITE lineDesc = arrayLineDesc[index]; 
                if (lineDesc.cElements == 0) { continue; }
 
                // Get list of line elements. 
                PTS.FSLINEELEMENT [] arrayLineElement;
                PtsHelper.LineElementListFromCompositeLine(PtsContext, ref lineDesc, out arrayLineElement); 

                for (int elIndex = 0; elIndex < arrayLineElement.Length; elIndex++)
                {
                    PTS.FSLINEELEMENT element = arrayLineElement[elIndex]; 

                    // Create line info 
                    Rect lbox = new Rect(TextDpi.FromTextDpi(element.urBBox), TextDpi.FromTextDpi(lineDesc.vrStart), 
                                         TextDpi.FromTextDpi(element.durBBox), TextDpi.FromTextDpi(element.dvrAscent + element.dvrDescent));
 
                    // Mirror layout box to page flow direction
                    if(ThisFlowDirection != PageFlowDirection)
                    {
                        PTS.FSRECT pageRect = _pageContext.PageRect; 
                        PTS.FSRECT rectTransform = new PTS.FSRECT(lbox);
                        PTS.Validate(PTS.FsTransformRectangle(PTS.FlowDirectionToFswdir(ThisFlowDirection), ref pageRect, ref rectTransform, PTS.FlowDirectionToFswdir(PageFlowDirection), out rectTransform)); 
                        lbox = rectTransform.FromTextDpi(); 
                    }
 
                    lines.Add(new TextParaLineResult(this, element.dcpFirst, element.dcpLim - element.dcpFirst,
                        lbox, TextDpi.FromTextDpi(element.dvrAscent)));
                }
            } 

            if (lines.Count != 0) 
            { 
                // Hide EOP character
                TextParaLineResult lastLineResult = (TextParaLineResult)lines[lines.Count - 1]; 
                if (HasEOP && lastLineResult.DcpLast > Paragraph.Cch)
                {
                    ErrorHandler.Assert(lastLineResult.DcpLast - Line.SyntheticCharacterLength == Paragraph.Cch, ErrorHandler.ParagraphCharacterCountMismatch);
                    lastLineResult.DcpLast -= Line.SyntheticCharacterLength; 
                }
            } 
 
            return (lines.Count > 0) ? new ReadOnlyCollection<LineResult>(lines) : null;
        }