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 / DtrList.cs / 1 / DtrList.cs
//---------------------------------------------------------------------------- // // Copyright (C) Microsoft Corporation. All rights reserved. // // File: DrtList.cs // // Description: Definition for DtrLits (Dirty Text Range List) which // contains information about tree changes. // // History: // 06/06/2003 : grzegorz - moving from Avalon branch. // //--------------------------------------------------------------------------- using System; using System.Diagnostics; namespace MS.Internal.PtsHost { // --------------------------------------------------------------------- // DtrLits (Dirty Text Range List) manages sorted list of accumulated // tree changes. // All entries in DtrList are sorted with respect to StartIndex. // StartIndex is always representing offset in the tree before any // changes. // --------------------------------------------------------------------- internal sealed class DtrList { // ------------------------------------------------------------------ // Construct a DtrList. The array of DTRs initially can store up to // 4 entries. Upon adding elements the capacity increased in multiples // of two as required. // ----------------------------------------------------------------- internal DtrList() { _dtrs = new DirtyTextRange[_defaultCapacity]; _count = 0; } // ------------------------------------------------------------------ // Merge new DTR with list of exising DTRs: // 1) Convert startIndex to index reflecting position before any changes. // 2) Merge it with existing list of DTRs. // // dtr - New DTR to be merged with exising list of DTRs. // ------------------------------------------------------------------ internal void Merge(DirtyTextRange dtr) { bool merge = false; int i = 0; int startIndexOld = dtr.StartIndex; // 1) Convert StartIndex to index reflecting position before any changes. // And find out if there is a need to merge DTRs if (_count > 0) { while (i < _count) { // a) New DTR starts before the next one. In this case there are // two possibilities: // * new DTR does not intersect with the beginning of the next DTR, // in this case insert new DTR before the next one. // * new DTR does intersect with the beginning of the next DTR, // in this case merge these 2 DTRs if (startIndexOld < _dtrs[i].StartIndex) { if (startIndexOld + dtr.PositionsRemoved > _dtrs[i].StartIndex) { merge = true; } // else new dtr has to be inserted at position 'i' break; } // b) New DTR starts in the range of the previous DTR. In this case // merge these 2 DTRs else if (startIndexOld <= _dtrs[i].StartIndex + _dtrs[i].PositionsAdded) { // merge with existing dtr at position 'i' merge = true; break; } // c) No intersection has been found, go to the next DTR in the list. startIndexOld -= _dtrs[i].PositionsAdded - _dtrs[i].PositionsRemoved; ++i; } // Update dcp of the new DTR, to reflect position before any tree changes. dtr.StartIndex = startIndexOld; } // 2) Insert new DTR into the list, merge if necessary if (i < _count) { if (merge) { // The simplest way to merge these two DTRs is to add together // cchAdded/cchDeleted form both DTRs, but it will invalidate more // than required. Formula used below is more accurate. // a) New DTR does intersect with the beginning of the next DTR, // in this case merge these 2 DTRs. // * dcp = dcpN (since it starts before dcpO) // * add = addN + addO - min(addO, delN - (dcpO - dcpN)) // * del = delN + delO - min(addO, delN - (dcpO - dcpN)) // NOTE: dcpO - dcpN is always <= delN if (dtr.StartIndex < _dtrs[i].StartIndex) { int delta = _dtrs[i].StartIndex - dtr.StartIndex; int adjust = Math.Min(_dtrs[i].PositionsAdded, dtr.PositionsRemoved - delta); _dtrs[i].StartIndex = dtr.StartIndex; _dtrs[i].PositionsAdded += dtr.PositionsAdded - adjust; _dtrs[i].PositionsRemoved += dtr.PositionsRemoved - adjust; } // b) New DTR starts in the range of the previous DTR. In this case // merge these 2 DTRs. // * dcp = dcpO (since it starts before dcpN) // * add = addN + addO - min(delN, addO - (dcpN - dcpO)) // * del = delN + delO - min(delN, addO - (dcpN - dcpO)) // NOTE: dcpN - dcpO is always <= addO else { int delta = dtr.StartIndex - _dtrs[i].StartIndex; int adjust = Math.Min(dtr.PositionsRemoved, _dtrs[i].PositionsAdded - delta); //_dtrs[i].dcp: no need to change it _dtrs[i].PositionsAdded += dtr.PositionsAdded - adjust; _dtrs[i].PositionsRemoved += dtr.PositionsRemoved - adjust; } // Merge AffectsRenderOnly. Always merge in favor of !AffectsRenderOnly. _dtrs[i].AffectsRenderOnly &= dtr.AffectsRenderOnly; } else { // The new DTR has to be inserted before DTR at position 'i'. if (_count == _dtrs.Length) { Resize(); } Array.Copy(_dtrs, i, _dtrs, i+1, _count-i); _dtrs[i] = dtr; ++_count; } MergeWithNext(i); } else { // The new DTR has to be appended to the end of the list. if (_count == _dtrs.Length) { Resize(); } _dtrs[_count] = dtr; ++_count; } #if TEXTPANELLAYOUTDEBUG System.Text.StringBuilder msg = new System.Text.StringBuilder(); msg.Append("Merge DTR (" + dtr.StartIndex + "," + dtr.PositionsAdded + "," + dtr.PositionsRemoved + ") ->"); for (i = 0; i < _count; i++) { msg.Append(" (" + _dtrs[i].StartIndex + "," + _dtrs[i].PositionsAdded + "," + _dtrs[i].PositionsRemoved + ")"); } TextPanelDebug.Log(msg.ToString(), TextPanelDebug.Category.ContentChange); #endif } // ----------------------------------------------------------------- // Retrieve list of dtrs from range. // // dcpNew - Distance from the beginning of TextContainer after all // tree changes. // cchOld - Number of characters in the range, but before any // tree changes. // // Returns: List of DRTs for specified range. // ------------------------------------------------------------------ internal DtrList DtrsFromRange(int dcpNew, int cchOld) { DtrList dtrs = null; int i = 0; int first, last; int positionsAdded = 0; // Find the first dtr intersecting with the specified range. // Since DTRs store dcp before any changes, during iteration // accumulate positionsAdded (number of characters added to the tree // up to the current point). while (i < _count) { if (dcpNew <= _dtrs[i].StartIndex + positionsAdded + _dtrs[i].PositionsAdded) { break; } positionsAdded += _dtrs[i].PositionsAdded - _dtrs[i].PositionsRemoved; ++i; } first = i; // Find the last dtr intersecting with the specified range. // dcpNew-positionsAdded points to position before any tree changes, from // where we start counting cchOld. // Do not add characters (positionsAdded), since start position has been already found. while (i < _count) { if (dcpNew - positionsAdded + cchOld <= _dtrs[i].StartIndex + _dtrs[i].PositionsRemoved) { // If there is no intersection with the current DTR, go to the previous one. if (dcpNew - positionsAdded + cchOld < _dtrs[i].StartIndex) { --i; } break; } ++i; } last = (i < _count) ? i : _count-1; // If there are DTRs in the specified range, create new DtrList object if (last >= first) { dtrs = new DtrList(); while (last >= first) { // Since dcpNew is after tree changes, add positionsAdded to all dtrs // to build dtr list relative to dcpNew position. DirtyTextRange dtr = _dtrs[first]; dtr.StartIndex += positionsAdded; dtrs.Append(dtr); ++first; } } return dtrs; } // ----------------------------------------------------------------- // Merge DRT at position 'index' with the next one, if possible. // // index - Index of the DTR to be merged with next one. // ----------------------------------------------------------------- private void MergeWithNext(int index) { while (index + 1 < _count) { DirtyTextRange dtrNext = _dtrs[index+1]; // DTR starts in the range of the previous DTR. In this case // merge these 2 DTRs. if (dtrNext.StartIndex <= _dtrs[index].StartIndex + _dtrs[index].PositionsRemoved) { //_dtrs[index].dcp: no need to change it _dtrs[index].PositionsAdded += dtrNext.PositionsAdded; _dtrs[index].PositionsRemoved += dtrNext.PositionsRemoved; // Merge AffectsRenderOnly. Always merge in favor of !AffectsRenderOnly. _dtrs[index].AffectsRenderOnly &= dtrNext.AffectsRenderOnly; // Remove merged entry for (int i = index + 2; i < _count; i++) { _dtrs[i - 1] = _dtrs[i]; } --_count; } else { break; } } } // ----------------------------------------------------------------- // Append new DTR to the list. // // dtr - DTR to be appended to the list. // ------------------------------------------------------------------ private void Append(DirtyTextRange dtr) { if (_count == _dtrs.Length) { Resize(); } _dtrs[_count] = dtr; ++_count; } // ----------------------------------------------------------------- // Increases the capacity of the DTR array. //= *2. // ------------------------------------------------------------------ private void Resize() { Debug.Assert(_dtrs.Length > 0); // Allocate new array and copy all existing entries into it DirtyTextRange [] newdtrs = new DirtyTextRange[_dtrs.Length * 2]; Array.Copy(_dtrs, newdtrs, _dtrs.Length); _dtrs = newdtrs; } // ------------------------------------------------------------------ // Array like access to list of DTRs. // ----------------------------------------------------------------- internal int Length { get { return _count; } } internal DirtyTextRange this[int index] { get { return _dtrs[index]; } } // ------------------------------------------------------------------ // Array of DTRs. This array stores sorted list of DTRs. // ----------------------------------------------------------------- private DirtyTextRange [] _dtrs; // ----------------------------------------------------------------- // Default capacity of the DTRs array. The array capacity is always // increased in multiples of two as required: 4*(2^N). // ----------------------------------------------------------------- private const int _defaultCapacity = 4; private int _count; } } // File provided for Reference Use Only by Microsoft Corporation (c) 2007. // Copyright (c) Microsoft Corporation. All rights reserved. //---------------------------------------------------------------------------- // // Copyright (C) Microsoft Corporation. All rights reserved. // // File: DrtList.cs // // Description: Definition for DtrLits (Dirty Text Range List) which // contains information about tree changes. // // History: // 06/06/2003 : grzegorz - moving from Avalon branch. // //--------------------------------------------------------------------------- using System; using System.Diagnostics; namespace MS.Internal.PtsHost { // --------------------------------------------------------------------- // DtrLits (Dirty Text Range List) manages sorted list of accumulated // tree changes. // All entries in DtrList are sorted with respect to StartIndex. // StartIndex is always representing offset in the tree before any // changes. // --------------------------------------------------------------------- internal sealed class DtrList { // ------------------------------------------------------------------ // Construct a DtrList. The array of DTRs initially can store up to // 4 entries. Upon adding elements the capacity increased in multiples // of two as required. // ----------------------------------------------------------------- internal DtrList() { _dtrs = new DirtyTextRange[_defaultCapacity]; _count = 0; } // ------------------------------------------------------------------ // Merge new DTR with list of exising DTRs: // 1) Convert startIndex to index reflecting position before any changes. // 2) Merge it with existing list of DTRs. // // dtr - New DTR to be merged with exising list of DTRs. // ------------------------------------------------------------------ internal void Merge(DirtyTextRange dtr) { bool merge = false; int i = 0; int startIndexOld = dtr.StartIndex; // 1) Convert StartIndex to index reflecting position before any changes. // And find out if there is a need to merge DTRs if (_count > 0) { while (i < _count) { // a) New DTR starts before the next one. In this case there are // two possibilities: // * new DTR does not intersect with the beginning of the next DTR, // in this case insert new DTR before the next one. // * new DTR does intersect with the beginning of the next DTR, // in this case merge these 2 DTRs if (startIndexOld < _dtrs[i].StartIndex) { if (startIndexOld + dtr.PositionsRemoved > _dtrs[i].StartIndex) { merge = true; } // else new dtr has to be inserted at position 'i' break; } // b) New DTR starts in the range of the previous DTR. In this case // merge these 2 DTRs else if (startIndexOld <= _dtrs[i].StartIndex + _dtrs[i].PositionsAdded) { // merge with existing dtr at position 'i' merge = true; break; } // c) No intersection has been found, go to the next DTR in the list. startIndexOld -= _dtrs[i].PositionsAdded - _dtrs[i].PositionsRemoved; ++i; } // Update dcp of the new DTR, to reflect position before any tree changes. dtr.StartIndex = startIndexOld; } // 2) Insert new DTR into the list, merge if necessary if (i < _count) { if (merge) { // The simplest way to merge these two DTRs is to add together // cchAdded/cchDeleted form both DTRs, but it will invalidate more // than required. Formula used below is more accurate. // a) New DTR does intersect with the beginning of the next DTR, // in this case merge these 2 DTRs. // * dcp = dcpN (since it starts before dcpO) // * add = addN + addO - min(addO, delN - (dcpO - dcpN)) // * del = delN + delO - min(addO, delN - (dcpO - dcpN)) // NOTE: dcpO - dcpN is always <= delN if (dtr.StartIndex < _dtrs[i].StartIndex) { int delta = _dtrs[i].StartIndex - dtr.StartIndex; int adjust = Math.Min(_dtrs[i].PositionsAdded, dtr.PositionsRemoved - delta); _dtrs[i].StartIndex = dtr.StartIndex; _dtrs[i].PositionsAdded += dtr.PositionsAdded - adjust; _dtrs[i].PositionsRemoved += dtr.PositionsRemoved - adjust; } // b) New DTR starts in the range of the previous DTR. In this case // merge these 2 DTRs. // * dcp = dcpO (since it starts before dcpN) // * add = addN + addO - min(delN, addO - (dcpN - dcpO)) // * del = delN + delO - min(delN, addO - (dcpN - dcpO)) // NOTE: dcpN - dcpO is always <= addO else { int delta = dtr.StartIndex - _dtrs[i].StartIndex; int adjust = Math.Min(dtr.PositionsRemoved, _dtrs[i].PositionsAdded - delta); //_dtrs[i].dcp: no need to change it _dtrs[i].PositionsAdded += dtr.PositionsAdded - adjust; _dtrs[i].PositionsRemoved += dtr.PositionsRemoved - adjust; } // Merge AffectsRenderOnly. Always merge in favor of !AffectsRenderOnly. _dtrs[i].AffectsRenderOnly &= dtr.AffectsRenderOnly; } else { // The new DTR has to be inserted before DTR at position 'i'. if (_count == _dtrs.Length) { Resize(); } Array.Copy(_dtrs, i, _dtrs, i+1, _count-i); _dtrs[i] = dtr; ++_count; } MergeWithNext(i); } else { // The new DTR has to be appended to the end of the list. if (_count == _dtrs.Length) { Resize(); } _dtrs[_count] = dtr; ++_count; } #if TEXTPANELLAYOUTDEBUG System.Text.StringBuilder msg = new System.Text.StringBuilder(); msg.Append("Merge DTR (" + dtr.StartIndex + "," + dtr.PositionsAdded + "," + dtr.PositionsRemoved + ") ->"); for (i = 0; i < _count; i++) { msg.Append(" (" + _dtrs[i].StartIndex + "," + _dtrs[i].PositionsAdded + "," + _dtrs[i].PositionsRemoved + ")"); } TextPanelDebug.Log(msg.ToString(), TextPanelDebug.Category.ContentChange); #endif } // ----------------------------------------------------------------- // Retrieve list of dtrs from range. // // dcpNew - Distance from the beginning of TextContainer after all // tree changes. // cchOld - Number of characters in the range, but before any // tree changes. // // Returns: List of DRTs for specified range. // ------------------------------------------------------------------ internal DtrList DtrsFromRange(int dcpNew, int cchOld) { DtrList dtrs = null; int i = 0; int first, last; int positionsAdded = 0; // Find the first dtr intersecting with the specified range. // Since DTRs store dcp before any changes, during iteration // accumulate positionsAdded (number of characters added to the tree // up to the current point). while (i < _count) { if (dcpNew <= _dtrs[i].StartIndex + positionsAdded + _dtrs[i].PositionsAdded) { break; } positionsAdded += _dtrs[i].PositionsAdded - _dtrs[i].PositionsRemoved; ++i; } first = i; // Find the last dtr intersecting with the specified range. // dcpNew-positionsAdded points to position before any tree changes, from // where we start counting cchOld. // Do not add characters (positionsAdded), since start position has been already found. while (i < _count) { if (dcpNew - positionsAdded + cchOld <= _dtrs[i].StartIndex + _dtrs[i].PositionsRemoved) { // If there is no intersection with the current DTR, go to the previous one. if (dcpNew - positionsAdded + cchOld < _dtrs[i].StartIndex) { --i; } break; } ++i; } last = (i < _count) ? i : _count-1; // If there are DTRs in the specified range, create new DtrList object if (last >= first) { dtrs = new DtrList(); while (last >= first) { // Since dcpNew is after tree changes, add positionsAdded to all dtrs // to build dtr list relative to dcpNew position. DirtyTextRange dtr = _dtrs[first]; dtr.StartIndex += positionsAdded; dtrs.Append(dtr); ++first; } } return dtrs; } // ----------------------------------------------------------------- // Merge DRT at position 'index' with the next one, if possible. // // index - Index of the DTR to be merged with next one. // ----------------------------------------------------------------- private void MergeWithNext(int index) { while (index + 1 < _count) { DirtyTextRange dtrNext = _dtrs[index+1]; // DTR starts in the range of the previous DTR. In this case // merge these 2 DTRs. if (dtrNext.StartIndex <= _dtrs[index].StartIndex + _dtrs[index].PositionsRemoved) { //_dtrs[index].dcp: no need to change it _dtrs[index].PositionsAdded += dtrNext.PositionsAdded; _dtrs[index].PositionsRemoved += dtrNext.PositionsRemoved; // Merge AffectsRenderOnly. Always merge in favor of !AffectsRenderOnly. _dtrs[index].AffectsRenderOnly &= dtrNext.AffectsRenderOnly; // Remove merged entry for (int i = index + 2; i < _count; i++) { _dtrs[i - 1] = _dtrs[i]; } --_count; } else { break; } } } // ----------------------------------------------------------------- // Append new DTR to the list. // // dtr - DTR to be appended to the list. // ------------------------------------------------------------------ private void Append(DirtyTextRange dtr) { if (_count == _dtrs.Length) { Resize(); } _dtrs[_count] = dtr; ++_count; } // ----------------------------------------------------------------- // Increases the capacity of the DTR array. // = *2. // ------------------------------------------------------------------ private void Resize() { Debug.Assert(_dtrs.Length > 0); // Allocate new array and copy all existing entries into it DirtyTextRange [] newdtrs = new DirtyTextRange[_dtrs.Length * 2]; Array.Copy(_dtrs, newdtrs, _dtrs.Length); _dtrs = newdtrs; } // ------------------------------------------------------------------ // Array like access to list of DTRs. // ----------------------------------------------------------------- internal int Length { get { return _count; } } internal DirtyTextRange this[int index] { get { return _dtrs[index]; } } // ------------------------------------------------------------------ // Array of DTRs. This array stores sorted list of DTRs. // ----------------------------------------------------------------- private DirtyTextRange [] _dtrs; // ----------------------------------------------------------------- // Default capacity of the DTRs array. The array capacity is always // increased in multiples of two as required: 4*(2^N). // ----------------------------------------------------------------- private const int _defaultCapacity = 4; private int _count; } } // 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
- TextEditorSelection.cs
- LocalizationCodeDomSerializer.cs
- ConvertersCollection.cs
- CorrelationQuery.cs
- hebrewshape.cs
- IFlowDocumentViewer.cs
- StylusPointDescription.cs
- RelationshipDetailsRow.cs
- ReadOnlyPropertyMetadata.cs
- XmlUrlResolver.cs
- SafeNativeMethods.cs
- IdentityNotMappedException.cs
- RangeValuePatternIdentifiers.cs
- safemediahandle.cs
- CryptoKeySecurity.cs
- ComplexPropertyEntry.cs
- DesignerObject.cs
- ObjectHandle.cs
- EncodingStreamWrapper.cs
- _Events.cs
- SchemaObjectWriter.cs
- DoubleKeyFrameCollection.cs
- _ScatterGatherBuffers.cs
- TextProperties.cs
- RSAOAEPKeyExchangeFormatter.cs
- GridSplitterAutomationPeer.cs
- ResourceDictionaryCollection.cs
- ReadOnlyHierarchicalDataSource.cs
- ContravarianceAdapter.cs
- TreeViewHitTestInfo.cs
- Size3DValueSerializer.cs
- MetadataProperty.cs
- ZoomPercentageConverter.cs
- TreeViewEvent.cs
- SerialStream.cs
- StylusSystemGestureEventArgs.cs
- ReadOnlyCollectionBase.cs
- CellParagraph.cs
- TransactionManager.cs
- StringSource.cs
- ScrollPattern.cs
- TraceContextRecord.cs
- RegexCapture.cs
- PropertyInformationCollection.cs
- QilVisitor.cs
- OrderedDictionary.cs
- ObjectParameterCollection.cs
- sqlstateclientmanager.cs
- TextTreeRootTextBlock.cs
- StandardToolWindows.cs
- ScrollableControl.cs
- RequestDescription.cs
- GiveFeedbackEventArgs.cs
- EnvelopedPkcs7.cs
- ToolBarButtonClickEvent.cs
- X509Chain.cs
- HttpHandlersSection.cs
- LineServices.cs
- recordstatescratchpad.cs
- ToolZone.cs
- VirtualDirectoryMapping.cs
- ResourceWriter.cs
- ComplusEndpointConfigContainer.cs
- ListDesigner.cs
- figurelengthconverter.cs
- ManagementDateTime.cs
- WindowsAltTab.cs
- PrimitiveXmlSerializers.cs
- AttachedAnnotationChangedEventArgs.cs
- ConfigurationStrings.cs
- DataGridViewCellErrorTextNeededEventArgs.cs
- ClientSideProviderDescription.cs
- TypedRowHandler.cs
- SqlInfoMessageEvent.cs
- CacheMode.cs
- webeventbuffer.cs
- ContextProperty.cs
- DefaultMemberAttribute.cs
- AutomationPeer.cs
- TypeBuilderInstantiation.cs
- TextEditorCopyPaste.cs
- TemplateControlCodeDomTreeGenerator.cs
- IPEndPoint.cs
- DiscoveryReferences.cs
- HttpResponseHeader.cs
- CompositeTypefaceMetrics.cs
- XmlSchemaSimpleContent.cs
- PersonalizableTypeEntry.cs
- TextTreeRootNode.cs
- OleDbErrorCollection.cs
- contentDescriptor.cs
- FormatConvertedBitmap.cs
- AnnouncementService.cs
- Context.cs
- HandlerBase.cs
- AutoGeneratedFieldProperties.cs
- DataGridViewColumnTypePicker.cs
- TemplateBaseAction.cs
- ScriptControl.cs
- ContextMenu.cs