Example #1
0
        internal int FormatCellFinite(
            IntPtr pfsclient,                       // IN:  
            IntPtr pfsparaclientTable,              // IN:  table's para client
            IntPtr pfsbrkcell,                      // IN:  not NULL if cell broken from previous page/column
            IntPtr nmCell,                          // IN:  for vMerged cells, the first cell (master)
            IntPtr pfsFtnRejector,                  // IN:  
            int fEmptyOK,                           // IN:  
            uint fswdirTable,                       // IN:  
            int dvrExtraHeight,                     // IN: height above current row (non-zero for vMerged cells)
            int dvrAvailable,                       // IN:  
            out PTS.FSFMTR pfmtr,                   // OUT: 
            out IntPtr ppfscell,                    // OUT: cell object
            out IntPtr pfsbrkcellOut,               // OUT: break if cell does not fit in dvrAvailable
            out int dvrUsed)                        // OUT: height -- min height required 
        {
            int fserr = PTS.fserrNone;
            try
            {
                CellParagraph cellParagraph = PtsContext.HandleToObject(nmCell) as CellParagraph;
                PTS.ValidateHandle(cellParagraph);

                TableParaClient tableParaClient = PtsContext.HandleToObject(pfsparaclientTable) as TableParaClient;
                PTS.ValidateHandle(tableParaClient);

                cellParagraph.FormatCellFinite(
                              tableParaClient, pfsbrkcell, pfsFtnRejector, fEmptyOK, fswdirTable, dvrAvailable, 
                              out pfmtr, out ppfscell, out pfsbrkcellOut, out dvrUsed);
            }
            catch (Exception e)
            {
                pfmtr = new PTS.FSFMTR();
                ppfscell = IntPtr.Zero;
                pfsbrkcellOut = IntPtr.Zero;
                dvrUsed = 0;
                PtsContext.CallbackException = e;
                fserr = PTS.fserrCallbackException;
            }
            catch
            {
                pfmtr = new PTS.FSFMTR();
                ppfscell = IntPtr.Zero;
                pfsbrkcellOut = IntPtr.Zero;
                dvrUsed = 0;
                PtsContext.CallbackException = new System.Exception("Caught a non CLS Exception");
                fserr = PTS.fserrCallbackException;
            }
            return (fserr);
        }
