Code:
/ Net / Net / 3.5.50727.3053 / DEVDIV / depot / DevDiv / releases / Orcas / SP / wpf / src / Framework / MS / Internal / PtsHost / BreakRecordTable.cs / 1 / 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 : grzegorz - 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[start].BreakRecord != null) { _breakRecords[start].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 : grzegorz - 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[start].BreakRecord != null) { _breakRecords[start].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
- ValidationEventArgs.cs
- FederatedMessageSecurityOverHttpElement.cs
- ObjectDataSourceFilteringEventArgs.cs
- IdentitySection.cs
- CustomAttribute.cs
- UserNamePasswordValidator.cs
- StandardCommands.cs
- PropertyTabAttribute.cs
- BCryptHashAlgorithm.cs
- HealthMonitoringSectionHelper.cs
- EntitySqlQueryState.cs
- DesignerOptionService.cs
- ServicesUtilities.cs
- PasswordRecovery.cs
- InternalBufferOverflowException.cs
- GridSplitter.cs
- ProfessionalColorTable.cs
- TextTreeUndo.cs
- CodeSnippetExpression.cs
- ToolStripCollectionEditor.cs
- PageAdapter.cs
- OleDbConnection.cs
- MailMessage.cs
- InternalResources.cs
- DetailsViewModeEventArgs.cs
- LogLogRecordEnumerator.cs
- ByteStreamMessageEncoderFactory.cs
- StreamInfo.cs
- HttpVersion.cs
- WebServiceHandler.cs
- TypeListConverter.cs
- querybuilder.cs
- BigInt.cs
- connectionpool.cs
- RuleInfoComparer.cs
- ItemsPresenter.cs
- EntityContainerRelationshipSet.cs
- SqlTransaction.cs
- IPAddressCollection.cs
- MatrixKeyFrameCollection.cs
- DropShadowBitmapEffect.cs
- MiniParameterInfo.cs
- EntityTypeEmitter.cs
- OleDbRowUpdatedEvent.cs
- HttpCapabilitiesSectionHandler.cs
- DeviceFilterEditorDialog.cs
- BezierSegment.cs
- RelationshipConstraintValidator.cs
- OptimizedTemplateContent.cs
- FontWeightConverter.cs
- XomlDesignerLoader.cs
- RemotingConfigParser.cs
- StrokeRenderer.cs
- ConfigXmlText.cs
- MiniConstructorInfo.cs
- DiagnosticStrings.cs
- EllipseGeometry.cs
- ScrollViewerAutomationPeer.cs
- DrawingAttributeSerializer.cs
- LoginView.cs
- TypeElement.cs
- DataBindingValueUIHandler.cs
- AggregateException.cs
- AuthenticatedStream.cs
- XmlSchemaFacet.cs
- errorpatternmatcher.cs
- StopRoutingHandler.cs
- HttpHostedTransportConfiguration.cs
- RegexMatchCollection.cs
- StaticContext.cs
- AppliedDeviceFiltersDialog.cs
- MsmqUri.cs
- IdnElement.cs
- ImageAutomationPeer.cs
- CodeCatchClauseCollection.cs
- StartUpEventArgs.cs
- DynamicEntity.cs
- DataGridCommandEventArgs.cs
- GridView.cs
- InvokeBase.cs
- FormatSettings.cs
- SmiSettersStream.cs
- DirtyTextRange.cs
- Task.cs
- WizardPanelChangingEventArgs.cs
- VirtualPathProvider.cs
- ListQueryResults.cs
- COM2EnumConverter.cs
- EnumMemberAttribute.cs
- SqlWebEventProvider.cs
- IOThreadScheduler.cs
- BaseTemplateCodeDomTreeGenerator.cs
- GridSplitterAutomationPeer.cs
- ItemCheckEvent.cs
- LocalizedNameDescriptionPair.cs
- RealProxy.cs
- PrivacyNoticeBindingElementImporter.cs
- TreeView.cs
- SvcFileManager.cs
- VerticalAlignConverter.cs