Code:
/ Dotnetfx_Win7_3.5.1 / Dotnetfx_Win7_3.5.1 / 3.5.1 / DEVDIV / depot / DevDiv / releases / Orcas / NetFXw7 / wpf / src / Framework / MS / Internal / documents / FlowDocumentFormatter.cs / 2 / FlowDocumentFormatter.cs
//---------------------------------------------------------------------------- // // Copyright (C) Microsoft Corporation. All rights reserved. // // File: FlowDocumentFormatter.cs // // Description: Bottomless content formatter associated with FlowDocument. // // History: // 11/07/2005 : grzegorz - created. // //--------------------------------------------------------------------------- using System; // Object using System.Windows; // Size using System.Windows.Documents; // FlowDocument using System.Windows.Media; // Visual using System.Windows.Threading; // DispatcherOperationCallback using MS.Internal.PtsHost; // FlowDocumentPage using MS.Internal.PtsHost.UnsafeNativeMethods; // PTS namespace MS.Internal.Documents { ////// Bottomless content formatter associated with FlowDocument. /// internal class FlowDocumentFormatter : IFlowDocumentFormatter { //------------------------------------------------------------------- // // Constructors // //------------------------------------------------------------------- #region Constructors ////// Constructor /// internal FlowDocumentFormatter(FlowDocument document) { _document = document; _documentPage = new FlowDocumentPage(_document.StructuralCache); } #endregion Constructors //-------------------------------------------------------------------- // // Internal Methods // //------------------------------------------------------------------- #region Internal Methods ////// Formatts content. /// /// Constraint size. internal void Format(Size constraint) { Thickness pageMargin; Size pageSize; // Reentrancy check. if (_document.StructuralCache.IsFormattingInProgress) { throw new InvalidOperationException(SR.Get(SRID.FlowDocumentFormattingReentrancy)); } if (_document.StructuralCache.IsContentChangeInProgress) { throw new InvalidOperationException(SR.Get(SRID.TextContainerChangingReentrancyInvalid)); } // Check if we can continue with formatting without nuking incremental udpate info. if (_document.StructuralCache.IsFormattedOnce) { if (!_lastFormatSuccessful) { // We cannot resolve update info if last formatting was unsuccessful. _document.StructuralCache.InvalidateFormatCache(true); } if (!_arrangedAfterFormat && (!_document.StructuralCache.ForceReformat || !_document.StructuralCache.DestroyStructure)) { // Need to clear update info by running arrange process. // This is necessary, because Format may be called more than once // before Arrange is called. But PTS is not able to merge update info. // To protect against loosing incremental changes delta, need // to arrange the page and create all necessary visuals. _documentPage.Arrange(_documentPage.ContentSize); _documentPage.EnsureValidVisuals(); } } _arrangedAfterFormat = false; _lastFormatSuccessful = false; _isContentFormatValid = false; pageSize = ComputePageSize(constraint); pageMargin = ComputePageMargin(); // Disable processing of the queue during blocking operations to prevent unrelated reentrancy. using (_document.Dispatcher.DisableProcessing()) { _document.StructuralCache.IsFormattingInProgress = true; // Set reentrancy flag. try { _document.StructuralCache.BackgroundFormatInfo.ViewportHeight = constraint.Height; _documentPage.FormatBottomless(pageSize, pageMargin); } finally { _document.StructuralCache.IsFormattingInProgress = false; // Clear reentrancy flag. } } _lastFormatSuccessful = true; } ////// Arranges content. /// /// Size that element should use to arrange itself and its children. /// Viewport for visible content. internal void Arrange(Size arrangeSize, Rect viewport) { Invariant.Assert(_document.StructuralCache.DtrList == null || _document.StructuralCache.DtrList.Length == 0 || (_document.StructuralCache.DtrList.Length == 1 && _document.StructuralCache.BackgroundFormatInfo.DoesFinalDTRCoverRestOfText)); // Arrange the content and create visual tree. _documentPage.Arrange(arrangeSize); _documentPage.EnsureValidVisuals(); _arrangedAfterFormat = true; // Render content only for the current viewport. if (viewport.IsEmpty) { viewport = new Rect(0, 0, arrangeSize.Width, _document.StructuralCache.BackgroundFormatInfo.ViewportHeight); } PTS.FSRECT fsrectViewport = new PTS.FSRECT(viewport); _documentPage.UpdateViewport(ref fsrectViewport, true); _isContentFormatValid = true; } #endregion Internal Methods //-------------------------------------------------------------------- // // Internal Properties // //-------------------------------------------------------------------- #region Internal Properties ////// DocumentPage representing formatted content. /// internal FlowDocumentPage DocumentPage { get { return _documentPage; } } #endregion Internal Properties //------------------------------------------------------------------- // // Internal Events // //-------------------------------------------------------------------- #region Internal Events ////// Fired when content has been invalidated. /// internal event EventHandler ContentInvalidated; ////// Fired when formatter has been suspended. /// internal event EventHandler Suspended; #endregion Internal Events //------------------------------------------------------------------- // // Private Methods // //------------------------------------------------------------------- #region Private Methods ////// Compute size for the page. /// private Size ComputePageSize(Size constraint) { double max, min; Size pageSize = new Size(_document.PageWidth, double.PositiveInfinity); if (DoubleUtil.IsNaN(pageSize.Width)) { pageSize.Width = constraint.Width; max = _document.MaxPageWidth; if (pageSize.Width > max) { pageSize.Width = max; } min = _document.MinPageWidth; if (pageSize.Width < min) { pageSize.Width = min; } } // If the width is Double.PositiveInfinity, crop it to predefined value. if (double.IsPositiveInfinity(pageSize.Width)) { pageSize.Width = _defaultWidth; } return pageSize; } ////// Compute margin for the page. /// private Thickness ComputePageMargin() { double lineHeight = MS.Internal.Text.DynamicPropertyReader.GetLineHeightValue(_document); Thickness pageMargin = _document.PagePadding; // If Padding value is 'Auto', treat it as 1*LineHeight. if (DoubleUtil.IsNaN(pageMargin.Left)) { pageMargin.Left = lineHeight; } if (DoubleUtil.IsNaN(pageMargin.Top)) { pageMargin.Top = lineHeight; } if (DoubleUtil.IsNaN(pageMargin.Right)) { pageMargin.Right = lineHeight; } if (DoubleUtil.IsNaN(pageMargin.Bottom)) { pageMargin.Bottom = lineHeight; } return pageMargin; } #endregion Private Methods //------------------------------------------------------------------- // // Private Fields // //-------------------------------------------------------------------- #region Private Fields ////// FlowDocument associated with the paginator. /// private readonly FlowDocument _document; ////// DocumentPage representing formatted content. /// private FlowDocumentPage _documentPage; ////// Whether Arrange was called after formatting. /// private bool _arrangedAfterFormat; ////// Whether last formatting was succesful. /// private bool _lastFormatSuccessful; ////// Width used when no width is specified. /// private const double _defaultWidth = 500.0; ////// Whether the current format for the content is valid /// private bool _isContentFormatValid = false; #endregion Private Fields //------------------------------------------------------------------- // // IFlowDocumentFormatter Members // //-------------------------------------------------------------------- #region IFlowDocumentFormatter Members ////// Responds to change affecting entire content of associated FlowDocument. /// /// Whether change affects layout. void IFlowDocumentFormatter.OnContentInvalidated(bool affectsLayout) { // If change happens before we've been arranged, we need to do a full reformat if (affectsLayout) { if(!_arrangedAfterFormat) { _document.StructuralCache.InvalidateFormatCache(true); } _isContentFormatValid = false; } if (ContentInvalidated != null) { ContentInvalidated(this, EventArgs.Empty); } } ////// Responds to change affecting entire content of associated FlowDocument. /// /// Whether change affects layout. /// Start of the affected content range. /// End of the affected content range. void IFlowDocumentFormatter.OnContentInvalidated(bool affectsLayout, ITextPointer start, ITextPointer end) { ((IFlowDocumentFormatter)this).OnContentInvalidated(affectsLayout); } ////// Suspend formatting. /// void IFlowDocumentFormatter.Suspend() { if (Suspended != null) { Suspended(this, EventArgs.Empty); } } ////// Is layout data in a valid state. /// bool IFlowDocumentFormatter.IsLayoutDataValid { get { // Layout is clean only when the page is calculated and it // is in the clean state - there are no pending changes that affect layout. // // Hittest can be called with invalid arrange. This happens in // following situation: // Something is causing to call InvalidateTree and eventually // InvalidateAllProperties will be called in such case. In responce // to that following properties are invalidated: // * ClipToBounds - invalidates arrange // * IsEnabled - calls MouseDevice.Synchronize and it will eventually // do hittesting. // // OR // TextContainer sends Changing event, which invalidates measure, // but we have not yet received a matching Changed event. // // So, it is possible to receive hittesting request on dirty layout. bool layoutValid = _documentPage != null && _document.StructuralCache.IsFormattedOnce && !_document.StructuralCache.ForceReformat && _isContentFormatValid && !_document.StructuralCache.IsContentChangeInProgress && !_document.StructuralCache.IsFormattingInProgress; return layoutValid; } } #endregion IFlowDocumentFormatter Members } } // 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. // // File: FlowDocumentFormatter.cs // // Description: Bottomless content formatter associated with FlowDocument. // // History: // 11/07/2005 : grzegorz - created. // //--------------------------------------------------------------------------- using System; // Object using System.Windows; // Size using System.Windows.Documents; // FlowDocument using System.Windows.Media; // Visual using System.Windows.Threading; // DispatcherOperationCallback using MS.Internal.PtsHost; // FlowDocumentPage using MS.Internal.PtsHost.UnsafeNativeMethods; // PTS namespace MS.Internal.Documents { ////// Bottomless content formatter associated with FlowDocument. /// internal class FlowDocumentFormatter : IFlowDocumentFormatter { //------------------------------------------------------------------- // // Constructors // //------------------------------------------------------------------- #region Constructors ////// Constructor /// internal FlowDocumentFormatter(FlowDocument document) { _document = document; _documentPage = new FlowDocumentPage(_document.StructuralCache); } #endregion Constructors //-------------------------------------------------------------------- // // Internal Methods // //------------------------------------------------------------------- #region Internal Methods ////// Formatts content. /// /// Constraint size. internal void Format(Size constraint) { Thickness pageMargin; Size pageSize; // Reentrancy check. if (_document.StructuralCache.IsFormattingInProgress) { throw new InvalidOperationException(SR.Get(SRID.FlowDocumentFormattingReentrancy)); } if (_document.StructuralCache.IsContentChangeInProgress) { throw new InvalidOperationException(SR.Get(SRID.TextContainerChangingReentrancyInvalid)); } // Check if we can continue with formatting without nuking incremental udpate info. if (_document.StructuralCache.IsFormattedOnce) { if (!_lastFormatSuccessful) { // We cannot resolve update info if last formatting was unsuccessful. _document.StructuralCache.InvalidateFormatCache(true); } if (!_arrangedAfterFormat && (!_document.StructuralCache.ForceReformat || !_document.StructuralCache.DestroyStructure)) { // Need to clear update info by running arrange process. // This is necessary, because Format may be called more than once // before Arrange is called. But PTS is not able to merge update info. // To protect against loosing incremental changes delta, need // to arrange the page and create all necessary visuals. _documentPage.Arrange(_documentPage.ContentSize); _documentPage.EnsureValidVisuals(); } } _arrangedAfterFormat = false; _lastFormatSuccessful = false; _isContentFormatValid = false; pageSize = ComputePageSize(constraint); pageMargin = ComputePageMargin(); // Disable processing of the queue during blocking operations to prevent unrelated reentrancy. using (_document.Dispatcher.DisableProcessing()) { _document.StructuralCache.IsFormattingInProgress = true; // Set reentrancy flag. try { _document.StructuralCache.BackgroundFormatInfo.ViewportHeight = constraint.Height; _documentPage.FormatBottomless(pageSize, pageMargin); } finally { _document.StructuralCache.IsFormattingInProgress = false; // Clear reentrancy flag. } } _lastFormatSuccessful = true; } ////// Arranges content. /// /// Size that element should use to arrange itself and its children. /// Viewport for visible content. internal void Arrange(Size arrangeSize, Rect viewport) { Invariant.Assert(_document.StructuralCache.DtrList == null || _document.StructuralCache.DtrList.Length == 0 || (_document.StructuralCache.DtrList.Length == 1 && _document.StructuralCache.BackgroundFormatInfo.DoesFinalDTRCoverRestOfText)); // Arrange the content and create visual tree. _documentPage.Arrange(arrangeSize); _documentPage.EnsureValidVisuals(); _arrangedAfterFormat = true; // Render content only for the current viewport. if (viewport.IsEmpty) { viewport = new Rect(0, 0, arrangeSize.Width, _document.StructuralCache.BackgroundFormatInfo.ViewportHeight); } PTS.FSRECT fsrectViewport = new PTS.FSRECT(viewport); _documentPage.UpdateViewport(ref fsrectViewport, true); _isContentFormatValid = true; } #endregion Internal Methods //-------------------------------------------------------------------- // // Internal Properties // //-------------------------------------------------------------------- #region Internal Properties ////// DocumentPage representing formatted content. /// internal FlowDocumentPage DocumentPage { get { return _documentPage; } } #endregion Internal Properties //------------------------------------------------------------------- // // Internal Events // //-------------------------------------------------------------------- #region Internal Events ////// Fired when content has been invalidated. /// internal event EventHandler ContentInvalidated; ////// Fired when formatter has been suspended. /// internal event EventHandler Suspended; #endregion Internal Events //------------------------------------------------------------------- // // Private Methods // //------------------------------------------------------------------- #region Private Methods ////// Compute size for the page. /// private Size ComputePageSize(Size constraint) { double max, min; Size pageSize = new Size(_document.PageWidth, double.PositiveInfinity); if (DoubleUtil.IsNaN(pageSize.Width)) { pageSize.Width = constraint.Width; max = _document.MaxPageWidth; if (pageSize.Width > max) { pageSize.Width = max; } min = _document.MinPageWidth; if (pageSize.Width < min) { pageSize.Width = min; } } // If the width is Double.PositiveInfinity, crop it to predefined value. if (double.IsPositiveInfinity(pageSize.Width)) { pageSize.Width = _defaultWidth; } return pageSize; } ////// Compute margin for the page. /// private Thickness ComputePageMargin() { double lineHeight = MS.Internal.Text.DynamicPropertyReader.GetLineHeightValue(_document); Thickness pageMargin = _document.PagePadding; // If Padding value is 'Auto', treat it as 1*LineHeight. if (DoubleUtil.IsNaN(pageMargin.Left)) { pageMargin.Left = lineHeight; } if (DoubleUtil.IsNaN(pageMargin.Top)) { pageMargin.Top = lineHeight; } if (DoubleUtil.IsNaN(pageMargin.Right)) { pageMargin.Right = lineHeight; } if (DoubleUtil.IsNaN(pageMargin.Bottom)) { pageMargin.Bottom = lineHeight; } return pageMargin; } #endregion Private Methods //------------------------------------------------------------------- // // Private Fields // //-------------------------------------------------------------------- #region Private Fields ////// FlowDocument associated with the paginator. /// private readonly FlowDocument _document; ////// DocumentPage representing formatted content. /// private FlowDocumentPage _documentPage; ////// Whether Arrange was called after formatting. /// private bool _arrangedAfterFormat; ////// Whether last formatting was succesful. /// private bool _lastFormatSuccessful; ////// Width used when no width is specified. /// private const double _defaultWidth = 500.0; ////// Whether the current format for the content is valid /// private bool _isContentFormatValid = false; #endregion Private Fields //------------------------------------------------------------------- // // IFlowDocumentFormatter Members // //-------------------------------------------------------------------- #region IFlowDocumentFormatter Members ////// Responds to change affecting entire content of associated FlowDocument. /// /// Whether change affects layout. void IFlowDocumentFormatter.OnContentInvalidated(bool affectsLayout) { // If change happens before we've been arranged, we need to do a full reformat if (affectsLayout) { if(!_arrangedAfterFormat) { _document.StructuralCache.InvalidateFormatCache(true); } _isContentFormatValid = false; } if (ContentInvalidated != null) { ContentInvalidated(this, EventArgs.Empty); } } ////// Responds to change affecting entire content of associated FlowDocument. /// /// Whether change affects layout. /// Start of the affected content range. /// End of the affected content range. void IFlowDocumentFormatter.OnContentInvalidated(bool affectsLayout, ITextPointer start, ITextPointer end) { ((IFlowDocumentFormatter)this).OnContentInvalidated(affectsLayout); } ////// Suspend formatting. /// void IFlowDocumentFormatter.Suspend() { if (Suspended != null) { Suspended(this, EventArgs.Empty); } } ////// Is layout data in a valid state. /// bool IFlowDocumentFormatter.IsLayoutDataValid { get { // Layout is clean only when the page is calculated and it // is in the clean state - there are no pending changes that affect layout. // // Hittest can be called with invalid arrange. This happens in // following situation: // Something is causing to call InvalidateTree and eventually // InvalidateAllProperties will be called in such case. In responce // to that following properties are invalidated: // * ClipToBounds - invalidates arrange // * IsEnabled - calls MouseDevice.Synchronize and it will eventually // do hittesting. // // OR // TextContainer sends Changing event, which invalidates measure, // but we have not yet received a matching Changed event. // // So, it is possible to receive hittesting request on dirty layout. bool layoutValid = _documentPage != null && _document.StructuralCache.IsFormattedOnce && !_document.StructuralCache.ForceReformat && _isContentFormatValid && !_document.StructuralCache.IsContentChangeInProgress && !_document.StructuralCache.IsFormattingInProgress; return layoutValid; } } #endregion IFlowDocumentFormatter Members } } // File provided for Reference Use Only by Microsoft Corporation (c) 2007. // Copyright (c) Microsoft Corporation. All rights reserved.
Link Menu
This book is available now!
Buy at Amazon US or
Buy at Amazon UK
- BaseWebProxyFinder.cs
- Version.cs
- GridViewEditEventArgs.cs
- RadioButtonAutomationPeer.cs
- AutoCompleteStringCollection.cs
- ContainerParagraph.cs
- WebPartZoneCollection.cs
- SlotInfo.cs
- XmlSchemaElement.cs
- CallTemplateAction.cs
- SqlServices.cs
- PeerName.cs
- TextBoxAutoCompleteSourceConverter.cs
- TdsParserStaticMethods.cs
- ClientSettings.cs
- Error.cs
- WebPartZoneBaseDesigner.cs
- Message.cs
- TextEditorTyping.cs
- ListViewSelectEventArgs.cs
- ADMembershipProvider.cs
- KeyConverter.cs
- ApplicationTrust.cs
- XmlReturnWriter.cs
- InstanceData.cs
- DataControlFieldHeaderCell.cs
- SecureEnvironment.cs
- SubclassTypeValidatorAttribute.cs
- OracleTransaction.cs
- SpellerError.cs
- Window.cs
- HTMLTagNameToTypeMapper.cs
- PerformanceCounterManager.cs
- MetaTable.cs
- ClientEventManager.cs
- XPathBinder.cs
- GlobalizationSection.cs
- WizardStepBase.cs
- ItemCheckEvent.cs
- ArgumentOutOfRangeException.cs
- RuntimeArgumentHandle.cs
- Adorner.cs
- ContentPlaceHolder.cs
- XmlParserContext.cs
- TrailingSpaceComparer.cs
- BitmapEffectGroup.cs
- FixedHighlight.cs
- PathFigureCollection.cs
- ReadOnlyNameValueCollection.cs
- AgileSafeNativeMemoryHandle.cs
- DataSysAttribute.cs
- indexingfiltermarshaler.cs
- ConfigurationManager.cs
- CompositeCollectionView.cs
- ObjectStateManager.cs
- PropertyItemInternal.cs
- ConnectionPointConverter.cs
- DesignerVerbCollection.cs
- PriorityChain.cs
- KeyValuePair.cs
- MetadataExchangeClient.cs
- Evidence.cs
- TypeUsageBuilder.cs
- Rijndael.cs
- HebrewCalendar.cs
- TileBrush.cs
- CheckBox.cs
- CoreSwitches.cs
- FormViewUpdateEventArgs.cs
- NavigationProperty.cs
- DataRowCollection.cs
- ReadOnlyCollectionBuilder.cs
- RoleManagerSection.cs
- SchemaCollectionPreprocessor.cs
- ScrollChrome.cs
- DataGridBoolColumn.cs
- DesignerGenericWebPart.cs
- WebControl.cs
- TabControl.cs
- CmsUtils.cs
- Section.cs
- BufferModesCollection.cs
- WrappedIUnknown.cs
- HttpModuleCollection.cs
- SQLChars.cs
- DebugViewWriter.cs
- SystemColors.cs
- DrawingServices.cs
- HttpCapabilitiesBase.cs
- BuildResult.cs
- DrawingServices.cs
- DateTimeUtil.cs
- AuthenticodeSignatureInformation.cs
- PersonalizationProviderCollection.cs
- BaseParagraph.cs
- TransformerConfigurationWizardBase.cs
- CollectionBase.cs
- AttributeAction.cs
- DataGridCaption.cs
- SettingsAttributes.cs