static gboolean clutter_clone_get_paint_volume (ClutterActor *actor, ClutterPaintVolume *volume) { ClutterClonePrivate *priv = CLUTTER_CLONE (actor)->priv; const ClutterPaintVolume *source_volume; /* if the source is not set the paint volume is defined to be empty */ if (priv->clone_source == NULL) return TRUE; /* query the volume of the source actor and simply masquarade it as * the clones volume... */ source_volume = clutter_actor_get_paint_volume (priv->clone_source); if (source_volume == NULL) return FALSE; _clutter_paint_volume_set_from_volume (volume, source_volume); _clutter_paint_volume_set_reference_actor (volume, actor); return TRUE; }
/** * clutter_paint_volume_union: * @pv: The first #ClutterPaintVolume and destination for resulting * union * @another_pv: A second #ClutterPaintVolume to union with @pv * * Updates the geometry of @pv to encompass @pv and @another_pv. * * There are no guarantees about how precisely the two volumes * will be unioned. * * Since: 1.6 */ void clutter_paint_volume_union (ClutterPaintVolume *pv, const ClutterPaintVolume *another_pv) { ClutterPaintVolume aligned_pv; g_return_if_fail (pv != NULL); g_return_if_fail (another_pv != NULL); /* Both volumes have to belong to the same local coordinate space */ g_return_if_fail (pv->actor == another_pv->actor); /* NB: we only have to update vertices 0, 1, 3 and 4 * (See the ClutterPaintVolume typedef for more details) */ /* We special case empty volumes because otherwise we'd end up * calculating a bounding box that would enclose the origin of * the empty volume which isn't desired. */ if (another_pv->is_empty) return; if (pv->is_empty) { _clutter_paint_volume_set_from_volume (pv, another_pv); goto done; } if (!pv->is_axis_aligned) _clutter_paint_volume_axis_align (pv); if (!another_pv->is_axis_aligned) { _clutter_paint_volume_copy_static (another_pv, &aligned_pv); _clutter_paint_volume_axis_align (&aligned_pv); another_pv = &aligned_pv; } /* grow left*/ /* left vertices 0, 3, 4, 7 */ if (another_pv->vertices[0].x < pv->vertices[0].x) { int min_x = another_pv->vertices[0].x; pv->vertices[0].x = min_x; pv->vertices[3].x = min_x; pv->vertices[4].x = min_x; /* pv->vertices[7].x = min_x; */ } /* grow right */ /* right vertices 1, 2, 5, 6 */ if (another_pv->vertices[1].x > pv->vertices[1].x) { int max_x = another_pv->vertices[1].x; pv->vertices[1].x = max_x; /* pv->vertices[2].x = max_x; */ /* pv->vertices[5].x = max_x; */ /* pv->vertices[6].x = max_x; */ } /* grow up */ /* top vertices 0, 1, 4, 5 */ if (another_pv->vertices[0].y < pv->vertices[0].y) { int min_y = another_pv->vertices[0].y; pv->vertices[0].y = min_y; pv->vertices[1].y = min_y; pv->vertices[4].y = min_y; /* pv->vertices[5].y = min_y; */ } /* grow down */ /* bottom vertices 2, 3, 6, 7 */ if (another_pv->vertices[3].y > pv->vertices[3].y) { int may_y = another_pv->vertices[3].y; /* pv->vertices[2].y = may_y; */ pv->vertices[3].y = may_y; /* pv->vertices[6].y = may_y; */ /* pv->vertices[7].y = may_y; */ } /* grow forward */ /* front vertices 0, 1, 2, 3 */ if (another_pv->vertices[0].z < pv->vertices[0].z) { int min_z = another_pv->vertices[0].z; pv->vertices[0].z = min_z; pv->vertices[1].z = min_z; /* pv->vertices[2].z = min_z; */ pv->vertices[3].z = min_z; } /* grow backward */ /* back vertices 4, 5, 6, 7 */ if (another_pv->vertices[4].z > pv->vertices[4].z) { int maz_z = another_pv->vertices[4].z; pv->vertices[4].z = maz_z; /* pv->vertices[5].z = maz_z; */ /* pv->vertices[6].z = maz_z; */ /* pv->vertices[7].z = maz_z; */ } if (pv->vertices[4].z == pv->vertices[0].z) pv->is_2d = TRUE; else pv->is_2d = FALSE; done: pv->is_empty = FALSE; pv->is_complete = FALSE; }