1 module skia.SKColorSpace;
2 
3 import skia.Definitions;
4 import skia.Exceptions;
5 import skia.SKObject;
6 import skia.SkiaApi;
7 import skia.SKColorSpaceStructs;
8 import skia.SKData;
9 import skia.SKMatrix44;
10 
11 import std.concurrency : initOnce;
12 
13 class SKColorSpace : SKObject, ISKNonVirtualReferenceCounted
14 {
15 	static SKColorSpace srgb() {
16 		__gshared SKColorSpace inst;
17 		return initOnce!inst(new SKColorSpaceStatic (SkiaApi.sk_colorspace_new_srgb ()));
18 	}
19 
20 	private static SKColorSpace srgbLinear() {
21 		__gshared SKColorSpace inst;
22 		return initOnce!inst(new SKColorSpaceStatic (SkiaApi.sk_colorspace_new_srgb_linear ()));
23 	}
24 
25 
26 	static void EnsureStaticInstanceAreInitialized ()
27 	{
28 		// IMPORTANT: do not remove to ensure that the static instances
29 		//            are initialized before any access is made to them
30 	}
31 
32 	this (void* handle, bool owns)
33 	{
34     super(handle, owns);
35 	}
36 
37 	void ReferenceNative ()	
38   {
39 		return SkiaApi.sk_colorspace_ref (cast(sk_colorspace_t*)Handle);
40 	}
41 
42 	void UnreferenceNative ()	
43   {
44 		return SkiaApi.sk_colorspace_unref (cast(sk_colorspace_t*)Handle);
45 	}
46 
47   protected override void Dispose (bool disposing)	
48   {
49 		return super.Dispose (disposing);
50 	}
51 
52 	// properties
53 
54   bool GammaIsCloseToSrgb()
55   {
56     return SkiaApi.sk_colorspace_gamma_close_to_srgb (cast(sk_colorspace_t*)Handle);
57   }
58 		
59 
60   bool GammaIsLinear()
61   {
62     return SkiaApi.sk_colorspace_gamma_is_linear (cast(sk_colorspace_t*)Handle);
63   }
64 		
65 
66   bool IsSrgb()
67   {
68     return SkiaApi.sk_colorspace_is_srgb (cast(sk_colorspace_t*)Handle);
69   }
70 	
71 
72   SKColorSpaceType Type()
73   {
74     return SKColorSpaceType.Rgb;
75   } 
76 
77   SKNamedGamma NamedGamma()
78   {
79 		SKColorSpaceTransferFn tf = GetNumericalTransferFunction ();
80 
81 		if(tf == SKColorSpaceTransferFn.Empty) {
82 			return SKNamedGamma.NonStandard;
83 		} else if(tf == SKColorSpaceTransferFn.Linear) {
84 			return SKNamedGamma.Linear;
85 		} else if(tf == SKColorSpaceTransferFn.Srgb) {
86 			return SKNamedGamma.Srgb;
87 		} else if(tf == SKColorSpaceTransferFn.TwoDotTwo) {
88 			return SKNamedGamma.TwoDotTwoCurve;
89 		} else {
90 			return SKNamedGamma.NonStandard;
91 		}
92 		
93 	}
94 
95 	bool IsNumericalTransferFunction()
96   {
97 	  SKColorSpaceTransferFn fn;
98     return GetNumericalTransferFunction (fn);
99 
100   }
101 		
102 	static bool Equal (SKColorSpace left, SKColorSpace right)
103 	{
104 		if (left is null)
105 			throw new ArgumentNullException (left.stringof);
106 		if (right is null)
107 			throw new ArgumentNullException (right.stringof);
108 
109 		return SkiaApi.sk_colorspace_equals (cast(sk_colorspace_t*)left.Handle, cast(sk_colorspace_t*)right.Handle);
110 	}
111 
112 	// CreateSrgb
113 
114 	static SKColorSpace CreateSrgb () 
115   {
116     return srgb;
117   } 
118 
119 	// CreateSrgbLinear
120 
121 	static SKColorSpace CreateSrgbLinear ()
122   {
123     return srgbLinear;
124   } 
125 
126 	// CreateIcc
127 
128 	static SKColorSpace CreateIcc (void* input, long length)
129   {
130     return CreateIcc (SKColorSpaceIccProfile.Create (input, length));
131   }
132 		
133 
134 	static SKColorSpace CreateIcc (byte[] input, long length)
135 	{
136 		if (input is null)
137 			throw new ArgumentNullException (input.stringof);
138 
139 		byte* i = input.ptr;
140 		return CreateIcc (SKColorSpaceIccProfile.Create (cast(void*)i, length));
141 	}
142 
143 // 	static SKColorSpace CreateIcc (byte[] input)
144 //   {
145 //     return 	CreateIcc (input.AsSpan ());
146 //   }
147 	
148 
149 	static SKColorSpace CreateIcc (byte[] input)
150   {
151     return CreateIcc (SKColorSpaceIccProfile.Create (input));
152   }
153 		
154 
155 	static SKColorSpace CreateIcc (SKData input)
156   {
157     return 	CreateIcc (SKColorSpaceIccProfile.Create (input));
158   }
159 	
160 
161 	static SKColorSpace CreateIcc (SKColorSpaceIccProfile profile)
162 	{
163 		if (profile is null)
164 			throw new ArgumentNullException (profile.stringof);
165 
166 		return Referenced (GetObject (SkiaApi.sk_colorspace_new_icc (cast(sk_colorspace_icc_profile_t*)profile.Handle)), profile);
167 	}
168 
169 	// CreateRgb
170 
171 	static SKColorSpace CreateRgb (SKColorSpaceRenderTargetGamma gamma, SKMatrix44 toXyzD50, SKColorSpaceFlags flags)	
172   {
173 		return CreateRgb (gamma, toXyzD50);
174 	}
175 
176 	static SKColorSpace CreateRgb (SKColorSpaceRenderTargetGamma gamma, SKColorSpaceGamut gamut, SKColorSpaceFlags flags)	
177   {
178 		return CreateRgb (gamma, gamut);
179 	}
180 
181 	static SKColorSpace CreateRgb (SKColorSpaceTransferFn coeffs, SKMatrix44 toXyzD50, SKColorSpaceFlags flags)	
182   {
183 		return CreateRgb (coeffs, toXyzD50);
184 	}
185 
186 	static SKColorSpace CreateRgb (SKColorSpaceTransferFn coeffs, SKColorSpaceGamut gamut, SKColorSpaceFlags flags)	
187   {
188 		return CreateRgb (coeffs, gamut);
189 	}
190 
191 	static SKColorSpace CreateRgb (SKColorSpaceRenderTargetGamma gamma, SKMatrix44 toXyzD50)
192 	{
193 		if (toXyzD50 is null)
194 			throw new ArgumentNullException (toXyzD50.stringof);
195 
196 		return CreateRgb (gamma.ToColorSpaceTransferFn (), toXyzD50.ToColorSpaceXyz ());
197 	}
198 
199 	static SKColorSpace CreateRgb (SKColorSpaceRenderTargetGamma gamma, SKColorSpaceGamut gamut)
200   {
201     return CreateRgb (gamma.ToColorSpaceTransferFn (), gamut.ToColorSpaceXyz ());
202   }
203 		
204 
205 	static SKColorSpace CreateRgb (SKColorSpaceTransferFn coeffs, SKMatrix44 toXyzD50)
206 	{
207 		if (toXyzD50 is null)
208 			throw new ArgumentNullException (toXyzD50.stringof);
209 
210 		return CreateRgb (coeffs, toXyzD50.ToColorSpaceXyz ());
211 	}
212 
213 	static SKColorSpace CreateRgb (SKColorSpaceTransferFn coeffs, SKColorSpaceGamut gamut)
214   {
215     return CreateRgb (coeffs, gamut.ToColorSpaceXyz ());
216   }
217 	
218 
219 	static SKColorSpace CreateRgb (SKNamedGamma gamma, SKMatrix44 toXyzD50)
220 	{
221 		if (toXyzD50 is null)
222 			throw new ArgumentNullException (toXyzD50.stringof);
223 
224 		return CreateRgb (gamma.ToColorSpaceTransferFn (), toXyzD50.ToColorSpaceXyz ());
225 	}
226 
227 	static SKColorSpace CreateRgb (SKNamedGamma gamma, SKColorSpaceGamut gamut)
228   {
229     return CreateRgb (gamma.ToColorSpaceTransferFn (), gamut.ToColorSpaceXyz ());
230   }
231 		
232 
233 	// CreateRgb
234 
235 	static SKColorSpace CreateRgb (SKColorSpaceTransferFn transferFn, SKColorSpaceXyz toXyzD50)
236   {
237     return GetObject (SkiaApi.sk_colorspace_new_rgb (&transferFn, &toXyzD50));
238   }
239 		
240 
241 	// GetNumericalTransferFunction
242 
243 	SKColorSpaceTransferFn GetNumericalTransferFunction ()
244   {
245     SKColorSpaceTransferFn fn;
246     return GetNumericalTransferFunction (fn) ? fn : SKColorSpaceTransferFn.Empty;
247   }
248 		
249 
250 	bool GetNumericalTransferFunction (ref SKColorSpaceTransferFn fn)
251 	{
252 		SKColorSpaceTransferFn* f = &fn;
253 		return SkiaApi.sk_colorspace_is_numerical_transfer_fn (cast(sk_colorspace_t*)Handle, f);
254 	}
255 
256 	// ToProfile
257 
258 	SKColorSpaceIccProfile ToProfile ()
259 	{
260 		auto profile = new SKColorSpaceIccProfile ();
261 		SkiaApi.sk_colorspace_to_profile (cast(sk_colorspace_t*)Handle, cast(sk_colorspace_icc_profile_t*)profile.Handle);
262 		return profile;
263 	}
264 
265 	// ToColorSpaceXyz
266 
267 	bool ToColorSpaceXyz (out SKColorSpaceXyz toXyzD50)
268 	{
269 		SKColorSpaceXyz* xyz = &toXyzD50;
270 		return SkiaApi.sk_colorspace_to_xyzd50 (cast(sk_colorspace_t*)Handle, xyz);
271 	}
272 
273 	SKColorSpaceXyz ToColorSpaceXyz ()
274   {
275     SKColorSpaceXyz toXYZ;
276     return ToColorSpaceXyz (toXYZ) ? toXYZ : SKColorSpaceXyz.Empty;
277   }
278 		
279 
280 	// To*Gamma
281 
282 	SKColorSpace ToLinearGamma ()	
283   {
284 		return GetObject (SkiaApi.sk_colorspace_make_linear_gamma (cast(sk_colorspace_t*)Handle));
285 	}
286 
287 	SKColorSpace ToSrgbGamma ()	
288   {
289 		return GetObject (SkiaApi.sk_colorspace_make_srgb_gamma (cast(sk_colorspace_t*)Handle));
290 	}
291 
292 	// *XyzD50
293 
294 	SKMatrix44 ToXyzD50 ()
295   {
296     return ToColorSpaceXyz ().ToMatrix44 ();
297   }
298 		
299 
300 	// bool ToXyzD50 (SKMatrix44 toXyzD50)
301 	// {
302 	// 	if (toXyzD50 is null)
303 	// 		throw new ArgumentNullException (toXyzD50.stringof);
304 
305 	// 	if (ToColorSpaceXyz ( var xyz) && xyz.ToMatrix44 () is SKMatrix44 m) {
306 	// 		toXyzD50.SetColumnMajor (m.ToColumnMajor ());
307 	// 		return true;
308 	// 	}
309 	// 	return false;
310 	// }
311 
312 	SKMatrix44 FromXyzD50 ()
313   {
314     return ToXyzD50 ().Invert ();
315   }
316 		
317 
318 	//
319 
320 	static SKColorSpace GetObject (void* handle, bool owns = true, bool unrefExisting = true)
321   {
322     return 	GetOrAddObject!(SKColorSpace) (handle, owns, unrefExisting, (h, o){return new SKColorSpace (h, o);});
323   }
324 	
325 
326 	private static final class SKColorSpaceStatic : SKColorSpace
327 	{
328 		this (void* x)
329 		{
330             super (x, true);
331 			IgnorePublicDispose = true;
332 		}
333 	}
334 
335 }
336