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 / PtsHost / StructuralCache.cs / 2 / 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.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;
_ptsContext = new PtsContext(true);
_textFormatterHost = new TextFormatterHost(_ptsContext.TextFormatter);
_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)
{
_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;
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
{
return _section;
}
set
{
_section = value;
}
}
///
/// Hyphenator
///
internal NaturalLanguageHyphenator Hyphenator
{
get
{
EnsureHyphenator();
return _hyphenator;
}
}
///
/// Context used to communicate with PTS component.
///
internal PtsContext PtsContext
{
get
{
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
{
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();
}
}
///
/// 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 readonly 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 readonly 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 true if tree and / or properties were changed during document page context life time
///
private bool _illegalTreeChangeDetected;
///
/// Set to true if full formatting needs to be done (incremental upate is not possible).
///
private bool _forceReformat;
///
/// Set to true if name table should be destroyed before reformatting.
///
private bool _destroyStructure;
///
/// 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();
}
///
/// 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()
{
_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() { 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.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;
_ptsContext = new PtsContext(true);
_textFormatterHost = new TextFormatterHost(_ptsContext.TextFormatter);
_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)
{
_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;
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
{
return _section;
}
set
{
_section = value;
}
}
///
/// Hyphenator
///
internal NaturalLanguageHyphenator Hyphenator
{
get
{
EnsureHyphenator();
return _hyphenator;
}
}
///
/// Context used to communicate with PTS component.
///
internal PtsContext PtsContext
{
get
{
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
{
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();
}
}
///
/// 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 readonly 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 readonly 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 true if tree and / or properties were changed during document page context life time
///
private bool _illegalTreeChangeDetected;
///
/// Set to true if full formatting needs to be done (incremental upate is not possible).
///
private bool _forceReformat;
///
/// Set to true if name table should be destroyed before reformatting.
///
private bool _destroyStructure;
///
/// 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();
}
///
/// 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()
{
_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() { 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
- ScriptResourceHandler.cs
- PixelFormats.cs
- SectionRecord.cs
- SubpageParagraph.cs
- CachingHintValidation.cs
- PackUriHelper.cs
- SymbolMethod.cs
- XmlSchemaComplexContent.cs
- PathSegment.cs
- AdornerLayer.cs
- ObjectResult.cs
- HttpFormatExtensions.cs
- TdsParserHelperClasses.cs
- Vector3D.cs
- regiisutil.cs
- ElementHostAutomationPeer.cs
- DataBinder.cs
- ColumnMapTranslator.cs
- ConnectionPoint.cs
- MatrixCamera.cs
- NativeMethods.cs
- MulticastNotSupportedException.cs
- NetworkAddressChange.cs
- XmlSchemaChoice.cs
- namescope.cs
- Convert.cs
- ScrollItemPatternIdentifiers.cs
- ReaderWriterLock.cs
- Item.cs
- RelOps.cs
- CompilerError.cs
- RetrieveVirtualItemEventArgs.cs
- MaterialCollection.cs
- CustomError.cs
- CapabilitiesAssignment.cs
- ValidatedControlConverter.cs
- HMACSHA512.cs
- IISUnsafeMethods.cs
- StylusCollection.cs
- Quad.cs
- ProcessInfo.cs
- WebConfigurationManager.cs
- SqlDataSourceSelectingEventArgs.cs
- RegexTree.cs
- NamedObject.cs
- TextSerializer.cs
- KeyInterop.cs
- UserPreferenceChangedEventArgs.cs
- SystemResourceKey.cs
- HMACSHA512.cs
- UnauthorizedWebPart.cs
- LassoHelper.cs
- EntityTemplateUserControl.cs
- RequestCacheManager.cs
- RuntimeArgumentHandle.cs
- ProviderCommandInfoUtils.cs
- Type.cs
- FunctionDetailsReader.cs
- FileAuthorizationModule.cs
- Rights.cs
- _DisconnectOverlappedAsyncResult.cs
- GeometryGroup.cs
- mediaeventargs.cs
- Color.cs
- ContainerSelectorBehavior.cs
- MediaPlayerState.cs
- InputBinder.cs
- NTAccount.cs
- tibetanshape.cs
- PageParser.cs
- UserThread.cs
- PackageRelationshipSelector.cs
- ResourcePropertyMemberCodeDomSerializer.cs
- Rotation3DAnimationUsingKeyFrames.cs
- HideDisabledControlAdapter.cs
- _SafeNetHandles.cs
- UIElement.cs
- QilLiteral.cs
- DataRelation.cs
- ExpandableObjectConverter.cs
- GridToolTip.cs
- UseAttributeSetsAction.cs
- MouseDevice.cs
- SqlInternalConnectionSmi.cs
- Console.cs
- KeyboardDevice.cs
- SupportsEventValidationAttribute.cs
- DataGridBeginningEditEventArgs.cs
- ParseChildrenAsPropertiesAttribute.cs
- ControlTemplate.cs
- WindowsComboBox.cs
- ChtmlCommandAdapter.cs
- DataGridViewRowsAddedEventArgs.cs
- clipboard.cs
- CharUnicodeInfo.cs
- DbParameterCollection.cs
- ConfigurationElementCollection.cs
- SerializationException.cs
- localization.cs
- TextEffect.cs