Code:
/ Net / Net / 3.5.50727.3053 / DEVDIV / depot / DevDiv / releases / Orcas / SP / 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
- ScheduleChanges.cs
- PolicyFactory.cs
- HttpListenerElement.cs
- HtmlTableCell.cs
- ResourceIDHelper.cs
- RoleGroup.cs
- __ComObject.cs
- ButtonFieldBase.cs
- PasswordDeriveBytes.cs
- QuadraticBezierSegment.cs
- Helpers.cs
- HuffmanTree.cs
- RouteParametersHelper.cs
- BeginStoryboard.cs
- UnsafeNativeMethods.cs
- SoapSchemaImporter.cs
- RectAnimationUsingKeyFrames.cs
- Paragraph.cs
- GridSplitter.cs
- EntityDataSourceUtil.cs
- AttributeUsageAttribute.cs
- Model3DGroup.cs
- TagNameToTypeMapper.cs
- RolePrincipal.cs
- AspCompat.cs
- TargetFrameworkAttribute.cs
- XPathScanner.cs
- CompatibleComparer.cs
- ImplicitInputBrush.cs
- Canvas.cs
- ObjectDataSourceMethodEventArgs.cs
- ColumnMapProcessor.cs
- PeerTransportListenAddressValidator.cs
- XmlQualifiedName.cs
- WebServiceResponse.cs
- InvalidWorkflowException.cs
- Descriptor.cs
- EmptyArray.cs
- SafeMemoryMappedFileHandle.cs
- FileDialogPermission.cs
- SafeNativeMethods.cs
- TextServicesCompartment.cs
- WizardStepBase.cs
- DependsOnAttribute.cs
- CompareValidator.cs
- PersonalizationProviderHelper.cs
- unsafenativemethodsother.cs
- SoapExtensionTypeElementCollection.cs
- RequestCache.cs
- PropertyGridEditorPart.cs
- StringReader.cs
- documentation.cs
- Parameter.cs
- StringPropertyBuilder.cs
- DbLambda.cs
- CorrelationToken.cs
- GroupItem.cs
- FixedSOMPageElement.cs
- figurelength.cs
- FormViewUpdateEventArgs.cs
- DataControlExtensions.cs
- BrushMappingModeValidation.cs
- SoapElementAttribute.cs
- CodeTypeReferenceExpression.cs
- ToolStripLabel.cs
- regiisutil.cs
- CompilerResults.cs
- DoubleLink.cs
- ChangeNode.cs
- Effect.cs
- LinkArea.cs
- BasicCellRelation.cs
- DataBoundControlDesigner.cs
- WebResourceUtil.cs
- FixedFindEngine.cs
- TagPrefixAttribute.cs
- DuplexChannelBinder.cs
- XmlSchemaAnnotated.cs
- MarkupCompiler.cs
- ClientFormsIdentity.cs
- ResourceReferenceExpression.cs
- WebBrowser.cs
- FileIOPermission.cs
- LassoHelper.cs
- DataGridViewCellErrorTextNeededEventArgs.cs
- Stroke2.cs
- XmlTextWriter.cs
- DelegatingHeader.cs
- OleDbDataReader.cs
- SubMenuStyleCollection.cs
- GlyphTypeface.cs
- ActivityInfo.cs
- VectorAnimation.cs
- JsonWriter.cs
- DbParameterHelper.cs
- BindableAttribute.cs
- PriorityBindingExpression.cs
- DataSysAttribute.cs
- ApplicationGesture.cs
- RequestCache.cs