Exemple #1
0
        // ------------------------------------------------------------------
        // Returns calculated column information -  count, width, gap and rule.
        // ------------------------------------------------------------------
        internal static void GetColumnMetrics(StructuralCache structuralCache, out int cColumns, out double width, out double gap, out double rule)
        {
            ColumnPropertiesGroup columnProperties = new ColumnPropertiesGroup(structuralCache.PropertyOwner);
            FontFamily            pageFontFamily   = (FontFamily)structuralCache.PropertyOwner.GetValue(Block.FontFamilyProperty);
            double    lineHeight   = DynamicPropertyReader.GetLineHeightValue(structuralCache.PropertyOwner);
            double    pageFontSize = (double)structuralCache.PropertyOwner.GetValue(Block.FontSizeProperty);
            Size      pageSize     = structuralCache.CurrentFormatContext.PageSize;
            Thickness pageMargin   = structuralCache.CurrentFormatContext.PageMargin;
            double    pageWidth    = pageSize.Width - (pageMargin.Left + pageMargin.Right);

            cColumns = PtsHelper.CalculateColumnCount(columnProperties, lineHeight, pageWidth, pageFontSize, pageFontFamily, true);

            double freeSpace;

            rule = columnProperties.ColumnRuleWidth;
            PtsHelper.GetColumnMetrics(columnProperties, pageWidth,
                                       pageFontSize, pageFontFamily, true, cColumns,
                                       ref lineHeight, out width, out freeSpace, out gap);

            if (columnProperties.IsColumnWidthFlexible && columnProperties.ColumnSpaceDistribution == ColumnSpaceDistribution.Between)
            {
                width += freeSpace / cColumns;
            }

            width = Math.Min(width, pageWidth);
        }
Exemple #2
0
        // ------------------------------------------------------------------
        // Calculates a page margin adjustment to eliminate free space if column width is not flexible
        // ------------------------------------------------------------------
        internal static double CalculatePageMarginAdjustment(StructuralCache structuralCache, double pageMarginWidth)
        {
            double pageMarginAdjustment = 0.0;

            DependencyObject o = structuralCache.Section.Element;

            if (o is FlowDocument)
            {
                ColumnPropertiesGroup columnProperties = new ColumnPropertiesGroup(o);

                if (!columnProperties.IsColumnWidthFlexible)
                {
                    double     lineHeight     = DynamicPropertyReader.GetLineHeightValue(o);
                    double     pageFontSize   = (double)structuralCache.PropertyOwner.GetValue(Block.FontSizeProperty);
                    FontFamily pageFontFamily = (FontFamily)structuralCache.PropertyOwner.GetValue(Block.FontFamilyProperty);

                    int ccol = PtsHelper.CalculateColumnCount(columnProperties, lineHeight, pageMarginWidth, pageFontSize, pageFontFamily, true);

                    double columnWidth;
                    double freeSpace;
                    double gap;

                    GetColumnMetrics(columnProperties, pageMarginWidth,
                                     pageFontSize, pageFontFamily, true, ccol,
                                     ref lineHeight, out columnWidth, out freeSpace, out gap);

                    pageMarginAdjustment = freeSpace;
                }
            }

            return(pageMarginAdjustment);
        }
        // Token: 0x06006A41 RID: 27201 RVA: 0x001E3E34 File Offset: 0x001E2034
        internal void GetSectionProperties(out int fNewPage, out uint fswdir, out int fApplyColumnBalancing, out int ccol, out int cSegmentDefinedColumnSpanAreas, out int cHeightDefinedColumnSpanAreas)
        {
            ColumnPropertiesGroup columnProperties = new ColumnPropertiesGroup(this.Element);
            Size       pageSize        = this._structuralCache.CurrentFormatContext.PageSize;
            double     lineHeightValue = DynamicPropertyReader.GetLineHeightValue(this.Element);
            Thickness  pageMargin      = this._structuralCache.CurrentFormatContext.PageMargin;
            double     pageFontSize    = (double)this._structuralCache.PropertyOwner.GetValue(TextElement.FontSizeProperty);
            FontFamily pageFontFamily  = (FontFamily)this._structuralCache.PropertyOwner.GetValue(TextElement.FontFamilyProperty);
            bool       finitePage      = this._structuralCache.CurrentFormatContext.FinitePage;

            fNewPage = 0;
            fswdir   = PTS.FlowDirectionToFswdir((FlowDirection)this._structuralCache.PropertyOwner.GetValue(FrameworkElement.FlowDirectionProperty));
            fApplyColumnBalancing = 0;
            ccol = PtsHelper.CalculateColumnCount(columnProperties, lineHeightValue, pageSize.Width - (pageMargin.Left + pageMargin.Right), pageFontSize, pageFontFamily, finitePage);
            cSegmentDefinedColumnSpanAreas = 0;
            cHeightDefinedColumnSpanAreas  = 0;
        }
