public static PreparedDecorationCollection Merge(PreparedDecorationCollection previous, PreparedDecorationCollection current, TextDelta td) { if (previous.mDecorations.Count == 0) { current.mDifferenceRange = current.Bounds(); return(current); } if (AreDecorationsSame(previous, current)) { PreparedDecorationCollection merged = new PreparedDecorationCollection(); TextIndexList differenceRanges = new TextIndexList(); for (int i = 0; i < previous.Count; i++) { TextIndexList previousIndex = previous.Index(i); TextIndexList currentIndex = current.Index(i); TextIndex differenceRange = currentIndex.RangeDifferentFrom(previousIndex); if (differenceRange != null && differenceRange.Length > 0) { differenceRanges.Add(differenceRange); } } differenceRanges.Add(td.TextIndex); merged.mDifferenceRange = differenceRanges.Bounds; TextIndex activeArea = differenceRanges.Bounds; if (activeArea != null) { for (int i = 0; i < previous.Count; i++) { TextIndexList currentIndex = current.Index(i); TextIndexList projected = currentIndex.Projection(activeArea); if (projected.IndexLengthUpperBound() > 0)// Are there and textindexes in projected that have a length > 0 { merged.Add(current.Decoration(i), projected); } } } return(merged); } else { current.mAreDecorationsChanged = true; return(current); } }
public void ApplyDecorations() { if (mDecorationInProgress) { return; } mDecorationInProgress = true; string testText = this.Text; if (testText.Trim() == "")//No text implies no need for decorations { mLastPrepared = new PreparedDecorationCollection(); mDecorationInProgress = false;; return; } DecorationCollection dc = new DecorationCollection(); dc.Add(mDecorationScheme); dc.Add(mDecorations); PreparedDecorationCollection current = dc.Prepare(testText); TextDelta td = new TextDelta(mLastText, testText); if (td.DeltaType == TextDelta.EDeltaType.Insert || td.DeltaType == TextDelta.EDeltaType.Delete) { mLastPrepared.Shift(td.Start, td.DeltaLength); } PreparedDecorationCollection active = PreparedDecorationCollection.Merge(mLastPrepared, current, td); //activeBounds refers to to the area where there a difference between the last and the current decorations TextIndex activeBounds = active.DifferenceRange; mLastPrepared = current; if (mLastText != this.Text) { mUndoText = mLastText; mLastText = this.Text; } if (activeBounds != null || active.AreDecorationsChanged) { //Prepare for decorating int selStart = this.SelectionStart; int selLength = this.SelectionLength; Point origScroll = ScrollPosition; LockWindowUpdate(this.Handle.ToInt32()); if (active.AreDecorationsChanged) { Select(0, testText.Length); } else { Select(activeBounds.Start, activeBounds.Length); } this.SelectionColor = this.ForeColor; this.SelectionBackColor = this.BackColor; for (int i = 0; i < active.Count; i++) { ApplyDecoration(active.Decoration(i), active.Index(i)); } //restore from decorating Select(selStart, selLength); this.SelectionColor = this.ForeColor; ScrollPosition = origScroll; LockWindowUpdate(0); } mDecorationInProgress = false; }