Browse Source

Use DrawingVisual for rendering a VisualLine. This seems to improve AvalonEdit rendering performance a lot in some scenarios.

4.1
Daniel Grunwald 15 years ago
parent
commit
3f05ced59c
  1. 34
      src/Libraries/AvalonEdit/ICSharpCode.AvalonEdit/Rendering/TextLayer.cs
  2. 14
      src/Libraries/AvalonEdit/ICSharpCode.AvalonEdit/Rendering/TextView.cs
  3. 30
      src/Libraries/AvalonEdit/ICSharpCode.AvalonEdit/Rendering/VisualLine.cs

34
src/Libraries/AvalonEdit/ICSharpCode.AvalonEdit/Rendering/TextLayer.cs

@ -33,10 +33,38 @@ namespace ICSharpCode.AvalonEdit.Rendering @@ -33,10 +33,38 @@ namespace ICSharpCode.AvalonEdit.Rendering
{
}
protected override void OnRender(DrawingContext drawingContext)
List<VisualLineDrawingVisual> visuals = new List<VisualLineDrawingVisual>();
internal void SetVisualLines(ICollection<VisualLine> visualLines)
{
foreach (VisualLineDrawingVisual v in visuals) {
if (v.VisualLine.IsDisposed)
RemoveVisualChild(v);
}
visuals.Clear();
foreach (VisualLine newLine in visualLines) {
VisualLineDrawingVisual v = newLine.Render();
if (!v.IsAdded) {
AddVisualChild(v);
v.IsAdded = true;
}
visuals.Add(v);
}
InvalidateArrange();
}
protected override int VisualChildrenCount {
get { return visuals.Count; }
}
protected override Visual GetVisualChild(int index)
{
return visuals[index];
}
protected override void ArrangeCore(Rect finalRect)
{
base.OnRender(drawingContext);
textView.RenderTextLayer(drawingContext);
textView.ArrangeTextLayer(visuals);
}
}
}

14
src/Libraries/AvalonEdit/ICSharpCode.AvalonEdit/Rendering/TextView.cs

@ -833,7 +833,6 @@ namespace ICSharpCode.AvalonEdit.Rendering @@ -833,7 +833,6 @@ namespace ICSharpCode.AvalonEdit.Rendering
MeasureInlineObjects();
InvalidateVisual(); // = InvalidateArrange+InvalidateRender
textLayer.InvalidateVisual();
double maxWidth;
if (document == null) {
@ -862,6 +861,8 @@ namespace ICSharpCode.AvalonEdit.Rendering @@ -862,6 +861,8 @@ namespace ICSharpCode.AvalonEdit.Rendering
}
}
textLayer.SetVisualLines(visibleVisualLines);
SetScrollData(availableSize,
new Size(maxWidth, heightTreeHeight),
scrollOffset);
@ -1153,14 +1154,13 @@ namespace ICSharpCode.AvalonEdit.Rendering @@ -1153,14 +1154,13 @@ namespace ICSharpCode.AvalonEdit.Rendering
}
}
internal void RenderTextLayer(DrawingContext drawingContext)
internal void ArrangeTextLayer(IList<VisualLineDrawingVisual> visuals)
{
Point pos = new Point(-scrollOffset.X, -clippedPixelsOnTop);
foreach (VisualLine visualLine in allVisualLines) {
foreach (TextLine textLine in visualLine.TextLines) {
textLine.Draw(drawingContext, pos, InvertAxes.None);
pos.Y += textLine.Height;
}
foreach (VisualLineDrawingVisual visual in visuals) {
visual.Transform = new TranslateTransform(pos.X, pos.Y);
visual.Transform.Freeze();
pos.Y += visual.Height;
}
}
#endregion

30
src/Libraries/AvalonEdit/ICSharpCode.AvalonEdit/Rendering/VisualLine.cs

@ -1,6 +1,7 @@ @@ -1,6 +1,7 @@
// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt)
// This code is distributed under the GNU LGPL (for details please see \doc\license.txt)
using System.Windows.Media;
using ICSharpCode.AvalonEdit.Utils;
using System;
using System.Collections.Generic;
@ -424,5 +425,34 @@ namespace ICSharpCode.AvalonEdit.Rendering @@ -424,5 +425,34 @@ namespace ICSharpCode.AvalonEdit.Rendering
{
return true;
}
VisualLineDrawingVisual visual;
internal VisualLineDrawingVisual Render()
{
if (visual == null)
visual = new VisualLineDrawingVisual(this);
return visual;
}
}
sealed class VisualLineDrawingVisual : DrawingVisual
{
public readonly VisualLine VisualLine;
public readonly double Height;
internal bool IsAdded;
public VisualLineDrawingVisual(VisualLine visualLine)
{
this.VisualLine = visualLine;
var drawingContext = RenderOpen();
double pos = 0;
foreach (TextLine textLine in visualLine.TextLines) {
textLine.Draw(drawingContext, new Point(0, pos), InvertAxes.None);
pos += textLine.Height;
}
this.Height = pos;
drawingContext.Close();
}
}
}

Loading…
Cancel
Save