1 /*
2  * This file is part of gtkD.
3  *
4  * gtkD is free software; you can redistribute it and/or modify
5  * it under the terms of the GNU Lesser General Public License
6  * as published by the Free Software Foundation; either version 3
7  * of the License, or (at your option) any later version, with
8  * some exceptions, please read the COPYING file.
9  *
10  * gtkD is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13  * GNU Lesser General Public License for more details.
14  *
15  * You should have received a copy of the GNU Lesser General Public License
16  * along with gtkD; if not, write to the Free Software
17  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110, USA
18  */
19 
20 // generated automatically - do not change
21 // find conversion definition on APILookup.txt
22 // implement new conversion functionalities on the wrap.utils pakage
23 
24 
25 module gsk.Transform;
26 
27 private import glib.ConstructionException;
28 private import glib.MemorySlice;
29 private import glib.Str;
30 private import glib.StringG;
31 private import glib.c.functions;
32 private import gobject.ObjectG;
33 private import graphene.Matrix;
34 private import graphene.Point;
35 private import graphene.Point3D;
36 private import graphene.Rect;
37 private import graphene.Vec3;
38 private import gsk.c.functions;
39 public  import gsk.c.types;
40 private import gtkd.Loader;
41 
42 
43 /**
44  * `GskTransform` is an object to describe transform matrices.
45  * 
46  * Unlike `graphene_matrix_t`, `GskTransform` retains the steps in how
47  * a transform was constructed, and allows inspecting them. It is modeled
48  * after the way CSS describes transforms.
49  * 
50  * `GskTransform` objects are immutable and cannot be changed after creation.
51  * This means code can safely expose them as properties of objects without
52  * having to worry about others changing them.
53  */
54 public class Transform
55 {
56 	/** the main Gtk struct */
57 	protected GskTransform* gskTransform;
58 	protected bool ownedRef;
59 
60 	/** Get the main Gtk struct */
61 	public GskTransform* getTransformStruct(bool transferOwnership = false)
62 	{
63 		if (transferOwnership)
64 			ownedRef = false;
65 		return gskTransform;
66 	}
67 
68 	/** the main Gtk struct as a void* */
69 	protected void* getStruct()
70 	{
71 		return cast(void*)gskTransform;
72 	}
73 
74 	/**
75 	 * Sets our main struct and passes it to the parent class.
76 	 */
77 	public this (GskTransform* gskTransform, bool ownedRef = false)
78 	{
79 		this.gskTransform = gskTransform;
80 		this.ownedRef = ownedRef;
81 	}
82 
83 	~this ()
84 	{
85 		if ( Linker.isLoaded(LIBRARY_GSK) && ownedRef )
86 			gsk_transform_unref(gskTransform);
87 	}
88 
89 
90 	/** */
91 	public static GType getType()
92 	{
93 		return gsk_transform_get_type();
94 	}
95 
96 	/** */
97 	public this()
98 	{
99 		auto __p = gsk_transform_new();
100 
101 		if(__p is null)
102 		{
103 			throw new ConstructionException("null returned by new");
104 		}
105 
106 		this(cast(GskTransform*) __p);
107 	}
108 
109 	/**
110 	 * Checks two transforms for equality.
111 	 *
112 	 * Params:
113 	 *     second = the second transform
114 	 *
115 	 * Returns: %TRUE if the two transforms perform the same operation.
116 	 */
117 	public bool equal(Transform second)
118 	{
119 		return gsk_transform_equal(gskTransform, (second is null) ? null : second.getTransformStruct()) != 0;
120 	}
121 
122 	/**
123 	 * Returns the category this transform belongs to.
124 	 *
125 	 * Returns: The category of the transform
126 	 */
127 	public GskTransformCategory getCategory()
128 	{
129 		return gsk_transform_get_category(gskTransform);
130 	}
131 
132 	/**
133 	 * Inverts the given transform.
134 	 *
135 	 * If @self is not invertible, %NULL is returned.
136 	 * Note that inverting %NULL also returns %NULL, which is
137 	 * the correct inverse of %NULL. If you need to differentiate
138 	 * between those cases, you should check @self is not %NULL
139 	 * before calling this function.
140 	 *
141 	 * Returns: The inverted transform or %NULL if the transform
142 	 *     cannot be inverted.
143 	 */
144 	public Transform invert()
145 	{
146 		auto __p = gsk_transform_invert(gskTransform);
147 
148 		if(__p is null)
149 		{
150 			return null;
151 		}
152 
153 		return ObjectG.getDObject!(Transform)(cast(GskTransform*) __p, true);
154 	}
155 
156 	/**
157 	 * Multiplies @next with the given @matrix.
158 	 *
159 	 * Params:
160 	 *     matrix = the matrix to multiply @next with
161 	 *
162 	 * Returns: The new transform
163 	 */
164 	public Transform matrix(Matrix matrix)
165 	{
166 		auto __p = gsk_transform_matrix(gskTransform, (matrix is null) ? null : matrix.getMatrixStruct());
167 
168 		if(__p is null)
169 		{
170 			return null;
171 		}
172 
173 		return ObjectG.getDObject!(Transform)(cast(GskTransform*) __p, true);
174 	}
175 
176 	/**
177 	 * Applies a perspective projection transform.
178 	 *
179 	 * This transform scales points in X and Y based on their Z value,
180 	 * scaling points with positive Z values away from the origin, and
181 	 * those with negative Z values towards the origin. Points
182 	 * on the z=0 plane are unchanged.
183 	 *
184 	 * Params:
185 	 *     depth = distance of the z=0 plane. Lower values give a more
186 	 *         flattened pyramid and therefore a more pronounced
187 	 *         perspective effect.
188 	 *
189 	 * Returns: The new transform
190 	 */
191 	public Transform perspective(float depth)
192 	{
193 		auto __p = gsk_transform_perspective(gskTransform, depth);
194 
195 		if(__p is null)
196 		{
197 			return null;
198 		}
199 
200 		return ObjectG.getDObject!(Transform)(cast(GskTransform*) __p, true);
201 	}
202 
203 	/**
204 	 * Converts @self into a human-readable string representation suitable
205 	 * for printing.
206 	 *
207 	 * The result of this function can later be parsed with
208 	 * [func@Gsk.Transform.parse].
209 	 *
210 	 * Params:
211 	 *     string_ = The string to print into
212 	 */
213 	public void print(StringG string_)
214 	{
215 		gsk_transform_print(gskTransform, (string_ is null) ? null : string_.getStringGStruct());
216 	}
217 
218 	alias doref = ref_;
219 	/**
220 	 * Acquires a reference on the given `GskTransform`.
221 	 *
222 	 * Returns: the `GskTransform` with an additional reference
223 	 */
224 	public Transform ref_()
225 	{
226 		auto __p = gsk_transform_ref(gskTransform);
227 
228 		if(__p is null)
229 		{
230 			return null;
231 		}
232 
233 		return ObjectG.getDObject!(Transform)(cast(GskTransform*) __p);
234 	}
235 
236 	/**
237 	 * Rotates @next @angle degrees in 2D - or in 3D-speak, around the z axis.
238 	 *
239 	 * Params:
240 	 *     angle = the rotation angle, in degrees (clockwise)
241 	 *
242 	 * Returns: The new transform
243 	 */
244 	public Transform rotate(float angle)
245 	{
246 		auto __p = gsk_transform_rotate(gskTransform, angle);
247 
248 		if(__p is null)
249 		{
250 			return null;
251 		}
252 
253 		return ObjectG.getDObject!(Transform)(cast(GskTransform*) __p, true);
254 	}
255 
256 	/**
257 	 * Rotates @next @angle degrees around @axis.
258 	 *
259 	 * For a rotation in 2D space, use [method@Gsk.Transform.rotate]
260 	 *
261 	 * Params:
262 	 *     angle = the rotation angle, in degrees (clockwise)
263 	 *     axis = The rotation axis
264 	 *
265 	 * Returns: The new transform
266 	 */
267 	public Transform rotate3d(float angle, Vec3 axis)
268 	{
269 		auto __p = gsk_transform_rotate_3d(gskTransform, angle, (axis is null) ? null : axis.getVec3Struct());
270 
271 		if(__p is null)
272 		{
273 			return null;
274 		}
275 
276 		return ObjectG.getDObject!(Transform)(cast(GskTransform*) __p, true);
277 	}
278 
279 	/**
280 	 * Scales @next in 2-dimensional space by the given factors.
281 	 *
282 	 * Use [method@Gsk.Transform.scale_3d] to scale in all 3 dimensions.
283 	 *
284 	 * Params:
285 	 *     factorX = scaling factor on the X axis
286 	 *     factorY = scaling factor on the Y axis
287 	 *
288 	 * Returns: The new transform
289 	 */
290 	public Transform scale(float factorX, float factorY)
291 	{
292 		auto __p = gsk_transform_scale(gskTransform, factorX, factorY);
293 
294 		if(__p is null)
295 		{
296 			return null;
297 		}
298 
299 		return ObjectG.getDObject!(Transform)(cast(GskTransform*) __p, true);
300 	}
301 
302 	/**
303 	 * Scales @next by the given factors.
304 	 *
305 	 * Params:
306 	 *     factorX = scaling factor on the X axis
307 	 *     factorY = scaling factor on the Y axis
308 	 *     factorZ = scaling factor on the Z axis
309 	 *
310 	 * Returns: The new transform
311 	 */
312 	public Transform scale3d(float factorX, float factorY, float factorZ)
313 	{
314 		auto __p = gsk_transform_scale_3d(gskTransform, factorX, factorY, factorZ);
315 
316 		if(__p is null)
317 		{
318 			return null;
319 		}
320 
321 		return ObjectG.getDObject!(Transform)(cast(GskTransform*) __p, true);
322 	}
323 
324 	/**
325 	 * Converts a `GskTransform` to a 2D transformation matrix.
326 	 *
327 	 * @self must be a 2D transformation. If you are not
328 	 * sure, use gsk_transform_get_category() >=
329 	 * %GSK_TRANSFORM_CATEGORY_2D to check.
330 	 *
331 	 * The returned values have the following layout:
332 	 *
333 	 * ```
334 	 * | xx yx |   |  a  b  0 |
335 	 * | xy yy | = |  c  d  0 |
336 	 * | dx dy |   | tx ty  1 |
337 	 * ```
338 	 *
339 	 * This function can be used to convert between a `GskTransform`
340 	 * and a matrix type from other 2D drawing libraries, in particular
341 	 * Cairo.
342 	 *
343 	 * Params:
344 	 *     outXx = return location for the xx member
345 	 *     outYx = return location for the yx member
346 	 *     outXy = return location for the xy member
347 	 *     outYy = return location for the yy member
348 	 *     outDx = return location for the x0 member
349 	 *     outDy = return location for the y0 member
350 	 */
351 	public void to2d(out float outXx, out float outYx, out float outXy, out float outYy, out float outDx, out float outDy)
352 	{
353 		gsk_transform_to_2d(gskTransform, &outXx, &outYx, &outXy, &outYy, &outDx, &outDy);
354 	}
355 
356 	/**
357 	 * Converts a `GskTransform` to 2D affine transformation factors.
358 	 *
359 	 * @self must be a 2D transformation. If you are not
360 	 * sure, use gsk_transform_get_category() >=
361 	 * %GSK_TRANSFORM_CATEGORY_2D_AFFINE to check.
362 	 *
363 	 * Params:
364 	 *     outScaleX = return location for the scale
365 	 *         factor in the x direction
366 	 *     outScaleY = return location for the scale
367 	 *         factor in the y direction
368 	 *     outDx = return location for the translation
369 	 *         in the x direction
370 	 *     outDy = return location for the translation
371 	 *         in the y direction
372 	 */
373 	public void toAffine(out float outScaleX, out float outScaleY, out float outDx, out float outDy)
374 	{
375 		gsk_transform_to_affine(gskTransform, &outScaleX, &outScaleY, &outDx, &outDy);
376 	}
377 
378 	/**
379 	 * Computes the actual value of @self and stores it in @out_matrix.
380 	 *
381 	 * The previous value of @out_matrix will be ignored.
382 	 *
383 	 * Params:
384 	 *     outMatrix = The matrix to set
385 	 */
386 	public void toMatrix(out Matrix outMatrix)
387 	{
388 		graphene_matrix_t* outoutMatrix = sliceNew!graphene_matrix_t();
389 
390 		gsk_transform_to_matrix(gskTransform, outoutMatrix);
391 
392 		outMatrix = ObjectG.getDObject!(Matrix)(outoutMatrix, true);
393 	}
394 
395 	/**
396 	 * Converts a matrix into a string that is suitable for printing.
397 	 *
398 	 * The resulting string can be parsed with [func@Gsk.Transform.parse].
399 	 *
400 	 * This is a wrapper around [method@Gsk.Transform.print].
401 	 *
402 	 * Returns: A new string for @self
403 	 */
404 	public override string toString()
405 	{
406 		auto retStr = gsk_transform_to_string(gskTransform);
407 
408 		scope(exit) Str.freeString(retStr);
409 		return Str.toString(retStr);
410 	}
411 
412 	/**
413 	 * Converts a `GskTransform` to a translation operation.
414 	 *
415 	 * @self must be a 2D transformation. If you are not
416 	 * sure, use gsk_transform_get_category() >=
417 	 * %GSK_TRANSFORM_CATEGORY_2D_TRANSLATE to check.
418 	 *
419 	 * Params:
420 	 *     outDx = return location for the translation
421 	 *         in the x direction
422 	 *     outDy = return location for the translation
423 	 *         in the y direction
424 	 */
425 	public void toTranslate(out float outDx, out float outDy)
426 	{
427 		gsk_transform_to_translate(gskTransform, &outDx, &outDy);
428 	}
429 
430 	/**
431 	 * Applies all the operations from @other to @next.
432 	 *
433 	 * Params:
434 	 *     other = Transform to apply
435 	 *
436 	 * Returns: The new transform
437 	 */
438 	public Transform transform(Transform other)
439 	{
440 		auto __p = gsk_transform_transform(gskTransform, (other is null) ? null : other.getTransformStruct());
441 
442 		if(__p is null)
443 		{
444 			return null;
445 		}
446 
447 		return ObjectG.getDObject!(Transform)(cast(GskTransform*) __p, true);
448 	}
449 
450 	/**
451 	 * Transforms a `graphene_rect_t` using the given transform @self.
452 	 *
453 	 * The result is the bounding box containing the coplanar quad.
454 	 *
455 	 * Params:
456 	 *     rect = a `graphene_rect_t`
457 	 *     outRect = return location for the bounds
458 	 *         of the transformed rectangle
459 	 */
460 	public void transformBounds(Rect rect, out Rect outRect)
461 	{
462 		graphene_rect_t* outoutRect = sliceNew!graphene_rect_t();
463 
464 		gsk_transform_transform_bounds(gskTransform, (rect is null) ? null : rect.getRectStruct(), outoutRect);
465 
466 		outRect = ObjectG.getDObject!(Rect)(outoutRect, true);
467 	}
468 
469 	/**
470 	 * Transforms a `graphene_point_t` using the given transform @self.
471 	 *
472 	 * Params:
473 	 *     point = a `graphene_point_t`
474 	 *     outPoint = return location for
475 	 *         the transformed point
476 	 */
477 	public void transformPoint(Point point, out Point outPoint)
478 	{
479 		graphene_point_t* outoutPoint = sliceNew!graphene_point_t();
480 
481 		gsk_transform_transform_point(gskTransform, (point is null) ? null : point.getPointStruct(), outoutPoint);
482 
483 		outPoint = ObjectG.getDObject!(Point)(outoutPoint, true);
484 	}
485 
486 	/**
487 	 * Translates @next in 2-dimensional space by @point.
488 	 *
489 	 * Params:
490 	 *     point = the point to translate the transform by
491 	 *
492 	 * Returns: The new transform
493 	 */
494 	public Transform translate(Point point)
495 	{
496 		auto __p = gsk_transform_translate(gskTransform, (point is null) ? null : point.getPointStruct());
497 
498 		if(__p is null)
499 		{
500 			return null;
501 		}
502 
503 		return ObjectG.getDObject!(Transform)(cast(GskTransform*) __p, true);
504 	}
505 
506 	/**
507 	 * Translates @next by @point.
508 	 *
509 	 * Params:
510 	 *     point = the point to translate the transform by
511 	 *
512 	 * Returns: The new transform
513 	 */
514 	public Transform translate3d(Point3D point)
515 	{
516 		auto __p = gsk_transform_translate_3d(gskTransform, (point is null) ? null : point.getPoint3DStruct());
517 
518 		if(__p is null)
519 		{
520 			return null;
521 		}
522 
523 		return ObjectG.getDObject!(Transform)(cast(GskTransform*) __p, true);
524 	}
525 
526 	/**
527 	 * Releases a reference on the given `GskTransform`.
528 	 *
529 	 * If the reference was the last, the resources associated to the @self are
530 	 * freed.
531 	 */
532 	public void unref()
533 	{
534 		gsk_transform_unref(gskTransform);
535 	}
536 
537 	/**
538 	 * Parses the given @string into a transform and puts it in
539 	 * @out_transform.
540 	 *
541 	 * Strings printed via [method@Gsk.Transform.to_string]
542 	 * can be read in again successfully using this function.
543 	 *
544 	 * If @string does not describe a valid transform, %FALSE is
545 	 * returned and %NULL is put in @out_transform.
546 	 *
547 	 * Params:
548 	 *     string_ = the string to parse
549 	 *     outTransform = The location to put the transform in
550 	 *
551 	 * Returns: %TRUE if @string described a valid transform.
552 	 */
553 	public static bool parse(string string_, out Transform outTransform)
554 	{
555 		GskTransform* outoutTransform = null;
556 
557 		auto __p = gsk_transform_parse(Str.toStringz(string_), &outoutTransform) != 0;
558 
559 		outTransform = ObjectG.getDObject!(Transform)(outoutTransform);
560 
561 		return __p;
562 	}
563 }