Example #2
0
        internal int SubpageFormatParaFinite(
            IntPtr pfssobjc,                    // IN:  object context
            IntPtr pfsparaclient,               // IN:
            IntPtr pfsobjbrk,                   // IN:  break record---use if !NULL
            int fBreakRecordFromPreviousPage,   // IN:  break record was created on previous page
            IntPtr nmp,                         // IN:  name of paragraph---use if break record is NULL
            int iArea,                          // IN:  column-span area index
            IntPtr pftnrej,                     // IN:
            IntPtr pfsgeom,                     // IN:  pointer to geometry
            int fEmptyOk,                       // IN:  is it OK not to add anything?
            int fSuppressTopSpace,              // IN:  suppress empty space at the top of the page
            uint fswdir,                        // IN:  current direction
            ref PTS.FSRECT fsrcToFill,          // IN:  rectangle to fill
            IntPtr pmcsclientIn,                // IN:  input margin collapsing state
            PTS.FSKCLEAR fskclearIn,            // IN:  clear property that must be satisfied
            PTS.FSKSUPPRESSHARDBREAKBEFOREFIRSTPARA fsksuppresshardbreakbeforefirstparaIn,

            int fBreakInside,                   // IN:  produce vertical break inside para; needed for recursive KWN logic;

            out PTS.FSFMTR fsfmtr,              // OUT: result of formatting the paragraph
            out IntPtr pfspara,                 // OUT: pointer to the para data
            out IntPtr pbrkrecpara,             // OUT: pointer to the para break record
            out int dvrUsed,                    // OUT: vertical space used by the para
            out PTS.FSBBOX fsbbox,              // OUT: para BBox
            out IntPtr pmcsclientOut,           // OUT: margin collapsing state at the bottom
            out PTS.FSKCLEAR fskclearOut,       // OUT: ClearIn for the next paragraph
            out int dvrTopSpace,                // OUT: top space due to collapsed margin
            out int fBreakInsidePossible)       // OUT: internal vertical break possible, needed for recursive KWN logic
        {
            int fserr = PTS.fserrNone;
            fBreakInsidePossible = PTS.False;
            try
            {
                SubpageParagraph para = PtsContext.HandleToObject(nmp) as SubpageParagraph;
                PTS.ValidateHandle(para);
                SubpageParaClient paraClient = PtsContext.HandleToObject(pfsparaclient) as SubpageParaClient;
                PTS.ValidateHandle(paraClient);
                MarginCollapsingState mcs = null;
                if (pmcsclientIn != IntPtr.Zero)
                {
                    mcs = PtsContext.HandleToObject(pmcsclientIn) as MarginCollapsingState;
                    PTS.ValidateHandle(mcs);
                }
                para.FormatParaFinite(paraClient, pfsobjbrk, fBreakRecordFromPreviousPage, pftnrej, 
                    fEmptyOk, fSuppressTopSpace, fswdir, ref fsrcToFill, mcs, fskclearIn, fsksuppresshardbreakbeforefirstparaIn, out fsfmtr, out pfspara, 
                    out pbrkrecpara, out dvrUsed, out fsbbox, out pmcsclientOut, out fskclearOut, out dvrTopSpace);
            }
            catch (Exception e)
            {
                fsfmtr = new PTS.FSFMTR(); pfspara = pbrkrecpara = pmcsclientOut = IntPtr.Zero; dvrUsed = dvrTopSpace = 0; fsbbox = new PTS.FSBBOX(); 
                fskclearOut = default(PTS.FSKCLEAR);
                PtsContext.CallbackException = e;
                fserr = PTS.fserrCallbackException;
            }
            catch
            {
                fsfmtr = new PTS.FSFMTR(); pfspara = pbrkrecpara = pmcsclientOut = IntPtr.Zero; dvrUsed = dvrTopSpace = 0; fsbbox = new PTS.FSBBOX(); 
                fskclearOut = default(PTS.FSKCLEAR);
                PtsContext.CallbackException = new System.Exception("Caught a non CLS Exception");
                fserr = PTS.fserrCallbackException;
            }
            return fserr;
        }
        internal override void FormatFloaterContentFinite(
            FloaterBaseParaClient paraClient,       // IN:
            IntPtr pbrkrecIn,                   // IN:  break record---use if !IntPtr.Zero
            int fBRFromPreviousPage,            // IN:  break record was created on previous page
            IntPtr footnoteRejector,            // IN: 
            int fEmptyOk,                       // IN:  is it OK not to add anything?
            int fSuppressTopSpace,              // IN:  suppress empty space at the top of the page
            uint fswdir,                        // IN:  direction of Track
            int fAtMaxWidth,                    // IN:  formating is at full width of column
            int durAvailable,                   // IN:  width of available space
            int dvrAvailable,                   // IN:  height of available space
            PTS.FSKSUPPRESSHARDBREAKBEFOREFIRSTPARA fsksuppresshardbreakbeforefirstparaIn,
                                                // IN: suppress breaks at track start?
            out PTS.FSFMTR fsfmtr,              // OUT: result of formatting
            out IntPtr pfsFloatContent,         // OUT: opaque for PTS pointer pointer to formatted content
            out IntPtr pbrkrecOut,              // OUT: pointer to the floater content break record
            out int durFloaterWidth,            // OUT: floater width
            out int dvrFloaterHeight,           // OUT: floater height
            out PTS.FSBBOX fsbbox,              // OUT: floater bbox
            out int cPolygons,                  // OUT: number of polygons
            out int cVertices)                  // OUT: total number of vertices in all polygons
        {
            uint fswdirPara = PTS.FlowDirectionToFswdir(((FlowDirection)Element.GetValue(FrameworkElement.FlowDirectionProperty)));

            int subpageWidth, subpageHeight;
            int dvrTopSpace;
            int cColumns;
            PTS.FSRECT fsrcSubpageMargin;
            PTS.FSCOLUMNINFO[] columnInfoCollection;
            IntPtr pmcsclientOut;
            double specifiedWidth;
            MbpInfo mbp;

            Invariant.Assert(paraClient is FloaterParaClient);

            // If horizontal alignment is Stretch and we are not formatting at max width,
            // we cannot proceed.
            if (IsFloaterRejected(PTS.ToBoolean(fAtMaxWidth), TextDpi.FromTextDpi(durAvailable)))
            {
                durFloaterWidth = dvrFloaterHeight = 0;
                cPolygons = cVertices = 0;
                fsfmtr = new PTS.FSFMTR();
                fsfmtr.kstop = PTS.FSFMTRKSTOP.fmtrNoProgressOutOfSpace;
                fsfmtr.fContainsItemThatStoppedBeforeFootnote = PTS.False;
                fsfmtr.fForcedProgress = PTS.False;
                fsbbox = new PTS.FSBBOX();
                fsbbox.fDefined = PTS.False;
                pbrkrecOut = IntPtr.Zero;
                pfsFloatContent = IntPtr.Zero;
            }
            else
            {
                // When formatting bottomless page, PTS may format paragraphs as finite. This happens
                // in case of multiple columns. In this case make sure that height is not too big.
                if (!StructuralCache.CurrentFormatContext.FinitePage)
                {
                    if (Double.IsInfinity(StructuralCache.CurrentFormatContext.PageHeight))
                    {
                        if (dvrAvailable > PTS.dvBottomUndefined / 2)
                        {
                            dvrAvailable = Math.Min(dvrAvailable, PTS.dvBottomUndefined / 2);
                            fEmptyOk = PTS.False;
                        }
                    }
                    else
                    {
                        dvrAvailable = Math.Min(dvrAvailable, TextDpi.ToTextDpi(StructuralCache.CurrentFormatContext.PageHeight));
                    }
                }

                // Initialize the subpage size. PTS subpage margin is always set to 0 for Floaters.
                // If width on floater is specified, use the specified value.
                // Margin, border and padding of the floater is extracted from available subpage height
                mbp = MbpInfo.FromElement(Element);
                
                // We do not mirror margin as it's used to dist text left and right, and is unnecessary.
                // Clip Floater.Width to available width
                specifiedWidth = CalculateWidth(TextDpi.FromTextDpi(durAvailable));
                AdjustDurAvailable(specifiedWidth, ref durAvailable, out subpageWidth);
                subpageHeight = Math.Max(1, dvrAvailable - (mbp.MBPTop + mbp.MBPBottom));
                fsrcSubpageMargin = new PTS.FSRECT();
                fsrcSubpageMargin.du = subpageWidth;
                fsrcSubpageMargin.dv = subpageHeight;

                // Initialize column info. Floater always has just 1 column.
                cColumns = 1;
                columnInfoCollection = new PTS.FSCOLUMNINFO[cColumns];
                columnInfoCollection[0].durBefore = 0;
                columnInfoCollection[0].durWidth = subpageWidth;

                // Format subpage
                CreateSubpageFiniteHelper(PtsContext, pbrkrecIn, fBRFromPreviousPage, _mainTextSegment.Handle,
                    footnoteRejector, fEmptyOk, PTS.True, fswdir, subpageWidth, subpageHeight,
                    ref fsrcSubpageMargin, cColumns, columnInfoCollection, PTS.False, fsksuppresshardbreakbeforefirstparaIn,
                    out fsfmtr, out pfsFloatContent, 
                    out pbrkrecOut, out dvrFloaterHeight, out fsbbox, out pmcsclientOut, out dvrTopSpace);

                // Initialize subpage metrics
                if (fsfmtr.kstop >= PTS.FSFMTRKSTOP.fmtrNoProgressOutOfSpace)   // No progress or collision
                {
                    Debug.Assert(pmcsclientOut == IntPtr.Zero);
                    durFloaterWidth = dvrFloaterHeight = 0;
                    cPolygons = cVertices = 0;
                    //pbrkrecpara = IntPtr.Zero;
                }
                else
                {
                    // PTS subpage does not support autosizing, but Floater needs to autosize to its
                    // content. To workaround this problem, second format of subpage is performed, if 
                    // necessary. It means that if the width of bounding box is smaller than subpage's
                    // width, second formatting is performed.
                    // However, if HorizontalAlignment is set to Stretch we should not reformat because floater
                    // should be at max width
                    if (PTS.ToBoolean(fsbbox.fDefined))
                    {
                        if(fsbbox.fsrc.du < subpageWidth && Double.IsNaN(specifiedWidth) && HorizontalAlignment != HorizontalAlignment.Stretch)
                        {
                            // There is a need to reformat PTS subpage, so destroy any resourcces allocated by PTS
                            // during previous formatting.
                            if (pfsFloatContent != IntPtr.Zero)
                            {
                                PTS.Validate(PTS.FsDestroySubpage(PtsContext.Context, pfsFloatContent), PtsContext);
                                pfsFloatContent = IntPtr.Zero;
                            }
                            if (pbrkrecOut != IntPtr.Zero)
                            {
                                PTS.Validate(PTS.FsDestroySubpageBreakRecord(PtsContext.Context, pbrkrecOut), PtsContext);
                                pbrkrecOut = IntPtr.Zero;
                            }
                            if (pmcsclientOut != IntPtr.Zero)
                            {
                                MarginCollapsingState mcs = PtsContext.HandleToObject(pmcsclientOut) as MarginCollapsingState;
                                PTS.ValidateHandle(mcs);
                                mcs.Dispose();
                                pmcsclientOut = IntPtr.Zero;
                            }
                            // Create subpage with new width.
                            subpageWidth = fsbbox.fsrc.du + 1; // add 1/300px to avoid rounding errors 
                            fsrcSubpageMargin.du = subpageWidth;
                            fsrcSubpageMargin.dv = subpageHeight;
                            columnInfoCollection[0].durWidth = subpageWidth;
                            CreateSubpageFiniteHelper(PtsContext, pbrkrecIn, fBRFromPreviousPage, _mainTextSegment.Handle,
                                 footnoteRejector, fEmptyOk, PTS.True, fswdir, subpageWidth, subpageHeight,
                                ref fsrcSubpageMargin, cColumns, columnInfoCollection, PTS.False, fsksuppresshardbreakbeforefirstparaIn,
                                out fsfmtr, out pfsFloatContent,
                                out pbrkrecOut, out dvrFloaterHeight, out fsbbox, out pmcsclientOut, out dvrTopSpace);
                        }
                    }
                    else
                    {
                        subpageWidth = TextDpi.ToTextDpi(TextDpi.MinWidth);
                    }

                    // Destroy objects created by PTS, but not used here.
                    if (pmcsclientOut != IntPtr.Zero)
                    {
                        MarginCollapsingState mcs = PtsContext.HandleToObject(pmcsclientOut) as MarginCollapsingState;
                        PTS.ValidateHandle(mcs);
                        mcs.Dispose();
                        pmcsclientOut = IntPtr.Zero;
                    }

                    // Get the size of the floater. For height PTS already reports calculated value.
                    // But width is the same as subpage width. Add margin values here since we do not use 
                    // distance to text anymore
                    durFloaterWidth = subpageWidth + mbp.MBPLeft + mbp.MBPRight;

                    // Add back all MBP values since we do not use dist to text
                    dvrFloaterHeight += mbp.MBPTop + mbp.MBPBottom;
                    // Check if floater width fits in available width. It may exceed available width because borders and
                    // padding are added.


                    fsbbox.fsrc.u = 0;
                    fsbbox.fsrc.v = 0;
                    fsbbox.fsrc.du = durFloaterWidth;
                    fsbbox.fsrc.dv = dvrFloaterHeight;
                    fsbbox.fDefined = PTS.True;

                    // Tight wrap is disabled for now.
                    cPolygons = cVertices = 0;

                    if(durFloaterWidth > durAvailable || dvrFloaterHeight > dvrAvailable)
                    {
                        if(PTS.ToBoolean(fEmptyOk))
                        {
                            // Get rid of any previous formatting 
                            if (pfsFloatContent != IntPtr.Zero)
                            {
                                PTS.Validate(PTS.FsDestroySubpage(PtsContext.Context, pfsFloatContent), PtsContext);
                                pfsFloatContent = IntPtr.Zero;
                            }
                            if (pbrkrecOut != IntPtr.Zero)
                            {
                                PTS.Validate(PTS.FsDestroySubpageBreakRecord(PtsContext.Context, pbrkrecOut), PtsContext);
                                pbrkrecOut = IntPtr.Zero;
                            }
                            cPolygons = cVertices = 0;
                            fsfmtr.kstop = PTS.FSFMTRKSTOP.fmtrNoProgressOutOfSpace;
                        }
                        else
                        {
                            fsfmtr.fForcedProgress = PTS.True;
                        }
                    }
                }
            }

            // Update handle to PTS subpage.
            ((FloaterParaClient)paraClient).SubpageHandle = pfsFloatContent;
        }
