Code:
/ 4.0 / 4.0 / DEVDIV_TFS / Dev10 / Releases / RTMRel / wpf / src / Framework / MS / Internal / PtsHost / BreakRecordTable.cs / 1305600 / BreakRecordTable.cs
//---------------------------------------------------------------------------- // // Copyright (C) Microsoft Corporation. All rights reserved. // // Description: BreakRecordTable manages cached informaion bout pages and // break records of FlowDocument contnet. // // History: // 01/24/2004 : [....] - Created // //--------------------------------------------------------------------------- using System; // WeakReference, ... using System.Collections.Generic; // Listusing System.Collections.ObjectModel; // ReadOnlyCollection using System.Windows.Documents; // FlowDocument, TextPointer using MS.Internal.Documents; // TextDocumentView namespace MS.Internal.PtsHost { /// /// BreakRecordTable manages cached informaion bout pages and break /// records of FlowDocument contnet. /// internal sealed class BreakRecordTable { //------------------------------------------------------------------- // // Constructors // //------------------------------------------------------------------- #region Constructors ////// Constructor. /// /// Ownder of the BreakRecordTable. internal BreakRecordTable(FlowDocumentPaginator owner) { _owner = owner; _breakRecords = new List(); } #endregion Constructors //-------------------------------------------------------------------- // // Internal Methods // //------------------------------------------------------------------- #region Internal Methods /// /// Retrieves input BreakRecord for given PageNumber. /// /// /// Page index indicating which input BreakRecord should be retrieved. ///Input BreakRecord for given PageNumber. internal PageBreakRecord GetPageBreakRecord(int pageNumber) { PageBreakRecord breakRecord = null; Invariant.Assert(pageNumber >= 0 && pageNumber <= _breakRecords.Count, "Invalid PageNumber."); // Input BreakRecord for the first page is always NULL. // For the rest of pages, go to the entry preceding requested index and // return the output BreakRecord. if (pageNumber > 0) { Invariant.Assert(_breakRecords[pageNumber - 1] != null, "Invalid BreakRecordTable entry."); breakRecord = _breakRecords[pageNumber - 1].BreakRecord; Invariant.Assert(breakRecord != null, "BreakRecord can be null only for the first page."); } return breakRecord; } ////// Retrieves cached DocumentPage for given PageNumber. /// /// /// Page index indicating which cached DocumentPage should be retrieved. /// ///Cached DocumentPage for given PageNumber. internal FlowDocumentPage GetCachedDocumentPage(int pageNumber) { WeakReference pageRef; FlowDocumentPage documentPage = null; if (pageNumber < _breakRecords.Count) { Invariant.Assert(_breakRecords[pageNumber] != null, "Invalid BreakRecordTable entry."); pageRef = _breakRecords[pageNumber].DocumentPage; if (pageRef != null) { documentPage = pageRef.Target as FlowDocumentPage; if (documentPage != null && documentPage.IsDisposed) { documentPage = null; } } } return documentPage; } ////// Retrieves PageNumber for specified ContentPosition. /// /// /// Represents content position for which PageNumber is requested. /// Starting index for search process. ////// Returns true, if successfull. 'pageNumber' is updated with actual /// page number that contains specified ContentPosition. /// Returns false, if BreakRecordTable is missing information about /// page that contains specified ContentPosition. 'pageNumber' /// is updated with the last investigated page number. /// internal bool GetPageNumberForContentPosition(TextPointer contentPosition, ref int pageNumber) { bool foundPageNumber = false; ReadOnlyCollectiontextSegments; Invariant.Assert(pageNumber >= 0 && pageNumber <= _breakRecords.Count, "Invalid PageNumber."); // Iterate through entries in the BreakRecordTable (starting from specified index) // and look for page that contains specified ContentPosition. // NOTE: For each cached page collection of TextSegments is stored to // optimize this search. while (pageNumber < _breakRecords.Count) { Invariant.Assert(_breakRecords[pageNumber] != null, "Invalid BreakRecordTable entry."); textSegments = _breakRecords[pageNumber].TextSegments; if (textSegments != null) { if (TextDocumentView.Contains(contentPosition, textSegments)) { foundPageNumber = true; break; } } else { // There is no information about this page. break; } ++pageNumber; } return foundPageNumber; } /// /// Layout of entire content has been affected. /// internal void OnInvalidateLayout() { if (_breakRecords.Count > 0) { // Destroy all affected BreakRecords. InvalidateBreakRecords(0, _breakRecords.Count); // Initiate the next async operation. _owner.InitiateNextAsyncOperation(); // Raise PagesChanged event. Start with the first page and set // count to Int.Max/2, because somebody might want to display a page // that wasn't available before, but will be right now. _owner.OnPagesChanged(0, int.MaxValue/2); } } ////// Layout for specified range has been affected. /// /// Start of the affected content range. /// End of the affected content range. internal void OnInvalidateLayout(ITextPointer start, ITextPointer end) { int pageStart, pageCount; if (_breakRecords.Count > 0) { // Get range of affected pages and dispose them GetAffectedPages(start, end, out pageStart, out pageCount); // Currently there is no possibility to do partial invalidation // of BreakRecordTable, so always extend pageCount to the end // of BreakRecordTable. pageCount = _breakRecords.Count - pageStart; if (pageCount > 0) { // Destroy all affected BreakRecords. InvalidateBreakRecords(pageStart, pageCount); // Initiate the next async operation. _owner.InitiateNextAsyncOperation(); // Raise PagesChanged event. Start with the first affected page and set // count to Int.Max/2, because somebody might want to display a page // that wasn't available before, but will be right now. _owner.OnPagesChanged(pageStart, int.MaxValue/2); } } } ////// Rendering of entire content has been affected. /// internal void OnInvalidateRender() { if (_breakRecords.Count > 0) { // Dispose all existing pages. DisposePages(0, _breakRecords.Count); // Raise PagesChanged event. Start with the first page and set // count to this.Count (number of pages have not been changed). _owner.OnPagesChanged(0, _breakRecords.Count); } } ////// Rendering for specified range has been affected. /// /// Start of the affected content range. /// End of the affected content range. internal void OnInvalidateRender(ITextPointer start, ITextPointer end) { int pageStart, pageCount; if (_breakRecords.Count > 0) { // Get range of affected pages and dispose them. GetAffectedPages(start, end, out pageStart, out pageCount); if (pageCount > 0) { // Dispose all affected pages. DisposePages(pageStart, pageCount); // Raise PagesChanged event. _owner.OnPagesChanged(pageStart, pageCount); } } } ////// Updates entry of BreakRecordTable with new data. /// /// Index of the entry to update. /// DocumentPage object that has been just created. /// Output BreakRecord for created page. /// Last content position that can affect the output break record. internal void UpdateEntry(int pageNumber, FlowDocumentPage page, PageBreakRecord brOut, TextPointer dependentMax) { ITextView textView; BreakRecordTableEntry entry; bool isClean; Invariant.Assert(pageNumber >= 0 && pageNumber <= _breakRecords.Count, "The previous BreakRecord does not exist."); Invariant.Assert(page != null && page != DocumentPage.Missing, "Cannot update BRT with an invalid document page."); // Get TextView for DocumentPage. This TextView is used to access list of // content ranges. Those serve as optimalization in finding affeceted pages. textView = (ITextView)((IServiceProvider)page).GetService(typeof(ITextView)); Invariant.Assert(textView != null, "Cannot access ITextView for FlowDocumentPage."); // Get current state of BreakRecordTable isClean = this.IsClean; // Add new entry into BreakRecordTable entry = new BreakRecordTableEntry(); entry.BreakRecord = brOut; entry.DocumentPage = new WeakReference(page); entry.TextSegments = textView.TextSegments; entry.DependentMax = dependentMax; if (pageNumber == _breakRecords.Count) { _breakRecords.Add(entry); // Raise PaginationProgress event only if we did not have valid // entry for specified page number. _owner.OnPaginationProgress(pageNumber, 1); } else { // If old Page and/or BreakRecord are not changing, do not dispose them. if (_breakRecords[pageNumber].BreakRecord != null && _breakRecords[pageNumber].BreakRecord != entry.BreakRecord) { _breakRecords[pageNumber].BreakRecord.Dispose(); } if (_breakRecords[pageNumber].DocumentPage != null && _breakRecords[pageNumber].DocumentPage.Target != null && _breakRecords[pageNumber].DocumentPage.Target != entry.DocumentPage.Target) { ((FlowDocumentPage)_breakRecords[pageNumber].DocumentPage.Target).Dispose(); } _breakRecords[pageNumber] = entry; } // Raise PaginationCompleted event only if the BreakRecordTable just // become clean. if (!isClean && this.IsClean) { _owner.OnPaginationCompleted(); } } ////// Determines whenever input BreakRecord for given page number exists. /// /// Page index. ///true, if BreakRecord for given page number exists. internal bool HasPageBreakRecord(int pageNumber) { Invariant.Assert(pageNumber >= 0, "Page number cannot be negative."); // For the first page, the input break record is always NULL. // For the rest of pages, it exists if the preceding entry has // non-NULL output BreakRecord. if (pageNumber == 0) return true; if (pageNumber > _breakRecords.Count) return false; Invariant.Assert(_breakRecords[pageNumber - 1] != null, "Invalid BreakRecordTable entry."); return (_breakRecords[pageNumber - 1].BreakRecord != null); } #endregion Internal Methods //-------------------------------------------------------------------- // // Internal Properties // //-------------------------------------------------------------------- #region Internal Properties ////// Current count reflecting number of known pages. /// internal int Count { get { return _breakRecords.Count; } } ////// Whether BreakRecordTable is clean. /// internal bool IsClean { get { if (_breakRecords.Count == 0) return false; Invariant.Assert(_breakRecords[_breakRecords.Count - 1] != null, "Invalid BreakRecordTable entry."); return (_breakRecords[_breakRecords.Count - 1].BreakRecord == null); } } #endregion Internal Properties //------------------------------------------------------------------- // // Private Methods // //-------------------------------------------------------------------- #region Private Methods ////// Dispose all alive pages for specified range. /// /// Index of the first page to dispose. /// Number of pages to dispose. private void DisposePages(int start, int count) { WeakReference pageRef; int index = start + count - 1; // Start from the end of BreakRecordTable Invariant.Assert(start >= 0 && start < _breakRecords.Count, "Invalid starting index for BreakRecordTable invalidation."); Invariant.Assert(start + count <= _breakRecords.Count, "Partial invalidation of BreakRecordTable is not allowed."); while (index >= start) { Invariant.Assert(_breakRecords[index] != null, "Invalid BreakRecordTable entry."); pageRef = _breakRecords[index].DocumentPage; if (pageRef != null && pageRef.Target != null) { ((FlowDocumentPage)pageRef.Target).Dispose(); } _breakRecords[index].DocumentPage = null; index--; } } ////// Destroy BreakRecordsTable entries for specified range. /// /// Index of the first entry to destroy. /// Nmber of entries to destroy. private void InvalidateBreakRecords(int start, int count) { WeakReference pageRef; int index = start + count - 1; // Start from the end of BreakRecordTable Invariant.Assert(start >= 0 && start < _breakRecords.Count, "Invalid starting index for BreakRecordTable invalidation."); Invariant.Assert(start + count == _breakRecords.Count, "Partial invalidation of BreakRecordTable is not allowed."); while (index >= start) { Invariant.Assert(_breakRecords[index] != null, "Invalid BreakRecordTable entry."); // Dispose Page and BreakRecord before removing the entry. pageRef = _breakRecords[index].DocumentPage; if (pageRef != null && pageRef.Target != null) { ((FlowDocumentPage)pageRef.Target).Dispose(); } if (_breakRecords[index].BreakRecord != null) { _breakRecords[index].BreakRecord.Dispose(); } // Remov the entry. _breakRecords.RemoveAt(index); index--; } } ////// Retrieves indices of affected pages by specified content range. /// /// Content change start position. /// Content change end position. /// The first affected page. /// Number of affected pages. private void GetAffectedPages(ITextPointer start, ITextPointer end, out int pageStart, out int pageCount) { bool affects; ReadOnlyCollectiontextSegments; TextPointer dependentMax; // Find the first affected page. pageStart = 0; while (pageStart < _breakRecords.Count) { Invariant.Assert(_breakRecords[pageStart] != null, "Invalid BreakRecordTable entry."); // If the start position is before last position affecting the output break record, // this page is affected. dependentMax = _breakRecords[pageStart].DependentMax; if (dependentMax != null) { if (start.CompareTo(dependentMax) <= 0) break; } textSegments = _breakRecords[pageStart].TextSegments; if (textSegments != null) { affects = false; foreach (TextSegment textSegment in textSegments) { if (start.CompareTo(textSegment.End) <= 0) { affects = true; break; } } if (affects) break; } else { // There is no information about this page, so assume that it is // affected. break; } ++pageStart; } // Find the last affected page // For now assume that all following pages are affected. pageCount = _breakRecords.Count - pageStart; } #endregion Private Methods //------------------------------------------------------------------- // // Private Fields // //------------------------------------------------------------------- #region Private Fields /// /// Owner of the BreakRecordTable. /// private FlowDocumentPaginator _owner; ////// Array of entries in the BreakRecordTable. /// private List_breakRecords; /// /// BreakRecordTableEntry /// private class BreakRecordTableEntry { public PageBreakRecord BreakRecord; public ReadOnlyCollectionTextSegments; public WeakReference DocumentPage; public TextPointer DependentMax; } #endregion Private Fields } } // 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: BreakRecordTable manages cached informaion bout pages and // break records of FlowDocument contnet. // // History: // 01/24/2004 : [....] - Created // //--------------------------------------------------------------------------- using System; // WeakReference, ... using System.Collections.Generic; // List using System.Collections.ObjectModel; // ReadOnlyCollection using System.Windows.Documents; // FlowDocument, TextPointer using MS.Internal.Documents; // TextDocumentView namespace MS.Internal.PtsHost { /// /// BreakRecordTable manages cached informaion bout pages and break /// records of FlowDocument contnet. /// internal sealed class BreakRecordTable { //------------------------------------------------------------------- // // Constructors // //------------------------------------------------------------------- #region Constructors ////// Constructor. /// /// Ownder of the BreakRecordTable. internal BreakRecordTable(FlowDocumentPaginator owner) { _owner = owner; _breakRecords = new List(); } #endregion Constructors //-------------------------------------------------------------------- // // Internal Methods // //------------------------------------------------------------------- #region Internal Methods /// /// Retrieves input BreakRecord for given PageNumber. /// /// /// Page index indicating which input BreakRecord should be retrieved. ///Input BreakRecord for given PageNumber. internal PageBreakRecord GetPageBreakRecord(int pageNumber) { PageBreakRecord breakRecord = null; Invariant.Assert(pageNumber >= 0 && pageNumber <= _breakRecords.Count, "Invalid PageNumber."); // Input BreakRecord for the first page is always NULL. // For the rest of pages, go to the entry preceding requested index and // return the output BreakRecord. if (pageNumber > 0) { Invariant.Assert(_breakRecords[pageNumber - 1] != null, "Invalid BreakRecordTable entry."); breakRecord = _breakRecords[pageNumber - 1].BreakRecord; Invariant.Assert(breakRecord != null, "BreakRecord can be null only for the first page."); } return breakRecord; } ////// Retrieves cached DocumentPage for given PageNumber. /// /// /// Page index indicating which cached DocumentPage should be retrieved. /// ///Cached DocumentPage for given PageNumber. internal FlowDocumentPage GetCachedDocumentPage(int pageNumber) { WeakReference pageRef; FlowDocumentPage documentPage = null; if (pageNumber < _breakRecords.Count) { Invariant.Assert(_breakRecords[pageNumber] != null, "Invalid BreakRecordTable entry."); pageRef = _breakRecords[pageNumber].DocumentPage; if (pageRef != null) { documentPage = pageRef.Target as FlowDocumentPage; if (documentPage != null && documentPage.IsDisposed) { documentPage = null; } } } return documentPage; } ////// Retrieves PageNumber for specified ContentPosition. /// /// /// Represents content position for which PageNumber is requested. /// Starting index for search process. ////// Returns true, if successfull. 'pageNumber' is updated with actual /// page number that contains specified ContentPosition. /// Returns false, if BreakRecordTable is missing information about /// page that contains specified ContentPosition. 'pageNumber' /// is updated with the last investigated page number. /// internal bool GetPageNumberForContentPosition(TextPointer contentPosition, ref int pageNumber) { bool foundPageNumber = false; ReadOnlyCollectiontextSegments; Invariant.Assert(pageNumber >= 0 && pageNumber <= _breakRecords.Count, "Invalid PageNumber."); // Iterate through entries in the BreakRecordTable (starting from specified index) // and look for page that contains specified ContentPosition. // NOTE: For each cached page collection of TextSegments is stored to // optimize this search. while (pageNumber < _breakRecords.Count) { Invariant.Assert(_breakRecords[pageNumber] != null, "Invalid BreakRecordTable entry."); textSegments = _breakRecords[pageNumber].TextSegments; if (textSegments != null) { if (TextDocumentView.Contains(contentPosition, textSegments)) { foundPageNumber = true; break; } } else { // There is no information about this page. break; } ++pageNumber; } return foundPageNumber; } /// /// Layout of entire content has been affected. /// internal void OnInvalidateLayout() { if (_breakRecords.Count > 0) { // Destroy all affected BreakRecords. InvalidateBreakRecords(0, _breakRecords.Count); // Initiate the next async operation. _owner.InitiateNextAsyncOperation(); // Raise PagesChanged event. Start with the first page and set // count to Int.Max/2, because somebody might want to display a page // that wasn't available before, but will be right now. _owner.OnPagesChanged(0, int.MaxValue/2); } } ////// Layout for specified range has been affected. /// /// Start of the affected content range. /// End of the affected content range. internal void OnInvalidateLayout(ITextPointer start, ITextPointer end) { int pageStart, pageCount; if (_breakRecords.Count > 0) { // Get range of affected pages and dispose them GetAffectedPages(start, end, out pageStart, out pageCount); // Currently there is no possibility to do partial invalidation // of BreakRecordTable, so always extend pageCount to the end // of BreakRecordTable. pageCount = _breakRecords.Count - pageStart; if (pageCount > 0) { // Destroy all affected BreakRecords. InvalidateBreakRecords(pageStart, pageCount); // Initiate the next async operation. _owner.InitiateNextAsyncOperation(); // Raise PagesChanged event. Start with the first affected page and set // count to Int.Max/2, because somebody might want to display a page // that wasn't available before, but will be right now. _owner.OnPagesChanged(pageStart, int.MaxValue/2); } } } ////// Rendering of entire content has been affected. /// internal void OnInvalidateRender() { if (_breakRecords.Count > 0) { // Dispose all existing pages. DisposePages(0, _breakRecords.Count); // Raise PagesChanged event. Start with the first page and set // count to this.Count (number of pages have not been changed). _owner.OnPagesChanged(0, _breakRecords.Count); } } ////// Rendering for specified range has been affected. /// /// Start of the affected content range. /// End of the affected content range. internal void OnInvalidateRender(ITextPointer start, ITextPointer end) { int pageStart, pageCount; if (_breakRecords.Count > 0) { // Get range of affected pages and dispose them. GetAffectedPages(start, end, out pageStart, out pageCount); if (pageCount > 0) { // Dispose all affected pages. DisposePages(pageStart, pageCount); // Raise PagesChanged event. _owner.OnPagesChanged(pageStart, pageCount); } } } ////// Updates entry of BreakRecordTable with new data. /// /// Index of the entry to update. /// DocumentPage object that has been just created. /// Output BreakRecord for created page. /// Last content position that can affect the output break record. internal void UpdateEntry(int pageNumber, FlowDocumentPage page, PageBreakRecord brOut, TextPointer dependentMax) { ITextView textView; BreakRecordTableEntry entry; bool isClean; Invariant.Assert(pageNumber >= 0 && pageNumber <= _breakRecords.Count, "The previous BreakRecord does not exist."); Invariant.Assert(page != null && page != DocumentPage.Missing, "Cannot update BRT with an invalid document page."); // Get TextView for DocumentPage. This TextView is used to access list of // content ranges. Those serve as optimalization in finding affeceted pages. textView = (ITextView)((IServiceProvider)page).GetService(typeof(ITextView)); Invariant.Assert(textView != null, "Cannot access ITextView for FlowDocumentPage."); // Get current state of BreakRecordTable isClean = this.IsClean; // Add new entry into BreakRecordTable entry = new BreakRecordTableEntry(); entry.BreakRecord = brOut; entry.DocumentPage = new WeakReference(page); entry.TextSegments = textView.TextSegments; entry.DependentMax = dependentMax; if (pageNumber == _breakRecords.Count) { _breakRecords.Add(entry); // Raise PaginationProgress event only if we did not have valid // entry for specified page number. _owner.OnPaginationProgress(pageNumber, 1); } else { // If old Page and/or BreakRecord are not changing, do not dispose them. if (_breakRecords[pageNumber].BreakRecord != null && _breakRecords[pageNumber].BreakRecord != entry.BreakRecord) { _breakRecords[pageNumber].BreakRecord.Dispose(); } if (_breakRecords[pageNumber].DocumentPage != null && _breakRecords[pageNumber].DocumentPage.Target != null && _breakRecords[pageNumber].DocumentPage.Target != entry.DocumentPage.Target) { ((FlowDocumentPage)_breakRecords[pageNumber].DocumentPage.Target).Dispose(); } _breakRecords[pageNumber] = entry; } // Raise PaginationCompleted event only if the BreakRecordTable just // become clean. if (!isClean && this.IsClean) { _owner.OnPaginationCompleted(); } } ////// Determines whenever input BreakRecord for given page number exists. /// /// Page index. ///true, if BreakRecord for given page number exists. internal bool HasPageBreakRecord(int pageNumber) { Invariant.Assert(pageNumber >= 0, "Page number cannot be negative."); // For the first page, the input break record is always NULL. // For the rest of pages, it exists if the preceding entry has // non-NULL output BreakRecord. if (pageNumber == 0) return true; if (pageNumber > _breakRecords.Count) return false; Invariant.Assert(_breakRecords[pageNumber - 1] != null, "Invalid BreakRecordTable entry."); return (_breakRecords[pageNumber - 1].BreakRecord != null); } #endregion Internal Methods //-------------------------------------------------------------------- // // Internal Properties // //-------------------------------------------------------------------- #region Internal Properties ////// Current count reflecting number of known pages. /// internal int Count { get { return _breakRecords.Count; } } ////// Whether BreakRecordTable is clean. /// internal bool IsClean { get { if (_breakRecords.Count == 0) return false; Invariant.Assert(_breakRecords[_breakRecords.Count - 1] != null, "Invalid BreakRecordTable entry."); return (_breakRecords[_breakRecords.Count - 1].BreakRecord == null); } } #endregion Internal Properties //------------------------------------------------------------------- // // Private Methods // //-------------------------------------------------------------------- #region Private Methods ////// Dispose all alive pages for specified range. /// /// Index of the first page to dispose. /// Number of pages to dispose. private void DisposePages(int start, int count) { WeakReference pageRef; int index = start + count - 1; // Start from the end of BreakRecordTable Invariant.Assert(start >= 0 && start < _breakRecords.Count, "Invalid starting index for BreakRecordTable invalidation."); Invariant.Assert(start + count <= _breakRecords.Count, "Partial invalidation of BreakRecordTable is not allowed."); while (index >= start) { Invariant.Assert(_breakRecords[index] != null, "Invalid BreakRecordTable entry."); pageRef = _breakRecords[index].DocumentPage; if (pageRef != null && pageRef.Target != null) { ((FlowDocumentPage)pageRef.Target).Dispose(); } _breakRecords[index].DocumentPage = null; index--; } } ////// Destroy BreakRecordsTable entries for specified range. /// /// Index of the first entry to destroy. /// Nmber of entries to destroy. private void InvalidateBreakRecords(int start, int count) { WeakReference pageRef; int index = start + count - 1; // Start from the end of BreakRecordTable Invariant.Assert(start >= 0 && start < _breakRecords.Count, "Invalid starting index for BreakRecordTable invalidation."); Invariant.Assert(start + count == _breakRecords.Count, "Partial invalidation of BreakRecordTable is not allowed."); while (index >= start) { Invariant.Assert(_breakRecords[index] != null, "Invalid BreakRecordTable entry."); // Dispose Page and BreakRecord before removing the entry. pageRef = _breakRecords[index].DocumentPage; if (pageRef != null && pageRef.Target != null) { ((FlowDocumentPage)pageRef.Target).Dispose(); } if (_breakRecords[index].BreakRecord != null) { _breakRecords[index].BreakRecord.Dispose(); } // Remov the entry. _breakRecords.RemoveAt(index); index--; } } ////// Retrieves indices of affected pages by specified content range. /// /// Content change start position. /// Content change end position. /// The first affected page. /// Number of affected pages. private void GetAffectedPages(ITextPointer start, ITextPointer end, out int pageStart, out int pageCount) { bool affects; ReadOnlyCollectiontextSegments; TextPointer dependentMax; // Find the first affected page. pageStart = 0; while (pageStart < _breakRecords.Count) { Invariant.Assert(_breakRecords[pageStart] != null, "Invalid BreakRecordTable entry."); // If the start position is before last position affecting the output break record, // this page is affected. dependentMax = _breakRecords[pageStart].DependentMax; if (dependentMax != null) { if (start.CompareTo(dependentMax) <= 0) break; } textSegments = _breakRecords[pageStart].TextSegments; if (textSegments != null) { affects = false; foreach (TextSegment textSegment in textSegments) { if (start.CompareTo(textSegment.End) <= 0) { affects = true; break; } } if (affects) break; } else { // There is no information about this page, so assume that it is // affected. break; } ++pageStart; } // Find the last affected page // For now assume that all following pages are affected. pageCount = _breakRecords.Count - pageStart; } #endregion Private Methods //------------------------------------------------------------------- // // Private Fields // //------------------------------------------------------------------- #region Private Fields /// /// Owner of the BreakRecordTable. /// private FlowDocumentPaginator _owner; ////// Array of entries in the BreakRecordTable. /// private List_breakRecords; /// /// BreakRecordTableEntry /// private class BreakRecordTableEntry { public PageBreakRecord BreakRecord; public ReadOnlyCollectionTextSegments; public WeakReference DocumentPage; public TextPointer DependentMax; } #endregion Private Fields } } // 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
- DefaultTraceListener.cs
- ImportCatalogPart.cs
- UnicodeEncoding.cs
- ContextQuery.cs
- WindowsTitleBar.cs
- ExclusiveTcpListener.cs
- XmlSchemaCollection.cs
- MDIClient.cs
- ScriptControlManager.cs
- PhotoPrintingIntent.cs
- MetadataArtifactLoaderResource.cs
- EditingMode.cs
- ToolStripItemDesigner.cs
- DataGridViewUtilities.cs
- OperationCanceledException.cs
- IFlowDocumentViewer.cs
- StickyNoteContentControl.cs
- SqlUserDefinedTypeAttribute.cs
- CompareValidator.cs
- UnSafeCharBuffer.cs
- WithParamAction.cs
- webbrowsersite.cs
- ByteStreamGeometryContext.cs
- ServiceManager.cs
- Hex.cs
- ToggleButtonAutomationPeer.cs
- securestring.cs
- DefaultProxySection.cs
- SystemWebSectionGroup.cs
- InheritablePropertyChangeInfo.cs
- Vector3DAnimationBase.cs
- DataControlFieldCollection.cs
- ExtendedTransformFactory.cs
- UpdateCommandGenerator.cs
- ApplicationManager.cs
- AsyncOperationManager.cs
- ZipIOExtraField.cs
- BindingContext.cs
- TextEffectResolver.cs
- BlurEffect.cs
- VisualBasicValue.cs
- DesignConnectionCollection.cs
- FileDialogPermission.cs
- TransmissionStrategy.cs
- XPathAxisIterator.cs
- RemotingSurrogateSelector.cs
- DCSafeHandle.cs
- FixedTextContainer.cs
- VariableDesigner.xaml.cs
- ClientConvert.cs
- Journaling.cs
- CallbackTimeoutsBehavior.cs
- ToolStripComboBox.cs
- State.cs
- WebPartDescription.cs
- SecurityTokenTypes.cs
- Roles.cs
- Block.cs
- InfoCardMasterKey.cs
- PropertyEntry.cs
- WindowsClaimSet.cs
- ListViewHitTestInfo.cs
- PixelFormats.cs
- ConfigXmlCDataSection.cs
- EventLogPermission.cs
- RowBinding.cs
- TraceListener.cs
- UIAgentAsyncParams.cs
- XmlQueryRuntime.cs
- AxisAngleRotation3D.cs
- ServiceContractGenerationContext.cs
- InternalsVisibleToAttribute.cs
- EmptyStringExpandableObjectConverter.cs
- UriWriter.cs
- Compiler.cs
- ImageDrawing.cs
- StaticSiteMapProvider.cs
- hresults.cs
- MultiPageTextView.cs
- TemplateBaseAction.cs
- StatusInfoItem.cs
- TreeNode.cs
- TextTreeText.cs
- ApplicationFileParser.cs
- InkCanvas.cs
- AssociationTypeEmitter.cs
- ListBox.cs
- ReliableRequestSessionChannel.cs
- oledbmetadatacollectionnames.cs
- EventItfInfo.cs
- _CookieModule.cs
- NamespaceCollection.cs
- CommandExpr.cs
- EntityConnectionStringBuilder.cs
- ObjectKeyFrameCollection.cs
- RoutedEventHandlerInfo.cs
- BypassElementCollection.cs
- PropertyGeneratedEventArgs.cs
- AlternateView.cs
- HttpServerUtilityWrapper.cs