Exemple #4
0
        // Token: 0x06006942 RID: 26946 RVA: 0x001DCDB0 File Offset: 0x001DAFB0
        internal static double CalculatePageMarginAdjustment(StructuralCache structuralCache, double pageMarginWidth)
        {
            double           result  = 0.0;
            DependencyObject element = structuralCache.Section.Element;

            if (element is FlowDocument)
            {
                ColumnPropertiesGroup columnPropertiesGroup = new ColumnPropertiesGroup(element);
                if (!columnPropertiesGroup.IsColumnWidthFlexible)
                {
                    double     lineHeightValue = DynamicPropertyReader.GetLineHeightValue(element);
                    double     pageFontSize    = (double)structuralCache.PropertyOwner.GetValue(TextElement.FontSizeProperty);
                    FontFamily pageFontFamily  = (FontFamily)structuralCache.PropertyOwner.GetValue(TextElement.FontFamilyProperty);
                    int        cColumns        = PtsHelper.CalculateColumnCount(columnPropertiesGroup, lineHeightValue, pageMarginWidth, pageFontSize, pageFontFamily, true);
                    double     num;
                    double     num2;
                    double     num3;
                    PtsHelper.GetColumnMetrics(columnPropertiesGroup, pageMarginWidth, pageFontSize, pageFontFamily, true, cColumns, ref lineHeightValue, out num, out num2, out num3);
                    result = num2;
                }
            }
            return(result);
        }
Exemple #5
0
        // ------------------------------------------------------------------
        // GetSectionProperties
        // ------------------------------------------------------------------

        /// <summary>
        /// Get section properties
        /// </summary>
        /// <param name="fNewPage">
        /// OUT: stop page before this section?
        /// </param>
        /// <param name="fswdir">
        /// OUT: direction of this section
        /// </param>
        /// <param name="fApplyColumnBalancing">
        /// OUT: apply column balancing to this section?
        /// </param>
        /// <param name="ccol">
        /// OUT: number of columns in the main text segment
        /// </param>
        /// <param name="cSegmentDefinedColumnSpanAreas">
        /// OUT: number of segment-defined columnspan areas
        /// </param>
        /// <param name="cHeightDefinedColumnSpanAreas">
        /// OUT: number of height-defined columnsapn areas
        /// </param>
        internal void GetSectionProperties(
            out int fNewPage,
            out uint fswdir,
            out int fApplyColumnBalancing,
            out int ccol,
            out int cSegmentDefinedColumnSpanAreas,
            out int cHeightDefinedColumnSpanAreas)
        {
            ColumnPropertiesGroup columnProperties = new ColumnPropertiesGroup(Element);
            Size       pageSize       = _structuralCache.CurrentFormatContext.PageSize;
            double     lineHeight     = DynamicPropertyReader.GetLineHeightValue(Element);
            Thickness  pageMargin     = _structuralCache.CurrentFormatContext.PageMargin;
            double     pageFontSize   = (double)_structuralCache.PropertyOwner.GetValue(Block.FontSizeProperty);
            FontFamily pageFontFamily = (FontFamily)_structuralCache.PropertyOwner.GetValue(Block.FontFamilyProperty);
            bool       enableColumns  = _structuralCache.CurrentFormatContext.FinitePage;

            fNewPage = PTS.False; // Since only one section is supported, don't force page break before.
            fswdir   = PTS.FlowDirectionToFswdir((FlowDirection)_structuralCache.PropertyOwner.GetValue(FrameworkElement.FlowDirectionProperty));
            fApplyColumnBalancing = PTS.False;
            ccol = PtsHelper.CalculateColumnCount(columnProperties, lineHeight, pageSize.Width - (pageMargin.Left + pageMargin.Right), pageFontSize, pageFontFamily, enableColumns);
            cSegmentDefinedColumnSpanAreas = 0;
            cHeightDefinedColumnSpanAreas  = 0;
        }