Example #4
0
        internal int FormatFloaterContentFinite(
            IntPtr pfsclient,                   // IN:  client opaque data
            IntPtr pfsparaclient,               // IN:
            IntPtr pfsbrkFloaterContentIn,      // IN:  break record---use if !NULL
            int fBreakRecordFromPreviousPage,   // IN:  break record was created on previous page
            IntPtr nmFloater,                   // IN:  name of floater
            IntPtr pftnrej,                     // IN: 
            int fEmptyOk,                       // IN:  is it OK not to add anything?
            int fSuppressTopSpace,              // IN:  suppress empty space at the top of the page
            uint fswdirTrack,                   // IN:  direction of Track
            int fAtMaxWidth,                    // IN:  formating is at full width of column
            int durAvailable,                   // IN:  width of available space
            int dvrAvailable,                   // IN:  height of available space
            PTS.FSKSUPPRESSHARDBREAKBEFOREFIRSTPARA fsksuppresshardbreakbeforefirstparaIn,

            out PTS.FSFMTR fsfmtr,              // OUT: result of formatting
            out IntPtr pfsFloatContent,         // OUT: opaque for PTS pointer pointer to formatted content
            out IntPtr pbrkrecpara,             // OUT: pointer to the floater content break record
            out int durFloaterWidth,            // OUT: floater width
            out int dvrFloaterHeight,           // OUT: floater height
            out PTS.FSBBOX fsbbox,              // OUT: floater bbox
            out int cPolygons,                  // OUT: number of polygons
            out int cVertices)                  // OUT: total number of vertices in all polygons
        {
            int fserr = PTS.fserrNone;
            try
            {
                FloaterBaseParagraph para = PtsContext.HandleToObject(nmFloater) as FloaterBaseParagraph;
                PTS.ValidateHandle(para);
                FloaterBaseParaClient paraClient = PtsContext.HandleToObject(pfsparaclient) as FloaterBaseParaClient;
                PTS.ValidateHandle(paraClient);
                para.FormatFloaterContentFinite(paraClient, pfsbrkFloaterContentIn, fBreakRecordFromPreviousPage,
                    pftnrej, fEmptyOk, fSuppressTopSpace, fswdirTrack, fAtMaxWidth, durAvailable, dvrAvailable, 
                    fsksuppresshardbreakbeforefirstparaIn, out fsfmtr, out pfsFloatContent, out pbrkrecpara, out durFloaterWidth, 
                    out dvrFloaterHeight, out fsbbox, out cPolygons, out cVertices);
            }
            catch (Exception e)
            {
                fsfmtr = new PTS.FSFMTR(); pfsFloatContent = pbrkrecpara = IntPtr.Zero; durFloaterWidth = dvrFloaterHeight = cPolygons = cVertices = 0; fsbbox = new PTS.FSBBOX();
                PtsContext.CallbackException = e;
                fserr = PTS.fserrCallbackException;
            }
            catch
            {
                fsfmtr = new PTS.FSFMTR(); pfsFloatContent = pbrkrecpara = IntPtr.Zero; durFloaterWidth = dvrFloaterHeight = cPolygons = cVertices = 0; fsbbox = new PTS.FSBBOX();
                PtsContext.CallbackException = new System.Exception("Caught a non CLS Exception");
                fserr = PTS.fserrCallbackException;
            }
            return fserr;
        }
