actor-box: Split out ActorBox into its own file
[profile/ivi/clutter.git] / clutter / clutter-actor-box.c
1 #ifdef HAVE_CONFIG_H
2 #include "config.h"
3 #endif
4
5 #include "clutter-types.h"
6 #include "clutter-interval.h"
7 #include "clutter-private.h"
8
9 /**
10  * clutter_actor_box_new:
11  * @x_1: X coordinate of the top left point
12  * @y_1: Y coordinate of the top left point
13  * @x_2: X coordinate of the bottom right point
14  * @y_2: Y coordinate of the bottom right point
15  *
16  * Allocates a new #ClutterActorBox using the passed coordinates
17  * for the top left and bottom right points
18  *
19  * Return value: the newly allocated #ClutterActorBox. Use
20  *   clutter_actor_box_free() to free the resources
21  *
22  * Since: 1.0
23  */
24 ClutterActorBox *
25 clutter_actor_box_new (gfloat x_1,
26                        gfloat y_1,
27                        gfloat x_2,
28                        gfloat y_2)
29 {
30   ClutterActorBox *box;
31
32   box = g_slice_new (ClutterActorBox);
33   box->x1 = x_1;
34   box->y1 = y_1;
35   box->x2 = x_2;
36   box->y2 = y_2;
37
38   return box;
39 }
40
41 /**
42  * clutter_actor_box_copy:
43  * @box: a #ClutterActorBox
44  *
45  * Copies @box
46  *
47  * Return value: a newly allocated copy of #ClutterActorBox. Use
48  *   clutter_actor_box_free() to free the allocated resources
49  *
50  * Since: 1.0
51  */
52 ClutterActorBox *
53 clutter_actor_box_copy (const ClutterActorBox *box)
54 {
55   if (G_LIKELY (box != NULL))
56     return g_slice_dup (ClutterActorBox, box);
57
58   return NULL;
59 }
60
61 /**
62  * clutter_actor_box_free:
63  * @box: a #ClutterActorBox
64  *
65  * Frees a #ClutterActorBox allocated using clutter_actor_box_new()
66  * or clutter_actor_box_copy()
67  *
68  * Since: 1.0
69  */
70 void
71 clutter_actor_box_free (ClutterActorBox *box)
72 {
73   if (G_LIKELY (box != NULL))
74     g_slice_free (ClutterActorBox, box);
75 }
76
77 static gboolean
78 clutter_actor_box_progress (const GValue *a,
79                             const GValue *b,
80                             gdouble       factor,
81                             GValue       *retval)
82 {
83   ClutterActorBox res = { 0, };
84
85   clutter_actor_box_interpolate (g_value_get_boxed (a),
86                                  g_value_get_boxed (b),
87                                  factor,
88                                  &res);
89
90   g_value_set_boxed (retval, &res);
91
92   return TRUE;
93 }
94
95 GType
96 clutter_actor_box_get_type (void)
97 {
98   static GType our_type = 0;
99
100   if (G_UNLIKELY (our_type == 0))
101     {
102       our_type =
103         g_boxed_type_register_static (I_("ClutterActorBox"),
104                                       (GBoxedCopyFunc) clutter_actor_box_copy,
105                                       (GBoxedFreeFunc) clutter_actor_box_free);
106
107       clutter_interval_register_progress_func (our_type,
108                                                clutter_actor_box_progress);
109     }
110
111   return our_type;
112 }
113
114 /**
115  * clutter_actor_box_equal:
116  * @box_a: a #ClutterActorBox
117  * @box_b: a #ClutterActorBox
118  *
119  * Checks @box_a and @box_b for equality
120  *
121  * Return value: %TRUE if the passed #ClutterActorBox are equal
122  *
123  * Since: 1.0
124  */
125 gboolean
126 clutter_actor_box_equal (const ClutterActorBox *box_a,
127                          const ClutterActorBox *box_b)
128 {
129   g_return_val_if_fail (box_a != NULL && box_b != NULL, FALSE);
130
131   if (box_a == box_b)
132     return TRUE;
133
134   return box_a->x1 == box_b->x1 && box_a->y1 == box_b->y1 &&
135          box_a->x2 == box_b->x2 && box_a->y2 == box_b->y2;
136 }
137
138 /**
139  * clutter_actor_box_get_x:
140  * @box: a #ClutterActorBox
141  *
142  * Retrieves the X coordinate of the origin of @box
143  *
144  * Return value: the X coordinate of the origin
145  *
146  * Since: 1.0
147  */
148 gfloat
149 clutter_actor_box_get_x (const ClutterActorBox *box)
150 {
151   g_return_val_if_fail (box != NULL, 0.);
152
153   return box->x1;
154 }
155
156 /**
157  * clutter_actor_box_get_y:
158  * @box: a #ClutterActorBox
159  *
160  * Retrieves the Y coordinate of the origin of @box
161  *
162  * Return value: the Y coordinate of the origin
163  *
164  * Since: 1.0
165  */
166 gfloat
167 clutter_actor_box_get_y (const ClutterActorBox *box)
168 {
169   g_return_val_if_fail (box != NULL, 0.);
170
171   return box->y1;
172 }
173
174 /**
175  * clutter_actor_box_get_width:
176  * @box: a #ClutterActorBox
177  *
178  * Retrieves the width of the @box
179  *
180  * Return value: the width of the box
181  *
182  * Since: 1.0
183  */
184 gfloat
185 clutter_actor_box_get_width (const ClutterActorBox *box)
186 {
187   g_return_val_if_fail (box != NULL, 0.);
188
189   return box->x2 - box->x1;
190 }
191
192 /**
193  * clutter_actor_box_get_height:
194  * @box: a #ClutterActorBox
195  *
196  * Retrieves the height of the @box
197  *
198  * Return value: the height of the box
199  *
200  * Since: 1.0
201  */
202 gfloat
203 clutter_actor_box_get_height (const ClutterActorBox *box)
204 {
205   g_return_val_if_fail (box != NULL, 0.);
206
207   return box->y2 - box->y1;
208 }
209
210 /**
211  * clutter_actor_box_get_origin:
212  * @box: a #ClutterActorBox
213  * @x: (out) (allow-none): return location for the X coordinate, or %NULL
214  * @y: (out) (allow-none): return location for the Y coordinate, or %NULL
215  *
216  * Retrieves the origin of @box
217  *
218  * Since: 1.0
219  */
220 void
221 clutter_actor_box_get_origin (const ClutterActorBox *box,
222                               gfloat                *x,
223                               gfloat                *y)
224 {
225   g_return_if_fail (box != NULL);
226
227   if (x)
228     *x = box->x1;
229
230   if (y)
231     *y = box->y1;
232 }
233
234 /**
235  * clutter_actor_box_get_size:
236  * @box: a #ClutterActorBox
237  * @width: (out) (allow-none): return location for the width, or %NULL
238  * @height: (out) (allow-none): return location for the height, or %NULL
239  *
240  * Retrieves the size of @box
241  *
242  * Since: 1.0
243  */
244 void
245 clutter_actor_box_get_size (const ClutterActorBox *box,
246                             gfloat                *width,
247                             gfloat                *height)
248 {
249   g_return_if_fail (box != NULL);
250
251   if (width)
252     *width = box->x2 - box->x1;
253
254   if (height)
255     *height = box->y2 - box->y1;
256 }
257
258 /**
259  * clutter_actor_box_get_area:
260  * @box: a #ClutterActorBox
261  *
262  * Retrieves the area of @box
263  *
264  * Return value: the area of a #ClutterActorBox, in pixels
265  *
266  * Since: 1.0
267  */
268 gfloat
269 clutter_actor_box_get_area (const ClutterActorBox *box)
270 {
271   g_return_val_if_fail (box != NULL, 0.);
272
273   return (box->x2 - box->x1) * (box->y2 - box->y1);
274 }
275
276 /**
277  * clutter_actor_box_contains:
278  * @box: a #ClutterActorBox
279  * @x: X coordinate of the point
280  * @y: Y coordinate of the point
281  *
282  * Checks whether a point with @x, @y coordinates is contained
283  * withing @box
284  *
285  * Return value: %TRUE if the point is contained by the #ClutterActorBox
286  *
287  * Since: 1.0
288  */
289 gboolean
290 clutter_actor_box_contains (const ClutterActorBox *box,
291                             gfloat                 x,
292                             gfloat                 y)
293 {
294   g_return_val_if_fail (box != NULL, FALSE);
295
296   return (x > box->x1 && x < box->x2) &&
297          (y > box->y1 && y < box->y2);
298 }
299
300 /**
301  * clutter_actor_box_from_vertices:
302  * @box: a #ClutterActorBox
303  * @verts: (array fixed-size=4): array of four #ClutterVertex
304  *
305  * Calculates the bounding box represented by the four vertices; for details
306  * of the vertex array see clutter_actor_get_abs_allocation_vertices().
307  *
308  * Since: 1.0
309  */
310 void
311 clutter_actor_box_from_vertices (ClutterActorBox     *box,
312                                  const ClutterVertex  verts[])
313 {
314   gfloat x_1, x_2, y_1, y_2;
315
316   g_return_if_fail (box != NULL);
317   g_return_if_fail (verts != NULL);
318
319   /* 4-way min/max */
320   x_1 = verts[0].x;
321   y_1 = verts[0].y;
322
323   if (verts[1].x < x_1)
324     x_1 = verts[1].x;
325
326   if (verts[2].x < x_1)
327     x_1 = verts[2].x;
328
329   if (verts[3].x < x_1)
330     x_1 = verts[3].x;
331
332   if (verts[1].y < y_1)
333     y_1 = verts[1].y;
334
335   if (verts[2].y < y_1)
336     y_1 = verts[2].y;
337
338   if (verts[3].y < y_1)
339     y_1 = verts[3].y;
340
341   x_2 = verts[0].x;
342   y_2 = verts[0].y;
343
344   if (verts[1].x > x_2)
345     x_2 = verts[1].x;
346
347   if (verts[2].x > x_2)
348     x_2 = verts[2].x;
349
350   if (verts[3].x > x_2)
351     x_2 = verts[3].x;
352
353   if (verts[1].y > y_2)
354     y_2 = verts[1].y;
355
356   if (verts[2].y > y_2)
357     y_2 = verts[2].y;
358
359   if (verts[3].y > y_2)
360     y_2 = verts[3].y;
361
362   box->x1 = x_1;
363   box->x2 = x_2;
364   box->y1 = y_1;
365   box->y2 = y_2;
366 }
367
368 /**
369  * clutter_actor_box_interpolate:
370  * @initial: the initial #ClutterActorBox
371  * @final: the final #ClutterActorBox
372  * @progress: the interpolation progress
373  * @result: (out): return location for the interpolation
374  *
375  * Interpolates between @initial and @final #ClutterActorBox<!-- -->es
376  * using @progress
377  *
378  * Since: 1.2
379  */
380 void
381 clutter_actor_box_interpolate (const ClutterActorBox *initial,
382                                const ClutterActorBox *final,
383                                gdouble                progress,
384                                ClutterActorBox       *result)
385 {
386   g_return_if_fail (initial != NULL);
387   g_return_if_fail (final != NULL);
388   g_return_if_fail (result != NULL);
389
390   result->x1 = initial->x1 + (final->x1 - initial->x1) * progress;
391   result->y1 = initial->y1 + (final->y1 - initial->y1) * progress;
392   result->x2 = initial->x2 + (final->x2 - initial->x2) * progress;
393   result->y2 = initial->y2 + (final->y2 - initial->y2) * progress;
394 }
395
396 /**
397  * clutter_actor_box_clamp_to_pixel:
398  * @box: (inout): the #ClutterActorBox to clamp
399  *
400  * Clamps the components of @box to the nearest integer
401  *
402  * Since: 1.2
403  */
404 void
405 clutter_actor_box_clamp_to_pixel (ClutterActorBox *box)
406 {
407   g_return_if_fail (box != NULL);
408
409   box->x1 = floorf (box->x1);
410   box->y1 = floorf (box->y1);
411   box->x2 = ceilf (box->x2);
412   box->y2 = ceilf (box->y2);
413 }
414
415 /**
416  * clutter_actor_box_union:
417  * @a: (in) the first #ClutterActorBox
418  * @b: (in): the second #ClutterActorBox
419  * @result: (out): the #ClutterActorBox representing a union
420  *   of @a and @b
421  *
422  * Unions the two boxes @a and @b and stores the result in @result.
423  *
424  * Since: 1.4
425  */
426 void
427 clutter_actor_box_union (const ClutterActorBox *a,
428                          const ClutterActorBox *b,
429                          ClutterActorBox       *result)
430 {
431   g_return_if_fail (a != NULL);
432   g_return_if_fail (b != NULL);
433   g_return_if_fail (result != NULL);
434
435   result->x1 = MIN (a->x1, b->x1);
436   result->y1 = MIN (a->y1, b->y1);
437
438   result->x2 = MAX (a->x2, b->x2);
439   result->y2 = MAX (a->y2, b->y2);
440 }