Code:
/ Dotnetfx_Vista_SP2 / Dotnetfx_Vista_SP2 / 8.0.50727.4016 / DEVDIV / depot / DevDiv / releases / Orcas / QFE / wpf / src / Framework / MS / Internal / PtsHost / UIElementParagraph.cs / 1 / UIElementParagraph.cs
//---------------------------------------------------------------------------- // // Copyright (C) Microsoft Corporation. All rights reserved. // // Description: UIElementParagraph class provides a wrapper for UIElements. // //--------------------------------------------------------------------------- #pragma warning disable 1634, 1691 // avoid generating warnings about unknown // message numbers and unknown pragmas for PRESharp contol using System; using System.Collections; // IEnumerator using System.Security; // SecurityCritical using System.Windows; // UIElement using System.Windows.Documents; // BlockUIContainer using MS.Internal.Text; // TextDpi using MS.Internal.Documents; // UIElementIsland using MS.Internal.PtsHost.UnsafeNativeMethods; // PTS namespace MS.Internal.PtsHost { ////// UIElementParagraph class provides a wrapper for UIElement objects. /// internal sealed class UIElementParagraph : FloaterBaseParagraph { //------------------------------------------------------------------- // // Constructors // //------------------------------------------------------------------- #region Constructors ////// Constructor. /// /// Element associated with paragraph. /// Content's structural cache. internal UIElementParagraph(TextElement element, StructuralCache structuralCache) : base(element, structuralCache) { } #endregion Constructors //-------------------------------------------------------------------- // // Internal Methods // //------------------------------------------------------------------- #region Internal Methods ////// Dispose the object and release handle. /// public override void Dispose() { ClearUIElementIsland(); base.Dispose(); } ////// Invalidate content's structural cache. Returns: 'true' if entire paragraph /// is invalid. /// /// /// Position to start invalidation from. /// internal override bool InvalidateStructure(int startPosition) { if (_uiElementIsland != null) { _uiElementIsland.DesiredSizeChanged -= new DesiredSizeChangedEventHandler(OnUIElementDesiredSizeChanged); _uiElementIsland.Dispose(); _uiElementIsland = null; } return base.InvalidateStructure(startPosition); } #endregion Internal Methods //-------------------------------------------------------------------- // // PTS callbacks // //-------------------------------------------------------------------- #region PTS callbacks //------------------------------------------------------------------- // CreateParaclient //-------------------------------------------------------------------- internal override void CreateParaclient( out IntPtr paraClientHandle) // OUT: opaque to PTS paragraph client { #pragma warning disable 6518 // Disable PRESharp warning 6518. FloaterParaClient is an UnmamangedHandle, that adds itself // to HandleMapper that holds a reference to it. PTS manages lifetime of this object, and // calls DestroyParaclient to get rid of it. DestroyParaclient will call Dispose() on the object // and remove it from HandleMapper. UIElementParaClient paraClient = new UIElementParaClient(this); paraClientHandle = paraClient.Handle; #pragma warning restore 6518 } //------------------------------------------------------------------- // CollapseMargin //------------------------------------------------------------------- internal override void CollapseMargin( BaseParaClient paraClient, // IN: MarginCollapsingState mcs, // IN: input margin collapsing state uint fswdir, // IN: current direction (of the track, in which margin collapsing is happening) bool suppressTopSpace, // IN: suppress empty space at the top of page out int dvr) // OUT: dvr, calculated based on margin collapsing state { MbpInfo mbp = MbpInfo.FromElement(Element); MarginCollapsingState mcsNew; int margin; MarginCollapsingState.CollapseTopMargin(PtsContext, mbp, mcs, out mcsNew, out margin); if (suppressTopSpace) { dvr = 0; } else { dvr = margin; if (mcsNew != null) { dvr += mcsNew.Margin; } } if (mcsNew != null) { mcsNew.Dispose(); } } //------------------------------------------------------------------- // GetFloaterProperties //-------------------------------------------------------------------- internal override void GetFloaterProperties( uint fswdirTrack, // IN: direction of track out PTS.FSFLOATERPROPS fsfloaterprops) // OUT: properties of the floater { fsfloaterprops = new PTS.FSFLOATERPROPS(); fsfloaterprops.fFloat = PTS.False; // Floater fsfloaterprops.fskclear = PTS.WrapDirectionToFskclear((WrapDirection)Element.GetValue(Block.ClearFloatersProperty)); // Set alignment to left alignment. Do not allow text wrap on any side fsfloaterprops.fskfloatalignment = PTS.FSKFLOATALIGNMENT.fskfloatalignMin; fsfloaterprops.fskwr = PTS.FSKWRAP.fskwrNone; // Always delay UIElement if there is no progress fsfloaterprops.fDelayNoProgress = PTS.True; } //------------------------------------------------------------------- // 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; } } //-------------------------------------------------------------------- // FormatFloaterContentBottomless //------------------------------------------------------------------- internal override void FormatFloaterContentBottomless( FloaterBaseParaClient paraClient, // IN: 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 out PTS.FSFMTRBL fsfmtrbl, // OUT: result of formatting out IntPtr pfsFloatContent, // OUT: opaque for PTS pointer pointer to formatted content 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) { // BlockUIContainer is only formatted at full column width // Set foater width, height to be greater than available values to signal to PTS that floater does not fit in the space durFloaterWidth = durAvailable + 1; dvrFloaterHeight = dvrAvailable + 1; cPolygons = cVertices = 0; fsfmtrbl = PTS.FSFMTRBL.fmtrblInterrupted; fsbbox = new PTS.FSBBOX(); fsbbox.fDefined = PTS.False; pfsFloatContent = IntPtr.Zero; } else { cPolygons = cVertices = 0; // Format UIElement if (((BlockUIContainer)Element).Child != null) { EnsureUIElementIsland(); FormatUIElement(durAvailable, out fsbbox); // Set output values for floater content pfsFloatContent = paraClient.Handle; fsfmtrbl = PTS.FSFMTRBL.fmtrblGoalReached; fsbbox.fDefined = PTS.True; durFloaterWidth = fsbbox.fsrc.du; dvrFloaterHeight = fsbbox.fsrc.dv; } else { ClearUIElementIsland(); MbpInfo mbp = MbpInfo.FromElement(Element); fsbbox.fsrc = new PTS.FSRECT(); fsbbox.fsrc.du = durAvailable; fsbbox.fsrc.dv = mbp.BPTop + mbp.BPBottom; fsbbox.fDefined = PTS.True; pfsFloatContent = paraClient.Handle; fsfmtrbl = PTS.FSFMTRBL.fmtrblGoalReached; durFloaterWidth = fsbbox.fsrc.du; dvrFloaterHeight = fsbbox.fsrc.dv; } } } //-------------------------------------------------------------------- // UpdateBottomlessFloaterContent //------------------------------------------------------------------- internal override void UpdateBottomlessFloaterContent( FloaterBaseParaClient paraClient, // IN: 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 IntPtr pfsFloatContent, // IN: floater content (in UIElementParagraph, this is an alias to the paraClient) out PTS.FSFMTRBL fsfmtrbl, // OUT: result of formatting 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 { // This implementation simply calls into format floater content bottomless. As para has no real content, this is ok. FormatFloaterContentBottomless(paraClient, fSuppressTopSpace, fswdir, fAtMaxWidth, durAvailable, dvrAvailable, out fsfmtrbl, out pfsFloatContent, out durFloaterWidth, out dvrFloaterHeight, out fsbbox, out cPolygons, out cVertices); } //------------------------------------------------------------------- // GetMCSClientAfterFloater //------------------------------------------------------------------- internal override void GetMCSClientAfterFloater( uint fswdirTrack, // IN: direction of Track MarginCollapsingState mcs, // IN: input margin collapsing state out IntPtr pmcsclientOut) // OUT: MCSCLIENT that floater will return to track { MarginCollapsingState mcsNew; int margin; MbpInfo mbp = MbpInfo.FromElement(Element); MarginCollapsingState.CollapseBottomMargin(PtsContext, mbp, null, out mcsNew, out margin); if (mcsNew != null) { pmcsclientOut = mcsNew.Handle; } else { pmcsclientOut = IntPtr.Zero; } } #endregion PTS callbacks //-------------------------------------------------------------------- // // Private methods // //------------------------------------------------------------------- #region Private Methods ////// Format UIElement /// private void FormatUIElement(int durAvailable, out PTS.FSBBOX fsbbox) { MbpInfo mbp = MbpInfo.FromElement(Element); double elementHeight; double elementWidth = TextDpi.FromTextDpi(Math.Max(1, durAvailable - (mbp.MBPLeft + mbp.MBPRight))); if (SizeToFigureParent) { // Only child of a figure whose height is set. Size to figure's page height less figure's MBP and BlockUIContainer's MBP // NOTE: BlockUIContainer margins are always extracted before formatting, either from Figure height or page height if (StructuralCache.CurrentFormatContext.FinitePage) { elementHeight = StructuralCache.CurrentFormatContext.PageHeight; } else { Figure figure = (Figure) ((BlockUIContainer)Element).Parent; Invariant.Assert(figure.Height.IsAbsolute); elementHeight = figure.Height.Value; } elementHeight = Math.Max(TextDpi.FromTextDpi(1), elementHeight - TextDpi.FromTextDpi(mbp.MBPTop + mbp.MBPBottom)); UIElementIsland.DoLayout(new Size(elementWidth, elementHeight), false, false); // Create fsbbox. Set width to available width since we want block ui container to occupy the full column // and UIElement to be algined within it. Set dv to elementHeight. fsbbox.fsrc = new PTS.FSRECT(); fsbbox.fsrc.du = durAvailable; fsbbox.fsrc.dv = TextDpi.ToTextDpi(elementHeight) + mbp.BPTop + mbp.BPBottom; fsbbox.fDefined = PTS.True; } else { // Either BlockUIContainer is not the only child of a figure or the figure's height is unspecified. // In this case, size to height of strcutural cache's current page less page margins and container MBP. // This is consistent with figure's behavior on sizing to content // Always measure at infinity for bottomless, consistent constraint. if (StructuralCache.CurrentFormatContext.FinitePage) { Thickness pageMargin = StructuralCache.CurrentFormatContext.DocumentPageMargin; elementHeight = StructuralCache.CurrentFormatContext.DocumentPageSize.Height - pageMargin.Top - pageMargin.Bottom - TextDpi.FromTextDpi(mbp.MBPTop + mbp.MBPBottom); elementHeight = Math.Max(TextDpi.FromTextDpi(1), elementHeight); } else { elementHeight = Double.PositiveInfinity; } Size uiIslandSize = UIElementIsland.DoLayout(new Size(elementWidth, elementHeight), false, true); // Create fsbbox. Set width to available width since we want block ui container to occupy the full column // and UIElement to be algined within it fsbbox.fsrc = new PTS.FSRECT(); fsbbox.fsrc.du = durAvailable; fsbbox.fsrc.dv = TextDpi.ToTextDpi(uiIslandSize.Height) + mbp.BPTop + mbp.BPBottom; fsbbox.fDefined = PTS.True; } } ////// Create UIElementIsland representing embedded Element Layout island within content world. /// private void EnsureUIElementIsland() { if (_uiElementIsland == null) { _uiElementIsland = new UIElementIsland(((BlockUIContainer)Element).Child); _uiElementIsland.DesiredSizeChanged += new DesiredSizeChangedEventHandler(OnUIElementDesiredSizeChanged); } } ////// Clear UIElementIsland, unsubscribing from events, etc. /// private void ClearUIElementIsland() { try { if (_uiElementIsland != null) { _uiElementIsland.DesiredSizeChanged -= new DesiredSizeChangedEventHandler(OnUIElementDesiredSizeChanged); _uiElementIsland.Dispose(); } } finally { _uiElementIsland = null; } } ////// Handler for DesiredSizeChanged raised by UIElement island. /// private void OnUIElementDesiredSizeChanged(object sender, DesiredSizeChangedEventArgs e) { StructuralCache.FormattingOwner.OnChildDesiredSizeChanged(e.Child); } #endregion Private Methods //-------------------------------------------------------------------- // // Private Properties // //-------------------------------------------------------------------- #region Private Properties ////// UIElementIsland representing embedded Element Layout island within content world. /// internal UIElementIsland UIElementIsland { get { return _uiElementIsland; } } ////// Whether sizing to fit entire figure area. /// private bool SizeToFigureParent { get { // Check for auto value for figure height. // If figure height is auto we do not size to it. if (!IsOnlyChildOfFigure) { return false; } Figure figure = (Figure)((BlockUIContainer)Element).Parent; if (figure.Height.IsAuto) { return false; } if (!StructuralCache.CurrentFormatContext.FinitePage && !figure.Height.IsAbsolute) { return false; } return true; } } ////// Whether this block is the only child of figure. /// private bool IsOnlyChildOfFigure { get { DependencyObject parent = ((BlockUIContainer)Element).Parent; if (parent is Figure) { Figure figure = parent as Figure; if (figure.Blocks.FirstChild == figure.Blocks.LastChild && figure.Blocks.FirstChild == Element) { return true; } } return false; } } #endregion Private Properties //------------------------------------------------------------------- // // Private Fields // //-------------------------------------------------------------------- #region Private Fields ////// UIElementIsland representing embedded ElementLayout island within content world. /// private UIElementIsland _uiElementIsland; #endregion Private Fields } } #pragma warning enable 1634, 1691 // File provided for Reference Use Only by Microsoft Corporation (c) 2007. // Copyright (c) Microsoft Corporation. All rights reserved. //---------------------------------------------------------------------------- // // Copyright (C) Microsoft Corporation. All rights reserved. // // Description: UIElementParagraph class provides a wrapper for UIElements. // //--------------------------------------------------------------------------- #pragma warning disable 1634, 1691 // avoid generating warnings about unknown // message numbers and unknown pragmas for PRESharp contol using System; using System.Collections; // IEnumerator using System.Security; // SecurityCritical using System.Windows; // UIElement using System.Windows.Documents; // BlockUIContainer using MS.Internal.Text; // TextDpi using MS.Internal.Documents; // UIElementIsland using MS.Internal.PtsHost.UnsafeNativeMethods; // PTS namespace MS.Internal.PtsHost { ////// UIElementParagraph class provides a wrapper for UIElement objects. /// internal sealed class UIElementParagraph : FloaterBaseParagraph { //------------------------------------------------------------------- // // Constructors // //------------------------------------------------------------------- #region Constructors ////// Constructor. /// /// Element associated with paragraph. /// Content's structural cache. internal UIElementParagraph(TextElement element, StructuralCache structuralCache) : base(element, structuralCache) { } #endregion Constructors //-------------------------------------------------------------------- // // Internal Methods // //------------------------------------------------------------------- #region Internal Methods ////// Dispose the object and release handle. /// public override void Dispose() { ClearUIElementIsland(); base.Dispose(); } ////// Invalidate content's structural cache. Returns: 'true' if entire paragraph /// is invalid. /// /// /// Position to start invalidation from. /// internal override bool InvalidateStructure(int startPosition) { if (_uiElementIsland != null) { _uiElementIsland.DesiredSizeChanged -= new DesiredSizeChangedEventHandler(OnUIElementDesiredSizeChanged); _uiElementIsland.Dispose(); _uiElementIsland = null; } return base.InvalidateStructure(startPosition); } #endregion Internal Methods //-------------------------------------------------------------------- // // PTS callbacks // //-------------------------------------------------------------------- #region PTS callbacks //------------------------------------------------------------------- // CreateParaclient //-------------------------------------------------------------------- internal override void CreateParaclient( out IntPtr paraClientHandle) // OUT: opaque to PTS paragraph client { #pragma warning disable 6518 // Disable PRESharp warning 6518. FloaterParaClient is an UnmamangedHandle, that adds itself // to HandleMapper that holds a reference to it. PTS manages lifetime of this object, and // calls DestroyParaclient to get rid of it. DestroyParaclient will call Dispose() on the object // and remove it from HandleMapper. UIElementParaClient paraClient = new UIElementParaClient(this); paraClientHandle = paraClient.Handle; #pragma warning restore 6518 } //------------------------------------------------------------------- // CollapseMargin //------------------------------------------------------------------- internal override void CollapseMargin( BaseParaClient paraClient, // IN: MarginCollapsingState mcs, // IN: input margin collapsing state uint fswdir, // IN: current direction (of the track, in which margin collapsing is happening) bool suppressTopSpace, // IN: suppress empty space at the top of page out int dvr) // OUT: dvr, calculated based on margin collapsing state { MbpInfo mbp = MbpInfo.FromElement(Element); MarginCollapsingState mcsNew; int margin; MarginCollapsingState.CollapseTopMargin(PtsContext, mbp, mcs, out mcsNew, out margin); if (suppressTopSpace) { dvr = 0; } else { dvr = margin; if (mcsNew != null) { dvr += mcsNew.Margin; } } if (mcsNew != null) { mcsNew.Dispose(); } } //------------------------------------------------------------------- // GetFloaterProperties //-------------------------------------------------------------------- internal override void GetFloaterProperties( uint fswdirTrack, // IN: direction of track out PTS.FSFLOATERPROPS fsfloaterprops) // OUT: properties of the floater { fsfloaterprops = new PTS.FSFLOATERPROPS(); fsfloaterprops.fFloat = PTS.False; // Floater fsfloaterprops.fskclear = PTS.WrapDirectionToFskclear((WrapDirection)Element.GetValue(Block.ClearFloatersProperty)); // Set alignment to left alignment. Do not allow text wrap on any side fsfloaterprops.fskfloatalignment = PTS.FSKFLOATALIGNMENT.fskfloatalignMin; fsfloaterprops.fskwr = PTS.FSKWRAP.fskwrNone; // Always delay UIElement if there is no progress fsfloaterprops.fDelayNoProgress = PTS.True; } //------------------------------------------------------------------- // 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; } } //-------------------------------------------------------------------- // FormatFloaterContentBottomless //------------------------------------------------------------------- internal override void FormatFloaterContentBottomless( FloaterBaseParaClient paraClient, // IN: 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 out PTS.FSFMTRBL fsfmtrbl, // OUT: result of formatting out IntPtr pfsFloatContent, // OUT: opaque for PTS pointer pointer to formatted content 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) { // BlockUIContainer is only formatted at full column width // Set foater width, height to be greater than available values to signal to PTS that floater does not fit in the space durFloaterWidth = durAvailable + 1; dvrFloaterHeight = dvrAvailable + 1; cPolygons = cVertices = 0; fsfmtrbl = PTS.FSFMTRBL.fmtrblInterrupted; fsbbox = new PTS.FSBBOX(); fsbbox.fDefined = PTS.False; pfsFloatContent = IntPtr.Zero; } else { cPolygons = cVertices = 0; // Format UIElement if (((BlockUIContainer)Element).Child != null) { EnsureUIElementIsland(); FormatUIElement(durAvailable, out fsbbox); // Set output values for floater content pfsFloatContent = paraClient.Handle; fsfmtrbl = PTS.FSFMTRBL.fmtrblGoalReached; fsbbox.fDefined = PTS.True; durFloaterWidth = fsbbox.fsrc.du; dvrFloaterHeight = fsbbox.fsrc.dv; } else { ClearUIElementIsland(); MbpInfo mbp = MbpInfo.FromElement(Element); fsbbox.fsrc = new PTS.FSRECT(); fsbbox.fsrc.du = durAvailable; fsbbox.fsrc.dv = mbp.BPTop + mbp.BPBottom; fsbbox.fDefined = PTS.True; pfsFloatContent = paraClient.Handle; fsfmtrbl = PTS.FSFMTRBL.fmtrblGoalReached; durFloaterWidth = fsbbox.fsrc.du; dvrFloaterHeight = fsbbox.fsrc.dv; } } } //-------------------------------------------------------------------- // UpdateBottomlessFloaterContent //------------------------------------------------------------------- internal override void UpdateBottomlessFloaterContent( FloaterBaseParaClient paraClient, // IN: 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 IntPtr pfsFloatContent, // IN: floater content (in UIElementParagraph, this is an alias to the paraClient) out PTS.FSFMTRBL fsfmtrbl, // OUT: result of formatting 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 { // This implementation simply calls into format floater content bottomless. As para has no real content, this is ok. FormatFloaterContentBottomless(paraClient, fSuppressTopSpace, fswdir, fAtMaxWidth, durAvailable, dvrAvailable, out fsfmtrbl, out pfsFloatContent, out durFloaterWidth, out dvrFloaterHeight, out fsbbox, out cPolygons, out cVertices); } //------------------------------------------------------------------- // GetMCSClientAfterFloater //------------------------------------------------------------------- internal override void GetMCSClientAfterFloater( uint fswdirTrack, // IN: direction of Track MarginCollapsingState mcs, // IN: input margin collapsing state out IntPtr pmcsclientOut) // OUT: MCSCLIENT that floater will return to track { MarginCollapsingState mcsNew; int margin; MbpInfo mbp = MbpInfo.FromElement(Element); MarginCollapsingState.CollapseBottomMargin(PtsContext, mbp, null, out mcsNew, out margin); if (mcsNew != null) { pmcsclientOut = mcsNew.Handle; } else { pmcsclientOut = IntPtr.Zero; } } #endregion PTS callbacks //-------------------------------------------------------------------- // // Private methods // //------------------------------------------------------------------- #region Private Methods ////// Format UIElement /// private void FormatUIElement(int durAvailable, out PTS.FSBBOX fsbbox) { MbpInfo mbp = MbpInfo.FromElement(Element); double elementHeight; double elementWidth = TextDpi.FromTextDpi(Math.Max(1, durAvailable - (mbp.MBPLeft + mbp.MBPRight))); if (SizeToFigureParent) { // Only child of a figure whose height is set. Size to figure's page height less figure's MBP and BlockUIContainer's MBP // NOTE: BlockUIContainer margins are always extracted before formatting, either from Figure height or page height if (StructuralCache.CurrentFormatContext.FinitePage) { elementHeight = StructuralCache.CurrentFormatContext.PageHeight; } else { Figure figure = (Figure) ((BlockUIContainer)Element).Parent; Invariant.Assert(figure.Height.IsAbsolute); elementHeight = figure.Height.Value; } elementHeight = Math.Max(TextDpi.FromTextDpi(1), elementHeight - TextDpi.FromTextDpi(mbp.MBPTop + mbp.MBPBottom)); UIElementIsland.DoLayout(new Size(elementWidth, elementHeight), false, false); // Create fsbbox. Set width to available width since we want block ui container to occupy the full column // and UIElement to be algined within it. Set dv to elementHeight. fsbbox.fsrc = new PTS.FSRECT(); fsbbox.fsrc.du = durAvailable; fsbbox.fsrc.dv = TextDpi.ToTextDpi(elementHeight) + mbp.BPTop + mbp.BPBottom; fsbbox.fDefined = PTS.True; } else { // Either BlockUIContainer is not the only child of a figure or the figure's height is unspecified. // In this case, size to height of strcutural cache's current page less page margins and container MBP. // This is consistent with figure's behavior on sizing to content // Always measure at infinity for bottomless, consistent constraint. if (StructuralCache.CurrentFormatContext.FinitePage) { Thickness pageMargin = StructuralCache.CurrentFormatContext.DocumentPageMargin; elementHeight = StructuralCache.CurrentFormatContext.DocumentPageSize.Height - pageMargin.Top - pageMargin.Bottom - TextDpi.FromTextDpi(mbp.MBPTop + mbp.MBPBottom); elementHeight = Math.Max(TextDpi.FromTextDpi(1), elementHeight); } else { elementHeight = Double.PositiveInfinity; } Size uiIslandSize = UIElementIsland.DoLayout(new Size(elementWidth, elementHeight), false, true); // Create fsbbox. Set width to available width since we want block ui container to occupy the full column // and UIElement to be algined within it fsbbox.fsrc = new PTS.FSRECT(); fsbbox.fsrc.du = durAvailable; fsbbox.fsrc.dv = TextDpi.ToTextDpi(uiIslandSize.Height) + mbp.BPTop + mbp.BPBottom; fsbbox.fDefined = PTS.True; } } ////// Create UIElementIsland representing embedded Element Layout island within content world. /// private void EnsureUIElementIsland() { if (_uiElementIsland == null) { _uiElementIsland = new UIElementIsland(((BlockUIContainer)Element).Child); _uiElementIsland.DesiredSizeChanged += new DesiredSizeChangedEventHandler(OnUIElementDesiredSizeChanged); } } ////// Clear UIElementIsland, unsubscribing from events, etc. /// private void ClearUIElementIsland() { try { if (_uiElementIsland != null) { _uiElementIsland.DesiredSizeChanged -= new DesiredSizeChangedEventHandler(OnUIElementDesiredSizeChanged); _uiElementIsland.Dispose(); } } finally { _uiElementIsland = null; } } ////// Handler for DesiredSizeChanged raised by UIElement island. /// private void OnUIElementDesiredSizeChanged(object sender, DesiredSizeChangedEventArgs e) { StructuralCache.FormattingOwner.OnChildDesiredSizeChanged(e.Child); } #endregion Private Methods //-------------------------------------------------------------------- // // Private Properties // //-------------------------------------------------------------------- #region Private Properties ////// UIElementIsland representing embedded Element Layout island within content world. /// internal UIElementIsland UIElementIsland { get { return _uiElementIsland; } } ////// Whether sizing to fit entire figure area. /// private bool SizeToFigureParent { get { // Check for auto value for figure height. // If figure height is auto we do not size to it. if (!IsOnlyChildOfFigure) { return false; } Figure figure = (Figure)((BlockUIContainer)Element).Parent; if (figure.Height.IsAuto) { return false; } if (!StructuralCache.CurrentFormatContext.FinitePage && !figure.Height.IsAbsolute) { return false; } return true; } } ////// Whether this block is the only child of figure. /// private bool IsOnlyChildOfFigure { get { DependencyObject parent = ((BlockUIContainer)Element).Parent; if (parent is Figure) { Figure figure = parent as Figure; if (figure.Blocks.FirstChild == figure.Blocks.LastChild && figure.Blocks.FirstChild == Element) { return true; } } return false; } } #endregion Private Properties //------------------------------------------------------------------- // // Private Fields // //-------------------------------------------------------------------- #region Private Fields ////// UIElementIsland representing embedded ElementLayout island within content world. /// private UIElementIsland _uiElementIsland; #endregion Private Fields } } #pragma warning enable 1634, 1691 // File provided for Reference Use Only by Microsoft Corporation (c) 2007. // Copyright (c) Microsoft Corporation. All rights reserved.
Link Menu
![Network programming in C#, Network Programming in VB.NET, Network Programming in .NET](/images/book.jpg)
This book is available now!
Buy at Amazon US or
Buy at Amazon UK
- BitmapEncoder.cs
- IBuiltInEvidence.cs
- DiscoveryClientChannelBase.cs
- CompositeDataBoundControl.cs
- QualificationDataItem.cs
- CircleHotSpot.cs
- SqlProcedureAttribute.cs
- HitTestResult.cs
- XmlSignificantWhitespace.cs
- ServiceHost.cs
- RankException.cs
- ColorMap.cs
- SymbolEqualComparer.cs
- SelectionRange.cs
- MasterPageBuildProvider.cs
- ReaderContextStackData.cs
- _SpnDictionary.cs
- UncommonField.cs
- SqlCacheDependencyDatabase.cs
- ToolboxComponentsCreatedEventArgs.cs
- LinkButton.cs
- VisemeEventArgs.cs
- ThreadSafeList.cs
- AnnotationDocumentPaginator.cs
- Function.cs
- sqlpipe.cs
- MessageSmuggler.cs
- MimeFormatter.cs
- WindowsGrip.cs
- AspCompat.cs
- ValueType.cs
- DbTransaction.cs
- DBCommand.cs
- COM2ColorConverter.cs
- PropertyGridCommands.cs
- RenderContext.cs
- RemoteWebConfigurationHost.cs
- DataGridViewCellValidatingEventArgs.cs
- Annotation.cs
- CodeDefaultValueExpression.cs
- XsltCompileContext.cs
- RemotingServices.cs
- ProtocolViolationException.cs
- MultiAsyncResult.cs
- MobileCapabilities.cs
- FixedSOMLineCollection.cs
- NameGenerator.cs
- DataRecordInternal.cs
- EntityDataSourceContainerNameItem.cs
- SctClaimDictionary.cs
- StringCollectionEditor.cs
- ImageCodecInfo.cs
- TextBlock.cs
- MouseEvent.cs
- OdbcReferenceCollection.cs
- WebZone.cs
- LongTypeConverter.cs
- RegexCompiler.cs
- LogicalTreeHelper.cs
- _BasicClient.cs
- ConditionalAttribute.cs
- ImplicitInputBrush.cs
- OrderingInfo.cs
- Contracts.cs
- SchemaContext.cs
- AngleUtil.cs
- Quad.cs
- AnimatedTypeHelpers.cs
- CellTreeNode.cs
- AsyncPostBackErrorEventArgs.cs
- EnterpriseServicesHelper.cs
- LZCodec.cs
- XamlBrushSerializer.cs
- TextDocumentView.cs
- MultipleViewPattern.cs
- Journaling.cs
- Matrix3DConverter.cs
- OdbcDataReader.cs
- TimeStampChecker.cs
- ListViewSelectEventArgs.cs
- QilFunction.cs
- DropShadowBitmapEffect.cs
- PropertyDescriptors.cs
- QuaternionAnimationBase.cs
- MimeMultiPart.cs
- ErrorFormatter.cs
- GeneratedContractType.cs
- SystemKeyConverter.cs
- ServiceCredentials.cs
- WsdlInspector.cs
- DisableDpiAwarenessAttribute.cs
- DynamicPropertyHolder.cs
- ThreadPoolTaskScheduler.cs
- UIElementCollection.cs
- PropertyKey.cs
- Size3DConverter.cs
- ModifierKeysConverter.cs
- UnknownBitmapDecoder.cs
- HitTestWithPointDrawingContextWalker.cs
- DelegateSerializationHolder.cs