Exemple #6
0
        internal unsafe void UpdateBottomlessPara(
            IntPtr pfspara,                      // IN:  pointer to the para data
            SubpageParaClient paraClient,        // IN:
            int fSuppressTopSpace,               // IN:  suppress empty space at the top of the page
            uint fswdir,                         // IN:  current direction
            int urTrack,                         // IN:  u of bootomless rectangle to fill
            int durTrack,                        // IN:  du of bootomless rectangle to fill
            int vrTrack,                         // IN:  v of bootomless rectangle to fill
            MarginCollapsingState mcs,           // IN:  input margin collapsing state
            PTS.FSKCLEAR fskclearIn,             // IN:  clear property that must be satisfied
            int fInterruptable,                  // IN:  formatting can be interrupted
            out PTS.FSFMTRBL fsfmtrbl,           // OUT: result of formatting the paragraph
            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 fPageBecomesUninterruptable) // OUT: interruption is prohibited from now on
        {
            int     subpageWidth, urSubpageMargin, durSubpageMargin, vrSubpageMargin;
            int     cColumns;
            int     marginTop, marginBottom;
            MbpInfo mbp;
            MarginCollapsingState mcsSubpage, mcsBottom;

            PTS.FSCOLUMNINFO[] columnInfoCollection;
            uint fswdirSubpage = PTS.FlowDirectionToFswdir(((FlowDirection)Element.GetValue(FrameworkElement.FlowDirectionProperty)));

            // Initialize the subpage size and its margin.
            subpageWidth    = durTrack;
            urSubpageMargin = vrSubpageMargin = 0;

            // Set clear property
            Invariant.Assert(Element is TableCell || Element is AnchoredBlock);
            fskclearIn = PTS.WrapDirectionToFskclear((WrapDirection)Element.GetValue(Block.ClearFloatersProperty));

            // Take into account MBPs and modify subpage metrics,
            // and make sure that subpage is at least 1 unit wide (cannot measure at width <= 0)
            // NOTE: Do not suppress top space for bottomles pages.
            mbp = MbpInfo.FromElement(Element, StructuralCache.TextFormatterHost.PixelsPerDip);

            if (fswdirSubpage != fswdir)
            {
                PTS.FSRECT fsrcToFillSubpage = new PTS.FSRECT(urTrack, 0, durTrack, 0);
                PTS.FSRECT pageRect          = StructuralCache.CurrentFormatContext.PageRect;
                PTS.Validate(PTS.FsTransformRectangle(fswdir, ref pageRect, ref fsrcToFillSubpage, fswdirSubpage, out fsrcToFillSubpage));

                urTrack  = fsrcToFillSubpage.u;
                durTrack = fsrcToFillSubpage.du;

                mbp.MirrorMargin();
            }

            subpageWidth = Math.Max(1, subpageWidth - (mbp.MBPLeft + mbp.MBPRight));
            MarginCollapsingState.CollapseTopMargin(PtsContext, mbp, mcs, out mcsSubpage, out marginTop);
            // Destroy top margin collapsing state (not needed anymore).
            if (mcsSubpage != null)
            {
                mcsSubpage.Dispose();
                mcsSubpage = null;
            }
            durSubpageMargin = subpageWidth;

            // Initialize column info
            // For bottomles spara, limit line height to the height of the current format context in structural cache.
            ColumnPropertiesGroup columnProperties = new ColumnPropertiesGroup(_element);
            double     lineHeight     = DynamicPropertyReader.GetLineHeightValue(_element);
            double     pageFontSize   = (double)_structuralCache.PropertyOwner.GetValue(Block.FontSizeProperty);
            FontFamily pageFontFamily = (FontFamily)_structuralCache.PropertyOwner.GetValue(Block.FontFamilyProperty);

            // Get columns info, setting ownerIsFlowDocument flag to false. A flow document should not be formatted as a subpage and we
            // do not want default column widths to be set on TableCells and floaters
            cColumns             = PtsHelper.CalculateColumnCount(columnProperties, lineHeight, TextDpi.FromTextDpi(subpageWidth), pageFontSize, pageFontFamily, false);
            columnInfoCollection = new PTS.FSCOLUMNINFO[cColumns];
            fixed(PTS.FSCOLUMNINFO *rgColumnInfo = columnInfoCollection)
            {
                PtsHelper.GetColumnsInfo(columnProperties, lineHeight, TextDpi.FromTextDpi(subpageWidth), pageFontSize, pageFontFamily, cColumns, rgColumnInfo, false);
            }

            StructuralCache.CurrentFormatContext.PushNewPageData(new Size(TextDpi.FromTextDpi(subpageWidth), TextDpi.MaxWidth),
                                                                 new Thickness(),
                                                                 true,
                                                                 false);

            // Create subpage
            fixed(PTS.FSCOLUMNINFO *rgColumnInfo = columnInfoCollection)
            {
                PTS.Validate(PTS.FsUpdateBottomlessSubpage(PtsContext.Context, pfspara, _mainTextSegment.Handle, fSuppressTopSpace,
                                                           fswdir, subpageWidth, urSubpageMargin, durSubpageMargin, vrSubpageMargin,
                                                           cColumns, rgColumnInfo, 0, null, null, 0, null, null, PTS.FromBoolean(true),
                                                           out fsfmtrbl, out dvrUsed, out fsbbox, out pmcsclientOut, out dvrTopSpace,
                                                           out fPageBecomesUninterruptable), PtsContext);
            }

            StructuralCache.CurrentFormatContext.PopPageData();

            fskclearOut = PTS.FSKCLEAR.fskclearNone;

            if (fsfmtrbl != PTS.FSFMTRBL.fmtrblCollision)
            {
                // Bottom margin collapsing:
                // (1) retrieve mcs from the subtrack
                // (2) do margin collapsing; create a new margin collapsing state
                if (pmcsclientOut != IntPtr.Zero)
                {
                    mcsSubpage = PtsContext.HandleToObject(pmcsclientOut) as MarginCollapsingState;
                    PTS.ValidateHandle(mcsSubpage);
                    pmcsclientOut = IntPtr.Zero;
                }
                MarginCollapsingState.CollapseBottomMargin(PtsContext, mbp, mcsSubpage, out mcsBottom, out marginBottom);
                pmcsclientOut = (mcsBottom != null) ? mcsBottom.Handle : IntPtr.Zero;

                // Since MCS returned by PTS is never passed back, destroy MCS provided by PTS.
                // If necessary, new MCS is created and passed back to PTS.
                if (mcsSubpage != null)
                {
                    mcsSubpage.Dispose();
                    mcsSubpage = null;
                }

                if (PTS.ToBoolean(fsbbox.fDefined))
                {
                    // Workaround for PTS bug 860: get max of the page rect and
                    // bounding box of the page.
                    dvrUsed  = Math.Max(dvrUsed, fsbbox.fsrc.dv + fsbbox.fsrc.v);
                    durTrack = Math.Max(durTrack, fsbbox.fsrc.du + fsbbox.fsrc.u);
                }

                // Take into account MBPs and modify subtrack metrics
                dvrTopSpace = (mbp.BPTop != 0) ? marginTop : dvrTopSpace;
                dvrUsed    += (marginTop + mbp.BPTop) + (marginBottom + mbp.BPBottom);

                // Update bounding box
                fsbbox.fsrc.u  = urTrack + mbp.MarginLeft;
                fsbbox.fsrc.v  = vrTrack + dvrTopSpace;
                fsbbox.fsrc.du = Math.Max(durTrack - (mbp.MarginLeft + mbp.MarginRight), 0);
                fsbbox.fsrc.dv = Math.Max(dvrUsed - dvrTopSpace, 0);
            }
            else
            {
                Debug.Assert(pmcsclientOut == IntPtr.Zero);
                pfspara = IntPtr.Zero;
                dvrUsed = dvrTopSpace = 0;
            }


            if (fswdirSubpage != fswdir)
            {
                PTS.FSRECT pageRect = StructuralCache.CurrentFormatContext.PageRect;
                PTS.Validate(PTS.FsTransformBbox(fswdirSubpage, ref pageRect, ref fsbbox, fswdir, out fsbbox));
            }

            // Update information about first/last chunk. In bottomless scenario
            // paragraph is not broken, so there is only one chunk.
            paraClient.SetChunkInfo(true, true);
        }
