[clutter/master-next: 4/51] Add base geometric types
- From: Emmanuele Bassi <ebassi src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [clutter/master-next: 4/51] Add base geometric types
- Date: Wed, 25 Apr 2012 16:38:00 +0000 (UTC)
commit 3d2a214cabaf89c7e7e01c4ee690479e195438fa
Author: Emmanuele Bassi <ebassi linux intel com>
Date: Fri Mar 30 18:22:04 2012 +0100
Add base geometric types
Clutter should provide some more basic geometric types - Point, Size,
Rect - so that we can use them in properties and accessors.
clutter/Makefile.am | 1 +
clutter/clutter-actor.c | 299 ------------
clutter/clutter-base-types.c | 1027 ++++++++++++++++++++++++++++++++++++++++++
clutter/clutter-types.h | 138 ++++++-
clutter/clutter.symbols | 30 ++
5 files changed, 1192 insertions(+), 303 deletions(-)
---
diff --git a/clutter/Makefile.am b/clutter/Makefile.am
index 8679249..9130af2 100644
--- a/clutter/Makefile.am
+++ b/clutter/Makefile.am
@@ -138,6 +138,7 @@ source_c = \
$(srcdir)/clutter-animation.c \
$(srcdir)/clutter-animator.c \
$(srcdir)/clutter-backend.c \
+ $(srcdir)/clutter-base-types.c \
$(srcdir)/clutter-bezier.c \
$(srcdir)/clutter-bind-constraint.c \
$(srcdir)/clutter-binding-pool.c \
diff --git a/clutter/clutter-actor.c b/clutter/clutter-actor.c
index a05d46b..85126e3 100644
--- a/clutter/clutter-actor.c
+++ b/clutter/clutter-actor.c
@@ -13264,247 +13264,6 @@ clutter_actor_transform_stage_point (ClutterActor *self,
return TRUE;
}
-/*
- * ClutterGeometry
- */
-
-static ClutterGeometry*
-clutter_geometry_copy (const ClutterGeometry *geometry)
-{
- return g_slice_dup (ClutterGeometry, geometry);
-}
-
-static void
-clutter_geometry_free (ClutterGeometry *geometry)
-{
- if (G_LIKELY (geometry != NULL))
- g_slice_free (ClutterGeometry, geometry);
-}
-
-/**
- * clutter_geometry_union:
- * @geometry_a: a #ClutterGeometry
- * @geometry_b: another #ClutterGeometry
- * @result: (out): location to store the result
- *
- * Find the union of two rectangles represented as #ClutterGeometry.
- *
- * Since: 1.4
- */
-void
-clutter_geometry_union (const ClutterGeometry *geometry_a,
- const ClutterGeometry *geometry_b,
- ClutterGeometry *result)
-{
- /* We don't try to handle rectangles that can't be represented
- * as a signed integer box */
- gint x_1 = MIN (geometry_a->x, geometry_b->x);
- gint y_1 = MIN (geometry_a->y, geometry_b->y);
- gint x_2 = MAX (geometry_a->x + (gint)geometry_a->width,
- geometry_b->x + (gint)geometry_b->width);
- gint y_2 = MAX (geometry_a->y + (gint)geometry_a->height,
- geometry_b->y + (gint)geometry_b->height);
- result->x = x_1;
- result->y = y_1;
- result->width = x_2 - x_1;
- result->height = y_2 - y_1;
-}
-
-/**
- * clutter_geometry_intersects:
- * @geometry0: The first geometry to test
- * @geometry1: The second geometry to test
- *
- * Determines if @geometry0 and geometry1 intersect returning %TRUE if
- * they do else %FALSE.
- *
- * Return value: %TRUE of @geometry0 and geometry1 intersect else
- * %FALSE.
- *
- * Since: 1.4
- */
-gboolean
-clutter_geometry_intersects (const ClutterGeometry *geometry0,
- const ClutterGeometry *geometry1)
-{
- if (geometry1->x >= (geometry0->x + (gint)geometry0->width) ||
- geometry1->y >= (geometry0->y + (gint)geometry0->height) ||
- (geometry1->x + (gint)geometry1->width) <= geometry0->x ||
- (geometry1->y + (gint)geometry1->height) <= geometry0->y)
- return FALSE;
- else
- return TRUE;
-}
-
-static gboolean
-clutter_geometry_progress (const GValue *a,
- const GValue *b,
- gdouble progress,
- GValue *retval)
-{
- const ClutterGeometry *a_geom = g_value_get_boxed (a);
- const ClutterGeometry *b_geom = g_value_get_boxed (b);
- ClutterGeometry res = { 0, };
- gint a_width = a_geom->width;
- gint b_width = b_geom->width;
- gint a_height = a_geom->height;
- gint b_height = b_geom->height;
-
- res.x = a_geom->x + (b_geom->x - a_geom->x) * progress;
- res.y = a_geom->y + (b_geom->y - a_geom->y) * progress;
-
- res.width = a_width + (b_width - a_width) * progress;
- res.height = a_height + (b_height - a_height) * progress;
-
- g_value_set_boxed (retval, &res);
-
- return TRUE;
-}
-
-G_DEFINE_BOXED_TYPE_WITH_CODE (ClutterGeometry, clutter_geometry,
- clutter_geometry_copy,
- clutter_geometry_free,
- CLUTTER_REGISTER_INTERVAL_PROGRESS (clutter_geometry_progress));
-
-/*
- * ClutterVertices
- */
-
-/**
- * clutter_vertex_new:
- * @x: X coordinate
- * @y: Y coordinate
- * @z: Z coordinate
- *
- * Creates a new #ClutterVertex for the point in 3D space
- * identified by the 3 coordinates @x, @y, @z
- *
- * Return value: the newly allocate #ClutterVertex. Use
- * clutter_vertex_free() to free the resources
- *
- * Since: 1.0
- */
-ClutterVertex *
-clutter_vertex_new (gfloat x,
- gfloat y,
- gfloat z)
-{
- ClutterVertex *vertex;
-
- vertex = g_slice_new (ClutterVertex);
- clutter_vertex_init (vertex, x, y, z);
-
- return vertex;
-}
-
-/**
- * clutter_vertex_init:
- * @vertex: a #ClutterVertex
- * @x: X coordinate
- * @y: Y coordinate
- * @z: Z coordinate
- *
- * Initializes @vertex with the given coordinates.
- *
- * Since: 1.10
- */
-void
-clutter_vertex_init (ClutterVertex *vertex,
- gfloat x,
- gfloat y,
- gfloat z)
-{
- g_return_if_fail (vertex != NULL);
-
- vertex->x = x;
- vertex->y = y;
- vertex->z = z;
-}
-
-/**
- * clutter_vertex_copy:
- * @vertex: a #ClutterVertex
- *
- * Copies @vertex
- *
- * Return value: a newly allocated copy of #ClutterVertex. Use
- * clutter_vertex_free() to free the allocated resources
- *
- * Since: 1.0
- */
-ClutterVertex *
-clutter_vertex_copy (const ClutterVertex *vertex)
-{
- if (G_LIKELY (vertex != NULL))
- return g_slice_dup (ClutterVertex, vertex);
-
- return NULL;
-}
-
-/**
- * clutter_vertex_free:
- * @vertex: a #ClutterVertex
- *
- * Frees a #ClutterVertex allocated using clutter_vertex_copy()
- *
- * Since: 1.0
- */
-void
-clutter_vertex_free (ClutterVertex *vertex)
-{
- if (G_UNLIKELY (vertex != NULL))
- g_slice_free (ClutterVertex, vertex);
-}
-
-/**
- * clutter_vertex_equal:
- * @vertex_a: a #ClutterVertex
- * @vertex_b: a #ClutterVertex
- *
- * Compares @vertex_a and @vertex_b for equality
- *
- * Return value: %TRUE if the passed #ClutterVertex are equal
- *
- * Since: 1.0
- */
-gboolean
-clutter_vertex_equal (const ClutterVertex *vertex_a,
- const ClutterVertex *vertex_b)
-{
- g_return_val_if_fail (vertex_a != NULL && vertex_b != NULL, FALSE);
-
- if (vertex_a == vertex_b)
- return TRUE;
-
- return vertex_a->x == vertex_b->x &&
- vertex_a->y == vertex_b->y &&
- vertex_a->z == vertex_b->z;
-}
-
-static gboolean
-clutter_vertex_progress (const GValue *a,
- const GValue *b,
- gdouble progress,
- GValue *retval)
-{
- const ClutterVertex *av = g_value_get_boxed (a);
- const ClutterVertex *bv = g_value_get_boxed (b);
- ClutterVertex res = { 0, };
-
- res.x = av->x + (bv->x - av->x) * progress;
- res.y = av->y + (bv->y - av->y) * progress;
- res.z = av->z + (bv->z - av->z) * progress;
-
- g_value_set_boxed (retval, &res);
-
- return TRUE;
-}
-
-G_DEFINE_BOXED_TYPE_WITH_CODE (ClutterVertex, clutter_vertex,
- clutter_vertex_copy,
- clutter_vertex_free,
- CLUTTER_REGISTER_INTERVAL_PROGRESS (clutter_vertex_progress));
-
/**
* clutter_actor_is_rotated:
* @self: a #ClutterActor
@@ -16229,64 +15988,6 @@ clutter_actor_get_y_align (ClutterActor *self)
return _clutter_actor_get_layout_info_or_defaults (self)->y_align;
}
-
-/**
- * clutter_margin_new:
- *
- * Creates a new #ClutterMargin.
- *
- * Return value: (transfer full): a newly allocated #ClutterMargin. Use
- * clutter_margin_free() to free the resources associated with it when
- * done.
- *
- * Since: 1.10
- */
-ClutterMargin *
-clutter_margin_new (void)
-{
- return g_slice_new0 (ClutterMargin);
-}
-
-/**
- * clutter_margin_copy:
- * @margin_: a #ClutterMargin
- *
- * Creates a new #ClutterMargin and copies the contents of @margin_ into
- * the newly created structure.
- *
- * Return value: (transfer full): a copy of the #ClutterMargin.
- *
- * Since: 1.10
- */
-ClutterMargin *
-clutter_margin_copy (const ClutterMargin *margin_)
-{
- if (G_LIKELY (margin_ != NULL))
- return g_slice_dup (ClutterMargin, margin_);
-
- return NULL;
-}
-
-/**
- * clutter_margin_free:
- * @margin_: a #ClutterMargin
- *
- * Frees the resources allocated by clutter_margin_new() and
- * clutter_margin_copy().
- *
- * Since: 1.10
- */
-void
-clutter_margin_free (ClutterMargin *margin_)
-{
- if (G_LIKELY (margin_ != NULL))
- g_slice_free (ClutterMargin, margin_);
-}
-
-G_DEFINE_BOXED_TYPE (ClutterMargin, clutter_margin,
- clutter_margin_copy,
- clutter_margin_free)
-
/**
* clutter_actor_set_margin:
* @self: a #ClutterActor
diff --git a/clutter/clutter-base-types.c b/clutter/clutter-base-types.c
new file mode 100644
index 0000000..493ff0d
--- /dev/null
+++ b/clutter/clutter-base-types.c
@@ -0,0 +1,1027 @@
+/*
+ * Clutter.
+ *
+ * An OpenGL based 'interactive canvas' library.
+ *
+ * Authored By Matthew Allum <mallum openedhand com>
+ *
+ * Copyright (C) 2006 OpenedHand
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+/**
+ * SECTION:clutter-base-types
+ * @Title: Base data types
+ * @Short_Description: Common data types used by Clutter
+ *
+ * Clutter defines a set of data structures that are commonly used across the
+ * whole API.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "clutter-types.h"
+#include "clutter-private.h"
+
+#include <math.h>
+
+
+
+/*
+ * ClutterGeometry
+ */
+
+static ClutterGeometry*
+clutter_geometry_copy (const ClutterGeometry *geometry)
+{
+ return g_slice_dup (ClutterGeometry, geometry);
+}
+
+static void
+clutter_geometry_free (ClutterGeometry *geometry)
+{
+ if (G_LIKELY (geometry != NULL))
+ g_slice_free (ClutterGeometry, geometry);
+}
+
+/**
+ * clutter_geometry_union:
+ * @geometry_a: a #ClutterGeometry
+ * @geometry_b: another #ClutterGeometry
+ * @result: (out): location to store the result
+ *
+ * Find the union of two rectangles represented as #ClutterGeometry.
+ *
+ * Since: 1.4
+ */
+void
+clutter_geometry_union (const ClutterGeometry *geometry_a,
+ const ClutterGeometry *geometry_b,
+ ClutterGeometry *result)
+{
+ /* We don't try to handle rectangles that can't be represented
+ * as a signed integer box */
+ gint x_1 = MIN (geometry_a->x, geometry_b->x);
+ gint y_1 = MIN (geometry_a->y, geometry_b->y);
+ gint x_2 = MAX (geometry_a->x + (gint)geometry_a->width,
+ geometry_b->x + (gint)geometry_b->width);
+ gint y_2 = MAX (geometry_a->y + (gint)geometry_a->height,
+ geometry_b->y + (gint)geometry_b->height);
+ result->x = x_1;
+ result->y = y_1;
+ result->width = x_2 - x_1;
+ result->height = y_2 - y_1;
+}
+
+/**
+ * clutter_geometry_intersects:
+ * @geometry0: The first geometry to test
+ * @geometry1: The second geometry to test
+ *
+ * Determines if @geometry0 and geometry1 intersect returning %TRUE if
+ * they do else %FALSE.
+ *
+ * Return value: %TRUE of @geometry0 and geometry1 intersect else
+ * %FALSE.
+ *
+ * Since: 1.4
+ */
+gboolean
+clutter_geometry_intersects (const ClutterGeometry *geometry0,
+ const ClutterGeometry *geometry1)
+{
+ if (geometry1->x >= (geometry0->x + (gint)geometry0->width) ||
+ geometry1->y >= (geometry0->y + (gint)geometry0->height) ||
+ (geometry1->x + (gint)geometry1->width) <= geometry0->x ||
+ (geometry1->y + (gint)geometry1->height) <= geometry0->y)
+ return FALSE;
+ else
+ return TRUE;
+}
+
+static gboolean
+clutter_geometry_progress (const GValue *a,
+ const GValue *b,
+ gdouble progress,
+ GValue *retval)
+{
+ const ClutterGeometry *a_geom = g_value_get_boxed (a);
+ const ClutterGeometry *b_geom = g_value_get_boxed (b);
+ ClutterGeometry res = { 0, };
+ gint a_width = a_geom->width;
+ gint b_width = b_geom->width;
+ gint a_height = a_geom->height;
+ gint b_height = b_geom->height;
+
+ res.x = a_geom->x + (b_geom->x - a_geom->x) * progress;
+ res.y = a_geom->y + (b_geom->y - a_geom->y) * progress;
+
+ res.width = a_width + (b_width - a_width) * progress;
+ res.height = a_height + (b_height - a_height) * progress;
+
+ g_value_set_boxed (retval, &res);
+
+ return TRUE;
+}
+
+G_DEFINE_BOXED_TYPE_WITH_CODE (ClutterGeometry, clutter_geometry,
+ clutter_geometry_copy,
+ clutter_geometry_free,
+ CLUTTER_REGISTER_INTERVAL_PROGRESS (clutter_geometry_progress));
+
+
+
+/*
+ * ClutterVertices
+ */
+
+/**
+ * clutter_vertex_new:
+ * @x: X coordinate
+ * @y: Y coordinate
+ * @z: Z coordinate
+ *
+ * Creates a new #ClutterVertex for the point in 3D space
+ * identified by the 3 coordinates @x, @y, @z
+ *
+ * Return value: the newly allocate #ClutterVertex. Use
+ * clutter_vertex_free() to free the resources
+ *
+ * Since: 1.0
+ */
+ClutterVertex *
+clutter_vertex_new (gfloat x,
+ gfloat y,
+ gfloat z)
+{
+ ClutterVertex *vertex;
+
+ vertex = g_slice_new (ClutterVertex);
+ clutter_vertex_init (vertex, x, y, z);
+
+ return vertex;
+}
+
+/**
+ * clutter_vertex_init:
+ * @vertex: a #ClutterVertex
+ * @x: X coordinate
+ * @y: Y coordinate
+ * @z: Z coordinate
+ *
+ * Initializes @vertex with the given coordinates.
+ *
+ * Since: 1.10
+ */
+void
+clutter_vertex_init (ClutterVertex *vertex,
+ gfloat x,
+ gfloat y,
+ gfloat z)
+{
+ g_return_if_fail (vertex != NULL);
+
+ vertex->x = x;
+ vertex->y = y;
+ vertex->z = z;
+}
+
+/**
+ * clutter_vertex_copy:
+ * @vertex: a #ClutterVertex
+ *
+ * Copies @vertex
+ *
+ * Return value: a newly allocated copy of #ClutterVertex. Use
+ * clutter_vertex_free() to free the allocated resources
+ *
+ * Since: 1.0
+ */
+ClutterVertex *
+clutter_vertex_copy (const ClutterVertex *vertex)
+{
+ if (G_LIKELY (vertex != NULL))
+ return g_slice_dup (ClutterVertex, vertex);
+
+ return NULL;
+}
+
+/**
+ * clutter_vertex_free:
+ * @vertex: a #ClutterVertex
+ *
+ * Frees a #ClutterVertex allocated using clutter_vertex_copy()
+ *
+ * Since: 1.0
+ */
+void
+clutter_vertex_free (ClutterVertex *vertex)
+{
+ if (G_UNLIKELY (vertex != NULL))
+ g_slice_free (ClutterVertex, vertex);
+}
+
+/**
+ * clutter_vertex_equal:
+ * @vertex_a: a #ClutterVertex
+ * @vertex_b: a #ClutterVertex
+ *
+ * Compares @vertex_a and @vertex_b for equality
+ *
+ * Return value: %TRUE if the passed #ClutterVertex are equal
+ *
+ * Since: 1.0
+ */
+gboolean
+clutter_vertex_equal (const ClutterVertex *vertex_a,
+ const ClutterVertex *vertex_b)
+{
+ g_return_val_if_fail (vertex_a != NULL && vertex_b != NULL, FALSE);
+
+ if (vertex_a == vertex_b)
+ return TRUE;
+
+ return vertex_a->x == vertex_b->x &&
+ vertex_a->y == vertex_b->y &&
+ vertex_a->z == vertex_b->z;
+}
+
+static gboolean
+clutter_vertex_progress (const GValue *a,
+ const GValue *b,
+ gdouble progress,
+ GValue *retval)
+{
+ const ClutterVertex *av = g_value_get_boxed (a);
+ const ClutterVertex *bv = g_value_get_boxed (b);
+ ClutterVertex res = { 0, };
+
+ res.x = av->x + (bv->x - av->x) * progress;
+ res.y = av->y + (bv->y - av->y) * progress;
+ res.z = av->z + (bv->z - av->z) * progress;
+
+ g_value_set_boxed (retval, &res);
+
+ return TRUE;
+}
+
+G_DEFINE_BOXED_TYPE_WITH_CODE (ClutterVertex, clutter_vertex,
+ clutter_vertex_copy,
+ clutter_vertex_free,
+ CLUTTER_REGISTER_INTERVAL_PROGRESS (clutter_vertex_progress));
+
+
+
+/*
+ * ClutterMargin
+ */
+
+/**
+ * clutter_margin_new:
+ *
+ * Creates a new #ClutterMargin.
+ *
+ * Return value: (transfer full): a newly allocated #ClutterMargin. Use
+ * clutter_margin_free() to free the resources associated with it when
+ * done.
+ *
+ * Since: 1.10
+ */
+ClutterMargin *
+clutter_margin_new (void)
+{
+ return g_slice_new0 (ClutterMargin);
+}
+
+/**
+ * clutter_margin_copy:
+ * @margin_: a #ClutterMargin
+ *
+ * Creates a new #ClutterMargin and copies the contents of @margin_ into
+ * the newly created structure.
+ *
+ * Return value: (transfer full): a copy of the #ClutterMargin.
+ *
+ * Since: 1.10
+ */
+ClutterMargin *
+clutter_margin_copy (const ClutterMargin *margin_)
+{
+ if (G_LIKELY (margin_ != NULL))
+ return g_slice_dup (ClutterMargin, margin_);
+
+ return NULL;
+}
+
+/**
+ * clutter_margin_free:
+ * @margin_: a #ClutterMargin
+ *
+ * Frees the resources allocated by clutter_margin_new() and
+ * clutter_margin_copy().
+ *
+ * Since: 1.10
+ */
+void
+clutter_margin_free (ClutterMargin *margin_)
+{
+ if (G_LIKELY (margin_ != NULL))
+ g_slice_free (ClutterMargin, margin_);
+}
+
+G_DEFINE_BOXED_TYPE (ClutterMargin, clutter_margin,
+ clutter_margin_copy,
+ clutter_margin_free)
+
+
+
+/*
+ * ClutterPoint
+ */
+
+ClutterPoint *
+clutter_point_new (void)
+{
+ return g_slice_new0 (ClutterPoint);
+}
+
+ClutterPoint *
+clutter_point_init (ClutterPoint *point,
+ float x,
+ float y)
+{
+ g_return_val_if_fail (point != NULL, NULL);
+
+ point->x = x;
+ point->y = y;
+
+ return point;
+}
+
+ClutterPoint *
+clutter_point_copy (const ClutterPoint *point)
+{
+ return g_slice_dup (ClutterPoint, point);
+}
+
+void
+clutter_point_free (ClutterPoint *point)
+{
+ if (point != NULL)
+ g_slice_free (ClutterPoint, point);
+}
+
+gboolean
+clutter_point_equals (const ClutterPoint *a,
+ const ClutterPoint *b)
+{
+ if (a == b)
+ return TRUE;
+
+ if (a == NULL || b == NULL)
+ return FALSE;
+
+ return a->x == b->x && a->y == b->y;
+}
+
+static gboolean
+clutter_point_progress (const GValue *a,
+ const GValue *b,
+ gdouble progress,
+ GValue *retval)
+{
+ const ClutterPoint *ap = g_value_get_boxed (a);
+ const ClutterPoint *bp = g_value_get_boxed (b);
+ ClutterPoint res = CLUTTER_POINT_INIT (0, 0);
+
+ res.x = ap->x + (bp->x - ap->x) * progress;
+ res.y = ap->y + (bp->y - ap->y) * progress;
+
+ g_value_set_boxed (retval, &res);
+
+ return TRUE;
+}
+
+G_DEFINE_BOXED_TYPE_WITH_CODE (ClutterPoint, clutter_point,
+ clutter_point_copy,
+ clutter_point_free,
+ CLUTTER_REGISTER_INTERVAL_PROGRESS (clutter_point_progress))
+
+
+
+/*
+ * ClutterSize
+ */
+
+ClutterSize *
+clutter_size_new (void)
+{
+ return g_slice_new0 (ClutterSize);
+}
+
+ClutterSize *
+clutter_size_init (ClutterSize *size,
+ float width,
+ float height)
+{
+ g_return_val_if_fail (size != NULL, NULL);
+
+ size->width = width;
+ size->height = height;
+
+ return size;
+}
+
+ClutterSize *
+clutter_size_copy (const ClutterSize *size)
+{
+ return g_slice_dup (ClutterSize, size);
+}
+
+void
+clutter_size_free (ClutterSize *size)
+{
+ if (size != NULL)
+ g_slice_free (ClutterSize, size);
+}
+
+gboolean
+clutter_size_equals (const ClutterSize *a,
+ const ClutterSize *b)
+{
+ if (a == b)
+ return TRUE;
+
+ if (a == NULL || b == NULL)
+ return FALSE;
+
+ return a->width == b->width && a->height == b->height;
+}
+
+static gboolean
+clutter_size_progress (const GValue *a,
+ const GValue *b,
+ gdouble progress,
+ GValue *retval)
+{
+ const ClutterSize *as = g_value_get_boxed (a);
+ const ClutterSize *bs = g_value_get_boxed (b);
+ ClutterSize res = CLUTTER_SIZE_INIT (0, 0);
+
+ res.width = as->width + (bs->width - as->width) * progress;
+ res.height = as->height + (bs->height - as->height) * progress;
+
+ g_value_set_boxed (retval, &res);
+
+ return TRUE;
+}
+
+G_DEFINE_BOXED_TYPE_WITH_CODE (ClutterSize, clutter_size,
+ clutter_size_copy,
+ clutter_size_free,
+ CLUTTER_REGISTER_INTERVAL_PROGRESS (clutter_size_progress))
+
+
+
+/*
+ * ClutterRect
+ */
+
+static gboolean clutter_rect_progress (const GValue *a,
+ const GValue *b,
+ gdouble progress,
+ GValue *res);
+
+G_DEFINE_BOXED_TYPE_WITH_CODE (ClutterRect, clutter_rect,
+ clutter_rect_copy,
+ clutter_rect_free,
+ CLUTTER_REGISTER_INTERVAL_PROGRESS (clutter_rect_progress))
+
+static inline void
+clutter_rect_normalize_internal (ClutterRect *rect)
+{
+ if (rect->size.width >= 0.f && rect->size.height >= 0.f)
+ return;
+
+ if (rect->size.width < 0.f)
+ {
+ float size = fabsf (rect->size.width);
+
+ rect->origin.x -= size;
+ rect->size.width = size;
+ }
+
+ if (rect->size.height < 0.f)
+ {
+ float size = fabsf (rect->size.height);
+
+ rect->origin.y -= size;
+ rect->size.height = size;
+ }
+}
+
+/**
+ * clutter_rect_new:
+ *
+ * Creates a new, empty #ClutterRect.
+ *
+ * You can use clutter_rect_init() to initialize the returned rectangle,
+ * for instance:
+ *
+ * |[
+ * ClutterRect *rect;
+ *
+ * rect = clutter_rect_init (clutter_rect_new (), x, y, width, height);
+ * ]|
+ *
+ * Return value: (transfer full): the newly allocated #ClutterRect.
+ * Use clutter_rect_free() to free its resources
+ *
+ * Since: 1.12
+ */
+ClutterRect *
+clutter_rect_new (void)
+{
+ return g_slice_new0 (ClutterRect);
+}
+
+/**
+ * clutter_rect_init:
+ * @rect: a #ClutterRect
+ * @x: X coordinate of the origin
+ * @y: Y coordinate of the origin
+ * @width: width of the rectangle
+ * @height: height of the rectangle
+ *
+ * Initializes a #ClutterRect with the given origin and size.
+ *
+ * Return value: (transfer none): the updated rectangle
+ *
+ * Since: 1.12
+ */
+ClutterRect *
+clutter_rect_init (ClutterRect *rect,
+ float x,
+ float y,
+ float width,
+ float height)
+{
+ g_return_val_if_fail (rect != NULL, NULL);
+
+ rect->origin.x = x;
+ rect->origin.y = y;
+
+ rect->size.width = width;
+ rect->size.height = height;
+
+ return rect;
+}
+
+/**
+ * clutter_rect_copy:
+ * @rect: a #ClutterRect
+ *
+ * Copies @rect into a new #ClutterRect instance.
+ *
+ * Return value: (transfer full): the newly allocate copy of @rect.
+ * Use clutter_rect_free() to free the associated resources
+ *
+ * Since: 1.12
+ */
+ClutterRect *
+clutter_rect_copy (const ClutterRect *rect)
+{
+ if (rect != NULL)
+ {
+ ClutterRect *res;
+
+ res = g_slice_dup (ClutterRect, rect);
+ clutter_rect_normalize_internal (res);
+
+ return res;
+ }
+
+ return NULL;
+}
+
+/**
+ * clutter_rect_free:
+ * @rect: a #ClutterRect
+ *
+ * Frees the resources allocated by @rect.
+ *
+ * Since: 1.12
+ */
+void
+clutter_rect_free (ClutterRect *rect)
+{
+ if (rect != NULL)
+ g_slice_free (ClutterRect, rect);
+}
+
+/**
+ * clutter_rect_equals:
+ * @a: a #ClutterRect
+ * @b: a #ClutterRect
+ *
+ * Checks whether @a and @b are equals.
+ *
+ * This function will normalize both @a and @b before comparing
+ * their origin and size.
+ *
+ * Return value: %TRUE if the rectangles match in origin and size.
+ *
+ * Since: 1.12
+ */
+gboolean
+clutter_rect_equals (ClutterRect *a,
+ ClutterRect *b)
+{
+ if (a == b)
+ return TRUE;
+
+ if (a == NULL || b == NULL)
+ return FALSE;
+
+ clutter_rect_normalize_internal (a);
+ clutter_rect_normalize_internal (b);
+
+ return clutter_point_equals (&a->origin, &b->origin) &&
+ clutter_size_equals (&a->size, &b->size);
+}
+
+/**
+ * clutter_rect_normalize:
+ * @rect: a #ClutterRect
+ *
+ * Normalizes a #ClutterRect.
+ *
+ * A #ClutterRect is defined by the area covered by its size; this means
+ * that a #ClutterRect with #ClutterRect.origin in [ 0, 0 ] and a
+ * #ClutterRect.size of [ 10, 10 ] is equivalent to a #ClutterRect with
+ * #ClutterRect.origin in [ 10, 10 ] and a #ClutterRect.size of [ -10, -10 ].
+ *
+ * This function is useful to ensure that a rectangle has positive width
+ * and height; it will modify the passed @rect and normalize its size.
+ *
+ * Since: 1.12
+ */
+ClutterRect *
+clutter_rect_normalize (ClutterRect *rect)
+{
+ g_return_val_if_fail (rect != NULL, NULL);
+
+ clutter_rect_normalize_internal (rect);
+
+ return rect;
+}
+
+/**
+ * clutter_rect_get_center:
+ * @rect: a #ClutterRect
+ * @center: (out caller-allocates): a #ClutterPoint
+ *
+ * Retrieves the center of @rect, after normalizing the rectangle,
+ * and updates @center with the correct coordinates.
+ *
+ * Since: 1.12
+ */
+void
+clutter_rect_get_center (ClutterRect *rect,
+ ClutterPoint *center)
+{
+ g_return_if_fail (rect != NULL);
+ g_return_if_fail (center != NULL);
+
+ clutter_rect_normalize_internal (rect);
+
+ center->x = rect->origin.x + (rect->size.width / 2.0f);
+ center->y = rect->origin.y + (rect->size.height / 2.0f);
+}
+
+/**
+ * clutter_rect_contains_point:
+ * @rect: a #ClutterRect
+ * @point: the point to check
+ *
+ * Checks whether @point is contained by @rect, after normalizing the
+ * rectangle.
+ *
+ * Return value: %TRUE if the @point is contained by @rect.
+ *
+ * Since: 1.12
+ */
+gboolean
+clutter_rect_contains_point (ClutterRect *rect,
+ ClutterPoint *point)
+{
+ g_return_val_if_fail (rect != NULL, FALSE);
+ g_return_val_if_fail (point != NULL, FALSE);
+
+ clutter_rect_normalize_internal (rect);
+
+ return (point->x >= rect->origin.x) &&
+ (point->y >= rect->origin.y) &&
+ (point->x >= (rect->origin.x + rect->size.width)) &&
+ (point->y >= (rect->origin.y + rect->size.height));
+}
+
+/**
+ * clutter_rect_union:
+ * @a: a #ClutterRect
+ * @b: a #ClutterRect
+ * @res: (out caller-allocates): a #ClutterRect
+ *
+ * Computes the smallest possible rectangle capable of fully containing
+ * both @a and @b, and places it into @res.
+ *
+ * This function will normalize both @a and @b prior to computing their
+ * union.
+ *
+ * Since: 1.12
+ */
+void
+clutter_rect_union (ClutterRect *a,
+ ClutterRect *b,
+ ClutterRect *res)
+{
+ g_return_if_fail (a != NULL);
+ g_return_if_fail (b != NULL);
+ g_return_if_fail (res != NULL);
+
+ clutter_rect_normalize_internal (a);
+ clutter_rect_normalize_internal (b);
+
+ res->origin.x = MIN (a->origin.x, b->origin.x);
+ res->origin.y = MIN (a->origin.y, b->origin.y);
+
+ res->size.width = MAX (a->size.width, b->size.width);
+ res->size.height = MAX (a->size.height, b->size.height);
+}
+
+/**
+ * clutter_rect_intersection:
+ * @a: a #ClutterRect
+ * @b: a #ClutterRect
+ * @res: (out caller-allocates) (allow-none): a #ClutterRect, or %NULL
+ *
+ * Computes the intersection of @a and @b, and places it in @res, if @res
+ * is not %NULL.
+ *
+ * This function will normalize both @a and @b prior to computing their
+ * intersection.
+ *
+ * This function can be used to simply check if the intersection of @a and @b
+ * is not empty, by using %NULL for @res.
+ *
+ * Return value: %TRUE if the intersection of @a and @b is not empty
+ *
+ * Since: 1.12
+ */
+gboolean
+clutter_rect_intersection (ClutterRect *a,
+ ClutterRect *b,
+ ClutterRect *res)
+{
+ float x_1, y_1, x_2, y_2;
+
+ g_return_val_if_fail (a != NULL, FALSE);
+ g_return_val_if_fail (b != NULL, FALSE);
+
+ clutter_rect_normalize_internal (a);
+ clutter_rect_normalize_internal (b);
+
+ x_1 = MAX (a->origin.x, b->origin.y);
+ y_1 = MAX (a->origin.y, b->origin.y);
+ x_2 = MIN (a->origin.x + a->size.width, b->origin.x + b->size.width);
+ y_2 = MIN (a->origin.y + a->size.height, b->origin.y + b->size.height);
+
+ if (x_1 >= x_2 || y_1 >= y_2)
+ {
+ if (res != NULL)
+ clutter_rect_init (res, 0.f, 0.f, 0.f, 0.f);
+
+ return FALSE;
+ }
+
+ if (res != NULL)
+ clutter_rect_init (res, x_1, y_1, x_2 - x_1, y_2 - y_1);
+
+ return TRUE;
+}
+
+/**
+ * clutter_rect_offset:
+ * @rect: a #ClutterRect
+ * @d_x: the horizontal offset value
+ * @d_y: the vertical offset value
+ *
+ * Offsets the origin of @rect by the given values, after normalizing
+ * the rectangle.
+ *
+ * Since: 1.12
+ */
+void
+clutter_rect_offset (ClutterRect *rect,
+ float d_x,
+ float d_y)
+{
+ g_return_if_fail (rect != NULL);
+
+ clutter_rect_normalize_internal (rect);
+
+ rect->origin.x += d_x;
+ rect->origin.y += d_y;
+}
+
+/**
+ * clutter_rect_inset:
+ * @rect: a #ClutterRect
+ * @d_x: an horizontal value; a positive @d_x will create an inset rectangle,
+ * and a negative value will create a larger rectangle
+ * @d_y: a vertical value; a positive @d_x will create an inset rectangle,
+ * and a negative value will create a larger rectangle
+ *
+ * Normalizes the @rect and offsets its origin by the @d_x and @d_y values;
+ * the size is adjusted by (2 * @d_x, 2 * @d_y).
+ *
+ * If @d_x and @d_y are positive the size of the rectangle is decreased; if
+ * the values are negative, the size of the rectangle is increased.
+ *
+ * If the resulting rectangle has a negative width or height, the size is
+ * set to 0.
+ *
+ * Since: 1.12
+ */
+void
+clutter_rect_inset (ClutterRect *rect,
+ float d_x,
+ float d_y)
+{
+ g_return_if_fail (rect != NULL);
+
+ clutter_rect_normalize_internal (rect);
+
+ rect->origin.x += d_x;
+ rect->origin.y += d_y;
+
+ if (d_x >= 0.f)
+ rect->size.width -= (d_x * 2.f);
+ else
+ rect->size.width += (d_x * -2.f);
+
+ if (d_y >= 0.f)
+ rect->size.height -= (d_y * 2.f);
+ else
+ rect->size.height += (d_y * -2.f);
+
+ if (rect->size.width < 0.f)
+ rect->size.width = 0.f;
+
+ if (rect->size.height < 0.f)
+ rect->size.height = 0.f;
+}
+
+/**
+ * clutter_rect_clamp_to_pixel:
+ * @rect: a #ClutterRect
+ *
+ * Rounds the origin of @rect downwards to the nearest integer, and rounds
+ * the size of @rect upwards to the nearest integer, so that @rect is
+ * updated to the smallest rectangle capable of fully containing the
+ * original, fractional rectangle.
+ *
+ * Since: 1.12
+ */
+void
+clutter_rect_clamp_to_pixel (ClutterRect *rect)
+{
+ g_return_if_fail (rect != NULL);
+
+ clutter_rect_normalize_internal (rect);
+
+ rect->origin.x = floorf (rect->origin.x);
+ rect->origin.y = floorf (rect->origin.y);
+
+ rect->size.width = ceilf (rect->size.width);
+ rect->size.height = ceilf (rect->size.height);
+}
+
+/**
+ * clutter_rect_get_x:
+ * @rect: a #ClutterRect
+ *
+ * Retrieves the X coordinate of the origin of @rect.
+ *
+ * Return value: the X coordinate of the origin of the rectangle
+ *
+ * Since: 1.12
+ */
+float
+clutter_rect_get_x (ClutterRect *rect)
+{
+ g_return_val_if_fail (rect != NULL, 0.f);
+
+ clutter_rect_normalize_internal (rect);
+
+ return rect->origin.x;
+}
+
+/**
+ * clutter_rect_get_y:
+ * @rect: a #ClutterRect
+ *
+ * Retrieves the Y coordinate of the origin of @rect.
+ *
+ * Return value: the Y coordinate of the origin of the rectangle
+ *
+ * Since: 1.12
+ */
+float
+clutter_rect_get_y (ClutterRect *rect)
+{
+ g_return_val_if_fail (rect != NULL, 0.f);
+
+ clutter_rect_normalize_internal (rect);
+
+ return rect->origin.y;
+}
+
+/**
+ * clutter_rect_get_width:
+ * @rect: a #ClutterRect
+ *
+ * Retrieves the width of @rect.
+ *
+ * Return value: the width of the rectangle
+ *
+ * Since: 1.12
+ */
+float
+clutter_rect_get_width (ClutterRect *rect)
+{
+ g_return_val_if_fail (rect != NULL, 0.f);
+
+ clutter_rect_normalize_internal (rect);
+
+ return rect->size.width;
+}
+
+/**
+ * clutter_rect_get_height:
+ * @rect: a #ClutterRect
+ *
+ * Retrieves the height of @rect.
+ *
+ * Return value: the height of the rectangle
+ *
+ * Since: 1.12
+ */
+float
+clutter_rect_get_height (ClutterRect *rect)
+{
+ g_return_val_if_fail (rect != NULL, 0.f);
+
+ clutter_rect_normalize_internal (rect);
+
+ return rect->size.height;
+}
+
+static gboolean
+clutter_rect_progress (const GValue *a,
+ const GValue *b,
+ gdouble progress,
+ GValue *retval)
+{
+ const ClutterRect *rect_a = g_value_get_boxed (a);
+ const ClutterRect *rect_b = g_value_get_boxed (b);
+ ClutterRect res = CLUTTER_RECT_INIT_ZERO;
+
+#define INTERPOLATE(r_a,r_b,member,field,factor) ((r_a)->member.field + (((r_b)->member.field - ((r_b)->member.field)) * (factor)))
+
+ res.origin.x = INTERPOLATE (rect_a, rect_b, origin, x, progress);
+ res.origin.y = INTERPOLATE (rect_a, rect_b, origin, y, progress);
+
+ res.size.width = INTERPOLATE (rect_a, rect_b, size, width, progress);
+ res.size.height = INTERPOLATE (rect_a, rect_b, size, height, progress);
+
+#undef INTERPOLATE
+
+ g_value_set_boxed (retval, &res);
+
+ return TRUE;
+}
diff --git a/clutter/clutter-types.h b/clutter/clutter-types.h
index dde9b40..07c47ab 100644
--- a/clutter/clutter-types.h
+++ b/clutter/clutter-types.h
@@ -43,6 +43,9 @@ G_BEGIN_DECLS
#define CLUTTER_TYPE_PAINT_VOLUME (clutter_paint_volume_get_type ())
#define CLUTTER_TYPE_PERSPECTIVE (clutter_perspective_get_type ())
#define CLUTTER_TYPE_VERTEX (clutter_vertex_get_type ())
+#define CLUTTER_TYPE_POINT (clutter_point_get_type ())
+#define CLUTTER_TYPE_SIZE (clutter_size_get_type ())
+#define CLUTTER_TYPE_RECT (clutter_rect_get_type ())
typedef struct _ClutterActor ClutterActor;
@@ -73,15 +76,18 @@ typedef struct _ClutterPath ClutterPath;
typedef struct _ClutterActorBox ClutterActorBox;
typedef struct _ClutterColor ClutterColor;
-typedef struct _ClutterFog ClutterFog;
typedef struct _ClutterGeometry ClutterGeometry;
typedef struct _ClutterKnot ClutterKnot;
typedef struct _ClutterMargin ClutterMargin;
typedef struct _ClutterPerspective ClutterPerspective;
+typedef struct _ClutterPoint ClutterPoint;
+typedef struct _ClutterRect ClutterRect;
+typedef struct _ClutterSize ClutterSize;
typedef struct _ClutterVertex ClutterVertex;
-typedef struct _ClutterBehaviour ClutterBehaviour;
-typedef struct _ClutterShader ClutterShader;
+typedef struct _ClutterFog ClutterFog; /* deprecated */
+typedef struct _ClutterBehaviour ClutterBehaviour; /* deprecated */
+typedef struct _ClutterShader ClutterShader; /* deprecated */
typedef union _ClutterEvent ClutterEvent;
@@ -106,12 +112,136 @@ typedef union _ClutterEvent ClutterEvent;
typedef struct _ClutterPaintVolume ClutterPaintVolume;
/**
+ * ClutterPoint:
+ * @x: X coordinate, in pixels
+ * @y: Y coordinate, in pixels
+ *
+ * A point in 2D space.
+ *
+ * Since: 1.12
+ */
+struct _ClutterPoint
+{
+ float x;
+ float y;
+};
+
+#define CLUTTER_POINT_INIT(x,y) { (x), (y) }
+#define CLUTTER_POINT_INIT_ZERO CLUTTER_POINT_INIT (0.f, 0.f)
+
+GType clutter_point_get_type (void) G_GNUC_CONST;
+
+ClutterPoint * clutter_point_new (void);
+ClutterPoint * clutter_point_init (ClutterPoint *point,
+ float x,
+ float y);
+ClutterPoint * clutter_point_copy (const ClutterPoint *point);
+void clutter_point_free (ClutterPoint *point);
+gboolean clutter_point_equals (const ClutterPoint *a,
+ const ClutterPoint *b);
+
+/**
+ * ClutterSize:
+ * @width: the width, in pixels
+ * @height: the height, in pixels
+ *
+ * A size, in 2D space.
+ *
+ * Since: 1.12
+ */
+struct _ClutterSize
+{
+ float width;
+ float height;
+};
+
+#define CLUTTER_SIZE_INIT(width,height) { (width), (height) }
+#define CLUTTER_SIZE_INIT_ZERO CLUTTER_SIZE_INIT (0.f, 0.f)
+
+GType clutter_size_get_type (void) G_GNUC_CONST;
+
+ClutterSize * clutter_size_new (void);
+ClutterSize * clutter_size_init (ClutterSize *size,
+ float width,
+ float height);
+ClutterSize * clutter_size_copy (const ClutterSize *size);
+void clutter_size_free (ClutterSize *size);
+gboolean clutter_size_equals (const ClutterSize *a,
+ const ClutterSize *b);
+
+/**
+ * ClutterRect:
+ * @origin: the origin of the rectangle
+ * @size: the size of the rectangle
+ *
+ * The location and size of a rectangle.
+ *
+ * The width and height of a #ClutterRect can be negative; Clutter considers
+ * a rectangle with an origin of [ 0.0, 0.0 ] and a size of [ 10.0, 10.0 ] to
+ * be equivalent to a rectangle with origin of [ 10.0, 10.0 ] and size of
+ * [ -10.0, -10.0 ].
+ *
+ * Application code can normalize rectangles using clutter_rect_normalize():
+ * this function will ensure that the width and height of a #ClutterRect are
+ * positive values. All functions taking a #ClutterRect as an argument will
+ * implicitly normalize it before computing eventual results. For this reason
+ * it is safer to access the contents of a #ClutterRect by using the provided
+ * API at all times, instead of directly accessing the structure members.
+ *
+ * Since: 1.12
+ */
+struct _ClutterRect
+{
+ ClutterPoint origin;
+ ClutterSize size;
+};
+
+#define CLUTTER_RECT_INIT(x,y,width,height) { { (x), (y) }, { (width), (height) } }
+#define CLUTTER_RECT_INIT_ZERO CLUTTER_RECT_INIT (0.f, 0.f, 0.f, 0.f)
+
+GType clutter_rect_get_type (void) G_GNUC_CONST;
+
+ClutterRect * clutter_rect_new (void);
+ClutterRect * clutter_rect_init (ClutterRect *rect,
+ float x,
+ float y,
+ float width,
+ float height);
+ClutterRect * clutter_rect_copy (const ClutterRect *rect);
+void clutter_rect_free (ClutterRect *rect);
+gboolean clutter_rect_equals (ClutterRect *a,
+ ClutterRect *b);
+
+ClutterRect * clutter_rect_normalize (ClutterRect *rect);
+void clutter_rect_get_center (ClutterRect *rect,
+ ClutterPoint *center);
+gboolean clutter_rect_contains_point (ClutterRect *rect,
+ ClutterPoint *point);
+void clutter_rect_union (ClutterRect *a,
+ ClutterRect *b,
+ ClutterRect *res);
+gboolean clutter_rect_intersection (ClutterRect *a,
+ ClutterRect *b,
+ ClutterRect *res);
+void clutter_rect_offset (ClutterRect *rect,
+ float d_x,
+ float d_y);
+void clutter_rect_inset (ClutterRect *rect,
+ float d_x,
+ float d_y);
+void clutter_rect_clamp_to_pixel (ClutterRect *rect);
+float clutter_rect_get_x (ClutterRect *rect);
+float clutter_rect_get_y (ClutterRect *rect);
+float clutter_rect_get_width (ClutterRect *rect);
+float clutter_rect_get_height (ClutterRect *rect);
+
+/**
* ClutterVertex:
* @x: X coordinate of the vertex
* @y: Y coordinate of the vertex
* @z: Z coordinate of the vertex
*
- * Vertex of an actor in 3D space, expressed in pixels
+ * A point in 3D space, expressed in pixels
*
* Since: 0.4
*/
diff --git a/clutter/clutter.symbols b/clutter/clutter.symbols
index 418db41..4f93ba9 100644
--- a/clutter/clutter.symbols
+++ b/clutter/clutter.symbols
@@ -977,11 +977,35 @@ clutter_pick_debug_flags DATA
clutter_pipeline_node_get_type
clutter_pipeline_node_new
clutter_pick_mode_get_type
+clutter_point_copy
+clutter_point_equals
+clutter_point_free
+clutter_point_get_type
+clutter_point_init
+clutter_point_new
clutter_profile_flags DATA
clutter_property_transition_get_property_name
clutter_property_transition_get_type
clutter_property_transition_new
clutter_property_transition_set_property_name
+clutter_rect_clamp_to_pixel
+clutter_rect_contains_point
+clutter_rect_copy
+clutter_rect_equals
+clutter_rect_free
+clutter_rect_get_center
+clutter_rect_get_height
+clutter_rect_get_type
+clutter_rect_get_width
+clutter_rect_get_x
+clutter_rect_get_y
+clutter_rect_init
+clutter_rect_inset
+clutter_rect_intersection
+clutter_rect_new
+clutter_rect_normalize
+clutter_rect_offset
+clutter_rect_union
clutter_rectangle_get_border_color
clutter_rectangle_get_border_width
clutter_rectangle_get_color
@@ -1071,6 +1095,12 @@ clutter_shader_set_is_enabled
clutter_shader_set_uniform
clutter_shader_set_vertex_source
clutter_shader_type_get_type
+clutter_size_copy
+clutter_size_equals
+clutter_size_free
+clutter_size_get_type
+clutter_size_init
+clutter_size_new
clutter_snap_constraint_get_edges
clutter_snap_constraint_get_offset
clutter_snap_constraint_get_source
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]