From ea9b7b6550718fa4e46e2027001cbcf934d45275 Mon Sep 17 00:00:00 2001 From: Tomas Frydrych Date: Fri, 15 Feb 2008 09:13:50 +0000 Subject: [PATCH] 2008-02-14 Tomas Frydrych * clutter/clutter-actor.c: * clutter/clutter-actor.h: (clutter_actor_is_scaled): (clutter_actor_is_rotated): Convenience functions to test whether actor is scaled or rotated. (clutter_actor_apply_relative_transform_to_point): Removed unused variable. * clutter/clutter-group.c: (clutter_group_query_coords): Use clutter_actor_get_relative_vertices() to calculate bounding boxes of children that are scaled or rotated. --- ChangeLog | 16 ++++++++ clutter/clutter-actor.c | 48 ++++++++++++++++++++++- clutter/clutter-actor.h | 2 + clutter/clutter-group.c | 86 +++++++++++++++++++++++++++++++++-------- 4 files changed, 134 insertions(+), 18 deletions(-) diff --git a/ChangeLog b/ChangeLog index 3534119a7..4905d66a2 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,19 @@ +2008-02-14 Tomas Frydrych + + * clutter/clutter-actor.c: + * clutter/clutter-actor.h: + (clutter_actor_is_scaled): + (clutter_actor_is_rotated): + Convenience functions to test whether actor is scaled or rotated. + + (clutter_actor_apply_relative_transform_to_point): + Removed unused variable. + + * clutter/clutter-group.c: + (clutter_group_query_coords): + Use clutter_actor_get_relative_vertices() to calculate bounding + boxes of children that are scaled or rotated. + 2008-02-14 Tomas Frydrych * clutter/clutter-actor.c: diff --git a/clutter/clutter-actor.c b/clutter/clutter-actor.c index ab07d96dd..06ca83ec8 100644 --- a/clutter/clutter-actor.c +++ b/clutter/clutter-actor.c @@ -660,7 +660,6 @@ clutter_actor_apply_relative_transform_to_point (ClutterActor *self, ClutterVertex *point, ClutterVertex *vertex) { - ClutterFixed mtx_p[16]; ClutterFixed v[4]; ClutterFixed w = CFX_ONE; @@ -5516,3 +5515,50 @@ clutter_actor_set_shader_param (ClutterActor *self, box->value = value; g_hash_table_insert (shader_data->float1f_hash, g_strdup (param), box); } + +/** + * clutter_actor_is_rotated: + * @self: a #ClutterActor + * + * Returns true if any rotation is applied to the actor. + * + * Since: 0.6 + */ +gboolean +clutter_actor_is_rotated (ClutterActor *self) +{ + ClutterActorPrivate *priv; + + g_return_val_if_fail (CLUTTER_IS_ACTOR (self), FALSE); + + priv = self->priv; + + if (priv->rxang || priv->ryang || priv->rzang) + return TRUE; + + return FALSE; +} + +/** + * clutter_actor_is_scaled: + * @self: a #ClutterActor + * + * Returns true if the actor is scaled in either dimension. + * + * Since: 0.6 + */ +gboolean +clutter_actor_is_scaled (ClutterActor *self) +{ + ClutterActorPrivate *priv; + + g_return_val_if_fail (CLUTTER_IS_ACTOR (self), FALSE); + + priv = self->priv; + + if (priv->scale_x != CFX_ONE || priv->scale_y != CFX_ONE) + return TRUE; + + return FALSE; +} + diff --git a/clutter/clutter-actor.h b/clutter/clutter-actor.h index d96310364..5a855d907 100644 --- a/clutter/clutter-actor.h +++ b/clutter/clutter-actor.h @@ -458,6 +458,8 @@ gboolean clutter_actor_transform_stage_point (ClutterActor *self, ClutterUnit y, ClutterUnit *x_out, ClutterUnit *y_out); +gboolean clutter_actor_is_rotated (ClutterActor *self); +gboolean clutter_actor_is_scaled (ClutterActor *self); G_END_DECLS diff --git a/clutter/clutter-group.c b/clutter/clutter-group.c index 5461bfe9d..adc44e7f0 100644 --- a/clutter/clutter-group.c +++ b/clutter/clutter-group.c @@ -148,6 +148,49 @@ clutter_group_request_coords (ClutterActor *self, CLUTTER_ACTOR_CLASS (clutter_group_parent_class)->request_coords (self, box); } +static void +clutter_group_get_box_from_vertices (ClutterActorBox *box, + ClutterVertex vtx[4]) +{ + ClutterUnit x1, x2, y1, y2; + + /* 4-way min/max */ + x1 = vtx[0].x; + y1 = vtx[0].y; + if (vtx[1].x < x1) + x1 = vtx[1].x; + if (vtx[2].x < x1) + x1 = vtx[2].x; + if (vtx[3].x < x1) + x1 = vtx[3].x; + if (vtx[1].y < y1) + y1 = vtx[1].y; + if (vtx[2].y < y1) + y1 = vtx[2].y; + if (vtx[3].y < y1) + y1 = vtx[3].y; + + x2 = vtx[0].x; + y2 = vtx[0].y; + if (vtx[1].x > x2) + x2 = vtx[1].x; + if (vtx[2].x > x2) + x2 = vtx[2].x; + if (vtx[3].x > x2) + x2 = vtx[3].x; + if (vtx[1].y > y2) + y2 = vtx[1].y; + if (vtx[2].y > y2) + y2 = vtx[2].y; + if (vtx[3].y > y2) + y2 = vtx[3].y; + + box->x1 = x1; + box->x2 = x2; + box->y1 = y1; + box->y2 = y2; +} + static void clutter_group_query_coords (ClutterActor *self, ClutterActorBox *box) @@ -167,12 +210,19 @@ clutter_group_query_coords (ClutterActor *self, { do { - ClutterActor *child = CLUTTER_ACTOR(child_item->data); + ClutterActor *child = CLUTTER_ACTOR(child_item->data); + ClutterActorBox cbox; - /* Once added we include in sizing - doesn't matter if visible */ - /* if (CLUTTER_ACTOR_IS_VISIBLE (child)) */ + if (clutter_actor_is_scaled (child) || + clutter_actor_is_rotated (child)) + { + ClutterVertex vtx[4]; + + clutter_actor_get_relative_vertices (child, self, vtx); + clutter_group_get_box_from_vertices (&cbox, vtx); + } + else { - ClutterActorBox cbox; gint anchor_x; gint anchor_y; @@ -188,20 +238,22 @@ clutter_group_query_coords (ClutterActor *self, cbox.x2 -= anchor_x; cbox.y1 -= anchor_y; cbox.y2 -= anchor_y; - - /* Ignore any children with offscreen ( negaive ) - * positions. - * - * Also x1 and x2 will be set by parent caller. - * - * FIXME: this assumes that children are not rotated in anyway. - */ - if (box->x2 - box->x1 < cbox.x2) - box->x2 = cbox.x2 + box->x1; - - if (box->y2 - box->y1 < cbox.y2) - box->y2 = cbox.y2 + box->y1; } + + /* FIXME: now that we go into the trouble of working out the + * projected sizes, we should do better than this (probably resize + * the box in all direction as required). + * + * Ignore any children with offscreen ( negaive ) + * positions. + * + * Also x1 and x2 will be set by parent caller. + */ + if (box->x2 - box->x1 < cbox.x2) + box->x2 = cbox.x2 + box->x1; + + if (box->y2 - box->y1 < cbox.y2) + box->y2 = cbox.y2 + box->y1; } while ((child_item = g_list_next(child_item)) != NULL); }