private unsafe void CreateSubpageBottomlessHelper(PtsContext ptsContext, IntPtr nSeg, int fSuppressTopSpace, uint fswdir, int lWidth, int urMargin, int durMargin, int vrMargin, int cColumns, PTS.FSCOLUMNINFO[] columnInfoCollection, out PTS.FSFMTRBL pfsfmtr, out IntPtr ppSubPage, out int pdvrUsed, out PTS.FSBBOX pfsBBox, out IntPtr pfsMcsClient, out int pTopSpace, out int fPageBecomesUninterruptible) { base.StructuralCache.CurrentFormatContext.PushNewPageData(new Size(TextDpi.FromTextDpi(lWidth), TextDpi.MaxWidth), default(Thickness), false, false); fixed(PTS.FSCOLUMNINFO *ptr = columnInfoCollection) { PTS.Validate(PTS.FsCreateSubpageBottomless(ptsContext.Context, nSeg, fSuppressTopSpace, fswdir, lWidth, urMargin, durMargin, vrMargin, cColumns, ptr, 0, null, null, 0, null, null, 0, out pfsfmtr, out ppSubPage, out pdvrUsed, out pfsBBox, out pfsMcsClient, out pTopSpace, out fPageBecomesUninterruptible), ptsContext); } base.StructuralCache.CurrentFormatContext.PopPageData(); }
private unsafe void CreateSubpageBottomlessHelper( PtsContext ptsContext, // IN: ptr to FS context IntPtr nSeg, // IN: name of the segment to start from int fSuppressTopSpace, // IN: suppress top space? uint fswdir, // IN: fswdir int lWidth, // IN: width of subpage int urMargin, // IN: ur of margin int durMargin, // IN: dur of margin int vrMargin, // IN: vr of margin int cColumns, // IN: number of columns PTS.FSCOLUMNINFO[] columnInfoCollection, // IN: array of column info out PTS.FSFMTRBL pfsfmtr, // OUT: why formatting was stopped out IntPtr ppSubPage, // OUT: ptr to the subpage out int pdvrUsed, // OUT: dvrUsed out PTS.FSBBOX pfsBBox, // OUT: subpage bbox out IntPtr pfsMcsClient, // OUT: margin collapsing state at the bottom out int pTopSpace, // OUT: top space due to collapsed margins out int fPageBecomesUninterruptible) // OUT: interruption is prohibited from now on { // Exceptions don't need to pop, as the top level measure context will be nulled out if thrown. StructuralCache.CurrentFormatContext.PushNewPageData(new Size(TextDpi.FromTextDpi(lWidth), TextDpi.MaxWidth), new Thickness(), false, false); fixed(PTS.FSCOLUMNINFO *rgColumnInfo = columnInfoCollection) { PTS.Validate(PTS.FsCreateSubpageBottomless(ptsContext.Context, nSeg, fSuppressTopSpace, fswdir, lWidth, urMargin, durMargin, vrMargin, cColumns, rgColumnInfo, 0, null, null, 0, null, null, PTS.False, out pfsfmtr, out ppSubPage, out pdvrUsed, out pfsBBox, out pfsMcsClient, out pTopSpace, out fPageBecomesUninterruptible), ptsContext); } StructuralCache.CurrentFormatContext.PopPageData(); }
internal unsafe void FormatParaBottomless( SubpageParaClient paraClient, // IN: int fSuppressTopSpace, // IN: suppress empty space at the top of the page uint fswdir, // IN: current direction int urTrack, // IN: ur of bottomless rectangle to fill int durTrack, // IN: dur of bottomless rectangle to fill int vrTrack, // IN: vr of bottomless 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 IntPtr pfspara, // OUT: pointer to the para data 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 ColumnPropertiesGroup columnProperties = new ColumnPropertiesGroup(_element); // For bottomles spara, limit line height to the height of the current format context in structural cache. 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); } // Create subpage StructuralCache.CurrentFormatContext.PushNewPageData(new Size(TextDpi.FromTextDpi(subpageWidth), TextDpi.MaxWidth), new Thickness(), false, false); fixed(PTS.FSCOLUMNINFO *rgColumnInfo = columnInfoCollection) { PTS.Validate(PTS.FsCreateSubpageBottomless(PtsContext.Context, _mainTextSegment.Handle, fSuppressTopSpace, fswdir, subpageWidth, urSubpageMargin, durSubpageMargin, vrSubpageMargin, cColumns, rgColumnInfo, 0, null, null, 0, null, null, PTS.FromBoolean(_isInterruptible), out fsfmtrbl, out pfspara, 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); }
internal unsafe void FormatParaBottomless(SubpageParaClient paraClient, int fSuppressTopSpace, uint fswdir, int urTrack, int durTrack, int vrTrack, MarginCollapsingState mcs, PTS.FSKCLEAR fskclearIn, int fInterruptable, out PTS.FSFMTRBL fsfmtrbl, out IntPtr pfspara, 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), false, false); fixed(PTS.FSCOLUMNINFO *ptr2 = array) { PTS.Validate(PTS.FsCreateSubpageBottomless(base.PtsContext.Context, this._mainTextSegment.Handle, fSuppressTopSpace, fswdir, num2, urMargin, durMargin, vrMargin, num4, ptr2, 0, null, null, 0, null, null, PTS.FromBoolean(this._isInterruptible), out fsfmtrbl, out pfspara, 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); }