internal void FormatCellFinite(TableParaClient tableParaClient, IntPtr pfsbrkcellIn, IntPtr pfsFtnRejector, int fEmptyOK, uint fswdirTable, int dvrAvailable, out PTS.FSFMTR pfmtr, out IntPtr ppfscell, out IntPtr pfsbrkcellOut, out int dvrUsed) { CellParaClient cellParaClient = new CellParaClient(this, tableParaClient); Size subpageSize = new Size(cellParaClient.CalculateCellWidth(tableParaClient), Math.Max(TextDpi.FromTextDpi(dvrAvailable), 0.0)); cellParaClient.FormatCellFinite(subpageSize, pfsbrkcellIn, PTS.ToBoolean(fEmptyOK), fswdirTable, PTS.FSKSUPPRESSHARDBREAKBEFOREFIRSTPARA.fsksuppresshardbreakbeforefirstparaNone, out pfmtr, out dvrUsed, out pfsbrkcellOut); ppfscell = cellParaClient.Handle; if (pfmtr.kstop == PTS.FSFMTRKSTOP.fmtrNoProgressOutOfSpace) { cellParaClient.Dispose(); ppfscell = IntPtr.Zero; dvrUsed = 0; } if (dvrAvailable < dvrUsed) { if (PTS.ToBoolean(fEmptyOK)) { if (cellParaClient != null) { cellParaClient.Dispose(); } if (pfsbrkcellOut != IntPtr.Zero) { PTS.Validate(PTS.FsDestroySubpageBreakRecord(cellParaClient.PtsContext.Context, pfsbrkcellOut), cellParaClient.PtsContext); pfsbrkcellOut = IntPtr.Zero; } ppfscell = IntPtr.Zero; pfmtr.kstop = PTS.FSFMTRKSTOP.fmtrNoProgressOutOfSpace; dvrUsed = 0; return; } pfmtr.fForcedProgress = 1; } }
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, StructuralCache.TextFormatterHost.PixelsPerDip); // 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; }
internal void FormatCellFinite( TableParaClient tableParaClient, // IN: IntPtr pfsbrkcellIn, // IN: not NULL if cell broken from previous page/column IntPtr pfsFtnRejector, // IN: int fEmptyOK, // IN: uint fswdirTable, // IN: 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 { Debug.Assert(Cell.Index != -1 && Cell.ColumnIndex != -1, "Cell is not in a table"); CellParaClient cellParaClient; Size subpageSize; Debug.Assert(Cell.Table != null); cellParaClient = new CellParaClient(this, tableParaClient); subpageSize = new Size( cellParaClient.CalculateCellWidth(tableParaClient), Math.Max(TextDpi.FromTextDpi(dvrAvailable), 0)); cellParaClient.FormatCellFinite(subpageSize, pfsbrkcellIn, PTS.ToBoolean(fEmptyOK), fswdirTable, PTS.FSKSUPPRESSHARDBREAKBEFOREFIRSTPARA.fsksuppresshardbreakbeforefirstparaNone, out pfmtr, out dvrUsed, out pfsbrkcellOut); // initialize output parameters ppfscell = cellParaClient.Handle; if (pfmtr.kstop == PTS.FSFMTRKSTOP.fmtrNoProgressOutOfSpace) { cellParaClient.Dispose(); ppfscell = IntPtr.Zero; dvrUsed = 0; } if (dvrAvailable < dvrUsed) { if (PTS.ToBoolean(fEmptyOK)) { if (cellParaClient != null) { cellParaClient.Dispose(); } if (pfsbrkcellOut != IntPtr.Zero) { PTS.Validate(PTS.FsDestroySubpageBreakRecord(cellParaClient.PtsContext.Context, pfsbrkcellOut), cellParaClient.PtsContext); pfsbrkcellOut = IntPtr.Zero; } ppfscell = IntPtr.Zero; pfmtr.kstop = PTS.FSFMTRKSTOP.fmtrNoProgressOutOfSpace; dvrUsed = 0; } else { pfmtr.fForcedProgress = PTS.True; } } }
internal void GetFigureProperties(FigureParaClient paraClient, int fInTextLine, uint fswdir, int fBottomUndefined, out int dur, out int dvr, out PTS.FSFIGUREPROPS fsfigprops, out int cPolygons, out int cVertices, out int durDistTextLeft, out int durDistTextRight, out int dvrDistTextTop, out int dvrDistTextBottom) { Invariant.Assert(base.StructuralCache.CurrentFormatContext.FinitePage); uint num = PTS.FlowDirectionToFswdir((FlowDirection)base.Element.GetValue(FrameworkElement.FlowDirectionProperty)); Figure figure = (Figure)base.Element; MbpInfo mbpInfo = MbpInfo.FromElement(base.Element, base.StructuralCache.TextFormatterHost.PixelsPerDip); durDistTextLeft = (durDistTextRight = (dvrDistTextTop = (dvrDistTextBottom = 0))); bool flag; double width = FigureHelper.CalculateFigureWidth(base.StructuralCache, figure, figure.Width, out flag); double d = this.LimitTotalWidthFromAnchor(width, TextDpi.FromTextDpi(mbpInfo.MarginLeft + mbpInfo.MarginRight)); int num2 = Math.Max(1, TextDpi.ToTextDpi(d) - (mbpInfo.BPLeft + mbpInfo.BPRight)); bool flag2; double height = FigureHelper.CalculateFigureHeight(base.StructuralCache, figure, figure.Height, out flag2); double d2 = this.LimitTotalHeightFromAnchor(height, TextDpi.FromTextDpi(mbpInfo.MarginTop + mbpInfo.MarginBottom)); int num3 = Math.Max(1, TextDpi.ToTextDpi(d2) - (mbpInfo.BPTop + mbpInfo.BPBottom)); int num4 = 1; PTS.FSCOLUMNINFO[] array = new PTS.FSCOLUMNINFO[num4]; array[0].durBefore = 0; array[0].durWidth = num2; PTS.FSRECT fsrect = new PTS.FSRECT(0, 0, num2, num3); PTS.FSFMTR fsfmtr; IntPtr intPtr; IntPtr intPtr2; PTS.FSBBOX fsbbox; IntPtr zero; int num5; this.CreateSubpageFiniteHelper(base.PtsContext, IntPtr.Zero, 0, this._mainTextSegment.Handle, IntPtr.Zero, 0, 1, fswdir, num2, num3, ref fsrect, num4, array, 0, out fsfmtr, out intPtr, out intPtr2, out dvr, out fsbbox, out zero, out num5); if (intPtr2 != IntPtr.Zero) { PTS.Validate(PTS.FsDestroySubpageBreakRecord(base.PtsContext.Context, intPtr2)); } if (PTS.ToBoolean(fsbbox.fDefined)) { if (fsbbox.fsrc.du < num2 && flag) { if (intPtr != IntPtr.Zero) { PTS.Validate(PTS.FsDestroySubpage(base.PtsContext.Context, intPtr), base.PtsContext); } if (zero != IntPtr.Zero) { MarginCollapsingState marginCollapsingState = base.PtsContext.HandleToObject(zero) as MarginCollapsingState; PTS.ValidateHandle(marginCollapsingState); marginCollapsingState.Dispose(); zero = IntPtr.Zero; } num2 = fsbbox.fsrc.du + 1; array[0].durWidth = num2; PTS.FSRECT fsrect2 = new PTS.FSRECT(0, 0, num2, num3); PTS.FSFMTR fsfmtr2; IntPtr intPtr3; this.CreateSubpageFiniteHelper(base.PtsContext, IntPtr.Zero, 0, this._mainTextSegment.Handle, IntPtr.Zero, 0, 1, fswdir, num2, num3, ref fsrect2, num4, array, 0, out fsfmtr2, out intPtr, out intPtr3, out dvr, out fsbbox, out zero, out num5); if (intPtr3 != IntPtr.Zero) { PTS.Validate(PTS.FsDestroySubpageBreakRecord(base.PtsContext.Context, intPtr3)); } } } else { num2 = TextDpi.ToTextDpi(TextDpi.MinWidth); } dur = num2 + mbpInfo.MBPLeft + mbpInfo.MBPRight; if (zero != IntPtr.Zero) { MarginCollapsingState marginCollapsingState2 = base.PtsContext.HandleToObject(zero) as MarginCollapsingState; PTS.ValidateHandle(marginCollapsingState2); marginCollapsingState2.Dispose(); zero = IntPtr.Zero; } dvr += mbpInfo.MBPTop + mbpInfo.MBPBottom; if (!flag2) { dvr = TextDpi.ToTextDpi(d2) + mbpInfo.MarginTop + mbpInfo.MarginBottom; } FigureHorizontalAnchor horizontalAnchor = figure.HorizontalAnchor; FigureVerticalAnchor verticalAnchor = figure.VerticalAnchor; fsfigprops.fskrefU = (PTS.FSKREF)(horizontalAnchor / FigureHorizontalAnchor.ContentLeft); fsfigprops.fskrefV = (PTS.FSKREF)(verticalAnchor / FigureVerticalAnchor.ContentTop); fsfigprops.fskalfU = (PTS.FSKALIGNFIG)(horizontalAnchor % FigureHorizontalAnchor.ContentLeft); fsfigprops.fskalfV = (PTS.FSKALIGNFIG)(verticalAnchor % FigureVerticalAnchor.ContentTop); if (!PTS.ToBoolean(fInTextLine)) { if (fsfigprops.fskrefU == PTS.FSKREF.fskrefChar) { fsfigprops.fskrefU = PTS.FSKREF.fskrefMargin; fsfigprops.fskalfU = PTS.FSKALIGNFIG.fskalfMin; } if (fsfigprops.fskrefV == PTS.FSKREF.fskrefChar) { fsfigprops.fskrefV = PTS.FSKREF.fskrefMargin; fsfigprops.fskalfV = PTS.FSKALIGNFIG.fskalfMin; } } fsfigprops.fskwrap = PTS.WrapDirectionToFskwrap(figure.WrapDirection); fsfigprops.fNonTextPlane = 0; fsfigprops.fAllowOverlap = 0; fsfigprops.fDelayable = PTS.FromBoolean(figure.CanDelayPlacement); cPolygons = (cVertices = 0); paraClient.SubpageHandle = intPtr; }
internal override void FormatFloaterContentFinite(FloaterBaseParaClient paraClient, IntPtr pbrkrecIn, int fBRFromPreviousPage, IntPtr footnoteRejector, int fEmptyOk, int fSuppressTopSpace, uint fswdir, int fAtMaxWidth, int durAvailable, int dvrAvailable, PTS.FSKSUPPRESSHARDBREAKBEFOREFIRSTPARA fsksuppresshardbreakbeforefirstparaIn, out PTS.FSFMTR fsfmtr, out IntPtr pfsFloatContent, out IntPtr pbrkrecOut, out int durFloaterWidth, out int dvrFloaterHeight, out PTS.FSBBOX fsbbox, out int cPolygons, out int cVertices) { uint num = PTS.FlowDirectionToFswdir((FlowDirection)base.Element.GetValue(FrameworkElement.FlowDirectionProperty)); Invariant.Assert(paraClient is FloaterParaClient); if (this.IsFloaterRejected(PTS.ToBoolean(fAtMaxWidth), TextDpi.FromTextDpi(durAvailable))) { durFloaterWidth = (dvrFloaterHeight = 0); cPolygons = (cVertices = 0); fsfmtr = default(PTS.FSFMTR); fsfmtr.kstop = PTS.FSFMTRKSTOP.fmtrNoProgressOutOfSpace; fsfmtr.fContainsItemThatStoppedBeforeFootnote = 0; fsfmtr.fForcedProgress = 0; fsbbox = default(PTS.FSBBOX); fsbbox.fDefined = 0; pbrkrecOut = IntPtr.Zero; pfsFloatContent = IntPtr.Zero; } else { if (!base.StructuralCache.CurrentFormatContext.FinitePage) { if (double.IsInfinity(base.StructuralCache.CurrentFormatContext.PageHeight)) { if (dvrAvailable > 1073741823) { dvrAvailable = Math.Min(dvrAvailable, 1073741823); fEmptyOk = 0; } } else { dvrAvailable = Math.Min(dvrAvailable, TextDpi.ToTextDpi(base.StructuralCache.CurrentFormatContext.PageHeight)); } } MbpInfo mbpInfo = MbpInfo.FromElement(base.Element, base.StructuralCache.TextFormatterHost.PixelsPerDip); double num2 = this.CalculateWidth(TextDpi.FromTextDpi(durAvailable)); int num3; this.AdjustDurAvailable(num2, ref durAvailable, out num3); int num4 = Math.Max(1, dvrAvailable - (mbpInfo.MBPTop + mbpInfo.MBPBottom)); PTS.FSRECT fsrect = default(PTS.FSRECT); fsrect.du = num3; fsrect.dv = num4; int num5 = 1; PTS.FSCOLUMNINFO[] array = new PTS.FSCOLUMNINFO[num5]; array[0].durBefore = 0; array[0].durWidth = num3; IntPtr zero; int num6; this.CreateSubpageFiniteHelper(base.PtsContext, pbrkrecIn, fBRFromPreviousPage, this._mainTextSegment.Handle, footnoteRejector, fEmptyOk, 1, fswdir, num3, num4, ref fsrect, num5, array, 0, fsksuppresshardbreakbeforefirstparaIn, out fsfmtr, out pfsFloatContent, out pbrkrecOut, out dvrFloaterHeight, out fsbbox, out zero, out num6); if (fsfmtr.kstop >= PTS.FSFMTRKSTOP.fmtrNoProgressOutOfSpace) { durFloaterWidth = (dvrFloaterHeight = 0); cPolygons = (cVertices = 0); } else { if (PTS.ToBoolean(fsbbox.fDefined)) { if (fsbbox.fsrc.du < num3 && double.IsNaN(num2) && this.HorizontalAlignment != HorizontalAlignment.Stretch) { if (pfsFloatContent != IntPtr.Zero) { PTS.Validate(PTS.FsDestroySubpage(base.PtsContext.Context, pfsFloatContent), base.PtsContext); pfsFloatContent = IntPtr.Zero; } if (pbrkrecOut != IntPtr.Zero) { PTS.Validate(PTS.FsDestroySubpageBreakRecord(base.PtsContext.Context, pbrkrecOut), base.PtsContext); pbrkrecOut = IntPtr.Zero; } if (zero != IntPtr.Zero) { MarginCollapsingState marginCollapsingState = base.PtsContext.HandleToObject(zero) as MarginCollapsingState; PTS.ValidateHandle(marginCollapsingState); marginCollapsingState.Dispose(); zero = IntPtr.Zero; } num3 = fsbbox.fsrc.du + 1; fsrect.du = num3; fsrect.dv = num4; array[0].durWidth = num3; this.CreateSubpageFiniteHelper(base.PtsContext, pbrkrecIn, fBRFromPreviousPage, this._mainTextSegment.Handle, footnoteRejector, fEmptyOk, 1, fswdir, num3, num4, ref fsrect, num5, array, 0, fsksuppresshardbreakbeforefirstparaIn, out fsfmtr, out pfsFloatContent, out pbrkrecOut, out dvrFloaterHeight, out fsbbox, out zero, out num6); } } else { num3 = TextDpi.ToTextDpi(TextDpi.MinWidth); } if (zero != IntPtr.Zero) { MarginCollapsingState marginCollapsingState2 = base.PtsContext.HandleToObject(zero) as MarginCollapsingState; PTS.ValidateHandle(marginCollapsingState2); marginCollapsingState2.Dispose(); zero = IntPtr.Zero; } durFloaterWidth = num3 + mbpInfo.MBPLeft + mbpInfo.MBPRight; dvrFloaterHeight += mbpInfo.MBPTop + mbpInfo.MBPBottom; fsbbox.fsrc.u = 0; fsbbox.fsrc.v = 0; fsbbox.fsrc.du = durFloaterWidth; fsbbox.fsrc.dv = dvrFloaterHeight; fsbbox.fDefined = 1; cPolygons = (cVertices = 0); if (durFloaterWidth > durAvailable || dvrFloaterHeight > dvrAvailable) { if (PTS.ToBoolean(fEmptyOk)) { if (pfsFloatContent != IntPtr.Zero) { PTS.Validate(PTS.FsDestroySubpage(base.PtsContext.Context, pfsFloatContent), base.PtsContext); pfsFloatContent = IntPtr.Zero; } if (pbrkrecOut != IntPtr.Zero) { PTS.Validate(PTS.FsDestroySubpageBreakRecord(base.PtsContext.Context, pbrkrecOut), base.PtsContext); pbrkrecOut = IntPtr.Zero; } cPolygons = (cVertices = 0); fsfmtr.kstop = PTS.FSFMTRKSTOP.fmtrNoProgressOutOfSpace; } else { fsfmtr.fForcedProgress = 1; } } } } ((FloaterParaClient)paraClient).SubpageHandle = pfsFloatContent; }
internal void GetFigureProperties( FigureParaClient paraClient, // IN: int fInTextLine, // IN: it is attached to text line uint fswdir, // IN: current direction int fBottomUndefined, // IN: bottom of page is not defined out int dur, // OUT: width of figure out int dvr, // OUT: height of figure out PTS.FSFIGUREPROPS fsfigprops, // OUT: figure attributes out int cPolygons, // OUT: number of polygons out int cVertices, // OUT: total number of vertices in all polygons out int durDistTextLeft, // OUT: distance to text from MinU side out int durDistTextRight, // OUT: distance to text from MaxU side out int dvrDistTextTop, // OUT: distance to text from MinV side out int dvrDistTextBottom) // OUT: distance to text from MaxV side { Invariant.Assert(StructuralCache.CurrentFormatContext.FinitePage); uint fswdirPara = PTS.FlowDirectionToFswdir(((FlowDirection)Element.GetValue(FrameworkElement.FlowDirectionProperty))); IntPtr pfsFigureContent; PTS.FSBBOX fsbbox; int cColumns; int dvrTopSpace; PTS.FSCOLUMNINFO[] columnInfoCollection; IntPtr pmcsclientOut; MbpInfo mbp; Figure element = (Figure)Element; // Initialize the subpage size. PTS subpage margin is always set to 0 for Figures. // If width on figure is specified, use the specified value. // Border and padding of the figure is extracted from available subpage width. // We use StructuralCache.CurrentFormatContext's page dimensions as limiting values for figure MBP mbp = MbpInfo.FromElement(Element); // We do not mirror margin as it's used to dist text left and right, and is unnecessary. durDistTextLeft = durDistTextRight = dvrDistTextTop = dvrDistTextBottom = 0; // Calculate specified width. IsAuto flag is needed because Auto is formatted the same way as column and will // not return Double.NaN. bool isWidthAuto; double specifiedWidth = FigureHelper.CalculateFigureWidth(StructuralCache, element, element.Width, out isWidthAuto); double anchorLimitedWidth = LimitTotalWidthFromAnchor(specifiedWidth, TextDpi.FromTextDpi(mbp.MarginLeft + mbp.MarginRight)); int subpageWidth = Math.Max(1, TextDpi.ToTextDpi(anchorLimitedWidth) - (mbp.BPLeft + mbp.BPRight)); // Calculate figure height, IsAuto flag is used as specifiedHeight will never be NaN. bool isHeightAuto; double specifiedHeight = FigureHelper.CalculateFigureHeight(StructuralCache, element, element.Height, out isHeightAuto); double anchorLimitedHeight = LimitTotalHeightFromAnchor(specifiedHeight, TextDpi.FromTextDpi(mbp.MarginTop + mbp.MarginBottom)); int subpageHeight = Math.Max(1, TextDpi.ToTextDpi(anchorLimitedHeight) - (mbp.BPTop + mbp.BPBottom)); // Initialize column info. Figure always has just 1 column. cColumns = 1; columnInfoCollection = new PTS.FSCOLUMNINFO[cColumns]; columnInfoCollection[0].durBefore = 0; columnInfoCollection[0].durWidth = subpageWidth; // Create subpage { PTS.FSFMTR fsfmtr; IntPtr brParaOut; PTS.FSRECT marginRect = new PTS.FSRECT(0, 0, subpageWidth, subpageHeight); CreateSubpageFiniteHelper(PtsContext, IntPtr.Zero, PTS.False, _mainTextSegment.Handle, IntPtr.Zero, PTS.False, PTS.True, fswdir, subpageWidth, subpageHeight, ref marginRect, cColumns, columnInfoCollection, PTS.False, out fsfmtr, out pfsFigureContent, out brParaOut, out dvr, out fsbbox, out pmcsclientOut, out dvrTopSpace); if (brParaOut != IntPtr.Zero) { PTS.Validate(PTS.FsDestroySubpageBreakRecord(PtsContext.Context, brParaOut)); } } // PTS subpage does not support autosizing, but Figure 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. if (PTS.ToBoolean(fsbbox.fDefined)) { if (fsbbox.fsrc.du < subpageWidth && isWidthAuto) { // There is a need to reformat PTS subpage, so destroy any resourcces allocated by PTS // during previous formatting. if (pfsFigureContent != IntPtr.Zero) { PTS.Validate(PTS.FsDestroySubpage(PtsContext.Context, pfsFigureContent), PtsContext); } 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 columnInfoCollection[0].durWidth = subpageWidth; // Create subpage PTS.FSFMTR fsfmtr; IntPtr brParaOut; PTS.FSRECT marginRect = new PTS.FSRECT(0, 0, subpageWidth, subpageHeight); CreateSubpageFiniteHelper(PtsContext, IntPtr.Zero, PTS.False, _mainTextSegment.Handle, IntPtr.Zero, PTS.False, PTS.True, fswdir, subpageWidth, subpageHeight, ref marginRect, cColumns, columnInfoCollection, PTS.False, out fsfmtr, out pfsFigureContent, out brParaOut, out dvr, out fsbbox, out pmcsclientOut, out dvrTopSpace); if (brParaOut != IntPtr.Zero) { PTS.Validate(PTS.FsDestroySubpageBreakRecord(PtsContext.Context, brParaOut)); } } } else { subpageWidth = TextDpi.ToTextDpi(TextDpi.MinWidth); } // Get the size of the figure. For height PTS already reports calculated value. // But width is the same as subpage width. Include margins in dur since we are not using // distance to text anymore. dur = subpageWidth + mbp.MBPLeft + mbp.MBPRight; // 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; } dvr += mbp.MBPTop + mbp.MBPBottom; if (!isHeightAuto) { // Replace height with explicit height if specified, adding margins in addition to height // Border and padding are included in specified height but margins are external dvr = TextDpi.ToTextDpi(anchorLimitedHeight) + mbp.MarginTop + mbp.MarginBottom; } FigureHorizontalAnchor horzAnchor = element.HorizontalAnchor; FigureVerticalAnchor vertAnchor = element.VerticalAnchor; fsfigprops.fskrefU = (PTS.FSKREF)(((int)horzAnchor) / 3); fsfigprops.fskrefV = (PTS.FSKREF)(((int)vertAnchor) / 3); fsfigprops.fskalfU = (PTS.FSKALIGNFIG)(((int)horzAnchor) % 3); fsfigprops.fskalfV = (PTS.FSKALIGNFIG)(((int)vertAnchor) % 3); // PTS does not allow to anchor delayed figures to 'Character' if (!PTS.ToBoolean(fInTextLine)) { if (fsfigprops.fskrefU == PTS.FSKREF.fskrefChar) { fsfigprops.fskrefU = PTS.FSKREF.fskrefMargin; fsfigprops.fskalfU = PTS.FSKALIGNFIG.fskalfMin; } if (fsfigprops.fskrefV == PTS.FSKREF.fskrefChar) { fsfigprops.fskrefV = PTS.FSKREF.fskrefMargin; fsfigprops.fskalfV = PTS.FSKALIGNFIG.fskalfMin; } } // Always wrap text on both sides of the floater. fsfigprops.fskwrap = PTS.WrapDirectionToFskwrap(element.WrapDirection); fsfigprops.fNonTextPlane = PTS.False; fsfigprops.fAllowOverlap = PTS.False; fsfigprops.fDelayable = PTS.FromBoolean(element.CanDelayPlacement); // Tight wrap is disabled for now. cPolygons = cVertices = 0; // Update handle to PTS subpage. ((FigureParaClient)paraClient).SubpageHandle = pfsFigureContent; }