/
DrawingImage.cs
86 lines (74 loc) · 2.42 KB
/
DrawingImage.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
using System;
using Avalonia.Metadata;
namespace Avalonia.Media
{
/// <summary>
/// An <see cref="IImage"/> that uses a <see cref="Drawing"/> for content.
/// </summary>
public class DrawingImage : AvaloniaObject, IImage, IAffectsRender
{
public DrawingImage()
{
}
public DrawingImage(Drawing drawing)
{
Drawing = drawing;
}
/// <summary>
/// Defines the <see cref="Drawing"/> property.
/// </summary>
public static readonly StyledProperty<Drawing?> DrawingProperty =
AvaloniaProperty.Register<DrawingImage, Drawing?>(nameof(Drawing));
/// <inheritdoc/>
public event EventHandler? Invalidated;
/// <summary>
/// Gets or sets the drawing content.
/// </summary>
[Content]
public Drawing? Drawing
{
get => GetValue(DrawingProperty);
set => SetValue(DrawingProperty, value);
}
/// <inheritdoc/>
public Size Size => Drawing?.GetBounds().Size ?? default;
/// <inheritdoc/>
void IImage.Draw(
DrawingContext context,
Rect sourceRect,
Rect destRect)
{
var drawing = Drawing;
if (drawing == null)
{
return;
}
var bounds = drawing.GetBounds();
var scale = Matrix.CreateScale(
destRect.Width / sourceRect.Width,
destRect.Height / sourceRect.Height);
var translate = Matrix.CreateTranslation(
-sourceRect.X + destRect.X - bounds.X,
-sourceRect.Y + destRect.Y - bounds.Y);
using (context.PushClip(destRect))
using (context.PushTransform(translate * scale))
{
Drawing?.Draw(context);
}
}
/// <inheritdoc/>
protected override void OnPropertyChanged(AvaloniaPropertyChangedEventArgs change)
{
base.OnPropertyChanged(change);
if (change.Property == DrawingProperty)
{
RaiseInvalidated(EventArgs.Empty);
}
}
/// <summary>
/// Raises the <see cref="Invalidated"/> event.
/// </summary>
/// <param name="e">The event args.</param>
protected void RaiseInvalidated(EventArgs e) => Invalidated?.Invoke(this, e);
}
}