Example #5
0
        //-------------------------------------------------------------------
        // FormatFloaterContentFinite
        //-------------------------------------------------------------------
        internal override void FormatFloaterContentFinite(
            FloaterBaseParaClient paraClient,   // IN:
            IntPtr pbrkrecIn,                   // IN:  break record---use if !IntPtr.Zero
            int fBRFromPreviousPage,            // IN:  break record was created on previous page
            IntPtr footnoteRejector,            // IN: 
            int fEmptyOk,                       // IN:  is it OK not to add anything?
            int fSuppressTopSpace,              // IN:  suppress empty space at the top of the page
            uint fswdir,                        // IN:  direction of Track
            int fAtMaxWidth,                    // IN:  formating is at full width of column
            int durAvailable,                   // IN:  width of available space
            int dvrAvailable,                   // IN:  height of available space
            PTS.FSKSUPPRESSHARDBREAKBEFOREFIRSTPARA fsksuppresshardbreakbeforefirstparaIn,
                                                // IN: suppress breaks at track start?
            out PTS.FSFMTR fsfmtr,              // OUT: result of formatting
            out IntPtr pfsFloatContent,         // OUT: opaque for PTS pointer pointer to formatted content
            out IntPtr pbrkrecOut,              // OUT: pointer to the floater content break record
            out int durFloaterWidth,            // OUT: floater width
            out int dvrFloaterHeight,           // OUT: floater height
            out PTS.FSBBOX fsbbox,              // OUT: floater bbox
            out int cPolygons,                  // OUT: number of polygons
            out int cVertices)                  // OUT: total number of vertices in all polygons
        {
            Invariant.Assert(paraClient is UIElementParaClient);
            Invariant.Assert(Element is BlockUIContainer);

            if (fAtMaxWidth == PTS.False && fEmptyOk == PTS.True)
            {
                // Do not format if not at max width, and if fEmptyOk is true
                durFloaterWidth = dvrFloaterHeight = 0;
                cPolygons = cVertices = 0;
                fsfmtr = new PTS.FSFMTR();
                fsfmtr.kstop = PTS.FSFMTRKSTOP.fmtrNoProgressOutOfSpace;
                fsfmtr.fContainsItemThatStoppedBeforeFootnote = PTS.False;
                fsfmtr.fForcedProgress = PTS.False;
                fsbbox = new PTS.FSBBOX();
                fsbbox.fDefined = PTS.False;
                pbrkrecOut = IntPtr.Zero;
                pfsFloatContent = IntPtr.Zero;
            }
            else
            {
                cPolygons = cVertices = 0;
                // Formatting is not at max width but proceeds anyway because adding no content is not allowed
                fsfmtr.fForcedProgress = PTS.FromBoolean(fAtMaxWidth == PTS.False);

                // Format UIElement
                if (((BlockUIContainer)Element).Child != null)
                {
                    EnsureUIElementIsland();
                    FormatUIElement(durAvailable, out fsbbox);
                }
                else
                {
                    // Child elementis null. Create fsbbox only with border and padding info
                    ClearUIElementIsland();

                    MbpInfo mbp = MbpInfo.FromElement(Element);
                    fsbbox.fsrc = new PTS.FSRECT();
                    fsbbox.fsrc.du = durAvailable;
                    fsbbox.fsrc.dv = mbp.BPTop + mbp.BPBottom;
                }

                durFloaterWidth = fsbbox.fsrc.du;
                dvrFloaterHeight = fsbbox.fsrc.dv;
                if (dvrAvailable < dvrFloaterHeight && fEmptyOk == PTS.True)
                {
                    // Will not fit in available space. Since fEmptyOk is true, we can return null floater
                    durFloaterWidth = dvrFloaterHeight = 0;
                    fsfmtr = new PTS.FSFMTR();
                    fsfmtr.kstop = PTS.FSFMTRKSTOP.fmtrNoProgressOutOfSpace;
                    fsbbox = new PTS.FSBBOX();
                    fsbbox.fDefined = PTS.False;
                    pfsFloatContent = IntPtr.Zero;
                }
                else
                {
                    // Either floater fits in available space or it doesn't but we cannot return nothing. 
                    // Use the space needed, and set formatter result to forced progress if BUC does not fit in available space.
                    fsbbox.fDefined = PTS.True;
                    pfsFloatContent = paraClient.Handle;
                    if (dvrAvailable < dvrFloaterHeight)
                    {
                        // Indicate that progress was forced
                        Invariant.Assert(fEmptyOk == PTS.False);
                        fsfmtr.fForcedProgress = PTS.True;
                    }
                    fsfmtr.kstop = PTS.FSFMTRKSTOP.fmtrGoalReached;
                }

                // Set output values for floater content
                pbrkrecOut = IntPtr.Zero;
                fsfmtr.fContainsItemThatStoppedBeforeFootnote = PTS.False;
            }
        }