From 580d62b9b66bcaaae78304e3ddc96a5b8be2fac4 Mon Sep 17 00:00:00 2001 From: Bilal Elmoussaoui Date: Sat, 2 Dec 2023 13:20:55 +0100 Subject: [PATCH] clutter: Remove unused Path related types Part-of: --- clutter/clutter/clutter-autocleanups.h | 3 - clutter/clutter/clutter-bezier.c | 304 ---- clutter/clutter/clutter-bezier.h | 55 - clutter/clutter/clutter-enums.h | 32 - clutter/clutter/clutter-path-constraint.c | 366 ----- clutter/clutter/clutter-path-constraint.h | 61 - clutter/clutter/clutter-path.c | 1423 ----------------- clutter/clutter/clutter-path.h | 159 -- clutter/clutter/clutter-types.h | 58 - clutter/clutter/clutter.h | 2 - clutter/clutter/meson.build | 6 - src/tests/clutter/conform/path.c | 644 -------- .../interactive/test-path-constraint.c | 138 -- 13 files changed, 3251 deletions(-) delete mode 100644 clutter/clutter/clutter-bezier.c delete mode 100644 clutter/clutter/clutter-bezier.h delete mode 100644 clutter/clutter/clutter-path-constraint.c delete mode 100644 clutter/clutter/clutter-path-constraint.h delete mode 100644 clutter/clutter/clutter-path.c delete mode 100644 clutter/clutter/clutter-path.h delete mode 100644 src/tests/clutter/conform/path.c delete mode 100644 src/tests/clutter/interactive/test-path-constraint.c diff --git a/clutter/clutter/clutter-autocleanups.h b/clutter/clutter/clutter-autocleanups.h index 8c2b141fb..f211e2843 100644 --- a/clutter/clutter/clutter-autocleanups.h +++ b/clutter/clutter/clutter-autocleanups.h @@ -53,8 +53,6 @@ G_DEFINE_AUTOPTR_CLEANUP_FUNC (ClutterKeyframeTransition, g_object_unref) G_DEFINE_AUTOPTR_CLEANUP_FUNC (ClutterOffscreenEffect, g_object_unref) G_DEFINE_AUTOPTR_CLEANUP_FUNC (ClutterPageTurnEffect, g_object_unref) G_DEFINE_AUTOPTR_CLEANUP_FUNC (ClutterPanAction, g_object_unref) -G_DEFINE_AUTOPTR_CLEANUP_FUNC (ClutterPathConstraint, g_object_unref) -G_DEFINE_AUTOPTR_CLEANUP_FUNC (ClutterPath, g_object_unref) G_DEFINE_AUTOPTR_CLEANUP_FUNC (ClutterPropertyTransition, g_object_unref) G_DEFINE_AUTOPTR_CLEANUP_FUNC (ClutterRotateAction, g_object_unref) G_DEFINE_AUTOPTR_CLEANUP_FUNC (ClutterScrollActor, g_object_unref) @@ -77,6 +75,5 @@ G_DEFINE_AUTOPTR_CLEANUP_FUNC (ClutterMargin, clutter_margin_free) G_DEFINE_AUTOPTR_CLEANUP_FUNC (ClutterPaintContext, clutter_paint_context_unref) G_DEFINE_AUTOPTR_CLEANUP_FUNC (ClutterPaintNode, clutter_paint_node_unref) G_DEFINE_AUTOPTR_CLEANUP_FUNC (ClutterPaintVolume, clutter_paint_volume_free) -G_DEFINE_AUTOPTR_CLEANUP_FUNC (ClutterPathNode, clutter_path_node_free) #endif /* __GI_SCANNER__ */ diff --git a/clutter/clutter/clutter-bezier.c b/clutter/clutter/clutter-bezier.c deleted file mode 100644 index d6d2a1543..000000000 --- a/clutter/clutter/clutter-bezier.c +++ /dev/null @@ -1,304 +0,0 @@ -/* - * Clutter. - * - * An OpenGL based 'interactive canvas' library. - * - * Authored By Tomas Frydrych - * - * Copyright (C) 2007 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 . - */ - -#include "config.h" - -#include -#include - -#include "clutter/clutter-bezier.h" -#include "clutter/clutter-debug.h" - -/**************************************************************************** - * ClutterBezier -- representation of a cubic bezier curve * - * (private; a building block for the public bspline object) * - ****************************************************************************/ - -/* - * The t parameter of the bezier is from interval <0,1>, so we can use - * 14.18 format and special multiplication functions that preserve - * more of the least significant bits but would overflow if the value - * is > 1 - */ -#define CBZ_T_Q 18 -#define CBZ_T_ONE (1 << CBZ_T_Q) -#define CBZ_T_MUL(x,y) ((((x) >> 3) * ((y) >> 3)) >> 12) -#define CBZ_T_POW2(x) CBZ_T_MUL (x, x) -#define CBZ_T_POW3(x) CBZ_T_MUL (CBZ_T_POW2 (x), x) -#define CBZ_T_DIV(x,y) ((((x) << 9)/(y)) << 9) - -/* - * Constants for sampling of the bezier - */ -#define CBZ_T_SAMPLES 128 -#define CBZ_T_STEP (CBZ_T_ONE / CBZ_T_SAMPLES) -#define CBZ_L_STEP (CBZ_T_ONE / CBZ_T_SAMPLES) - -#define FIXED_BITS (32) -#define FIXED_Q (FIXED_BITS - 16) -#define FIXED_FROM_INT(x) ((x) << FIXED_Q) - -typedef gint32 _FixedT; - -/* - * This is a private type representing a single cubic bezier - */ -struct _ClutterBezier -{ - /* - * bezier coefficients -- these are calculated using multiplication and - * addition from integer input, so these are also integers - */ - gint ax; - gint bx; - gint cx; - gint dx; - - gint ay; - gint by; - gint cy; - gint dy; - - /* length of the bezier */ - guint length; -}; - -ClutterBezier * -_clutter_bezier_new (void) -{ - return g_new0 (ClutterBezier, 1); -} - -void -_clutter_bezier_free (ClutterBezier * b) -{ - if (G_LIKELY (b)) - { - g_free (b); - } -} - -static gint -_clutter_bezier_t2x (const ClutterBezier * b, _FixedT t) -{ - /* - * NB -- the int coefficients can be at most 8192 for the multiplication - * to work in this fashion due to the limits of the 14.18 fixed. - */ - return ((b->ax*CBZ_T_POW3(t) + b->bx*CBZ_T_POW2(t) + b->cx*t) >> CBZ_T_Q) - + b->dx; -} - -static gint -_clutter_bezier_t2y (const ClutterBezier * b, _FixedT t) -{ - /* - * NB -- the int coefficients can be at most 8192 for the multiplication - * to work in this fashion due to the limits of the 14.18 fixed. - */ - return ((b->ay*CBZ_T_POW3(t) + b->by*CBZ_T_POW2(t) + b->cy*t) >> CBZ_T_Q) - + b->dy; -} - -/* - * Advances along the bezier to relative length L and returns the coordinances - * in knot - */ -void -_clutter_bezier_advance (const ClutterBezier *b, gint L, ClutterKnot * knot) -{ - _FixedT t = L; - - knot->x = _clutter_bezier_t2x (b, t); - knot->y = _clutter_bezier_t2y (b, t); - - CLUTTER_NOTE (MISC, "advancing to relative pt %f: t %f, {%d,%d}", - (double) L / (double) CBZ_T_ONE, - (double) t / (double) CBZ_T_ONE, - knot->x, knot->y); -} - -static int -sqrti (int number) -{ -#if defined __SSE2__ - /* The GCC built-in with SSE2 (sqrtsd) is up to twice as fast as - * the pure integer code below. It is also more accurate. - */ - return __builtin_sqrt (number); -#else - /* This is a fixed point implementation of the Quake III sqrt algorithm, - * described, for example, at - * http://www.codemaestro.com/reviews/review00000105.html - * - * While the original QIII is extremely fast, the use of floating division - * and multiplication makes it perform very on arm processors without FPU. - * - * The key to successfully replacing the floating point operations with - * fixed point is in the choice of the fixed point format. The QIII - * algorithm does not calculate the square root, but its reciprocal ('y' - * below), which is only at the end turned to the inverse value. In order - * for the algorithm to produce satisfactory results, the reciprocal value - * must be represented with sufficient precision; the 16.16 we use - * elsewhere in clutter is not good enough, and 10.22 is used instead. - */ - _FixedT x; - uint32_t y_1; /* 10.22 fixed point */ - uint32_t f = 0x600000; /* '1.5' as 10.22 fixed */ - - union - { - float f; - uint32_t i; - } flt, flt2; - - flt.f = number; - - x = FIXED_FROM_INT (number) / 2; - - /* The QIII initial estimate */ - flt.i = 0x5f3759df - ( flt.i >> 1 ); - - /* Now, we convert the float to 10.22 fixed. We exploit the mechanism - * described at http://www.d6.com/users/checker/pdfs/gdmfp.pdf. - * - * We want 22 bit fraction; a single precision float uses 23 bit - * mantisa, so we only need to add 2^(23-22) (no need for the 1.5 - * multiplier as we are only dealing with positive numbers). - * - * Note: we have to use two separate variables here -- for some reason, - * if we try to use just the flt variable, gcc on ARM optimises the whole - * addition out, and it all goes pear shape, since without it, the bits - * in the float will not be correctly aligned. - */ - flt2.f = flt.f + 2.0; - flt2.i &= 0x7FFFFF; - - /* Now we correct the estimate */ - y_1 = (flt2.i >> 11) * (flt2.i >> 11); - y_1 = (y_1 >> 8) * (x >> 8); - - y_1 = f - y_1; - flt2.i = (flt2.i >> 11) * (y_1 >> 11); - - /* If the original argument is less than 342, we do another - * iteration to improve precision (for arguments >= 342, the single - * iteration produces generally better results). - */ - if (x < 171) - { - y_1 = (flt2.i >> 11) * (flt2.i >> 11); - y_1 = (y_1 >> 8) * (x >> 8); - - y_1 = f - y_1; - flt2.i = (flt2.i >> 11) * (y_1 >> 11); - } - - /* Invert, round and convert from 10.22 to an integer - * 0x1e3c68 is a magical rounding constant that produces slightly - * better results than 0x200000. - */ - return (number * flt2.i + 0x1e3c68) >> 22; -#endif -} - -void -_clutter_bezier_init (ClutterBezier *b, - gint x_0, gint y_0, - gint x_1, gint y_1, - gint x_2, gint y_2, - gint x_3, gint y_3) -{ - _FixedT t; - int i; - int xp = x_0; - int yp = y_0; - _FixedT length [CBZ_T_SAMPLES + 1]; - -#if 0 - g_debug ("Initializing bezier at {{%d,%d},{%d,%d},{%d,%d},{%d,%d}}", - x0, y0, x1, y1, x2, y2, x3, y3); -#endif - - b->dx = x_0; - b->dy = y_0; - - b->cx = 3 * (x_1 - x_0); - b->cy = 3 * (y_1 - y_0); - - b->bx = 3 * (x_2 - x_1) - b->cx; - b->by = 3 * (y_2 - y_1) - b->cy; - - b->ax = x_3 - 3 * x_2 + 3 * x_1 - x_0; - b->ay = y_3 - 3 * y_2 + 3 * y_1 - y_0; - -#if 0 - g_debug ("Cooeficients {{%d,%d},{%d,%d},{%d,%d},{%d,%d}}", - b->ax, b->ay, b->bx, b->by, b->cx, b->cy, b->dx, b->dy); -#endif - - /* - * Because of the way we do the multiplication in bezeir_t2x,y - * these coefficients need to be at most 0x1fff; this should be the case, - * I think, but have added this warning to catch any problems -- if it - * triggers, we need to change those two functions a bit. - */ - if (b->ax > 0x1fff || b->bx > 0x1fff || b->cx > 0x1fff) - g_warning ("Calculated coefficients will result in multiplication " - "overflow in clutter_bezier_t2x and clutter_bezier_t2y."); - - /* - * Sample the bezier with CBZ_T_SAMPLES and calculate length at - * each point. - * - * We are working with integers here, so we use the fast sqrti function. - */ - length[0] = 0; - - for (t = CBZ_T_STEP, i = 1; i <= CBZ_T_SAMPLES; ++i, t += CBZ_T_STEP) - { - int x = _clutter_bezier_t2x (b, t); - int y = _clutter_bezier_t2y (b, t); - - guint l = sqrti ((y - yp)*(y - yp) + (x - xp)*(x - xp)); - - l += length[i-1]; - - length[i] = l; - - xp = x; - yp = y; - } - - b->length = length[CBZ_T_SAMPLES]; - -#if 0 - g_debug ("length %d", b->length); -#endif -} - -guint -_clutter_bezier_get_length (const ClutterBezier *b) -{ - return b->length; -} diff --git a/clutter/clutter/clutter-bezier.h b/clutter/clutter/clutter-bezier.h deleted file mode 100644 index b9a412a35..000000000 --- a/clutter/clutter/clutter-bezier.h +++ /dev/null @@ -1,55 +0,0 @@ -/* - * Clutter. - * - * An OpenGL based 'interactive canvas' library. - * - * Authored By Tomas Frydrych - * - * Copyright (C) 2006, 2007 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 . - */ - -#pragma once - -#include - -#include "clutter/clutter-types.h" - -G_BEGIN_DECLS - -/* This is used in _clutter_bezier_advance to represent the full - length of the bezier curve. Anything less than that represents a - fraction of the length */ -#define CLUTTER_BEZIER_MAX_LENGTH (1 << 18) - -typedef struct _ClutterBezier ClutterBezier; - -ClutterBezier *_clutter_bezier_new (void); - -void _clutter_bezier_free (ClutterBezier * b); - -void _clutter_bezier_advance (const ClutterBezier *b, - gint L, - ClutterKnot *knot); - -void _clutter_bezier_init (ClutterBezier *b, - gint x_0, gint y_0, - gint x_1, gint y_1, - gint x_2, gint y_2, - gint x_3, gint y_3); - -guint _clutter_bezier_get_length (const ClutterBezier *b); - -G_END_DECLS diff --git a/clutter/clutter/clutter-enums.h b/clutter/clutter/clutter-enums.h index 7a86d8b72..c15786dd2 100644 --- a/clutter/clutter/clutter-enums.h +++ b/clutter/clutter/clutter-enums.h @@ -1021,38 +1021,6 @@ typedef enum /*< prefix=CLUTTER_UNIT >*/ CLUTTER_UNIT_CM } ClutterUnitType; -#define CLUTTER_PATH_RELATIVE (32) - -/** - * ClutterPathNodeType: - * @CLUTTER_PATH_MOVE_TO: jump to the given position - * @CLUTTER_PATH_LINE_TO: create a line from the last node to the - * given position - * @CLUTTER_PATH_CURVE_TO: bezier curve using the last position and - * three control points. - * @CLUTTER_PATH_CLOSE: create a line from the last node to the last - * %CLUTTER_PATH_MOVE_TO node. - * @CLUTTER_PATH_REL_MOVE_TO: same as %CLUTTER_PATH_MOVE_TO but with - * coordinates relative to the last node. - * @CLUTTER_PATH_REL_LINE_TO: same as %CLUTTER_PATH_LINE_TO but with - * coordinates relative to the last node. - * @CLUTTER_PATH_REL_CURVE_TO: same as %CLUTTER_PATH_CURVE_TO but with - * coordinates relative to the last node. - * - * Types of nodes in a #ClutterPath. - */ -typedef enum -{ - CLUTTER_PATH_MOVE_TO = 0, - CLUTTER_PATH_LINE_TO = 1, - CLUTTER_PATH_CURVE_TO = 2, - CLUTTER_PATH_CLOSE = 3, - - CLUTTER_PATH_REL_MOVE_TO = CLUTTER_PATH_MOVE_TO | CLUTTER_PATH_RELATIVE, - CLUTTER_PATH_REL_LINE_TO = CLUTTER_PATH_LINE_TO | CLUTTER_PATH_RELATIVE, - CLUTTER_PATH_REL_CURVE_TO = CLUTTER_PATH_CURVE_TO | CLUTTER_PATH_RELATIVE -} ClutterPathNodeType; - /** * ClutterActorAlign: * @CLUTTER_ACTOR_ALIGN_FILL: Stretch to cover the whole allocated space diff --git a/clutter/clutter/clutter-path-constraint.c b/clutter/clutter/clutter-path-constraint.c deleted file mode 100644 index 619ac3151..000000000 --- a/clutter/clutter/clutter-path-constraint.c +++ /dev/null @@ -1,366 +0,0 @@ -/* - * Clutter. - * - * An OpenGL based 'interactive canvas' library. - * - * Copyright (C) 2010 Intel Corporation. - * - * 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 . - * - * Author: - * Emmanuele Bassi - */ - -/** - * ClutterPathConstraint: - * - * A constraint that follows a path - * - * #ClutterPathConstraint is a simple constraint that modifies the allocation - * of the [class@Actor] to which it has been applied using a [class@Path]. - * - * By setting the [property@PathConstraint:offset] property it is possible to - * control how far along the path the [class@Actor] should be.. - */ - -#include "config.h" - -#include "clutter/clutter-path-constraint.h" - -#include "clutter/clutter-debug.h" -#include "clutter/clutter-marshal.h" -#include "clutter/clutter-private.h" - -#define CLUTTER_PATH_CONSTRAINT_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), CLUTTER_TYPE_PATH_CONSTRAINT, ClutterPathConstraintClass)) -#define CLUTTER_IS_PATH_CONSTRAINT_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), CLUTTER_TYPE_PATH_CONSTRAINT)) -#define CLUTTER_PATH_CONSTRAINT_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), CLUTTER_TYPE_PATH_CONSTRAINT, ClutterPathConstraintClass)) - -struct _ClutterPathConstraint -{ - ClutterConstraint parent_instance; - - ClutterPath *path; - - gfloat offset; - - ClutterActor *actor; - - guint current_node; -}; - -struct _ClutterPathConstraintClass -{ - ClutterConstraintClass parent_class; -}; - -enum -{ - PROP_0, - - PROP_PATH, - PROP_OFFSET, - - LAST_PROPERTY -}; - -enum -{ - NODE_REACHED, - - LAST_SIGNAL -}; - -G_DEFINE_TYPE (ClutterPathConstraint, clutter_path_constraint, CLUTTER_TYPE_CONSTRAINT); - -static GParamSpec *path_properties[LAST_PROPERTY] = { NULL, }; -static guint path_signals[LAST_SIGNAL] = { 0, }; - -static void -clutter_path_constraint_update_allocation (ClutterConstraint *constraint, - ClutterActor *actor, - ClutterActorBox *allocation) -{ - ClutterPathConstraint *self = CLUTTER_PATH_CONSTRAINT (constraint); - gfloat width, height; - ClutterKnot position; - guint knot_id; - - if (self->path == NULL) - return; - - knot_id = clutter_path_get_position (self->path, self->offset, &position); - clutter_actor_box_get_size (allocation, &width, &height); - allocation->x1 = position.x; - allocation->y1 = position.y; - allocation->x2 = allocation->x1 + width; - allocation->y2 = allocation->y1 + height; - - if (knot_id != self->current_node) - { - self->current_node = knot_id; - g_signal_emit (self, path_signals[NODE_REACHED], 0, - self->actor, - self->current_node); - } -} - -static void -clutter_path_constraint_set_actor (ClutterActorMeta *meta, - ClutterActor *new_actor) -{ - ClutterPathConstraint *path = CLUTTER_PATH_CONSTRAINT (meta); - ClutterActorMetaClass *parent; - - /* store the pointer to the actor, for later use */ - path->actor = new_actor; - - parent = CLUTTER_ACTOR_META_CLASS (clutter_path_constraint_parent_class); - parent->set_actor (meta, new_actor); -} - -static void -clutter_path_constraint_dispose (GObject *gobject) -{ - ClutterPathConstraint *self = CLUTTER_PATH_CONSTRAINT (gobject); - - g_clear_object (&self->path); - - G_OBJECT_CLASS (clutter_path_constraint_parent_class)->dispose (gobject); -} - -static void -clutter_path_constraint_set_property (GObject *gobject, - guint prop_id, - const GValue *value, - GParamSpec *pspec) -{ - ClutterPathConstraint *self = CLUTTER_PATH_CONSTRAINT (gobject); - - switch (prop_id) - { - case PROP_PATH: - clutter_path_constraint_set_path (self, g_value_get_object (value)); - break; - - case PROP_OFFSET: - clutter_path_constraint_set_offset (self, g_value_get_float (value)); - break; - - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (gobject, prop_id, pspec); - } -} - -static void -clutter_path_constraint_get_property (GObject *gobject, - guint prop_id, - GValue *value, - GParamSpec *pspec) -{ - ClutterPathConstraint *self = CLUTTER_PATH_CONSTRAINT (gobject); - - switch (prop_id) - { - case PROP_PATH: - g_value_set_object (value, self->path); - break; - - case PROP_OFFSET: - g_value_set_float (value, self->offset); - break; - - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (gobject, prop_id, pspec); - } -} - -static void -clutter_path_constraint_class_init (ClutterPathConstraintClass *klass) -{ - GObjectClass *gobject_class = G_OBJECT_CLASS (klass); - ClutterActorMetaClass *meta_class = CLUTTER_ACTOR_META_CLASS (klass); - ClutterConstraintClass *constraint_class = CLUTTER_CONSTRAINT_CLASS (klass); - - /** - * ClutterPathConstraint:path: - * - * The #ClutterPath used to constrain the position of an actor. - */ - path_properties[PROP_PATH] = - g_param_spec_object ("path", NULL, NULL, - CLUTTER_TYPE_PATH, - G_PARAM_READWRITE | - G_PARAM_STATIC_STRINGS); - - /** - * ClutterPathConstraint:offset: - * - * The offset along the #ClutterPathConstraint:path, between -1.0 and 2.0. - */ - path_properties[PROP_OFFSET] = - g_param_spec_float ("offset", NULL, NULL, - -1.0, 2.0, - 0.0, - G_PARAM_READWRITE | - G_PARAM_STATIC_STRINGS); - - gobject_class->set_property = clutter_path_constraint_set_property; - gobject_class->get_property = clutter_path_constraint_get_property; - gobject_class->dispose = clutter_path_constraint_dispose; - g_object_class_install_properties (gobject_class, - LAST_PROPERTY, - path_properties); - - meta_class->set_actor = clutter_path_constraint_set_actor; - - constraint_class->update_allocation = clutter_path_constraint_update_allocation; - - /** - * ClutterPathConstraint::node-reached: - * @constraint: the #ClutterPathConstraint that emitted the signal - * @actor: the #ClutterActor using the @constraint - * @index: the index of the node that has been reached - * - * The signal is emitted each time a - * #ClutterPathConstraint:offset value results in the actor - * passing a #ClutterPathNode - */ - path_signals[NODE_REACHED] = - g_signal_new (I_("node-reached"), - G_TYPE_FROM_CLASS (klass), - G_SIGNAL_RUN_LAST, - 0, - NULL, NULL, - _clutter_marshal_VOID__OBJECT_UINT, - G_TYPE_NONE, 2, - CLUTTER_TYPE_ACTOR, - G_TYPE_UINT); -} - -static void -clutter_path_constraint_init (ClutterPathConstraint *self) -{ - self->offset = 0.0f; - self->current_node = G_MAXUINT; -} - -/** - * clutter_path_constraint_new: - * @path: (allow-none): a #ClutterPath, or %NULL - * @offset: the offset along the #ClutterPath - * - * Creates a new #ClutterPathConstraint with the given @path and @offset - * - * Return value: the newly created #ClutterPathConstraint - */ -ClutterConstraint * -clutter_path_constraint_new (ClutterPath *path, - gfloat offset) -{ - g_return_val_if_fail (path == NULL || CLUTTER_IS_PATH (path), NULL); - - return g_object_new (CLUTTER_TYPE_PATH_CONSTRAINT, - "path", path, - "offset", offset, - NULL); -} - -/** - * clutter_path_constraint_set_path: - * @constraint: a #ClutterPathConstraint - * @path: (allow-none): a #ClutterPath - * - * Sets the @path to be followed by the #ClutterPathConstraint. - * - * The @constraint will take ownership of the #ClutterPath passed to this - * function. - */ -void -clutter_path_constraint_set_path (ClutterPathConstraint *constraint, - ClutterPath *path) -{ - g_return_if_fail (CLUTTER_IS_PATH_CONSTRAINT (constraint)); - g_return_if_fail (path == NULL || CLUTTER_IS_PATH (path)); - - if (constraint->path == path) - return; - - g_clear_object (&constraint->path); - - if (path != NULL) - constraint->path = g_object_ref_sink (path); - - if (constraint->actor != NULL) - clutter_actor_queue_relayout (constraint->actor); - - g_object_notify_by_pspec (G_OBJECT (constraint), path_properties[PROP_PATH]); -} - -/** - * clutter_path_constraint_get_path: - * @constraint: a #ClutterPathConstraint - * - * Retrieves a pointer to the #ClutterPath used by @constraint. - * - * Return value: (transfer none): the #ClutterPath used by the - * #ClutterPathConstraint, or %NULL. The returned #ClutterPath is owned - * by the constraint and it should not be unreferenced - */ -ClutterPath * -clutter_path_constraint_get_path (ClutterPathConstraint *constraint) -{ - g_return_val_if_fail (CLUTTER_IS_PATH_CONSTRAINT (constraint), NULL); - - return constraint->path; -} - -/** - * clutter_path_constraint_set_offset: - * @constraint: a #ClutterPathConstraint - * @offset: the offset along the path - * - * Sets the offset along the #ClutterPath used by @constraint. - */ -void -clutter_path_constraint_set_offset (ClutterPathConstraint *constraint, - gfloat offset) -{ - g_return_if_fail (CLUTTER_IS_PATH_CONSTRAINT (constraint)); - - if (constraint->offset == offset) - return; - - constraint->offset = offset; - - if (constraint->actor != NULL) - clutter_actor_queue_relayout (constraint->actor); - - g_object_notify_by_pspec (G_OBJECT (constraint), path_properties[PROP_OFFSET]); -} - -/** - * clutter_path_constraint_get_offset: - * @constraint: a #ClutterPathConstraint - * - * Retrieves the offset along the [class@Path] used by @constraint. - * - * Return value: the offset - */ -gfloat -clutter_path_constraint_get_offset (ClutterPathConstraint *constraint) -{ - g_return_val_if_fail (CLUTTER_IS_PATH_CONSTRAINT (constraint), 0.0); - - return constraint->offset; -} diff --git a/clutter/clutter/clutter-path-constraint.h b/clutter/clutter/clutter-path-constraint.h deleted file mode 100644 index 193103049..000000000 --- a/clutter/clutter/clutter-path-constraint.h +++ /dev/null @@ -1,61 +0,0 @@ -/* - * Clutter. - * - * An OpenGL based 'interactive canvas' library. - * - * Copyright (C) 2010 Intel Corporation. - * - * 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 . - * - * Author: - * Emmanuele Bassi - */ - -#pragma once - -#if !defined(__CLUTTER_H_INSIDE__) && !defined(CLUTTER_COMPILATION) -#error "Only can be included directly." -#endif - -#include "clutter/clutter-constraint.h" -#include "clutter/clutter-path.h" - -G_BEGIN_DECLS - -#define CLUTTER_TYPE_PATH_CONSTRAINT (clutter_path_constraint_get_type ()) -#define CLUTTER_PATH_CONSTRAINT(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), CLUTTER_TYPE_PATH_CONSTRAINT, ClutterPathConstraint)) -#define CLUTTER_IS_PATH_CONSTRAINT(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), CLUTTER_TYPE_PATH_CONSTRAINT)) - -typedef struct _ClutterPathConstraint ClutterPathConstraint; -typedef struct _ClutterPathConstraintClass ClutterPathConstraintClass; - -CLUTTER_EXPORT -GType clutter_path_constraint_get_type (void) G_GNUC_CONST; - -CLUTTER_EXPORT -ClutterConstraint *clutter_path_constraint_new (ClutterPath *path, - gfloat offset); - -CLUTTER_EXPORT -void clutter_path_constraint_set_path (ClutterPathConstraint *constraint, - ClutterPath *path); -CLUTTER_EXPORT -ClutterPath * clutter_path_constraint_get_path (ClutterPathConstraint *constraint); -CLUTTER_EXPORT -void clutter_path_constraint_set_offset (ClutterPathConstraint *constraint, - gfloat offset); -CLUTTER_EXPORT -gfloat clutter_path_constraint_get_offset (ClutterPathConstraint *constraint); - -G_END_DECLS diff --git a/clutter/clutter/clutter-path.c b/clutter/clutter/clutter-path.c deleted file mode 100644 index 57c4bc719..000000000 --- a/clutter/clutter/clutter-path.c +++ /dev/null @@ -1,1423 +0,0 @@ -/* - * Clutter. - * - * An OpenGL based 'interactive canvas' library. - * - * Authored By Matthew Allum - * - * Copyright (C) 2008 Intel Corporation - * - * 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 . - */ - -/** - * ClutterPath: - * - * An object describing a path with straight lines and bezier curves. - * - * A #ClutterPath contains a description of a path consisting of - * straight lines and bezier curves. - * - * The path consists of a series of nodes. Each node is one of the - * following four types: - * - * - %CLUTTER_PATH_MOVE_TO, changes the position of the path to the - * given pair of coordinates. This is usually used as the first node - * of a path to mark the start position. If it is used in the middle - * of a path then the path will be disjoint and the actor will appear - * to jump to the new position when animated. - * - %CLUTTER_PATH_LINE_TO, creates a straight line from the previous - * point to the given point. - * - %CLUTTER_PATH_CURVE_TO, creates a bezier curve. The end of the - * last node is used as the first control point and the three - * subsequent coordinates given in the node as used as the other three. - * - %CLUTTER_PATH_CLOSE, creates a straight line from the last node to - * the last %CLUTTER_PATH_MOVE_TO node. This can be used to close a - * path so that it will appear as a loop when animated. - * - * The first three types have the corresponding relative versions - * %CLUTTER_PATH_REL_MOVE_TO, %CLUTTER_PATH_REL_LINE_TO and - * %CLUTTER_PATH_REL_CURVE_TO. These are exactly the same except the - * coordinates are given relative to the previous node instead of as - * direct screen positions. - * - * You can build a path using the node adding functions such as - * [method@Path.add_line_to]. Alternatively the path can be described - * in a string using a subset of the SVG path syntax. See - * [method@Path.add_string] for details. - */ - -#include "config.h" - -#include -#include -#include -#include - -#include "clutter/clutter-path.h" -#include "clutter/clutter-types.h" -#include "clutter/clutter-bezier.h" -#include "clutter/clutter-private.h" - -#define CLUTTER_PATH_NODE_TYPE_IS_VALID(t) \ - ((((t) & ~CLUTTER_PATH_RELATIVE) >= CLUTTER_PATH_MOVE_TO \ - && ((t) & ~CLUTTER_PATH_RELATIVE) <= CLUTTER_PATH_CURVE_TO) \ - || (t) == CLUTTER_PATH_CLOSE) - -enum -{ - PROP_0, - - PROP_DESCRIPTION, - PROP_LENGTH, - - PROP_LAST -}; - -static GParamSpec *obj_props[PROP_LAST]; - -typedef struct _ClutterPathNodeFull ClutterPathNodeFull; - -struct _ClutterPathNodeFull -{ - ClutterPathNode k; - - ClutterBezier *bezier; - - guint length; -}; - -struct _ClutterPathPrivate -{ - GSList *nodes, *nodes_tail; - gboolean nodes_dirty; - - guint total_length; -}; - -/* Character tests that don't pay attention to the locale */ -#define clutter_path_isspace(ch) memchr (" \f\n\r\t\v", (ch), 6) -#define clutter_path_isdigit(ch) ((ch) >= '0' && (ch) <= '9') - -static ClutterPathNodeFull *clutter_path_node_full_new (void); -static void clutter_path_node_full_free (ClutterPathNodeFull *node); - -static void clutter_path_finalize (GObject *object); - -static void clutter_value_transform_path_string (const GValue *src, - GValue *dest); -static void clutter_value_transform_string_path (const GValue *src, - GValue *dest); - -G_DEFINE_BOXED_TYPE (ClutterPathNode, clutter_path_node, - clutter_path_node_copy, - clutter_path_node_free); - -G_DEFINE_TYPE_WITH_CODE (ClutterPath, - clutter_path, - G_TYPE_INITIALLY_UNOWNED, - G_ADD_PRIVATE (ClutterPath) - CLUTTER_REGISTER_VALUE_TRANSFORM_TO (G_TYPE_STRING, clutter_value_transform_path_string) - CLUTTER_REGISTER_VALUE_TRANSFORM_FROM (G_TYPE_STRING, clutter_value_transform_string_path)); - -static void -clutter_path_get_property (GObject *gobject, - guint prop_id, - GValue *value, - GParamSpec *pspec) -{ - ClutterPath *path = CLUTTER_PATH (gobject); - - switch (prop_id) - { - case PROP_DESCRIPTION: - g_value_take_string (value, clutter_path_get_description (path)); - break; - case PROP_LENGTH: - g_value_set_uint (value, clutter_path_get_length (path)); - break; - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (gobject, prop_id, pspec); - break; - } -} - -static void -clutter_path_set_property (GObject *gobject, - guint prop_id, - const GValue *value, - GParamSpec *pspec) -{ - ClutterPath *path = CLUTTER_PATH (gobject); - - switch (prop_id) - { - case PROP_DESCRIPTION: - if (!clutter_path_set_description (path, g_value_get_string (value))) - g_warning ("Invalid path description"); - break; - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (gobject, prop_id, pspec); - break; - } -} - -static void -clutter_path_class_init (ClutterPathClass *klass) -{ - GObjectClass *gobject_class = (GObjectClass *) klass; - GParamSpec *pspec; - - gobject_class->get_property = clutter_path_get_property; - gobject_class->set_property = clutter_path_set_property; - gobject_class->finalize = clutter_path_finalize; - - pspec = g_param_spec_string ("description", NULL, NULL, - "", - G_PARAM_READWRITE | - G_PARAM_STATIC_STRINGS); - obj_props[PROP_DESCRIPTION] = pspec; - g_object_class_install_property (gobject_class, PROP_DESCRIPTION, pspec); - - pspec = g_param_spec_uint ("length", NULL, NULL, - 0, G_MAXUINT, 0, - G_PARAM_READABLE | - G_PARAM_STATIC_STRINGS); - obj_props[PROP_LENGTH] = pspec; - g_object_class_install_property (gobject_class, PROP_LENGTH, pspec); -} - -static void -clutter_path_init (ClutterPath *self) -{ - self->priv = clutter_path_get_instance_private (self); -} - -static void -clutter_value_transform_path_string (const GValue *src, - GValue *dest) -{ - if (src->data[0].v_pointer != NULL) - { - gchar *string = clutter_path_get_description (src->data[0].v_pointer); - - g_value_take_string (dest, string); - } -} - -static void -clutter_value_transform_string_path (const GValue *src, - GValue *dest) -{ - const char *str; - - str = g_value_get_string (src); - if (str != NULL) - { - ClutterPath *new_path = clutter_path_new_with_description (str); - g_value_take_object (dest, new_path); - } -} - -static void -clutter_path_finalize (GObject *object) -{ - ClutterPath *self = (ClutterPath *) object; - - clutter_path_clear (self); - - G_OBJECT_CLASS (clutter_path_parent_class)->finalize (object); -} - -/** - * clutter_path_new: - * - * Creates a new #ClutterPath instance with no nodes. - * - * Return value: the newly created #ClutterPath - */ -ClutterPath * -clutter_path_new (void) -{ - ClutterPath *self = g_object_new (CLUTTER_TYPE_PATH, NULL); - - return self; -} - -/** - * clutter_path_new_with_description: - * @desc: a string describing the path - * - * Creates a new #ClutterPath instance with the nodes described in - * @desc. See [method@Path.add_string] for details of the format of - * the string. - * - * Return value: the newly created #ClutterPath - */ -ClutterPath * -clutter_path_new_with_description (const gchar *desc) -{ - return g_object_new (CLUTTER_TYPE_PATH, - "description", desc, - NULL); -} - -/** - * clutter_path_clear: - * @path: a #ClutterPath - * - * Removes all nodes from the path. - */ -void -clutter_path_clear (ClutterPath *path) -{ - ClutterPathPrivate *priv = path->priv; - - g_slist_free_full (priv->nodes, (GDestroyNotify) clutter_path_node_full_free); - - priv->nodes = priv->nodes_tail = NULL; - priv->nodes_dirty = TRUE; -} - -/* Takes ownership of the node */ -static void -clutter_path_add_node_full (ClutterPath *path, - ClutterPathNodeFull *node) -{ - ClutterPathPrivate *priv = path->priv; - GSList *new_node; - - new_node = g_slist_prepend (NULL, node); - - if (priv->nodes_tail == NULL) - priv->nodes = new_node; - else - priv->nodes_tail->next = new_node; - - priv->nodes_tail = new_node; - - priv->nodes_dirty = TRUE; -} - -/* Helper function to make the rest of the add_* functions shorter */ -static void -clutter_path_add_node_helper (ClutterPath *path, - ClutterPathNodeType type, - int num_coords, - ...) -{ - ClutterPathNodeFull *node; - int i; - va_list ap; - - node = clutter_path_node_full_new (); - - node->k.type = type; - - va_start (ap, num_coords); - - for (i = 0; i < num_coords; i++) - { - node->k.points[i].x = va_arg (ap, gint); - node->k.points[i].y = va_arg (ap, gint); - } - - va_end (ap); - - clutter_path_add_node_full (path, node); -} - -/** - * clutter_path_add_move_to: - * @path: a #ClutterPath - * @x: the x coordinate - * @y: the y coordinate - * - * Adds a %CLUTTER_PATH_MOVE_TO type node to the path. This is usually - * used as the first node in a path. It can also be used in the middle - * of the path to cause the actor to jump to the new coordinate. - */ -void -clutter_path_add_move_to (ClutterPath *path, - gint x, - gint y) -{ - g_return_if_fail (CLUTTER_IS_PATH (path)); - - clutter_path_add_node_helper (path, CLUTTER_PATH_MOVE_TO, 1, x, y); -} - -/** - * clutter_path_add_rel_move_to: - * @path: a #ClutterPath - * @x: the x coordinate - * @y: the y coordinate - * - * Same as [method@Path.add_move_to] except the coordinates are - * relative to the previous node. - */ -void -clutter_path_add_rel_move_to (ClutterPath *path, - gint x, - gint y) -{ - g_return_if_fail (CLUTTER_IS_PATH (path)); - - clutter_path_add_node_helper (path, CLUTTER_PATH_REL_MOVE_TO, 1, x, y); -} - -/** - * clutter_path_add_line_to: - * @path: a #ClutterPath - * @x: the x coordinate - * @y: the y coordinate - * - * Adds a %CLUTTER_PATH_LINE_TO type node to the path. This causes the - * actor to move to the new coordinates in a straight line. - */ -void -clutter_path_add_line_to (ClutterPath *path, - gint x, - gint y) -{ - g_return_if_fail (CLUTTER_IS_PATH (path)); - - clutter_path_add_node_helper (path, CLUTTER_PATH_LINE_TO, 1, x, y); -} - -/** - * clutter_path_add_rel_line_to: - * @path: a #ClutterPath - * @x: the x coordinate - * @y: the y coordinate - * - * Same as [method@Path.add_line_to] except the coordinates are - * relative to the previous node. - */ -void -clutter_path_add_rel_line_to (ClutterPath *path, - gint x, - gint y) -{ - g_return_if_fail (CLUTTER_IS_PATH (path)); - - clutter_path_add_node_helper (path, CLUTTER_PATH_REL_LINE_TO, 1, x, y); -} - -/** - * clutter_path_add_curve_to: - * @path: a #ClutterPath - * @x_1: the x coordinate of the first control point - * @y_1: the y coordinate of the first control point - * @x_2: the x coordinate of the second control point - * @y_2: the y coordinate of the second control point - * @x_3: the x coordinate of the third control point - * @y_3: the y coordinate of the third control point - * - * Adds a %CLUTTER_PATH_CURVE_TO type node to the path. This causes - * the actor to follow a bezier from the last node to (@x_3, @y_3) using - * (@x_1, @y_1) and (@x_2,@y_2) as control points. - */ -void -clutter_path_add_curve_to (ClutterPath *path, - gint x_1, - gint y_1, - gint x_2, - gint y_2, - gint x_3, - gint y_3) -{ - g_return_if_fail (CLUTTER_IS_PATH (path)); - - clutter_path_add_node_helper (path, CLUTTER_PATH_CURVE_TO, 3, - x_1, y_1, - x_2, y_2, - x_3, y_3); -} - -/** - * clutter_path_add_rel_curve_to: - * @path: a #ClutterPath - * @x_1: the x coordinate of the first control point - * @y_1: the y coordinate of the first control point - * @x_2: the x coordinate of the second control point - * @y_2: the y coordinate of the second control point - * @x_3: the x coordinate of the third control point - * @y_3: the y coordinate of the third control point - * - * Same as [method@Path.add_curve_to] except the coordinates are - * relative to the previous node. - */ -void -clutter_path_add_rel_curve_to (ClutterPath *path, - gint x_1, - gint y_1, - gint x_2, - gint y_2, - gint x_3, - gint y_3) -{ - g_return_if_fail (CLUTTER_IS_PATH (path)); - - clutter_path_add_node_helper (path, CLUTTER_PATH_REL_CURVE_TO, 3, - x_1, y_1, - x_2, y_2, - x_3, y_3); -} - -/** - * clutter_path_add_close: - * @path: a #ClutterPath - * - * Adds a %CLUTTER_PATH_CLOSE type node to the path. This creates a - * straight line from the last node to the last %CLUTTER_PATH_MOVE_TO - * type node. - */ -void -clutter_path_add_close (ClutterPath *path) -{ - g_return_if_fail (CLUTTER_IS_PATH (path)); - - clutter_path_add_node_helper (path, CLUTTER_PATH_CLOSE, 0); -} - -static gboolean -clutter_path_parse_number (const gchar **pin, - gboolean allow_comma, - gint *ret) -{ - gint val = 0; - gboolean negative = FALSE; - gint digit_count = 0; - const gchar *p = *pin; - - /* Skip leading spaces */ - while (clutter_path_isspace (*p)) - p++; - - /* Optional comma */ - if (allow_comma && *p == ',') - { - p++; - while (clutter_path_isspace (*p)) - p++; - } - - /* Optional sign */ - if (*p == '+') - p++; - else if (*p == '-') - { - negative = TRUE; - p++; - } - - /* Some digits */ - while (clutter_path_isdigit (*p)) - { - val = val * 10 + *p - '0'; - digit_count++; - p++; - } - - /* We need at least one digit */ - if (digit_count < 1) - return FALSE; - - /* Optional fractional part which we ignore */ - if (*p == '.') - { - p++; - digit_count = 0; - while (clutter_path_isdigit (*p)) - { - digit_count++; - p++; - } - /* If there is a fractional part then it also needs at least one - digit */ - if (digit_count < 1) - return FALSE; - } - - *pin = p; - *ret = negative ? -val : val; - - return TRUE; -} - -static gboolean -clutter_path_parse_description (const gchar *p, - GSList **ret) -{ - ClutterPathNodeFull *node; - GSList *nodes = NULL; - - if (p == NULL || *p == '\0') - return FALSE; - - while (TRUE) - { - /* Skip leading whitespace */ - while (clutter_path_isspace (*p)) - p++; - - /* It is not an error to end now */ - if (*p == '\0') - break; - - switch (*p) - { - case 'M': - case 'm': - case 'L': - case 'l': - node = clutter_path_node_full_new (); - nodes = g_slist_prepend (nodes, node); - - node->k.type = (*p == 'M' ? CLUTTER_PATH_MOVE_TO : - *p == 'm' ? CLUTTER_PATH_REL_MOVE_TO : - *p == 'L' ? CLUTTER_PATH_LINE_TO : - CLUTTER_PATH_REL_LINE_TO); - p++; - - if (!clutter_path_parse_number (&p, FALSE, &node->k.points[0].x) || - !clutter_path_parse_number (&p, TRUE, &node->k.points[0].y)) - goto fail; - break; - - case 'C': - case 'c': - node = clutter_path_node_full_new (); - nodes = g_slist_prepend (nodes, node); - - node->k.type = (*p == 'C' ? CLUTTER_PATH_CURVE_TO : - CLUTTER_PATH_REL_CURVE_TO); - p++; - - if (!clutter_path_parse_number (&p, FALSE, &node->k.points[0].x) || - !clutter_path_parse_number (&p, TRUE, &node->k.points[0].y) || - !clutter_path_parse_number (&p, TRUE, &node->k.points[1].x) || - !clutter_path_parse_number (&p, TRUE, &node->k.points[1].y) || - !clutter_path_parse_number (&p, TRUE, &node->k.points[2].x) || - !clutter_path_parse_number (&p, TRUE, &node->k.points[2].y)) - goto fail; - break; - - case 'Z': - case 'z': - node = clutter_path_node_full_new (); - nodes = g_slist_prepend (nodes, node); - p++; - - node->k.type = CLUTTER_PATH_CLOSE; - break; - - default: - goto fail; - } - } - - *ret = g_slist_reverse (nodes); - return TRUE; - - fail: - g_slist_free_full (nodes, (GDestroyNotify) clutter_path_node_full_free); - return FALSE; -} - -/* Takes ownership of the node list */ -static void -clutter_path_add_nodes (ClutterPath *path, - GSList *nodes) -{ - ClutterPathPrivate *priv = path->priv; - - if (priv->nodes_tail == NULL) - priv->nodes = nodes; - else - priv->nodes_tail->next = nodes; - - while (nodes) - { - priv->nodes_tail = nodes; - nodes = nodes->next; - } - - priv->nodes_dirty = TRUE; -} - -/** - * clutter_path_add_string: - * @path: a #ClutterPath - * @str: a string describing the new nodes - * - * Adds new nodes to the end of the path as described in @str. The - * format is a subset of the SVG path format. Each node is represented - * by a letter and is followed by zero, one or three pairs of - * coordinates. The coordinates can be separated by spaces or a - * comma. The types are: - * - * - `M`: Adds a %CLUTTER_PATH_MOVE_TO node. Takes one pair of coordinates. - * - `L`: Adds a %CLUTTER_PATH_LINE_TO node. Takes one pair of coordinates. - * - `C`: Adds a %CLUTTER_PATH_CURVE_TO node. Takes three pairs of coordinates. - * - `z`: Adds a %CLUTTER_PATH_CLOSE node. No coordinates are needed. - * - * The M, L and C commands can also be specified in lower case which - * means the coordinates are relative to the previous node. - * - * For example, to move an actor in a 100 by 100 pixel square centered - * on the point 300,300 you could use the following path: - * - * ``` - * M 250,350 l 0 -100 L 350,250 l 0 100 z - * ``` - * - * If the path description isn't valid %FALSE will be returned and no - * nodes will be added. - * - * Return value: %TRUE is the path description was valid or %FALSE - * otherwise. - */ -gboolean -clutter_path_add_string (ClutterPath *path, - const gchar *str) -{ - GSList *nodes; - - g_return_val_if_fail (CLUTTER_IS_PATH (path), FALSE); - g_return_val_if_fail (str != NULL, FALSE); - - if (clutter_path_parse_description (str, &nodes)) - { - clutter_path_add_nodes (path, nodes); - - return TRUE; - } - else - return FALSE; -} - -/** - * clutter_path_add_node: - * @path: a #ClutterPath - * @node: a #ClutterPathNode - * - * Adds @node to the end of the path. - */ -void -clutter_path_add_node (ClutterPath *path, - const ClutterPathNode *node) -{ - ClutterPathNodeFull *node_full; - - g_return_if_fail (CLUTTER_IS_PATH (path)); - g_return_if_fail (node != NULL); - g_return_if_fail (CLUTTER_PATH_NODE_TYPE_IS_VALID (node->type)); - - node_full = clutter_path_node_full_new (); - node_full->k = *node; - - clutter_path_add_node_full (path, node_full); -} - -/** - * clutter_path_get_n_nodes: - * @path: a #ClutterPath - * - * Retrieves the number of nodes in the path. - * - * Return value: the number of nodes. - */ -guint -clutter_path_get_n_nodes (ClutterPath *path) -{ - ClutterPathPrivate *priv; - - g_return_val_if_fail (CLUTTER_IS_PATH (path), 0); - - priv = path->priv; - - return g_slist_length (priv->nodes); -} - -/** - * clutter_path_get_node: - * @path: a #ClutterPath - * @index_: the node number to retrieve - * @node: (out): a location to store a copy of the node - * - * Retrieves the node of the path indexed by @index. - */ -void -clutter_path_get_node (ClutterPath *path, - guint index_, - ClutterPathNode *node) -{ - ClutterPathNodeFull *node_full; - ClutterPathPrivate *priv; - - g_return_if_fail (CLUTTER_IS_PATH (path)); - - priv = path->priv; - - node_full = g_slist_nth_data (priv->nodes, index_); - - g_return_if_fail (node_full != NULL); - - *node = node_full->k; -} - -/** - * clutter_path_get_nodes: - * @path: a #ClutterPath - * - * Returns a #GSList of [struct@PathNode]s. - * - * The list should be freed with g_slist_free(). The nodes are owned - * by the path and should not be freed. Altering the path may cause - * the nodes in the list to become invalid so you should copy them - * if you want to keep the list. - * - * Return value: (transfer container) (element-type Clutter.PathNode): a - * list of nodes in the path. - */ -GSList * -clutter_path_get_nodes (ClutterPath *path) -{ - ClutterPathPrivate *priv; - - g_return_val_if_fail (CLUTTER_IS_PATH (path), NULL); - - priv = path->priv; - - return g_slist_copy (priv->nodes); -} - -/** - * clutter_path_foreach: - * @path: a #ClutterPath - * @callback: (scope call): the function to call with each node - * @user_data: user data to pass to the function - * - * Calls a function for each node of the path. - */ -void -clutter_path_foreach (ClutterPath *path, - ClutterPathCallback callback, - gpointer user_data) -{ - ClutterPathPrivate *priv; - - g_return_if_fail (CLUTTER_IS_PATH (path)); - - priv = path->priv; - - g_slist_foreach (priv->nodes, (GFunc) callback, user_data); -} - -/** - * clutter_path_insert_node: - * @path: a #ClutterPath - * @index_: offset of where to insert the node - * @node: the node to insert - * - * Inserts @node into the path before the node at the given offset. If - * @index_ is negative it will append the node to the end of the path. - */ -void -clutter_path_insert_node (ClutterPath *path, - gint index_, - const ClutterPathNode *node) -{ - ClutterPathPrivate *priv; - ClutterPathNodeFull *node_full; - - g_return_if_fail (CLUTTER_IS_PATH (path)); - g_return_if_fail (node != NULL); - g_return_if_fail (CLUTTER_PATH_NODE_TYPE_IS_VALID (node->type)); - - priv = path->priv; - - node_full = clutter_path_node_full_new (); - node_full->k = *node; - - priv->nodes = g_slist_insert (priv->nodes, node_full, index_); - - if (priv->nodes_tail == NULL) - priv->nodes_tail = priv->nodes; - else if (priv->nodes_tail->next) - priv->nodes_tail = priv->nodes_tail->next; - - priv->nodes_dirty = TRUE; -} - -/** - * clutter_path_remove_node: - * @path: a #ClutterPath - * @index_: index of the node to remove - * - * Removes the node at the given offset from the path. - */ -void -clutter_path_remove_node (ClutterPath *path, - guint index_) -{ - ClutterPathPrivate *priv; - GSList *node, *prev = NULL; - - g_return_if_fail (CLUTTER_IS_PATH (path)); - - priv = path->priv; - - for (node = priv->nodes; node && index_--; node = node->next) - prev = node; - - if (node) - { - clutter_path_node_full_free (node->data); - - if (prev) - prev->next = node->next; - else - priv->nodes = node->next; - - if (node == priv->nodes_tail) - priv->nodes_tail = prev; - - g_slist_free_1 (node); - - priv->nodes_dirty = TRUE; - } -} - -/** - * clutter_path_replace_node: - * @path: a #ClutterPath - * @index_: index to the existing node - * @node: the replacement node - * - * Replaces the node at offset @index_ with @node. - */ -void -clutter_path_replace_node (ClutterPath *path, - guint index_, - const ClutterPathNode *node) -{ - ClutterPathPrivate *priv; - ClutterPathNodeFull *node_full; - - g_return_if_fail (CLUTTER_IS_PATH (path)); - g_return_if_fail (node != NULL); - g_return_if_fail (CLUTTER_PATH_NODE_TYPE_IS_VALID (node->type)); - - priv = path->priv; - - if ((node_full = g_slist_nth_data (priv->nodes, index_))) - { - node_full->k = *node; - - priv->nodes_dirty = TRUE; - } -} - -/** - * clutter_path_set_description: - * @path: a #ClutterPath - * @str: a string describing the path - * - * Replaces all of the nodes in the path with nodes described by - * @str. See [method@Path.add_string] for details of the format. - * - * If the string is invalid then %FALSE is returned and the path is - * unaltered. - * - * Return value: %TRUE is the path was valid, %FALSE otherwise. - */ -gboolean -clutter_path_set_description (ClutterPath *path, - const gchar *str) -{ - GSList *nodes; - - g_return_val_if_fail (CLUTTER_IS_PATH (path), FALSE); - g_return_val_if_fail (str != NULL, FALSE); - - if (clutter_path_parse_description (str, &nodes)) - { - clutter_path_clear (path); - clutter_path_add_nodes (path, nodes); - - return TRUE; - } - else - return FALSE; -} - -/** - * clutter_path_get_description: - * @path: a #ClutterPath - * - * Returns a newly allocated string describing the path in the same - * format as used by [method@Path.add_string]. - * - * Return value: a string description of the path. Free with g_free(). - */ -gchar * -clutter_path_get_description (ClutterPath *path) -{ - ClutterPathPrivate *priv; - GString *str; - GSList *l; - - g_return_val_if_fail (CLUTTER_IS_PATH (path), NULL); - - priv = path->priv; - - str = g_string_new (""); - - for (l = priv->nodes; l; l = l->next) - { - ClutterPathNodeFull *node = l->data; - gchar letter = '?'; - gint params = 0; - gint i; - - switch (node->k.type) - { - case CLUTTER_PATH_MOVE_TO: - letter = 'M'; - params = 1; - break; - - case CLUTTER_PATH_REL_MOVE_TO: - letter = 'm'; - params = 1; - break; - - case CLUTTER_PATH_LINE_TO: - letter = 'L'; - params = 1; - break; - - case CLUTTER_PATH_REL_LINE_TO: - letter = 'l'; - params = 1; - break; - - case CLUTTER_PATH_CURVE_TO: - letter = 'C'; - params = 3; - break; - - case CLUTTER_PATH_REL_CURVE_TO: - letter = 'c'; - params = 3; - break; - - case CLUTTER_PATH_CLOSE: - letter = 'z'; - params = 0; - break; - } - - if (str->len > 0) - g_string_append_c (str, ' '); - g_string_append_c (str, letter); - - for (i = 0; i < params; i++) - g_string_append_printf (str, " %i %i", - node->k.points[i].x, - node->k.points[i].y); - } - - return g_string_free (str, FALSE); -} - -static guint -clutter_path_node_distance (const ClutterKnot *start, - const ClutterKnot *end) -{ - gint64 x_d, y_d; - float t; - - g_return_val_if_fail (start != NULL, 0); - g_return_val_if_fail (end != NULL, 0); - - if (clutter_knot_equal (start, end)) - return 0; - - x_d = end->x - start->x; - y_d = end->y - start->y; - - t = floorf (sqrtf ((x_d * x_d) + (y_d * y_d))); - - return (guint) t; -} - -static void -clutter_path_ensure_node_data (ClutterPath *path) -{ - ClutterPathPrivate *priv = path->priv; - - /* Recalculate the nodes data if has changed */ - if (priv->nodes_dirty) - { - GSList *l; - ClutterKnot last_position = { 0, 0 }; - ClutterKnot loop_start = { 0, 0 }; - ClutterKnot points[3]; - - priv->total_length = 0; - - for (l = priv->nodes; l; l = l->next) - { - ClutterPathNodeFull *node = l->data; - gboolean relative = (node->k.type & CLUTTER_PATH_RELATIVE) != 0; - - switch (node->k.type & ~CLUTTER_PATH_RELATIVE) - { - case CLUTTER_PATH_MOVE_TO: - node->length = 0; - - /* Store the actual position in point[1] */ - if (relative) - { - node->k.points[1].x = last_position.x + node->k.points[0].x; - node->k.points[1].y = last_position.y + node->k.points[0].y; - } - else - node->k.points[1] = node->k.points[0]; - - last_position = node->k.points[1]; - loop_start = node->k.points[1]; - break; - - case CLUTTER_PATH_LINE_TO: - /* Use point[1] as the start point and point[2] as the end - point */ - node->k.points[1] = last_position; - - if (relative) - { - node->k.points[2].x = (node->k.points[1].x - + node->k.points[0].x); - node->k.points[2].y = (node->k.points[1].y - + node->k.points[0].y); - } - else - node->k.points[2] = node->k.points[0]; - - last_position = node->k.points[2]; - - node->length = clutter_path_node_distance (node->k.points + 1, - node->k.points + 2); - break; - - case CLUTTER_PATH_CURVE_TO: - /* Convert to a bezier curve */ - if (node->bezier == NULL) - node->bezier = _clutter_bezier_new (); - - if (relative) - { - int i; - - for (i = 0; i < 3; i++) - { - points[i].x = last_position.x + node->k.points[i].x; - points[i].y = last_position.y + node->k.points[i].y; - } - } - else - memcpy (points, node->k.points, sizeof (ClutterKnot) * 3); - - _clutter_bezier_init (node->bezier, - last_position.x, last_position.y, - points[0].x, points[0].y, - points[1].x, points[1].y, - points[2].x, points[2].y); - - last_position = points[2]; - - node->length = _clutter_bezier_get_length (node->bezier); - - break; - - case CLUTTER_PATH_CLOSE: - /* Convert to a line to from last_point to loop_start */ - node->k.points[1] = last_position; - node->k.points[2] = loop_start; - last_position = node->k.points[2]; - - node->length = clutter_path_node_distance (node->k.points + 1, - node->k.points + 2); - break; - } - - priv->total_length += node->length; - } - - priv->nodes_dirty = FALSE; - } -} - -/** - * clutter_path_get_position: - * @path: a #ClutterPath - * @progress: a position along the path as a fraction of its length - * @position: (out): location to store the position - * - * The value in @progress represents a position along the path where - * 0.0 is the beginning and 1.0 is the end of the path. An - * interpolated position is then stored in @position. - * - * Return value: index of the node used to calculate the position. - */ -guint -clutter_path_get_position (ClutterPath *path, - gdouble progress, - ClutterKnot *position) -{ - ClutterPathPrivate *priv; - GSList *l; - guint point_distance, length = 0, node_num = 0; - ClutterPathNodeFull *node; - - g_return_val_if_fail (CLUTTER_IS_PATH (path), 0); - g_return_val_if_fail (progress >= 0.0 && progress <= 1.0, 0); - - priv = path->priv; - - clutter_path_ensure_node_data (path); - - /* Special case if the path is empty, just return 0,0 for want of - something better */ - if (priv->nodes == NULL) - { - memset (position, 0, sizeof (ClutterKnot)); - return 0; - } - - /* Convert the progress to a length along the path */ - point_distance = progress * priv->total_length; - - /* Find the node that covers this point */ - for (l = priv->nodes; - l->next && point_distance >= (((ClutterPathNodeFull *) l->data)->length - + length); - l = l->next) - { - length += ((ClutterPathNodeFull *) l->data)->length; - node_num++; - } - - node = l->data; - - /* Convert the point distance to a distance along the node */ - point_distance -= length; - if (point_distance > node->length) - point_distance = node->length; - - switch (node->k.type & ~CLUTTER_PATH_RELATIVE) - { - case CLUTTER_PATH_MOVE_TO: - *position = node->k.points[1]; - break; - - case CLUTTER_PATH_LINE_TO: - case CLUTTER_PATH_CLOSE: - if (node->length == 0) - *position = node->k.points[1]; - else - { - position->x = (node->k.points[1].x - + ((node->k.points[2].x - node->k.points[1].x) - * (gint) point_distance / (gint) node->length)); - position->y = (node->k.points[1].y - + ((node->k.points[2].y - node->k.points[1].y) - * (gint) point_distance / (gint) node->length)); - } - break; - - case CLUTTER_PATH_CURVE_TO: - if (node->length == 0) - *position = node->k.points[2]; - else - { - _clutter_bezier_advance (node->bezier, - point_distance * CLUTTER_BEZIER_MAX_LENGTH - / node->length, - position); - } - break; - } - - return node_num; -} - -/** - * clutter_path_get_length: - * @path: a #ClutterPath - * - * Retrieves an approximation of the total length of the path. - * - * Return value: the length of the path. - */ -guint -clutter_path_get_length (ClutterPath *path) -{ - g_return_val_if_fail (CLUTTER_IS_PATH (path), 0); - - clutter_path_ensure_node_data (path); - - return path->priv->total_length; -} - -static ClutterPathNodeFull * -clutter_path_node_full_new (void) -{ - return g_new0 (ClutterPathNodeFull, 1); -} - -static void -clutter_path_node_full_free (ClutterPathNodeFull *node) -{ - if (node->bezier) - _clutter_bezier_free (node->bezier); - - g_free (node); -} - -/** - * clutter_path_node_copy: - * @node: a #ClutterPathNode - * - * Makes an allocated copy of a node. - * - * Return value: the copied node. - */ -ClutterPathNode * -clutter_path_node_copy (const ClutterPathNode *node) -{ - return g_memdup2 (node, sizeof (ClutterPathNode)); -} - -/** - * clutter_path_node_free: - * @node: a #ClutterPathNode - * - * Frees the memory of an allocated node. - */ -void -clutter_path_node_free (ClutterPathNode *node) -{ - if (G_LIKELY (node)) - g_free (node); -} - -/** - * clutter_path_node_equal: - * @node_a: First node - * @node_b: Second node - * - * Compares two nodes and checks if they are the same type with the - * same coordinates. - * - * Return value: %TRUE if the nodes are the same. - */ -gboolean -clutter_path_node_equal (const ClutterPathNode *node_a, - const ClutterPathNode *node_b) -{ - guint n_points, i; - - g_return_val_if_fail (node_a != NULL, FALSE); - g_return_val_if_fail (node_b != NULL, FALSE); - - if (node_a->type != node_b->type) - return FALSE; - - switch (node_a->type & ~CLUTTER_PATH_RELATIVE) - { - case CLUTTER_PATH_MOVE_TO: n_points = 1; break; - case CLUTTER_PATH_LINE_TO: n_points = 1; break; - case CLUTTER_PATH_CURVE_TO: n_points = 3; break; - case CLUTTER_PATH_CLOSE: n_points = 0; break; - default: return FALSE; - } - - for (i = 0; i < n_points; i++) - if (node_a->points[i].x != node_b->points[i].x - || node_a->points[i].y != node_b->points[i].y) - return FALSE; - - return TRUE; -} - -G_DEFINE_BOXED_TYPE (ClutterKnot, clutter_knot, - clutter_knot_copy, - clutter_knot_free); - -/** - * clutter_knot_copy: - * @knot: a #ClutterKnot - * - * Makes an allocated copy of a knot. - * - * Return value: the copied knot. - */ -ClutterKnot * -clutter_knot_copy (const ClutterKnot *knot) -{ - if (G_UNLIKELY (knot == NULL)) - return NULL; - - return g_memdup2 (knot, sizeof (ClutterKnot)); -} - -/** - * clutter_knot_free: - * @knot: a #ClutterKnot - * - * Frees the memory of an allocated knot. - */ -void -clutter_knot_free (ClutterKnot *knot) -{ - if (G_LIKELY (knot != NULL)) - g_free (knot); -} - -/** - * clutter_knot_equal: - * @knot_a: First knot - * @knot_b: Second knot - * - * Compares to knot and checks if the point to the same location. - * - * Return value: %TRUE if the knots point to the same location. - */ -gboolean -clutter_knot_equal (const ClutterKnot *knot_a, - const ClutterKnot *knot_b) -{ - g_return_val_if_fail (knot_a != NULL, FALSE); - g_return_val_if_fail (knot_b != NULL, FALSE); - - if (knot_a == knot_b) - return TRUE; - - return knot_a->x == knot_b->x && knot_a->y == knot_b->y; -} diff --git a/clutter/clutter/clutter-path.h b/clutter/clutter/clutter-path.h deleted file mode 100644 index 42a118e48..000000000 --- a/clutter/clutter/clutter-path.h +++ /dev/null @@ -1,159 +0,0 @@ -/* - * Clutter. - * - * An OpenGL based 'interactive canvas' library. - * - * Authored By Matthew Allum - * - * Copyright (C) 2008 Intel Corporation - * - * 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 . - */ - -#pragma once - -#if !defined(__CLUTTER_H_INSIDE__) && !defined(CLUTTER_COMPILATION) -#error "Only can be included directly." -#endif - -#include "clutter/clutter-types.h" - -G_BEGIN_DECLS - -#define CLUTTER_TYPE_PATH (clutter_path_get_type ()) -#define CLUTTER_TYPE_PATH_NODE (clutter_path_node_get_type ()) -#define CLUTTER_PATH(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), CLUTTER_TYPE_PATH, ClutterPath)) -#define CLUTTER_PATH_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), CLUTTER_TYPE_PATH, ClutterPathClass)) -#define CLUTTER_IS_PATH(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), CLUTTER_TYPE_PATH)) -#define CLUTTER_IS_PATH_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), CLUTTER_TYPE_PATH)) -#define CLUTTER_PATH_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), CLUTTER_TYPE_PATH, ClutterPathClass)) - -typedef struct _ClutterPathClass ClutterPathClass; -typedef struct _ClutterPathPrivate ClutterPathPrivate; - -/** - * ClutterPathCallback: - * @node: the node - * @data: (closure): optional data passed to the function - * - * This function is passed to [method@Path.foreach] and will be - * called for each node contained in the path. - */ -typedef void (* ClutterPathCallback) (const ClutterPathNode *node, - gpointer data); - -struct _ClutterPath -{ - /*< private >*/ - GInitiallyUnowned parent; - - ClutterPathPrivate *priv; -}; - -/** - * ClutterPathClass: - * - * The #ClutterPathClass struct contains only private data. - */ -struct _ClutterPathClass -{ - /*< private >*/ - GInitiallyUnownedClass parent_class; -}; - -CLUTTER_EXPORT -GType clutter_path_get_type (void) G_GNUC_CONST; - -CLUTTER_EXPORT -ClutterPath *clutter_path_new (void); -CLUTTER_EXPORT -ClutterPath *clutter_path_new_with_description (const gchar *desc); -CLUTTER_EXPORT -void clutter_path_add_move_to (ClutterPath *path, - gint x, - gint y); -CLUTTER_EXPORT -void clutter_path_add_rel_move_to (ClutterPath *path, - gint x, - gint y); -CLUTTER_EXPORT -void clutter_path_add_line_to (ClutterPath *path, - gint x, - gint y); -CLUTTER_EXPORT -void clutter_path_add_rel_line_to (ClutterPath *path, - gint x, - gint y); -CLUTTER_EXPORT -void clutter_path_add_curve_to (ClutterPath *path, - gint x_1, - gint y_1, - gint x_2, - gint y_2, - gint x_3, - gint y_3); -CLUTTER_EXPORT -void clutter_path_add_rel_curve_to (ClutterPath *path, - gint x_1, - gint y_1, - gint x_2, - gint y_2, - gint x_3, - gint y_3); -CLUTTER_EXPORT -void clutter_path_add_close (ClutterPath *path); -CLUTTER_EXPORT -gboolean clutter_path_add_string (ClutterPath *path, - const gchar *str); -CLUTTER_EXPORT -void clutter_path_add_node (ClutterPath *path, - const ClutterPathNode *node); -CLUTTER_EXPORT -guint clutter_path_get_n_nodes (ClutterPath *path); -CLUTTER_EXPORT -void clutter_path_get_node (ClutterPath *path, - guint index_, - ClutterPathNode *node); -CLUTTER_EXPORT -GSList * clutter_path_get_nodes (ClutterPath *path); -CLUTTER_EXPORT -void clutter_path_foreach (ClutterPath *path, - ClutterPathCallback callback, - gpointer user_data); -CLUTTER_EXPORT -void clutter_path_insert_node (ClutterPath *path, - gint index_, - const ClutterPathNode *node); -CLUTTER_EXPORT -void clutter_path_remove_node (ClutterPath *path, - guint index_); -CLUTTER_EXPORT -void clutter_path_replace_node (ClutterPath *path, - guint index_, - const ClutterPathNode *node); -CLUTTER_EXPORT -gchar * clutter_path_get_description (ClutterPath *path); -CLUTTER_EXPORT -gboolean clutter_path_set_description (ClutterPath *path, - const gchar *str); -CLUTTER_EXPORT -void clutter_path_clear (ClutterPath *path); -CLUTTER_EXPORT -guint clutter_path_get_position (ClutterPath *path, - gdouble progress, - ClutterKnot *position); -CLUTTER_EXPORT -guint clutter_path_get_length (ClutterPath *path); - -G_END_DECLS diff --git a/clutter/clutter/clutter-types.h b/clutter/clutter/clutter-types.h index 03cd9c152..2237e00d1 100644 --- a/clutter/clutter/clutter-types.h +++ b/clutter/clutter/clutter-types.h @@ -36,7 +36,6 @@ G_BEGIN_DECLS #define CLUTTER_TYPE_ACTOR_BOX (clutter_actor_box_get_type ()) -#define CLUTTER_TYPE_KNOT (clutter_knot_get_type ()) #define CLUTTER_TYPE_MARGIN (clutter_margin_get_type ()) #define CLUTTER_TYPE_PAINT_VOLUME (clutter_paint_volume_get_type ()) #define CLUTTER_TYPE_PERSPECTIVE (clutter_perspective_get_type ()) @@ -69,13 +68,9 @@ typedef struct _ClutterAction ClutterAction; typedef struct _ClutterConstraint ClutterConstraint; typedef struct _ClutterEffect ClutterEffect; -typedef struct _ClutterPath ClutterPath; -typedef struct _ClutterPathNode ClutterPathNode; - typedef struct _ClutterActorBox ClutterActorBox; typedef struct _ClutterColor ClutterColor; typedef struct _ClutterColorState ClutterColorState; -typedef struct _ClutterKnot ClutterKnot; typedef struct _ClutterMargin ClutterMargin; typedef struct _ClutterPerspective ClutterPerspective; @@ -258,59 +253,6 @@ void clutter_actor_box_scale (ClutterActorBox *box, CLUTTER_EXPORT gboolean clutter_actor_box_is_initialized (ClutterActorBox *box); -/** - * ClutterKnot: - * @x: X coordinate of the knot - * @y: Y coordinate of the knot - * - * Point in a path behaviour. - */ -struct _ClutterKnot -{ - gint x; - gint y; -}; - -CLUTTER_EXPORT -GType clutter_knot_get_type (void) G_GNUC_CONST; -CLUTTER_EXPORT -ClutterKnot *clutter_knot_copy (const ClutterKnot *knot); -CLUTTER_EXPORT -void clutter_knot_free (ClutterKnot *knot); -CLUTTER_EXPORT -gboolean clutter_knot_equal (const ClutterKnot *knot_a, - const ClutterKnot *knot_b); - -/** - * ClutterPathNode: - * @type: the node's type - * @points: the coordinates of the node - * - * Represents a single node of a #ClutterPath. - * - * Some of the coordinates in @points may be unused for some node - * types. %CLUTTER_PATH_MOVE_TO and %CLUTTER_PATH_LINE_TO use only one - * pair of coordinates, %CLUTTER_PATH_CURVE_TO uses all three and - * %CLUTTER_PATH_CLOSE uses none. - */ -struct _ClutterPathNode -{ - ClutterPathNodeType type; - - ClutterKnot points[3]; -}; - -CLUTTER_EXPORT -GType clutter_path_node_get_type (void) G_GNUC_CONST; - -CLUTTER_EXPORT -ClutterPathNode *clutter_path_node_copy (const ClutterPathNode *node); -CLUTTER_EXPORT -void clutter_path_node_free (ClutterPathNode *node); -CLUTTER_EXPORT -gboolean clutter_path_node_equal (const ClutterPathNode *node_a, - const ClutterPathNode *node_b); - /* * ClutterPaintVolume */ diff --git a/clutter/clutter/clutter.h b/clutter/clutter/clutter.h index cb3965d70..b7451f6cd 100644 --- a/clutter/clutter/clutter.h +++ b/clutter/clutter/clutter.h @@ -82,8 +82,6 @@ #include "clutter/clutter-paint-nodes.h" #include "clutter/clutter-paint-node.h" #include "clutter/clutter-pan-action.h" -#include "clutter/clutter-path-constraint.h" -#include "clutter/clutter-path.h" #include "clutter/clutter-property-transition.h" #include "clutter/clutter-rotate-action.h" #include "clutter/clutter-scroll-actor.h" diff --git a/clutter/clutter/meson.build b/clutter/clutter/meson.build index c87e7163d..732d9c4fc 100644 --- a/clutter/clutter/meson.build +++ b/clutter/clutter/meson.build @@ -60,8 +60,6 @@ clutter_headers = [ 'clutter-paint-nodes.h', 'clutter-paint-node.h', 'clutter-pan-action.h', - 'clutter-path-constraint.h', - 'clutter-path.h', 'clutter-pick-context.h', 'clutter-property-transition.h', 'clutter-rotate-action.h', @@ -96,7 +94,6 @@ clutter_sources = [ 'clutter-animatable.c', 'clutter-backend.c', 'clutter-base-types.c', - 'clutter-bezier.c', 'clutter-bind-constraint.c', 'clutter-binding-pool.c', 'clutter-bin-layout.c', @@ -148,8 +145,6 @@ clutter_sources = [ 'clutter-paint-nodes.c', 'clutter-paint-node.c', 'clutter-pan-action.c', - 'clutter-path-constraint.c', - 'clutter-path.c', 'clutter-pick-context.c', 'clutter-pick-stack.c', 'clutter-property-transition.c', @@ -181,7 +176,6 @@ clutter_private_headers = [ 'clutter-actor-meta-private.h', 'clutter-actor-private.h', 'clutter-backend-private.h', - 'clutter-bezier.h', 'clutter-blur-private.h', 'clutter-constraint-private.h', 'clutter-content-private.h', diff --git a/src/tests/clutter/conform/path.c b/src/tests/clutter/conform/path.c deleted file mode 100644 index 7bb7c872f..000000000 --- a/src/tests/clutter/conform/path.c +++ /dev/null @@ -1,644 +0,0 @@ -#include -#include -#include -#include - -#include "test-conform-common.h" - -#define MAX_NODES 128 - -#define FLOAT_FUZZ_AMOUNT 5.0f - -typedef struct _CallbackData CallbackData; - -typedef gboolean (* PathTestFunc) (CallbackData *data); - -static void compare_node (const ClutterPathNode *node, gpointer data_p); - -struct _CallbackData -{ - ClutterPath *path; - - guint n_nodes; - ClutterPathNode nodes[MAX_NODES]; - - gboolean nodes_different; - guint nodes_found; -}; - -static const char path_desc[] = - "M 21 22 " - "L 25 26 " - "C 29 30 31 32 33 34 " - "m 23 24 " - "l 27 28 " - "c 35 36 37 38 39 40 " - "z"; -static const ClutterPathNode path_nodes[] = - { { CLUTTER_PATH_MOVE_TO, { { 21, 22 }, { 0, 0 }, { 0, 0 } } }, - { CLUTTER_PATH_LINE_TO, { { 25, 26 }, { 0, 0 }, { 0, 0 } } }, - { CLUTTER_PATH_CURVE_TO, { { 29, 30 }, { 31, 32 }, { 33, 34 } } }, - { CLUTTER_PATH_REL_MOVE_TO, { { 23, 24 }, { 0, 0 }, { 0, 0 } } }, - { CLUTTER_PATH_REL_LINE_TO, { { 27, 28 }, { 0, 0 }, { 0, 0 } } }, - { CLUTTER_PATH_REL_CURVE_TO, { { 35, 36 }, { 37, 38 }, { 39, 40 } } }, - { CLUTTER_PATH_CLOSE, { { 0, 0 }, { 0, 0 }, { 0, 0 } } } }; - -static gboolean -path_test_add_move_to (CallbackData *data) -{ - ClutterPathNode node = { 0, }; - - node.type = CLUTTER_PATH_MOVE_TO; - node.points[0].x = 1; - node.points[0].y = 2; - - clutter_path_add_move_to (data->path, node.points[0].x, node.points[0].y); - - data->nodes[data->n_nodes++] = node; - - return TRUE; -} - -static gboolean -path_test_add_line_to (CallbackData *data) -{ - ClutterPathNode node = { 0, }; - - node.type = CLUTTER_PATH_LINE_TO; - node.points[0].x = 3; - node.points[0].y = 4; - - clutter_path_add_line_to (data->path, node.points[0].x, node.points[0].y); - - data->nodes[data->n_nodes++] = node; - - return TRUE; -} - -static gboolean -path_test_add_curve_to (CallbackData *data) -{ - ClutterPathNode node = { 0, }; - - node.type = CLUTTER_PATH_CURVE_TO; - node.points[0].x = 5; - node.points[0].y = 6; - node.points[1].x = 7; - node.points[1].y = 8; - node.points[2].x = 9; - node.points[2].y = 10; - - clutter_path_add_curve_to (data->path, - node.points[0].x, node.points[0].y, - node.points[1].x, node.points[1].y, - node.points[2].x, node.points[2].y); - - data->nodes[data->n_nodes++] = node; - - return TRUE; -} - -static gboolean -path_test_add_close (CallbackData *data) -{ - ClutterPathNode node = { 0, }; - - node.type = CLUTTER_PATH_CLOSE; - - clutter_path_add_close (data->path); - - data->nodes[data->n_nodes++] = node; - - return TRUE; -} - -static gboolean -path_test_add_rel_move_to (CallbackData *data) -{ - ClutterPathNode node = { 0, }; - - node.type = CLUTTER_PATH_REL_MOVE_TO; - node.points[0].x = 11; - node.points[0].y = 12; - - clutter_path_add_rel_move_to (data->path, node.points[0].x, node.points[0].y); - - data->nodes[data->n_nodes++] = node; - - return TRUE; -} - -static gboolean -path_test_add_rel_line_to (CallbackData *data) -{ - ClutterPathNode node = { 0, }; - - node.type = CLUTTER_PATH_REL_LINE_TO; - node.points[0].x = 13; - node.points[0].y = 14; - - clutter_path_add_rel_line_to (data->path, node.points[0].x, node.points[0].y); - - data->nodes[data->n_nodes++] = node; - - return TRUE; -} - -static gboolean -path_test_add_rel_curve_to (CallbackData *data) -{ - ClutterPathNode node = { 0, }; - - node.type = CLUTTER_PATH_REL_CURVE_TO; - node.points[0].x = 15; - node.points[0].y = 16; - node.points[1].x = 17; - node.points[1].y = 18; - node.points[2].x = 19; - node.points[2].y = 20; - - clutter_path_add_rel_curve_to (data->path, - node.points[0].x, node.points[0].y, - node.points[1].x, node.points[1].y, - node.points[2].x, node.points[2].y); - - data->nodes[data->n_nodes++] = node; - - return TRUE; -} - -static gboolean -path_test_add_string (CallbackData *data) -{ - int i; - - for (i = 0; i < G_N_ELEMENTS (path_nodes); i++) - data->nodes[data->n_nodes++] = path_nodes[i]; - - clutter_path_add_string (data->path, path_desc); - - return TRUE; -} - -static gboolean -path_test_add_node_by_struct (CallbackData *data) -{ - int i; - - for (i = 0; i < G_N_ELEMENTS (path_nodes); i++) - { - data->nodes[data->n_nodes++] = path_nodes[i]; - clutter_path_add_node (data->path, path_nodes + i); - } - - return TRUE; -} - -static gboolean -path_test_get_n_nodes (CallbackData *data) -{ - return clutter_path_get_n_nodes (data->path) == data->n_nodes; -} - -static gboolean -path_test_get_node (CallbackData *data) -{ - int i; - - data->nodes_found = 0; - data->nodes_different = FALSE; - - for (i = 0; i < data->n_nodes; i++) - { - ClutterPathNode node; - - clutter_path_get_node (data->path, i, &node); - - compare_node (&node, data); - } - - return !data->nodes_different; -} - -static gboolean -path_test_get_nodes (CallbackData *data) -{ - GSList *list, *node; - - data->nodes_found = 0; - data->nodes_different = FALSE; - - list = clutter_path_get_nodes (data->path); - - for (node = list; node; node = node->next) - compare_node (node->data, data); - - g_slist_free (list); - - return !data->nodes_different && data->nodes_found == data->n_nodes; -} - -static gboolean -path_test_insert_beginning (CallbackData *data) -{ - ClutterPathNode node; - - node.type = CLUTTER_PATH_LINE_TO; - node.points[0].x = 41; - node.points[0].y = 42; - - memmove (data->nodes + 1, data->nodes, - data->n_nodes++ * sizeof (ClutterPathNode)); - data->nodes[0] = node; - - clutter_path_insert_node (data->path, 0, &node); - - return TRUE; -} - -static gboolean -path_test_insert_end (CallbackData *data) -{ - ClutterPathNode node; - - node.type = CLUTTER_PATH_LINE_TO; - node.points[0].x = 43; - node.points[0].y = 44; - - data->nodes[data->n_nodes++] = node; - - clutter_path_insert_node (data->path, -1, &node); - - return TRUE; -} - -static gboolean -path_test_insert_middle (CallbackData *data) -{ - ClutterPathNode node; - int pos = data->n_nodes / 2; - - node.type = CLUTTER_PATH_LINE_TO; - node.points[0].x = 45; - node.points[0].y = 46; - - memmove (data->nodes + pos + 1, data->nodes + pos, - (data->n_nodes - pos) * sizeof (ClutterPathNode)); - data->nodes[pos] = node; - data->n_nodes++; - - clutter_path_insert_node (data->path, pos, &node); - - return TRUE; -} - -static gboolean -path_test_clear (CallbackData *data) -{ - clutter_path_clear (data->path); - - data->n_nodes = 0; - - return TRUE; -} - -static gboolean -path_test_clear_insert (CallbackData *data) -{ - return path_test_clear (data) && path_test_insert_middle (data); -} - -static gboolean -path_test_remove_beginning (CallbackData *data) -{ - memmove (data->nodes, data->nodes + 1, - --data->n_nodes * sizeof (ClutterPathNode)); - - clutter_path_remove_node (data->path, 0); - - return TRUE; -} - -static gboolean -path_test_remove_end (CallbackData *data) -{ - clutter_path_remove_node (data->path, --data->n_nodes); - - return TRUE; -} - -static gboolean -path_test_remove_middle (CallbackData *data) -{ - int pos = data->n_nodes / 2; - - memmove (data->nodes + pos, data->nodes + pos + 1, - (--data->n_nodes - pos) * sizeof (ClutterPathNode)); - - clutter_path_remove_node (data->path, pos); - - return TRUE; -} - -static gboolean -path_test_remove_only (CallbackData *data) -{ - return path_test_clear (data) - && path_test_add_line_to (data) - && path_test_remove_beginning (data); -} - -static gboolean -path_test_replace (CallbackData *data) -{ - ClutterPathNode node; - int pos = data->n_nodes / 2; - - node.type = CLUTTER_PATH_LINE_TO; - node.points[0].x = 47; - node.points[0].y = 48; - - data->nodes[pos] = node; - - clutter_path_replace_node (data->path, pos, &node); - - return TRUE; -} - -static gboolean -path_test_set_description (CallbackData *data) -{ - data->n_nodes = G_N_ELEMENTS (path_nodes); - memcpy (data->nodes, path_nodes, sizeof (path_nodes)); - - return clutter_path_set_description (data->path, path_desc); -} - -static gboolean -path_test_get_description (CallbackData *data) -{ - char *desc1, *desc2; - gboolean ret = TRUE; - - desc1 = clutter_path_get_description (data->path); - clutter_path_clear (data->path); - if (!clutter_path_set_description (data->path, desc1)) - ret = FALSE; - desc2 = clutter_path_get_description (data->path); - - if (strcmp (desc1, desc2)) - ret = FALSE; - - g_free (desc1); - g_free (desc2); - - return ret; -} - -static gboolean -float_fuzzy_equals (float fa, float fb) -{ - return fabs (fa - fb) <= FLOAT_FUZZ_AMOUNT; -} - -static void -set_triangle_path (CallbackData *data) -{ - /* Triangular shaped path hitting (0,0), (64,64) and (128,0) in four - parts. The two curves are actually straight lines */ - static const ClutterPathNode nodes[] = - { { CLUTTER_PATH_MOVE_TO, { { 0, 0 } } }, - { CLUTTER_PATH_LINE_TO, { { 32, 32 } } }, - { CLUTTER_PATH_CURVE_TO, { { 40, 40 }, { 56, 56 }, { 64, 64 } } }, - { CLUTTER_PATH_REL_CURVE_TO, { { 8, -8 }, { 24, -24 }, { 32, -32 } } }, - { CLUTTER_PATH_REL_LINE_TO, { { 32, -32 } } } }; - gint i; - - clutter_path_clear (data->path); - - for (i = 0; i < G_N_ELEMENTS (nodes); i++) - clutter_path_add_node (data->path, nodes + i); - - memcpy (data->nodes, nodes, sizeof (nodes)); - data->n_nodes = G_N_ELEMENTS (nodes); -} - -static gboolean -path_test_get_position (CallbackData *data) -{ - static const float values[] = { 0.125f, 16.0f, 16.0f, - 0.375f, 48.0f, 48.0f, - 0.625f, 80.0f, 48.0f, - 0.875f, 112.0f, 16.0f }; - gint i; - - set_triangle_path (data); - - for (i = 0; i < G_N_ELEMENTS (values); i += 3) - { - ClutterKnot pos; - - clutter_path_get_position (data->path, - values[i], - &pos); - - if (!float_fuzzy_equals (values[i + 1], pos.x) - || !float_fuzzy_equals (values[i + 2], pos.y)) - return FALSE; - } - - return TRUE; -} - -static gboolean -path_test_get_length (CallbackData *data) -{ - const float actual_length /* sqrt(64**2 + 64**2) * 2 */ = 181.019336f; - guint approx_length; - - clutter_path_set_description (data->path, "M 0 0 L 46340 0"); - g_object_get (data->path, "length", &approx_length, NULL); - - if (!(fabs (approx_length - 46340.f) / 46340.f <= 0.15f)) - { - if (!g_test_quiet ()) - g_print ("M 0 0 L 46340 0 - Expected 46340, got %d instead.", approx_length); - - return FALSE; - } - - clutter_path_set_description (data->path, "M 0 0 L 46341 0"); - g_object_get (data->path, "length", &approx_length, NULL); - - if (!(fabs (approx_length - 46341.f) / 46341.f <= 0.15f)) - { - if (!g_test_quiet ()) - g_print ("M 0 0 L 46341 0 - Expected 46341, got %d instead.", approx_length); - - return FALSE; - } - - set_triangle_path (data); - - g_object_get (data->path, "length", &approx_length, NULL); - - /* Allow 15% margin of error */ - if (!(fabs (approx_length - actual_length) / (float) actual_length <= 0.15f)) - { - if (!g_test_quiet ()) - g_print ("Expected %g, got %d instead.\n", actual_length, approx_length); - - return FALSE; - } - - return TRUE; -} - -static gboolean -path_test_boxed_type (CallbackData *data) -{ - gboolean ret = TRUE; - GSList *nodes, *l; - GValue value; - - nodes = clutter_path_get_nodes (data->path); - - memset (&value, 0, sizeof (value)); - - for (l = nodes; l; l = l->next) - { - g_value_init (&value, CLUTTER_TYPE_PATH_NODE); - - g_value_set_boxed (&value, l->data); - - if (!clutter_path_node_equal (l->data, - g_value_get_boxed (&value))) - ret = FALSE; - - g_value_unset (&value); - } - - g_slist_free (nodes); - - return ret; -} - -static const struct -{ - const char *desc; - PathTestFunc func; -} -path_tests[] = - { - { "Add line to", path_test_add_line_to }, - { "Add move to", path_test_add_move_to }, - { "Add curve to", path_test_add_curve_to }, - { "Add close", path_test_add_close }, - { "Add relative line to", path_test_add_rel_line_to }, - { "Add relative move to", path_test_add_rel_move_to }, - { "Add relative curve to", path_test_add_rel_curve_to }, - { "Add string", path_test_add_string }, - { "Add node by struct", path_test_add_node_by_struct }, - { "Get number of nodes", path_test_get_n_nodes }, - { "Get a node", path_test_get_node }, - { "Get all nodes", path_test_get_nodes }, - { "Insert at beginning", path_test_insert_beginning }, - { "Insert at end", path_test_insert_end }, - { "Insert at middle", path_test_insert_middle }, - { "Add after insert", path_test_add_line_to }, - { "Clear then insert", path_test_clear_insert }, - { "Add string again", path_test_add_string }, - { "Remove from beginning", path_test_remove_beginning }, - { "Remove from end", path_test_remove_end }, - { "Remove from middle", path_test_remove_middle }, - { "Add after remove", path_test_add_line_to }, - { "Remove only node", path_test_remove_only }, - { "Add after remove again", path_test_add_line_to }, - { "Replace a node", path_test_replace }, - { "Set description", path_test_set_description }, - { "Get description", path_test_get_description }, - { "Clear", path_test_clear }, - { "Get position", path_test_get_position }, - { "Check node boxed type", path_test_boxed_type }, - { "Get length", path_test_get_length } - }; - -static void -compare_node (const ClutterPathNode *node, gpointer data_p) -{ - CallbackData *data = data_p; - - if (data->nodes_found >= data->n_nodes) - data->nodes_different = TRUE; - else - { - guint n_points = 0, i; - const ClutterPathNode *onode = data->nodes + data->nodes_found; - - if (node->type != onode->type) - data->nodes_different = TRUE; - - switch (node->type & ~CLUTTER_PATH_RELATIVE) - { - case CLUTTER_PATH_MOVE_TO: n_points = 1; break; - case CLUTTER_PATH_LINE_TO: n_points = 1; break; - case CLUTTER_PATH_CURVE_TO: n_points = 3; break; - case CLUTTER_PATH_CLOSE: n_points = 0; break; - - default: - data->nodes_different = TRUE; - break; - } - - for (i = 0; i < n_points; i++) - if (node->points[i].x != onode->points[i].x - || node->points[i].y != onode->points[i].y) - { - data->nodes_different = TRUE; - break; - } - } - - data->nodes_found++; -} - -static gboolean -compare_nodes (CallbackData *data) -{ - data->nodes_different = FALSE; - data->nodes_found = 0; - - clutter_path_foreach (data->path, compare_node, data); - - return !data->nodes_different && data->nodes_found == data->n_nodes; -} - -void -path_base (TestConformSimpleFixture *fixture, - gconstpointer _data) -{ - CallbackData data; - gint i; - - memset (&data, 0, sizeof (data)); - - data.path = clutter_path_new (); - - for (i = 0; i < G_N_ELEMENTS (path_tests); i++) - { - gboolean succeeded; - - if (!g_test_quiet ()) - g_print ("%s... ", path_tests[i].desc); - - succeeded = path_tests[i].func (&data) && compare_nodes (&data); - - if (!g_test_quiet ()) - g_print ("%s\n", succeeded ? "ok" : "FAIL"); - - g_assert (succeeded); - } - - g_object_unref (data.path); -} - diff --git a/src/tests/clutter/interactive/test-path-constraint.c b/src/tests/clutter/interactive/test-path-constraint.c deleted file mode 100644 index 0d0fb5586..000000000 --- a/src/tests/clutter/interactive/test-path-constraint.c +++ /dev/null @@ -1,138 +0,0 @@ -#include -#include -#include - -#include "tests/clutter-test-utils.h" - -#define PATH_DESCRIPTION \ - "M 0, 0 " \ - "L 0, 300 " \ - "L 300, 300 " \ - "L 300, 0 " \ - "L 0, 0" - -static gboolean toggled = FALSE; - -int -test_path_constraint_main (int argc, - char *argv[]); - -static gboolean -on_button_press (ClutterActor *actor, - const ClutterEvent *event, - gpointer dummy G_GNUC_UNUSED) -{ - if (!toggled) - clutter_actor_animate (actor, CLUTTER_EASE_OUT_CUBIC, 500, - "@constraints.path.offset", 1.0, - NULL); - else - clutter_actor_animate (actor, CLUTTER_EASE_OUT_CUBIC, 500, - "@constraints.path.offset", 0.0, - NULL); - - toggled = !toggled; - - return TRUE; -} - -static gchar * -node_to_string (const ClutterPathNode *node) -{ - GString *buffer = g_string_sized_new (256); - gsize len = 0, i; - - switch (node->type) - { - case CLUTTER_PATH_MOVE_TO: - g_string_append (buffer, "move-to "); - len = 1; - break; - - case CLUTTER_PATH_LINE_TO: - g_string_append (buffer, "line-to "); - len = 1; - break; - - case CLUTTER_PATH_CURVE_TO: - g_string_append (buffer, "curve-to "); - len = 3; - break; - - case CLUTTER_PATH_CLOSE: - g_string_append (buffer, "close"); - len = 0; - break; - - default: - break; - } - - for (i = 0; i < len; i++) - { - if (i == 0) - g_string_append (buffer, "[ "); - - g_string_append_printf (buffer, "[ %d, %d ]", - node->points[i].x, - node->points[i].y); - - if (i == len - 1) - g_string_append (buffer, " ]"); - } - - return g_string_free (buffer, FALSE); -} - -static void -on_node_reached (ClutterPathConstraint *constraint, - ClutterActor *actor, - guint index_) -{ - ClutterPath *path = clutter_path_constraint_get_path (constraint); - ClutterPathNode node; - gchar *str; - - clutter_path_get_node (path, index_, &node); - - str = node_to_string (&node); - g_print ("Node %d reached: %s\n", index_, str); - g_free (str); -} - -G_MODULE_EXPORT int -test_path_constraint_main (int argc, - char *argv[]) -{ - ClutterActor *stage, *rect; - ClutterPath *path; - ClutterColor rect_color = { 0xcc, 0x00, 0x00, 0xff }; - - clutter_test_init (&argc, &argv); - - stage = clutter_test_get_stage (); - clutter_stage_set_title (CLUTTER_STAGE (stage), "Path Constraint"); - g_signal_connect (stage, "destroy", G_CALLBACK (clutter_test_quit), NULL); - - path = clutter_path_new (); - clutter_path_set_description (path, PATH_DESCRIPTION); - - rect = clutter_actor_new (); - clutter_actor_set_background_color (rect, &rect_color); - clutter_actor_set_size (rect, 128, 128); - clutter_actor_set_reactive (rect, TRUE); - clutter_actor_add_constraint_with_name (rect, "path", clutter_path_constraint_new (path, 0.0)); - clutter_actor_add_child (stage, rect); - - g_signal_connect (rect, "button-press-event", G_CALLBACK (on_button_press), NULL); - g_signal_connect (clutter_actor_get_constraint (rect, "path"), - "node-reached", - G_CALLBACK (on_node_reached), - NULL); - - clutter_actor_show (stage); - - clutter_test_main (); - - return EXIT_SUCCESS; -}