aboutsummaryrefslogtreecommitdiffstatsci
path: root/Backends/SkiaBackend/src/Gradient.cs
blob: c940e7d2690cdef2210b3a516884f17de8b23066 (plain)
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
87
88
89
90
91
92
93
// Copyright (c) 2018-2021  Jean-Philippe Bruyère <jp_bruyere@hotmail.com>
//
// This code is licensed under the MIT license (MIT) (http://opensource.org/licenses/MIT)

using System;
using System.Collections.Generic;
using Drawing2D;
using SkiaSharp;

namespace Crow.SkiaBackend
{
	public abstract class Gradient : IGradient
	{
		internal SKShader shader;
		protected SKPoint[] points;
		protected List<SKColor> colorStops = new List<SKColor> ();
		protected List<float> offsets = new List<float>();
		protected SKShaderTileMode tileMode = SKShaderTileMode.Clamp;
		protected Filter filter = Filter.Fast;
		protected Gradient (SKPoint p0, SKPoint p1) {
			points = new SKPoint[] {p0, p1};
		}
		~Gradient()
		{
			Dispose(false);
		}
		public Extend Extend {
			get => (Extend)tileMode;
			set => tileMode = (SKShaderTileMode)value;
		}
		public Filter Filter {
			get => throw new NotImplementedException();
			set => throw new NotImplementedException();
		}

		public void AddColorStop (double offset, Color c) {
			shader?.Dispose();
			shader = null;
			offsets.Add ((float)offset);
			colorStops.Add (c.ToSkiaColor());
		}
		public void AddColorStop(float offset, float r, float g, float b, float a = 1f) {
			shader?.Dispose();
			shader = null;
			offsets.Add ((float)offset);
			colorStops.Add (new Color (a,r,g,b).Value);
		}
		internal abstract void Activate ();

		#region IDisposable implementation
		public void Dispose()
		{
			Dispose(true);
			GC.SuppressFinalize(this);
		}

		protected virtual void Dispose(bool disposing)
		{
			if (!disposing)
				return;
			shader?.Dispose ();
		}
		#endregion
	}
	public class LinearGradient : Gradient {
		public LinearGradient (float x0, float y0, float x1, float y1)
		: base (new SKPoint (x0, y0), new SKPoint (x1, y1)) { }

		internal override void Activate()
		{
			if (shader != null)
				return;
			shader = SKShader.CreateLinearGradient (points[0], points[1],
				colorStops.ToArray(), offsets.ToArray(), tileMode);
		}
	}
	public class RadialGradient : Gradient {
		float[] radiuses;
		public RadialGradient (	float cx0, float cy0, float radius0,
								float cx1, float cy1, float radius1)
		: base (new SKPoint (cx0, cy0), new SKPoint (cx1, cy1)) {
			radiuses = new float[] {radius0, radius1};
		}

		internal override void Activate()
		{
			if (shader != null)
				return;
			shader = SKShader.CreateRadialGradient (points[0], radiuses[0],
				colorStops.ToArray(), offsets.ToArray(), tileMode);
		}
	}
}