Exemple #7
0
        internal unsafe void FormatParaFinite(
            SubpageParaClient paraClient,       // IN:
            IntPtr pbrkrecIn,                   // IN:  break record---use if !NULL
            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:  current direction
            ref PTS.FSRECT fsrcToFill,          // IN:  rectangle to fill
            MarginCollapsingState mcs,          // IN:  input margin collapsing state
            PTS.FSKCLEAR fskclearIn,            // IN:  clear property that must be satisfied
            PTS.FSKSUPPRESSHARDBREAKBEFOREFIRSTPARA fsksuppresshardbreakbeforefirstparaIn,
            // IN: suppress breaks at track start?
            out PTS.FSFMTR fsfmtr,              // OUT: result of formatting the paragraph
            out IntPtr pfspara,                 // OUT: pointer to the para data
            out IntPtr pbrkrecOut,              // 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
        {
            uint fswdirSubpage = PTS.FlowDirectionToFswdir(((FlowDirection)Element.GetValue(FrameworkElement.FlowDirectionProperty)));

            int     subpageWidth, subpageHeight;
            int     cColumns;
            int     marginTop, marginBottom;
            MbpInfo mbp;
            MarginCollapsingState mcsSubpage, mcsBottom;

            PTS.FSRECT          fsrcSubpageMargin;
            PTS.FSCOLUMNINFO [] columnInfoCollection;

            // Currently it is possible to get MCS and BR in following situation:
            // At the end of the page there is a paragraph with delayed figure, so the figure
            // gets delayed to the next page. But part of the next paragraph fits in the page,
            // so it gets broken. PTS creates BR with delayed figure and broken para.
            // PTS will format the next page starting from delayed figure, which can produce MCS.
            // So when the next paragraph is continued from BR, it has MCS.
            // This problem is currently investigated by PTS team: PTSLS bug 915.
            // For now, MCS gets ignored here.
            //Debug.Assert(pbrkrecIn == IntPtr.Zero || mcs == null, "Broken paragraph cannot have margin collapsing state.");
            if (mcs != null && pbrkrecIn != IntPtr.Zero)
            {
                mcs = null;
            }

            // Initialize the subpage size and its margin.
            fsrcSubpageMargin = new PTS.FSRECT();
            subpageWidth      = fsrcToFill.du;
            subpageHeight     = fsrcToFill.dv;

            // Set clear property
            Invariant.Assert(Element is TableCell || Element is AnchoredBlock);
            fskclearIn = PTS.WrapDirectionToFskclear((WrapDirection)Element.GetValue(Block.ClearFloatersProperty));

            // Take into account MBPs and modify subpage metrics,
            // and make sure that subpage is at least 1 unit wide (cannot measure at width <= 0)
            marginTop  = 0;
            mcsSubpage = null;

            // Get MBP info. Since subpage height and width must be at least 1, the max size for MBP is subpage dimensions less 1
            mbp = MbpInfo.FromElement(Element, StructuralCache.TextFormatterHost.PixelsPerDip);

            if (fswdirSubpage != fswdir)
            {
                PTS.FSRECT pageRect = StructuralCache.CurrentFormatContext.PageRect;
                PTS.Validate(PTS.FsTransformRectangle(fswdir, ref pageRect, ref fsrcToFill, fswdirSubpage, out fsrcToFill));
                mbp.MirrorMargin();
            }

            subpageWidth = Math.Max(1, subpageWidth - (mbp.MBPLeft + mbp.MBPRight));
            if (pbrkrecIn == IntPtr.Zero)
            {
                // Top margin collapsing. If suppresing top space, top margin is always 0.
                MarginCollapsingState.CollapseTopMargin(PtsContext, mbp, mcs, out mcsSubpage, out marginTop);
                if (PTS.ToBoolean(fSuppressTopSpace))
                {
                    marginTop = 0;
                }
                subpageHeight = Math.Max(1, subpageHeight - (marginTop + mbp.BPTop));
                // Destroy top margin collapsing state (not needed anymore).
                if (mcsSubpage != null)
                {
                    mcsSubpage.Dispose();
                    mcsSubpage = null;
                }
            }
            else
            {
                Debug.Assert(fSuppressTopSpace == 1, "Top space should be always suppressed at the top of broken paragraph.");
            }
            fsrcSubpageMargin.du = subpageWidth;
            fsrcSubpageMargin.dv = subpageHeight;

            // Initialize column info
            ColumnPropertiesGroup columnProperties = new ColumnPropertiesGroup(_element);
            double     lineHeight     = DynamicPropertyReader.GetLineHeightValue(_element);
            double     pageFontSize   = (double)_structuralCache.PropertyOwner.GetValue(Block.FontSizeProperty);
            FontFamily pageFontFamily = (FontFamily)_structuralCache.PropertyOwner.GetValue(Block.FontFamilyProperty);

            // Get columns info, setting ownerIsFlowDocument flag to false. A flow document should not be formatted as a subpage and we
            // do not want default column widths to be set on TableCells and floaters
            cColumns             = PtsHelper.CalculateColumnCount(columnProperties, lineHeight, TextDpi.FromTextDpi(subpageWidth), pageFontSize, pageFontFamily, false);
            columnInfoCollection = new PTS.FSCOLUMNINFO[cColumns];
            fixed(PTS.FSCOLUMNINFO *rgColumnInfo = columnInfoCollection)
            {
                PtsHelper.GetColumnsInfo(columnProperties, lineHeight, TextDpi.FromTextDpi(subpageWidth), pageFontSize, pageFontFamily, cColumns, rgColumnInfo, false);
            }

            // Format subpage
            StructuralCache.CurrentFormatContext.PushNewPageData(new Size(TextDpi.FromTextDpi(subpageWidth), TextDpi.FromTextDpi(subpageHeight)),
                                                                 new Thickness(),
                                                                 false,
                                                                 true);

            fixed(PTS.FSCOLUMNINFO *rgColumnInfo = columnInfoCollection)
            {
                PTS.Validate(PTS.FsCreateSubpageFinite(PtsContext.Context, pbrkrecIn, fBRFromPreviousPage, _mainTextSegment.Handle,
                                                       footnoteRejector, fEmptyOk, fSuppressTopSpace, fswdir, subpageWidth, subpageHeight,
                                                       ref fsrcSubpageMargin, cColumns, rgColumnInfo, PTS.False,
                                                       0, null, null, 0, null, null, PTS.FromBoolean(false),
                                                       fsksuppresshardbreakbeforefirstparaIn,
                                                       out fsfmtr, out pfspara, out pbrkrecOut, out dvrUsed, out fsbbox, out pmcsclientOut, out dvrTopSpace), PtsContext);
            }

            StructuralCache.CurrentFormatContext.PopPageData();

            fskclearOut = PTS.FSKCLEAR.fskclearNone;

            if (PTS.ToBoolean(fsbbox.fDefined))
            {
                // Workaround for PTS bug 860: get max of the page rect and
                // bounding box of the page.
                dvrUsed       = Math.Max(dvrUsed, fsbbox.fsrc.dv + fsbbox.fsrc.v);
                fsrcToFill.du = Math.Max(fsrcToFill.du, fsbbox.fsrc.du + fsbbox.fsrc.u);
            }

            if (pbrkrecIn == IntPtr.Zero) // if first chunk
            {
                // Take into account MBPs and modify subpage metrics
                dvrTopSpace = (mbp.BPTop != 0) ? marginTop : dvrTopSpace;
                dvrUsed    += (marginTop + mbp.BPTop);
            }

            if (pmcsclientOut != IntPtr.Zero)
            {
                mcsSubpage = PtsContext.HandleToObject(pmcsclientOut) as MarginCollapsingState;
                PTS.ValidateHandle(mcsSubpage);
                pmcsclientOut = IntPtr.Zero;
            }

            // Initialize subpage metrics
            if (fsfmtr.kstop >= PTS.FSFMTRKSTOP.fmtrNoProgressOutOfSpace)   // No progress or collision
            {
                dvrUsed = dvrTopSpace = 0;
                //pbrkrecOut = IntPtr.Zero;
                //pfspara = IntPtr.Zero;
                //pmcsclientOut = IntPtr.Zero;
            }
            else
            {
                if (fsfmtr.kstop == PTS.FSFMTRKSTOP.fmtrGoalReached)
                {
                    // Bottom margin collapsing:
                    // (a) retrieve mcs from the subpage
                    // (b) do margin collapsing; create a new margin collapsing state
                    // There is no bottom margin collapsing if paragraph will be continued (output break record is not null).
                    MarginCollapsingState.CollapseBottomMargin(PtsContext, mbp, mcsSubpage, out mcsBottom, out marginBottom);
                    pmcsclientOut = (mcsBottom != null) ? mcsBottom.Handle : IntPtr.Zero;

                    if (pmcsclientOut == IntPtr.Zero) // if last chunk
                    {
                        dvrUsed += marginBottom + mbp.BPBottom;
                    }
                }

                // Update bounding box
                fsbbox.fsrc.u  = fsrcToFill.u + mbp.MarginLeft;
                fsbbox.fsrc.v  = fsrcToFill.v + dvrTopSpace;
                fsbbox.fsrc.du = Math.Max(fsrcToFill.du - (mbp.MarginLeft + mbp.MarginRight), 0);
                fsbbox.fsrc.dv = Math.Max(dvrUsed - dvrTopSpace, 0);
            }

            if (fswdirSubpage != fswdir)
            {
                PTS.FSRECT pageRect = StructuralCache.CurrentFormatContext.PageRect;
                PTS.Validate(PTS.FsTransformBbox(fswdirSubpage, ref pageRect, ref fsbbox, fswdir, out fsbbox));
            }


            // Since MCS returned by PTS is never passed back, destroy MCS provided by PTS.
            // If necessary, new MCS is created and passed back to PTS (see above).
            if (mcsSubpage != null)
            {
                mcsSubpage.Dispose();
                mcsSubpage = null;
            }


            // Update information about first/last chunk
            paraClient.SetChunkInfo(pbrkrecIn == IntPtr.Zero, pbrkrecOut == IntPtr.Zero);
        }
        internal unsafe void FormatParaFinite(SubpageParaClient paraClient, IntPtr pbrkrecIn, int fBRFromPreviousPage, IntPtr footnoteRejector, int fEmptyOk, int fSuppressTopSpace, uint fswdir, ref PTS.FSRECT fsrcToFill, MarginCollapsingState mcs, PTS.FSKCLEAR fskclearIn, PTS.FSKSUPPRESSHARDBREAKBEFOREFIRSTPARA fsksuppresshardbreakbeforefirstparaIn, out PTS.FSFMTR fsfmtr, out IntPtr pfspara, out IntPtr pbrkrecOut, out int dvrUsed, out PTS.FSBBOX fsbbox, out IntPtr pmcsclientOut, out PTS.FSKCLEAR fskclearOut, out int dvrTopSpace)
        {
            uint num = PTS.FlowDirectionToFswdir((FlowDirection)base.Element.GetValue(FrameworkElement.FlowDirectionProperty));

            if (mcs != null && pbrkrecIn != IntPtr.Zero)
            {
                mcs = null;
            }
            PTS.FSRECT fsrect = default(PTS.FSRECT);
            int        num2   = fsrcToFill.du;
            int        num3   = fsrcToFill.dv;

            Invariant.Assert(base.Element is TableCell || base.Element is AnchoredBlock);
            fskclearIn = PTS.WrapDirectionToFskclear((WrapDirection)base.Element.GetValue(Block.ClearFloatersProperty));
            int num4 = 0;
            MarginCollapsingState marginCollapsingState = null;
            MbpInfo mbpInfo = MbpInfo.FromElement(base.Element, base.StructuralCache.TextFormatterHost.PixelsPerDip);

            if (num != fswdir)
            {
                PTS.FSRECT pageRect = base.StructuralCache.CurrentFormatContext.PageRect;
                PTS.Validate(PTS.FsTransformRectangle(fswdir, ref pageRect, ref fsrcToFill, num, out fsrcToFill));
                mbpInfo.MirrorMargin();
            }
            num2 = Math.Max(1, num2 - (mbpInfo.MBPLeft + mbpInfo.MBPRight));
            if (pbrkrecIn == IntPtr.Zero)
            {
                MarginCollapsingState.CollapseTopMargin(base.PtsContext, mbpInfo, mcs, out marginCollapsingState, out num4);
                if (PTS.ToBoolean(fSuppressTopSpace))
                {
                    num4 = 0;
                }
                num3 = Math.Max(1, num3 - (num4 + mbpInfo.BPTop));
                if (marginCollapsingState != null)
                {
                    marginCollapsingState.Dispose();
                    marginCollapsingState = null;
                }
            }
            fsrect.du = num2;
            fsrect.dv = num3;
            ColumnPropertiesGroup columnProperties = new ColumnPropertiesGroup(this._element);
            double     lineHeightValue             = DynamicPropertyReader.GetLineHeightValue(this._element);
            double     pageFontSize   = (double)this._structuralCache.PropertyOwner.GetValue(TextElement.FontSizeProperty);
            FontFamily pageFontFamily = (FontFamily)this._structuralCache.PropertyOwner.GetValue(TextElement.FontFamilyProperty);
            int        num5           = PtsHelper.CalculateColumnCount(columnProperties, lineHeightValue, TextDpi.FromTextDpi(num2), pageFontSize, pageFontFamily, false);

            PTS.FSCOLUMNINFO[] array = new PTS.FSCOLUMNINFO[num5];
            fixed(PTS.FSCOLUMNINFO *ptr = array)
            {
                PtsHelper.GetColumnsInfo(columnProperties, lineHeightValue, TextDpi.FromTextDpi(num2), pageFontSize, pageFontFamily, num5, ptr, false);
            }

            base.StructuralCache.CurrentFormatContext.PushNewPageData(new Size(TextDpi.FromTextDpi(num2), TextDpi.FromTextDpi(num3)), default(Thickness), false, true);
            fixed(PTS.FSCOLUMNINFO *ptr2 = array)
            {
                PTS.Validate(PTS.FsCreateSubpageFinite(base.PtsContext.Context, pbrkrecIn, fBRFromPreviousPage, this._mainTextSegment.Handle, footnoteRejector, fEmptyOk, fSuppressTopSpace, fswdir, num2, num3, ref fsrect, num5, ptr2, 0, 0, null, null, 0, null, null, PTS.FromBoolean(false), fsksuppresshardbreakbeforefirstparaIn, out fsfmtr, out pfspara, out pbrkrecOut, out dvrUsed, out fsbbox, out pmcsclientOut, out dvrTopSpace), base.PtsContext);
            }

            base.StructuralCache.CurrentFormatContext.PopPageData();
            fskclearOut = PTS.FSKCLEAR.fskclearNone;
            if (PTS.ToBoolean(fsbbox.fDefined))
            {
                dvrUsed       = Math.Max(dvrUsed, fsbbox.fsrc.dv + fsbbox.fsrc.v);
                fsrcToFill.du = Math.Max(fsrcToFill.du, fsbbox.fsrc.du + fsbbox.fsrc.u);
            }
            if (pbrkrecIn == IntPtr.Zero)
            {
                dvrTopSpace = ((mbpInfo.BPTop != 0) ? num4 : dvrTopSpace);
                dvrUsed    += num4 + mbpInfo.BPTop;
            }
            if (pmcsclientOut != IntPtr.Zero)
            {
                marginCollapsingState = (base.PtsContext.HandleToObject(pmcsclientOut) as MarginCollapsingState);
                PTS.ValidateHandle(marginCollapsingState);
                pmcsclientOut = IntPtr.Zero;
            }
            if (fsfmtr.kstop >= PTS.FSFMTRKSTOP.fmtrNoProgressOutOfSpace)
            {
                dvrUsed = (dvrTopSpace = 0);
            }
            else
            {
                if (fsfmtr.kstop == PTS.FSFMTRKSTOP.fmtrGoalReached)
                {
                    MarginCollapsingState marginCollapsingState2;
                    int num6;
                    MarginCollapsingState.CollapseBottomMargin(base.PtsContext, mbpInfo, marginCollapsingState, out marginCollapsingState2, out num6);
                    pmcsclientOut = ((marginCollapsingState2 != null) ? marginCollapsingState2.Handle : IntPtr.Zero);
                    if (pmcsclientOut == IntPtr.Zero)
                    {
                        dvrUsed += num6 + mbpInfo.BPBottom;
                    }
                }
                fsbbox.fsrc.u  = fsrcToFill.u + mbpInfo.MarginLeft;
                fsbbox.fsrc.v  = fsrcToFill.v + dvrTopSpace;
                fsbbox.fsrc.du = Math.Max(fsrcToFill.du - (mbpInfo.MarginLeft + mbpInfo.MarginRight), 0);
                fsbbox.fsrc.dv = Math.Max(dvrUsed - dvrTopSpace, 0);
            }
            if (num != fswdir)
            {
                PTS.FSRECT pageRect2 = base.StructuralCache.CurrentFormatContext.PageRect;
                PTS.Validate(PTS.FsTransformBbox(num, ref pageRect2, ref fsbbox, fswdir, out fsbbox));
            }
            if (marginCollapsingState != null)
            {
                marginCollapsingState.Dispose();
                marginCollapsingState = null;
            }
            paraClient.SetChunkInfo(pbrkrecIn == IntPtr.Zero, pbrkrecOut == IntPtr.Zero);
        }
        internal unsafe void UpdateBottomlessPara(IntPtr pfspara, SubpageParaClient paraClient, int fSuppressTopSpace, uint fswdir, int urTrack, int durTrack, int vrTrack, MarginCollapsingState mcs, PTS.FSKCLEAR fskclearIn, int fInterruptable, out PTS.FSFMTRBL fsfmtrbl, out int dvrUsed, out PTS.FSBBOX fsbbox, out IntPtr pmcsclientOut, out PTS.FSKCLEAR fskclearOut, out int dvrTopSpace, out int fPageBecomesUninterruptable)
        {
            uint num  = PTS.FlowDirectionToFswdir((FlowDirection)base.Element.GetValue(FrameworkElement.FlowDirectionProperty));
            int  num2 = durTrack;
            int  urMargin;
            int  vrMargin = urMargin = 0;

            Invariant.Assert(base.Element is TableCell || base.Element is AnchoredBlock);
            fskclearIn = PTS.WrapDirectionToFskclear((WrapDirection)base.Element.GetValue(Block.ClearFloatersProperty));
            MbpInfo mbpInfo = MbpInfo.FromElement(base.Element, base.StructuralCache.TextFormatterHost.PixelsPerDip);

            if (num != fswdir)
            {
                PTS.FSRECT fsrect   = new PTS.FSRECT(urTrack, 0, durTrack, 0);
                PTS.FSRECT pageRect = base.StructuralCache.CurrentFormatContext.PageRect;
                PTS.Validate(PTS.FsTransformRectangle(fswdir, ref pageRect, ref fsrect, num, out fsrect));
                urTrack  = fsrect.u;
                durTrack = fsrect.du;
                mbpInfo.MirrorMargin();
            }
            num2 = Math.Max(1, num2 - (mbpInfo.MBPLeft + mbpInfo.MBPRight));
            MarginCollapsingState marginCollapsingState;
            int num3;

            MarginCollapsingState.CollapseTopMargin(base.PtsContext, mbpInfo, mcs, out marginCollapsingState, out num3);
            if (marginCollapsingState != null)
            {
                marginCollapsingState.Dispose();
                marginCollapsingState = null;
            }
            int durMargin = num2;
            ColumnPropertiesGroup columnProperties = new ColumnPropertiesGroup(this._element);
            double     lineHeightValue             = DynamicPropertyReader.GetLineHeightValue(this._element);
            double     pageFontSize   = (double)this._structuralCache.PropertyOwner.GetValue(TextElement.FontSizeProperty);
            FontFamily pageFontFamily = (FontFamily)this._structuralCache.PropertyOwner.GetValue(TextElement.FontFamilyProperty);
            int        num4           = PtsHelper.CalculateColumnCount(columnProperties, lineHeightValue, TextDpi.FromTextDpi(num2), pageFontSize, pageFontFamily, false);

            PTS.FSCOLUMNINFO[] array = new PTS.FSCOLUMNINFO[num4];
            fixed(PTS.FSCOLUMNINFO *ptr = array)
            {
                PtsHelper.GetColumnsInfo(columnProperties, lineHeightValue, TextDpi.FromTextDpi(num2), pageFontSize, pageFontFamily, num4, ptr, false);
            }

            base.StructuralCache.CurrentFormatContext.PushNewPageData(new Size(TextDpi.FromTextDpi(num2), TextDpi.MaxWidth), default(Thickness), true, false);
            fixed(PTS.FSCOLUMNINFO *ptr2 = array)
            {
                PTS.Validate(PTS.FsUpdateBottomlessSubpage(base.PtsContext.Context, pfspara, this._mainTextSegment.Handle, fSuppressTopSpace, fswdir, num2, urMargin, durMargin, vrMargin, num4, ptr2, 0, null, null, 0, null, null, PTS.FromBoolean(true), out fsfmtrbl, out dvrUsed, out fsbbox, out pmcsclientOut, out dvrTopSpace, out fPageBecomesUninterruptable), base.PtsContext);
            }

            base.StructuralCache.CurrentFormatContext.PopPageData();
            fskclearOut = PTS.FSKCLEAR.fskclearNone;
            if (fsfmtrbl != PTS.FSFMTRBL.fmtrblCollision)
            {
                if (pmcsclientOut != IntPtr.Zero)
                {
                    marginCollapsingState = (base.PtsContext.HandleToObject(pmcsclientOut) as MarginCollapsingState);
                    PTS.ValidateHandle(marginCollapsingState);
                    pmcsclientOut = IntPtr.Zero;
                }
                MarginCollapsingState marginCollapsingState2;
                int num5;
                MarginCollapsingState.CollapseBottomMargin(base.PtsContext, mbpInfo, marginCollapsingState, out marginCollapsingState2, out num5);
                pmcsclientOut = ((marginCollapsingState2 != null) ? marginCollapsingState2.Handle : IntPtr.Zero);
                if (marginCollapsingState != null)
                {
                    marginCollapsingState.Dispose();
                    marginCollapsingState = null;
                }
                if (PTS.ToBoolean(fsbbox.fDefined))
                {
                    dvrUsed  = Math.Max(dvrUsed, fsbbox.fsrc.dv + fsbbox.fsrc.v);
                    durTrack = Math.Max(durTrack, fsbbox.fsrc.du + fsbbox.fsrc.u);
                }
                dvrTopSpace    = ((mbpInfo.BPTop != 0) ? num3 : dvrTopSpace);
                dvrUsed       += num3 + mbpInfo.BPTop + (num5 + mbpInfo.BPBottom);
                fsbbox.fsrc.u  = urTrack + mbpInfo.MarginLeft;
                fsbbox.fsrc.v  = vrTrack + dvrTopSpace;
                fsbbox.fsrc.du = Math.Max(durTrack - (mbpInfo.MarginLeft + mbpInfo.MarginRight), 0);
                fsbbox.fsrc.dv = Math.Max(dvrUsed - dvrTopSpace, 0);
            }
            else
            {
                pfspara = IntPtr.Zero;
                dvrUsed = (dvrTopSpace = 0);
            }
            if (num != fswdir)
            {
                PTS.FSRECT pageRect2 = base.StructuralCache.CurrentFormatContext.PageRect;
                PTS.Validate(PTS.FsTransformBbox(num, ref pageRect2, ref fsbbox, fswdir, out fsbbox));
            }
            paraClient.SetChunkInfo(true, true);
        }