From bc6a107ff6b3b7a6cd5c314c25894327b68dc955 Mon Sep 17 00:00:00 2001 From: Emmanuele Bassi Date: Wed, 10 Dec 2008 23:00:48 +0000 Subject: [PATCH] Do not modify parameters in place When the apply_transform_to_point() and its relative variant landed in Clutter 0.3, the initial approach was to modify the passed vertex as an in-out parameter. This was later dropped in favour of a more consistent out parameter. Unfortunately, the implementation never changed: both methods where modifying the passed vertex with the partial results of the computations. This commit copies the contents of the "point" ClutterVertex argument inside a stack variable and, for good measure, constifies the argument. Thanks to Thomas Steinacher for catching this in Python. --- clutter/clutter-actor.c | 52 ++++++++++++++++++++++++----------------- clutter/clutter-actor.h | 14 +++++------ 2 files changed, 38 insertions(+), 28 deletions(-) diff --git a/clutter/clutter-actor.c b/clutter/clutter-actor.c index f6c040b43..424144436 100644 --- a/clutter/clutter-actor.c +++ b/clutter/clutter-actor.c @@ -891,20 +891,25 @@ clutter_actor_transform_point (ClutterActor *actor, * Since: 0.6 */ void -clutter_actor_apply_relative_transform_to_point (ClutterActor *self, - ClutterActor *ancestor, - ClutterVertex *point, - ClutterVertex *vertex) +clutter_actor_apply_relative_transform_to_point (ClutterActor *self, + ClutterActor *ancestor, + const ClutterVertex *point, + ClutterVertex *vertex) { - ClutterFixed v[4]; - ClutterFixed w = COGL_FIXED_1; + ClutterVertex tmp = { 0, }; + ClutterFixed v[4]; + ClutterFixed w = COGL_FIXED_1; g_return_if_fail (CLUTTER_IS_ACTOR (self)); g_return_if_fail (ancestor == NULL || CLUTTER_IS_ACTOR (ancestor)); + g_return_if_fail (point != NULL); + g_return_if_fail (vertex != NULL); + + tmp = *point; /* First we tranform the point using the OpenGL modelview matrix */ clutter_actor_transform_point_relative (self, ancestor, - &point->x, &point->y, &point->z, + &tmp.x, &tmp.y, &tmp.z, &w); cogl_get_viewport (v); @@ -913,9 +918,9 @@ clutter_actor_apply_relative_transform_to_point (ClutterActor *self, * The w[3] parameter should always be 1.0 here, so we ignore it; otherwise * we would have to divide the original verts with it. */ - vertex->x = COGL_FIXED_MUL ((point->x + COGL_FIXED_0_5), v[2]); - vertex->y = COGL_FIXED_MUL ((COGL_FIXED_0_5 - point->y), v[3]); - vertex->z = COGL_FIXED_MUL ((point->z + COGL_FIXED_0_5), v[2]); + vertex->x = COGL_FIXED_MUL ((tmp.x + COGL_FIXED_0_5), v[2]); + vertex->y = COGL_FIXED_MUL ((COGL_FIXED_0_5 - tmp.y), v[3]); + vertex->z = COGL_FIXED_MUL ((tmp.z + COGL_FIXED_0_5), v[2]); } /** @@ -931,29 +936,34 @@ clutter_actor_apply_relative_transform_to_point (ClutterActor *self, * Since: 0.4 **/ void -clutter_actor_apply_transform_to_point (ClutterActor *self, - ClutterVertex *point, - ClutterVertex *vertex) +clutter_actor_apply_transform_to_point (ClutterActor *self, + const ClutterVertex *point, + ClutterVertex *vertex) { - ClutterFixed mtx_p[16]; - ClutterFixed v[4]; - ClutterFixed w = COGL_FIXED_1; + ClutterVertex tmp = { 0, }; + ClutterFixed mtx_p[16]; + ClutterFixed v[4]; + ClutterFixed w = COGL_FIXED_1; g_return_if_fail (CLUTTER_IS_ACTOR (self)); + g_return_if_fail (point != NULL); + g_return_if_fail (vertex != NULL); + + tmp = *point; /* First we tranform the point using the OpenGL modelview matrix */ - clutter_actor_transform_point (self, &point->x, &point->y, &point->z, &w); + clutter_actor_transform_point (self, &tmp.x, &tmp.y, &tmp.z, &w); cogl_get_projection_matrix (mtx_p); cogl_get_viewport (v); /* Now, transform it again with the projection matrix */ - mtx_transform (mtx_p, &point->x, &point->y, &point->z, &w); + mtx_transform (mtx_p, &tmp.x, &tmp.y, &tmp.z, &w); /* Finaly translate from OpenGL coords to window coords */ - vertex->x = MTX_GL_SCALE_X (point->x, w, v[2], v[0]); - vertex->y = MTX_GL_SCALE_Y (point->y, w, v[3], v[1]); - vertex->z = MTX_GL_SCALE_Z (point->z, w, v[2], v[0]); + vertex->x = MTX_GL_SCALE_X (tmp.x, w, v[2], v[0]); + vertex->y = MTX_GL_SCALE_Y (tmp.y, w, v[3], v[1]); + vertex->z = MTX_GL_SCALE_Z (tmp.z, w, v[2], v[0]); } /* Recursively tranform supplied vertices with the tranform for the current diff --git a/clutter/clutter-actor.h b/clutter/clutter-actor.h index 021460b78..e964a9ef0 100644 --- a/clutter/clutter-actor.h +++ b/clutter/clutter-actor.h @@ -551,13 +551,13 @@ void clutter_actor_box_get_from_vertices (ClutterVertex vtx[4], void clutter_actor_get_abs_allocation_vertices (ClutterActor *self, ClutterVertex verts[4]); -void clutter_actor_apply_transform_to_point (ClutterActor *self, - ClutterVertex *point, - ClutterVertex *vertex); -void clutter_actor_apply_relative_transform_to_point (ClutterActor *self, - ClutterActor *ancestor, - ClutterVertex *point, - ClutterVertex *vertex); +void clutter_actor_apply_transform_to_point (ClutterActor *self, + const ClutterVertex *point, + ClutterVertex *vertex); +void clutter_actor_apply_relative_transform_to_point (ClutterActor *self, + ClutterActor *ancestor, + const ClutterVertex *point, + ClutterVertex *vertex); gboolean clutter_actor_get_paint_visibility (ClutterActor *self);