Files
community/InkCanvasForClass/Helpers/InkStrokesOverlay.cs
2025-08-23 21:39:21 +08:00

96 lines
3.1 KiB
C#

using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Drawing;
using System.Runtime.Remoting.Contexts;
using System.Windows;
using System.Windows.Ink;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using Pen = System.Windows.Media.Pen;
namespace Ink_Canvas.Helpers
{
public class InkStrokesOverlay : FrameworkElement
{
private VisualCollection _children;
private ImprovedDrawingVisual _layer = new ImprovedDrawingVisual();
private StrokeCollection cachedStrokeCollection = new StrokeCollection();
private DrawingGroup cachedDrawingGroup = new DrawingGroup();
private bool isCached = false;
private DrawingContext context;
public class ImprovedDrawingVisual: DrawingVisual {
public ImprovedDrawingVisual() {
CacheMode = new BitmapCache() {
EnableClearType = false,
RenderAtScale = 1,
SnapsToDevicePixels = false
};
}
}
public InkStrokesOverlay()
{
_children = new VisualCollection(this) {
_layer // 初始化DrawingVisual
};
}
protected override int VisualChildrenCount => _children.Count;
protected override Visual GetVisualChild(int index)
{
if (index < 0 || index >= _children.Count) throw new ArgumentOutOfRangeException();
return _children[index];
}
public DrawingContext Open() {
context = _layer.RenderOpen();
return context;
}
public void Close() {
context.Close();
}
public void DrawStrokes(StrokeCollection strokes, Matrix? matrixTransform, bool isOneTimeDrawing = true) {
if (isOneTimeDrawing) {
context = _layer.RenderOpen();
}
if (matrixTransform != null) context.PushTransform(new MatrixTransform((Matrix)matrixTransform));
if (strokes.Count != 0) {
if (!isCached || (isCached && !strokes.Equals(cachedStrokeCollection))) {
cachedStrokeCollection = strokes;
cachedDrawingGroup = new DrawingGroup();
var gp_context = cachedDrawingGroup.Open();
var stks_cloned = strokes.Clone();
foreach (var stroke in stks_cloned) {
stroke.DrawingAttributes.Width += 2;
stroke.DrawingAttributes.Height += 2;
}
stks_cloned.Draw(gp_context);
foreach (var ori_stk in strokes) {
var geo = ori_stk.GetGeometry();
gp_context.DrawGeometry(new SolidColorBrush(Colors.White),null,geo);
}
gp_context.Close();
}
}
context.DrawDrawing(cachedDrawingGroup);
if (matrixTransform != null) context.Pop();
if (isOneTimeDrawing) {
context.Close();
}
}
}
}