Code:
/ 4.0 / 4.0 / DEVDIV_TFS / Dev10 / Releases / RTMRel / wpf / src / Framework / MS / Internal / PtsHost / StructuralCache.cs / 1305600 / StructuralCache.cs
//---------------------------------------------------------------------------- // //// Copyright (C) Microsoft Corporation. All rights reserved. // // // // Description: PTS structural cache related data. // // History: // 06/03/2003 : olego - Created // //--------------------------------------------------------------------------- using MS.Internal.Text; using MS.Internal.PtsHost.UnsafeNativeMethods; using MS.Utility; using System; using System.Collections.Generic; using System.Diagnostics; using System.Globalization; using System.Windows; using System.Windows.Media; using System.Windows.Documents; namespace MS.Internal.PtsHost { ////// PTS structural cache related data /// internal sealed class StructuralCache { //----------------------------------------------------- // // Constructors // //----------------------------------------------------- #region Constructors ////// Structural Cache contructor. /// /// Owner of the conent /// TextContainer representing content internal StructuralCache(FlowDocument owner, TextContainer textContainer) { Invariant.Assert(owner != null); Invariant.Assert(textContainer != null); Invariant.Assert(textContainer.Parent != null); _owner = owner; _textContainer = textContainer; _backgroundFormatInfo = new BackgroundFormatInfo(this); } ////// Finalizer /// ~StructuralCache() { // Notify the PtsCache about the fact that PtsContext needs to be destroyed. // NOTE: It is safe to access PtsContext, because the PtsContext // does not have a finalizer. if (_ptsContext != null) { PtsCache.ReleaseContext(_ptsContext); } } #endregion Constructors //------------------------------------------------------ // // Internal Methods // //----------------------------------------------------- #region Internal Methods ////// Sets current page context to be used in the cache's queries /// /// Document page to become current in the context ///Reference to object compatible with IDisposable to re-initialize page context internal IDisposable SetDocumentFormatContext(FlowDocumentPage currentPage) { if (!CheckFlags(Flags.FormattedOnce)) { SetFlags(true, Flags.FormattedOnce); _owner.InitializeForFirstFormatting(); } return (new DocumentFormatContext(this, currentPage) as IDisposable); } ////// Sets current page context to be used in the cache's queries /// /// Document page to become current in the context ///Reference to object compatible with IDisposable to re-initialize page context internal IDisposable SetDocumentArrangeContext(FlowDocumentPage currentPage) { return (new DocumentArrangeContext(this, currentPage) as IDisposable); } ////// Sets current page context to be used in the cache's queries /// /// Document page to become current in the context ///Reference to object compatible with IDisposable to re-initialize page context internal IDisposable SetDocumentVisualValidationContext(FlowDocumentPage currentPage) { return (new DocumentVisualValidationContext(this, currentPage) as IDisposable); } ////// Detects if illegal tree change operation has been performed, but hidden by external /// code through try-catch statement. /// internal void DetectInvalidOperation() { if (_illegalTreeChangeDetected) { throw new InvalidOperationException(SR.Get(SRID.IllegalTreeChangeDetectedPostAction)); } } ////// Notes the fact that world has changed while in measure / arrange. /// internal void OnInvalidOperationDetected() { if (_currentPage != null) { _illegalTreeChangeDetected = true; } } ////// Invalidate format caches accumulated in the NameTable. /// internal void InvalidateFormatCache(bool destroyStructure) { if (_section != null) { _section.InvalidateFormatCache(); _destroyStructure = _destroyStructure || destroyStructure; // Formatting caches are acquired during page formatting (full or incremental). // But since there is no DTR available, need to force reformatting // to reacquire formatting caches. _forceReformat = true; } } ////// Add new DirtyTextRange. /// /// New DTR being added. internal void AddDirtyTextRange(DirtyTextRange dtr) { if (_dtrs == null) { _dtrs = new DtrList(); } _dtrs.Merge(dtr); } ////// Retrieve list of dtrs from range. /// DTR StartIndex for each dtr returned is scaled to be relative to dcpNew, no other translation required. /// /// Distance from the beginning of textContainer after all tree changes /// Number of characters in the range, but before any tree changes ///List of DRTs for specified range. internal DtrList DtrsFromRange(int dcpNew, int cchOld) { return (_dtrs != null) ? _dtrs.DtrsFromRange(dcpNew, cchOld) : null; } ////// Clear update info. /// /// Destroy structure cache. internal void ClearUpdateInfo(bool destroyStructureCache) { _dtrs = null; _forceReformat = false; _destroyStructure = false; /* * Have to make sure the ptsContext is not disposed * as the resulting call to ReleaseHandle will throw an exception. * * This is possible when the dispatcher.Shutdown event fires before * the Visibility changed event fires. **/ if (_section != null && !_ptsContext.Disposed) { if (destroyStructureCache) { _section.DestroyStructure(); } _section.ClearUpdateInfo(); } } ////// This method is called after user input. /// Temporarily drop our background layout time slice to cut down on /// latency. /// internal void ThrottleBackgroundFormatting() { _backgroundFormatInfo.ThrottleBackgroundFormatting(); } #endregion Internal Methods // ------------------------------------------------------------------ // // Internal Properties // // ------------------------------------------------------------------ #region Internal Properties ////// The DependencyObject supplying property values for this cache. /// ////// Typically PropertyOwner == FormattingOwner. However, when content /// is hosted by TextBox or RichTextBox, we want to read property values /// from the control, not FlowDocument. /// internal DependencyObject PropertyOwner { get { return _textContainer.Parent; } } ////// The DependencyObject whose structure is represented by this cache. /// internal FlowDocument FormattingOwner { get { return _owner; } } ////// PTS section object. /// internal Section Section { get { EnsurePtsContext(); return _section; } } ////// Hyphenator /// internal NaturalLanguageHyphenator Hyphenator { get { EnsureHyphenator(); return _hyphenator; } } ////// Context used to communicate with PTS component. /// internal PtsContext PtsContext { get { EnsurePtsContext(); return _ptsContext; } } ////// Context used to communicate with PTS component. /// internal DocumentFormatContext CurrentFormatContext { get { return _documentFormatContext; } } ////// Context used to communicate with PTS component. /// internal DocumentArrangeContext CurrentArrangeContext { get { return _documentArrangeContext; } } ////// TextFormatter host. /// internal TextFormatterHost TextFormatterHost { get { EnsurePtsContext(); return _textFormatterHost; } } ////// TextContainer exposing access to the content. /// internal TextContainer TextContainer { get { return _textContainer; } } ////// TextContainer exposing access to the content. /// internal FlowDirection PageFlowDirection { get { return _pageFlowDirection; } set { _pageFlowDirection = value; } } ////// Force content reformatting? /// internal bool ForceReformat { get { return _forceReformat; } set { _forceReformat = value; } } ////// destroy name table on reformatting? /// internal bool DestroyStructure { get { return _destroyStructure; } } ////// DTRs list. /// internal DtrList DtrList { get { return _dtrs; } } ////// Whether deferred visual creation is supported for the given context /// internal bool IsDeferredVisualCreationSupported { get { return _currentPage != null && !_currentPage.FinitePage; } } ////// Background formatting information /// internal BackgroundFormatInfo BackgroundFormatInfo { get { return _backgroundFormatInfo; } } ////// Is Optimal paragraph enabled for this session /// internal bool IsOptimalParagraphEnabled { get { if (PtsContext.IsOptimalParagraphEnabled) { return (bool)this.PropertyOwner.GetValue(FlowDocument.IsOptimalParagraphEnabledProperty); } return false; } } ////// Whether formatting is currently in progress. /// internal bool IsFormattingInProgress { get { return CheckFlags(Flags.FormattingInProgress); } set { SetFlags(value, Flags.FormattingInProgress); } } ////// Whether content change is currently in progress. /// internal bool IsContentChangeInProgress { get { return CheckFlags(Flags.ContentChangeInProgress); } set { SetFlags(value, Flags.ContentChangeInProgress); } } ////// Whether the first formatting was done. /// internal bool IsFormattedOnce { get { return CheckFlags(Flags.FormattedOnce); } set { SetFlags(value, Flags.FormattedOnce); } } #endregion Internal Properties // ----------------------------------------------------------------- // // Private Methods // // ------------------------------------------------------------------ #region Private Methods ////// Ensures the hyphenator exists. /// private void EnsureHyphenator() { if (_hyphenator == null) { _hyphenator = new NaturalLanguageHyphenator(); } } ////// Ensures the PtsContext exists. /// private void EnsurePtsContext() { if (_ptsContext == null) { TextFormattingMode textFormattingMode = TextOptions.GetTextFormattingMode(this.PropertyOwner); _ptsContext = new PtsContext(true, textFormattingMode); _textFormatterHost = new TextFormatterHost(_ptsContext.TextFormatter, textFormattingMode); _section = new MS.Internal.PtsHost.Section(this); } } ////// SetFlags is used to set or unset one or multiple flags. /// private void SetFlags(bool value, Flags flags) { _flags = value ? (_flags | flags) : (_flags & (~flags)); } ////// CheckFlags returns true if all of passed flags in the bitmask are set. /// private bool CheckFlags(Flags flags) { return ((_flags & flags) == flags); } #endregion Private Methods // ----------------------------------------------------------------- // // Private Fields // // ----------------------------------------------------------------- #region Private Fields ////// Owner of the content. /// private readonly FlowDocument _owner; ////// Context used to communicate with PTS. /// private PtsContext _ptsContext; ////// Root of the NameTable for PTS. Encapsulates all content of TextFlow and Cell. /// There is always one section. /// private Section _section; ////// TextContainer exposing access to the content. /// private TextContainer _textContainer; ////// TextFormatter host. /// private TextFormatterHost _textFormatterHost; ////// Currently formatted page. Valid only during measure pass. /// private FlowDocumentPage _currentPage; ////// Document Format Context - All information necessary during document formatting. Null outside of DocumentFormat. /// private DocumentFormatContext _documentFormatContext; ////// Document Arrange Context - All information necessary during document arrange. Null outside of Arrange. /// private DocumentArrangeContext _documentArrangeContext; ////// List of dirty text ranges. /// private DtrList _dtrs = null; ////// Set to private bool _illegalTreeChangeDetected; ///true if tree and / or properties were changed during document page context life time ////// Set to private bool _forceReformat; ///true if full formatting needs to be done (incremental upate is not possible). ////// Set to private bool _destroyStructure; ///true if name table should be destroyed before reformatting. ////// Info class with background format information /// private BackgroundFormatInfo _backgroundFormatInfo; ////// Flow direction for page. /// private FlowDirection _pageFlowDirection; ////// Hyphenator /// private NaturalLanguageHyphenator _hyphenator; ////// Flags reflecting various aspects of FlowDocumentPaginator's state. /// private Flags _flags; [System.Flags] private enum Flags { FormattedOnce = 0x001, // Element has been formatted at least once. ContentChangeInProgress = 0x002, // Content change is in progress. FormattingInProgress = 0x008, // Formatting operation in progress. } #endregion Private Fields // ----------------------------------------------------------------- // // Private Structures and Classes // // ------------------------------------------------------------------ #region Private Structures and Classes ////// Base helper class for setting / resetting structural cache state /// internal abstract class DocumentOperationContext { ////// Constructor /// /// Associated structural cache instance /// Document page to set internal DocumentOperationContext(StructuralCache owner, FlowDocumentPage page) { Invariant.Assert(owner != null, "Invalid owner object."); Invariant.Assert(page != null, "Invalid page object."); Invariant.Assert(owner._currentPage == null, "Page formatting reentrancy detected. Trying to create second _DocumentPageContext for the same StructuralCache."); _owner = owner; _owner._currentPage = page; _owner._illegalTreeChangeDetected = false; owner.PtsContext.Enter(); } ////// protected void Dispose() { Invariant.Assert(_owner._currentPage != null, "DocumentPageContext is already disposed."); try { _owner.PtsContext.Leave(); } finally { _owner._currentPage = null; } } ////// /// Size of document /// internal Size DocumentPageSize { get { return _owner._currentPage.Size; } } ////// Thickness of document margin /// internal Thickness DocumentPageMargin { get { return _owner._currentPage.Margin; } } ////// Owner of the _DocumentPageContext. /// protected readonly StructuralCache _owner; } ////// Document format context - holds any information needed during the formatting of a document. /// internal class DocumentFormatContext : DocumentOperationContext, IDisposable { ////// Constructor /// /// Associated structural cache instance /// Document page to set internal DocumentFormatContext(StructuralCache owner, FlowDocumentPage page) : base(owner, page) { _owner._documentFormatContext = this; } ////// void IDisposable.Dispose() { _owner._documentFormatContext = null; base.Dispose(); GC.SuppressFinalize(this); } ////// /// OnFormatLine - Adds to current line format count. /// internal void OnFormatLine() { _owner._currentPage.OnFormatLine(); } ////// PushNewPageData - Pushes new page data to the top of the stack. /// /// Size of page /// Margin of page /// Are we in Incremental Update /// Is the current page a Finite Page internal void PushNewPageData(Size pageSize, Thickness pageMargin, bool incrementalUpdate, bool finitePage) { _documentFormatInfoStack.Push(_currentFormatInfo); _currentFormatInfo.PageSize = pageSize; _currentFormatInfo.PageMargin = pageMargin; _currentFormatInfo.IncrementalUpdate = incrementalUpdate; _currentFormatInfo.FinitePage = finitePage; } ////// PopPageData - Pops page data from top of stack. /// internal void PopPageData() { _currentFormatInfo = _documentFormatInfoStack.Pop(); } ////// Height of page /// internal double PageHeight { get { return _currentFormatInfo.PageSize.Height; } } ////// Width of page /// internal double PageWidth { get { return _currentFormatInfo.PageSize.Width; } } ////// PageSize as a size /// internal Size PageSize { get { return _currentFormatInfo.PageSize; } } ////// Margin in page. /// internal Thickness PageMargin { get { return _currentFormatInfo.PageMargin; } } ////// Incremental update mode /// internal bool IncrementalUpdate { get { return _currentFormatInfo.IncrementalUpdate; } } ////// Is Finite or Bottomless Page /// internal bool FinitePage { get { return _currentFormatInfo.FinitePage; } } ////// Rectangle of current page in TextDpi /// internal PTS.FSRECT PageRect { get { return new PTS.FSRECT(new Rect(0, 0, PageWidth, PageHeight)); } } ////// Rectangle of margin in TextDpi /// internal PTS.FSRECT PageMarginRect { get { return new PTS.FSRECT(new Rect(PageMargin.Left, PageMargin.Top, PageSize.Width - PageMargin.Left - PageMargin.Right, PageSize.Height - PageMargin.Top - PageMargin.Bottom)); } } ////// DependentMax used for invalidation calculations /// internal TextPointer DependentMax { set { _owner._currentPage.DependentMax = value; } } private struct DocumentFormatInfo { internal Size PageSize; internal Thickness PageMargin; internal bool IncrementalUpdate; internal bool FinitePage; }; private DocumentFormatInfo _currentFormatInfo; private Stack_documentFormatInfoStack = new Stack (); } /// /// Document arrange context - holds any information needed during the arrange of a document. /// internal class DocumentArrangeContext : DocumentOperationContext, IDisposable { ////// Constructor /// /// Associated structural cache instance /// Document page to set internal DocumentArrangeContext(StructuralCache owner, FlowDocumentPage page) : base(owner, page) { _owner._documentArrangeContext = this; } ////// PushNewPageData - Pushes new page data to the top of the stack. /// /// Page context we were formatted in /// Rect of current column /// Is the current page a Finite Page internal void PushNewPageData(PageContext pageContext, PTS.FSRECT columnRect, bool finitePage) { _documentArrangeInfoStack.Push(_currentArrangeInfo); _currentArrangeInfo.PageContext = pageContext; _currentArrangeInfo.ColumnRect = columnRect; _currentArrangeInfo.FinitePage = finitePage; } ////// PopPageData - Pops page data from top of stack. /// internal void PopPageData() { _currentArrangeInfo = _documentArrangeInfoStack.Pop(); } ////// void IDisposable.Dispose() { GC.SuppressFinalize(this); _owner._documentArrangeContext = null; base.Dispose(); } ////// /// Page Context (used to register/unregister floating elements) /// internal PageContext PageContext { get { return _currentArrangeInfo.PageContext; } } ////// Rectangle of current column /// internal PTS.FSRECT ColumnRect { get { return _currentArrangeInfo.ColumnRect; } } ////// Is current page Finite /// internal bool FinitePage { get { return _currentArrangeInfo.FinitePage; } } private struct DocumentArrangeInfo { internal PageContext PageContext; internal PTS.FSRECT ColumnRect; internal bool FinitePage; }; private DocumentArrangeInfo _currentArrangeInfo; private Stack_documentArrangeInfoStack = new Stack (); } /// /// Document visual validation context - holds any information needed during the visual validation of a document. /// internal class DocumentVisualValidationContext : DocumentOperationContext, IDisposable { ////// Constructor /// /// Associated structural cache instance /// Document page to set internal DocumentVisualValidationContext(StructuralCache owner, FlowDocumentPage page) : base(owner, page) { } ////// void IDisposable.Dispose() { GC.SuppressFinalize(this); base.Dispose(); } } #endregion Private Structures and Classes } } // 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: PTS structural cache related data. // // History: // 06/03/2003 : olego - Created // //--------------------------------------------------------------------------- using MS.Internal.Text; using MS.Internal.PtsHost.UnsafeNativeMethods; using MS.Utility; using System; using System.Collections.Generic; using System.Diagnostics; using System.Globalization; using System.Windows; using System.Windows.Media; using System.Windows.Documents; namespace MS.Internal.PtsHost { ////// PTS structural cache related data /// internal sealed class StructuralCache { //----------------------------------------------------- // // Constructors // //----------------------------------------------------- #region Constructors ////// Structural Cache contructor. /// /// Owner of the conent /// TextContainer representing content internal StructuralCache(FlowDocument owner, TextContainer textContainer) { Invariant.Assert(owner != null); Invariant.Assert(textContainer != null); Invariant.Assert(textContainer.Parent != null); _owner = owner; _textContainer = textContainer; _backgroundFormatInfo = new BackgroundFormatInfo(this); } ////// Finalizer /// ~StructuralCache() { // Notify the PtsCache about the fact that PtsContext needs to be destroyed. // NOTE: It is safe to access PtsContext, because the PtsContext // does not have a finalizer. if (_ptsContext != null) { PtsCache.ReleaseContext(_ptsContext); } } #endregion Constructors //------------------------------------------------------ // // Internal Methods // //----------------------------------------------------- #region Internal Methods ////// Sets current page context to be used in the cache's queries /// /// Document page to become current in the context ///Reference to object compatible with IDisposable to re-initialize page context internal IDisposable SetDocumentFormatContext(FlowDocumentPage currentPage) { if (!CheckFlags(Flags.FormattedOnce)) { SetFlags(true, Flags.FormattedOnce); _owner.InitializeForFirstFormatting(); } return (new DocumentFormatContext(this, currentPage) as IDisposable); } ////// Sets current page context to be used in the cache's queries /// /// Document page to become current in the context ///Reference to object compatible with IDisposable to re-initialize page context internal IDisposable SetDocumentArrangeContext(FlowDocumentPage currentPage) { return (new DocumentArrangeContext(this, currentPage) as IDisposable); } ////// Sets current page context to be used in the cache's queries /// /// Document page to become current in the context ///Reference to object compatible with IDisposable to re-initialize page context internal IDisposable SetDocumentVisualValidationContext(FlowDocumentPage currentPage) { return (new DocumentVisualValidationContext(this, currentPage) as IDisposable); } ////// Detects if illegal tree change operation has been performed, but hidden by external /// code through try-catch statement. /// internal void DetectInvalidOperation() { if (_illegalTreeChangeDetected) { throw new InvalidOperationException(SR.Get(SRID.IllegalTreeChangeDetectedPostAction)); } } ////// Notes the fact that world has changed while in measure / arrange. /// internal void OnInvalidOperationDetected() { if (_currentPage != null) { _illegalTreeChangeDetected = true; } } ////// Invalidate format caches accumulated in the NameTable. /// internal void InvalidateFormatCache(bool destroyStructure) { if (_section != null) { _section.InvalidateFormatCache(); _destroyStructure = _destroyStructure || destroyStructure; // Formatting caches are acquired during page formatting (full or incremental). // But since there is no DTR available, need to force reformatting // to reacquire formatting caches. _forceReformat = true; } } ////// Add new DirtyTextRange. /// /// New DTR being added. internal void AddDirtyTextRange(DirtyTextRange dtr) { if (_dtrs == null) { _dtrs = new DtrList(); } _dtrs.Merge(dtr); } ////// Retrieve list of dtrs from range. /// DTR StartIndex for each dtr returned is scaled to be relative to dcpNew, no other translation required. /// /// Distance from the beginning of textContainer after all tree changes /// Number of characters in the range, but before any tree changes ///List of DRTs for specified range. internal DtrList DtrsFromRange(int dcpNew, int cchOld) { return (_dtrs != null) ? _dtrs.DtrsFromRange(dcpNew, cchOld) : null; } ////// Clear update info. /// /// Destroy structure cache. internal void ClearUpdateInfo(bool destroyStructureCache) { _dtrs = null; _forceReformat = false; _destroyStructure = false; /* * Have to make sure the ptsContext is not disposed * as the resulting call to ReleaseHandle will throw an exception. * * This is possible when the dispatcher.Shutdown event fires before * the Visibility changed event fires. **/ if (_section != null && !_ptsContext.Disposed) { if (destroyStructureCache) { _section.DestroyStructure(); } _section.ClearUpdateInfo(); } } ////// This method is called after user input. /// Temporarily drop our background layout time slice to cut down on /// latency. /// internal void ThrottleBackgroundFormatting() { _backgroundFormatInfo.ThrottleBackgroundFormatting(); } #endregion Internal Methods // ------------------------------------------------------------------ // // Internal Properties // // ------------------------------------------------------------------ #region Internal Properties ////// The DependencyObject supplying property values for this cache. /// ////// Typically PropertyOwner == FormattingOwner. However, when content /// is hosted by TextBox or RichTextBox, we want to read property values /// from the control, not FlowDocument. /// internal DependencyObject PropertyOwner { get { return _textContainer.Parent; } } ////// The DependencyObject whose structure is represented by this cache. /// internal FlowDocument FormattingOwner { get { return _owner; } } ////// PTS section object. /// internal Section Section { get { EnsurePtsContext(); return _section; } } ////// Hyphenator /// internal NaturalLanguageHyphenator Hyphenator { get { EnsureHyphenator(); return _hyphenator; } } ////// Context used to communicate with PTS component. /// internal PtsContext PtsContext { get { EnsurePtsContext(); return _ptsContext; } } ////// Context used to communicate with PTS component. /// internal DocumentFormatContext CurrentFormatContext { get { return _documentFormatContext; } } ////// Context used to communicate with PTS component. /// internal DocumentArrangeContext CurrentArrangeContext { get { return _documentArrangeContext; } } ////// TextFormatter host. /// internal TextFormatterHost TextFormatterHost { get { EnsurePtsContext(); return _textFormatterHost; } } ////// TextContainer exposing access to the content. /// internal TextContainer TextContainer { get { return _textContainer; } } ////// TextContainer exposing access to the content. /// internal FlowDirection PageFlowDirection { get { return _pageFlowDirection; } set { _pageFlowDirection = value; } } ////// Force content reformatting? /// internal bool ForceReformat { get { return _forceReformat; } set { _forceReformat = value; } } ////// destroy name table on reformatting? /// internal bool DestroyStructure { get { return _destroyStructure; } } ////// DTRs list. /// internal DtrList DtrList { get { return _dtrs; } } ////// Whether deferred visual creation is supported for the given context /// internal bool IsDeferredVisualCreationSupported { get { return _currentPage != null && !_currentPage.FinitePage; } } ////// Background formatting information /// internal BackgroundFormatInfo BackgroundFormatInfo { get { return _backgroundFormatInfo; } } ////// Is Optimal paragraph enabled for this session /// internal bool IsOptimalParagraphEnabled { get { if (PtsContext.IsOptimalParagraphEnabled) { return (bool)this.PropertyOwner.GetValue(FlowDocument.IsOptimalParagraphEnabledProperty); } return false; } } ////// Whether formatting is currently in progress. /// internal bool IsFormattingInProgress { get { return CheckFlags(Flags.FormattingInProgress); } set { SetFlags(value, Flags.FormattingInProgress); } } ////// Whether content change is currently in progress. /// internal bool IsContentChangeInProgress { get { return CheckFlags(Flags.ContentChangeInProgress); } set { SetFlags(value, Flags.ContentChangeInProgress); } } ////// Whether the first formatting was done. /// internal bool IsFormattedOnce { get { return CheckFlags(Flags.FormattedOnce); } set { SetFlags(value, Flags.FormattedOnce); } } #endregion Internal Properties // ----------------------------------------------------------------- // // Private Methods // // ------------------------------------------------------------------ #region Private Methods ////// Ensures the hyphenator exists. /// private void EnsureHyphenator() { if (_hyphenator == null) { _hyphenator = new NaturalLanguageHyphenator(); } } ////// Ensures the PtsContext exists. /// private void EnsurePtsContext() { if (_ptsContext == null) { TextFormattingMode textFormattingMode = TextOptions.GetTextFormattingMode(this.PropertyOwner); _ptsContext = new PtsContext(true, textFormattingMode); _textFormatterHost = new TextFormatterHost(_ptsContext.TextFormatter, textFormattingMode); _section = new MS.Internal.PtsHost.Section(this); } } ////// SetFlags is used to set or unset one or multiple flags. /// private void SetFlags(bool value, Flags flags) { _flags = value ? (_flags | flags) : (_flags & (~flags)); } ////// CheckFlags returns true if all of passed flags in the bitmask are set. /// private bool CheckFlags(Flags flags) { return ((_flags & flags) == flags); } #endregion Private Methods // ----------------------------------------------------------------- // // Private Fields // // ----------------------------------------------------------------- #region Private Fields ////// Owner of the content. /// private readonly FlowDocument _owner; ////// Context used to communicate with PTS. /// private PtsContext _ptsContext; ////// Root of the NameTable for PTS. Encapsulates all content of TextFlow and Cell. /// There is always one section. /// private Section _section; ////// TextContainer exposing access to the content. /// private TextContainer _textContainer; ////// TextFormatter host. /// private TextFormatterHost _textFormatterHost; ////// Currently formatted page. Valid only during measure pass. /// private FlowDocumentPage _currentPage; ////// Document Format Context - All information necessary during document formatting. Null outside of DocumentFormat. /// private DocumentFormatContext _documentFormatContext; ////// Document Arrange Context - All information necessary during document arrange. Null outside of Arrange. /// private DocumentArrangeContext _documentArrangeContext; ////// List of dirty text ranges. /// private DtrList _dtrs = null; ////// Set to private bool _illegalTreeChangeDetected; ///true if tree and / or properties were changed during document page context life time ////// Set to private bool _forceReformat; ///true if full formatting needs to be done (incremental upate is not possible). ////// Set to private bool _destroyStructure; ///true if name table should be destroyed before reformatting. ////// Info class with background format information /// private BackgroundFormatInfo _backgroundFormatInfo; ////// Flow direction for page. /// private FlowDirection _pageFlowDirection; ////// Hyphenator /// private NaturalLanguageHyphenator _hyphenator; ////// Flags reflecting various aspects of FlowDocumentPaginator's state. /// private Flags _flags; [System.Flags] private enum Flags { FormattedOnce = 0x001, // Element has been formatted at least once. ContentChangeInProgress = 0x002, // Content change is in progress. FormattingInProgress = 0x008, // Formatting operation in progress. } #endregion Private Fields // ----------------------------------------------------------------- // // Private Structures and Classes // // ------------------------------------------------------------------ #region Private Structures and Classes ////// Base helper class for setting / resetting structural cache state /// internal abstract class DocumentOperationContext { ////// Constructor /// /// Associated structural cache instance /// Document page to set internal DocumentOperationContext(StructuralCache owner, FlowDocumentPage page) { Invariant.Assert(owner != null, "Invalid owner object."); Invariant.Assert(page != null, "Invalid page object."); Invariant.Assert(owner._currentPage == null, "Page formatting reentrancy detected. Trying to create second _DocumentPageContext for the same StructuralCache."); _owner = owner; _owner._currentPage = page; _owner._illegalTreeChangeDetected = false; owner.PtsContext.Enter(); } ////// protected void Dispose() { Invariant.Assert(_owner._currentPage != null, "DocumentPageContext is already disposed."); try { _owner.PtsContext.Leave(); } finally { _owner._currentPage = null; } } ////// /// Size of document /// internal Size DocumentPageSize { get { return _owner._currentPage.Size; } } ////// Thickness of document margin /// internal Thickness DocumentPageMargin { get { return _owner._currentPage.Margin; } } ////// Owner of the _DocumentPageContext. /// protected readonly StructuralCache _owner; } ////// Document format context - holds any information needed during the formatting of a document. /// internal class DocumentFormatContext : DocumentOperationContext, IDisposable { ////// Constructor /// /// Associated structural cache instance /// Document page to set internal DocumentFormatContext(StructuralCache owner, FlowDocumentPage page) : base(owner, page) { _owner._documentFormatContext = this; } ////// void IDisposable.Dispose() { _owner._documentFormatContext = null; base.Dispose(); GC.SuppressFinalize(this); } ////// /// OnFormatLine - Adds to current line format count. /// internal void OnFormatLine() { _owner._currentPage.OnFormatLine(); } ////// PushNewPageData - Pushes new page data to the top of the stack. /// /// Size of page /// Margin of page /// Are we in Incremental Update /// Is the current page a Finite Page internal void PushNewPageData(Size pageSize, Thickness pageMargin, bool incrementalUpdate, bool finitePage) { _documentFormatInfoStack.Push(_currentFormatInfo); _currentFormatInfo.PageSize = pageSize; _currentFormatInfo.PageMargin = pageMargin; _currentFormatInfo.IncrementalUpdate = incrementalUpdate; _currentFormatInfo.FinitePage = finitePage; } ////// PopPageData - Pops page data from top of stack. /// internal void PopPageData() { _currentFormatInfo = _documentFormatInfoStack.Pop(); } ////// Height of page /// internal double PageHeight { get { return _currentFormatInfo.PageSize.Height; } } ////// Width of page /// internal double PageWidth { get { return _currentFormatInfo.PageSize.Width; } } ////// PageSize as a size /// internal Size PageSize { get { return _currentFormatInfo.PageSize; } } ////// Margin in page. /// internal Thickness PageMargin { get { return _currentFormatInfo.PageMargin; } } ////// Incremental update mode /// internal bool IncrementalUpdate { get { return _currentFormatInfo.IncrementalUpdate; } } ////// Is Finite or Bottomless Page /// internal bool FinitePage { get { return _currentFormatInfo.FinitePage; } } ////// Rectangle of current page in TextDpi /// internal PTS.FSRECT PageRect { get { return new PTS.FSRECT(new Rect(0, 0, PageWidth, PageHeight)); } } ////// Rectangle of margin in TextDpi /// internal PTS.FSRECT PageMarginRect { get { return new PTS.FSRECT(new Rect(PageMargin.Left, PageMargin.Top, PageSize.Width - PageMargin.Left - PageMargin.Right, PageSize.Height - PageMargin.Top - PageMargin.Bottom)); } } ////// DependentMax used for invalidation calculations /// internal TextPointer DependentMax { set { _owner._currentPage.DependentMax = value; } } private struct DocumentFormatInfo { internal Size PageSize; internal Thickness PageMargin; internal bool IncrementalUpdate; internal bool FinitePage; }; private DocumentFormatInfo _currentFormatInfo; private Stack_documentFormatInfoStack = new Stack (); } /// /// Document arrange context - holds any information needed during the arrange of a document. /// internal class DocumentArrangeContext : DocumentOperationContext, IDisposable { ////// Constructor /// /// Associated structural cache instance /// Document page to set internal DocumentArrangeContext(StructuralCache owner, FlowDocumentPage page) : base(owner, page) { _owner._documentArrangeContext = this; } ////// PushNewPageData - Pushes new page data to the top of the stack. /// /// Page context we were formatted in /// Rect of current column /// Is the current page a Finite Page internal void PushNewPageData(PageContext pageContext, PTS.FSRECT columnRect, bool finitePage) { _documentArrangeInfoStack.Push(_currentArrangeInfo); _currentArrangeInfo.PageContext = pageContext; _currentArrangeInfo.ColumnRect = columnRect; _currentArrangeInfo.FinitePage = finitePage; } ////// PopPageData - Pops page data from top of stack. /// internal void PopPageData() { _currentArrangeInfo = _documentArrangeInfoStack.Pop(); } ////// void IDisposable.Dispose() { GC.SuppressFinalize(this); _owner._documentArrangeContext = null; base.Dispose(); } ////// /// Page Context (used to register/unregister floating elements) /// internal PageContext PageContext { get { return _currentArrangeInfo.PageContext; } } ////// Rectangle of current column /// internal PTS.FSRECT ColumnRect { get { return _currentArrangeInfo.ColumnRect; } } ////// Is current page Finite /// internal bool FinitePage { get { return _currentArrangeInfo.FinitePage; } } private struct DocumentArrangeInfo { internal PageContext PageContext; internal PTS.FSRECT ColumnRect; internal bool FinitePage; }; private DocumentArrangeInfo _currentArrangeInfo; private Stack_documentArrangeInfoStack = new Stack (); } /// /// Document visual validation context - holds any information needed during the visual validation of a document. /// internal class DocumentVisualValidationContext : DocumentOperationContext, IDisposable { ////// Constructor /// /// Associated structural cache instance /// Document page to set internal DocumentVisualValidationContext(StructuralCache owner, FlowDocumentPage page) : base(owner, page) { } ////// void IDisposable.Dispose() { GC.SuppressFinalize(this); base.Dispose(); } } #endregion Private Structures and Classes } } // 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
- ThreadInterruptedException.cs
- TileModeValidation.cs
- SchemaNotation.cs
- DesignerTransaction.cs
- MailAddress.cs
- AtomServiceDocumentSerializer.cs
- DataColumnMapping.cs
- TextEditorDragDrop.cs
- MasterPageParser.cs
- ZipPackagePart.cs
- MimeTextImporter.cs
- SingleTagSectionHandler.cs
- NonClientArea.cs
- DesignerLabelAdapter.cs
- HttpCacheVaryByContentEncodings.cs
- FragmentQueryProcessor.cs
- NamedPipeTransportSecurity.cs
- PixelFormatConverter.cs
- DataGridrowEditEndingEventArgs.cs
- SystemIPInterfaceProperties.cs
- Monitor.cs
- DataGridViewCellStyleChangedEventArgs.cs
- TypeSource.cs
- WindowsFormsHost.cs
- SqlStream.cs
- ConnectorMovedEventArgs.cs
- DecoderExceptionFallback.cs
- DeclarativeCatalogPart.cs
- Group.cs
- WindowsPrincipal.cs
- XmlDataSource.cs
- ComponentResourceKey.cs
- HtmlElementErrorEventArgs.cs
- InternalsVisibleToAttribute.cs
- TraceInternal.cs
- TypedTableBaseExtensions.cs
- LinqDataSourceHelper.cs
- PersonalizableAttribute.cs
- X509ChainElement.cs
- IndexOutOfRangeException.cs
- COM2IPerPropertyBrowsingHandler.cs
- JobDuplex.cs
- SqlBooleanizer.cs
- CompilerWrapper.cs
- ToolStripDesignerAvailabilityAttribute.cs
- CroppedBitmap.cs
- ReferencedType.cs
- Track.cs
- X509IssuerSerialKeyIdentifierClause.cs
- EntityDataSourceMemberPath.cs
- DataSourceCacheDurationConverter.cs
- TypeElement.cs
- RouteItem.cs
- TablePatternIdentifiers.cs
- HttpWebRequest.cs
- PassportAuthenticationModule.cs
- EntityViewContainer.cs
- WorkBatch.cs
- StrokeCollectionDefaultValueFactory.cs
- HiddenField.cs
- SoapCommonClasses.cs
- IpcClientChannel.cs
- UTF8Encoding.cs
- PrinterSettings.cs
- KeyInfo.cs
- SignedXml.cs
- SiteMapDataSourceView.cs
- DataControlButton.cs
- ProtocolsInstallComponent.cs
- nulltextnavigator.cs
- StickyNoteAnnotations.cs
- CollectionBase.cs
- DocumentPageHost.cs
- DiagnosticsConfiguration.cs
- FormViewModeEventArgs.cs
- SecurityPermission.cs
- PageBuildProvider.cs
- FlowStep.cs
- ThreadAttributes.cs
- WrappedIUnknown.cs
- ZipIOLocalFileHeader.cs
- wgx_render.cs
- CookieParameter.cs
- Graph.cs
- FormatSettings.cs
- ApplicationInfo.cs
- CacheForPrimitiveTypes.cs
- InputReferenceExpression.cs
- ObjectDataSourceEventArgs.cs
- XmlAnyAttributeAttribute.cs
- SubtreeProcessor.cs
- FunctionOverloadResolver.cs
- ImageAutomationPeer.cs
- xamlnodes.cs
- QuotedPairReader.cs
- CheckBoxRenderer.cs
- ThicknessAnimation.cs
- CutCopyPasteHelper.cs
- StdValidatorsAndConverters.cs
- CheckPair.cs