2
* Pretty cairo flower hack.
4
#include <clutter/clutter.h>
7
#include <unistd.h> /* for sleep(), used for screenshots */
11
#define _USE_MATH_DEFINES
17
#define N_FLOWERS 40 /* reduce if you have a small card */
26
static ClutterActor *stage = NULL;
29
draw_flower (ClutterCanvas *canvas,
35
/* No science here, just a hack from toying */
54
gint n_groups; /* Num groups of petals 1-3 */
55
gint n_petals; /* num of petals 4 - 8 */
58
gint idx, last_idx = -1;
60
petal_size = GPOINTER_TO_INT (user_data);
61
size = petal_size * 8;
63
n_groups = rand() % 3 + 1;
65
cairo_set_tolerance (cr, 0.1);
68
cairo_set_operator (cr, CAIRO_OPERATOR_CLEAR);
70
cairo_set_operator (cr, CAIRO_OPERATOR_OVER);
72
cairo_translate(cr, size/2, size/2);
74
for (i=0; i<n_groups; i++)
76
n_petals = rand() % 5 + 4;
79
cairo_rotate (cr, rand() % 6);
82
idx = (rand() % (sizeof (colors) / sizeof (double) / 3)) * 3;
83
} while (idx == last_idx);
85
cairo_set_source_rgba (cr, colors[idx], colors[idx+1],
90
/* some bezier randomness */
94
for (j=1; j<n_petals+1; j++)
97
cairo_rotate (cr, ((2*M_PI)/n_petals)*j);
99
/* Petals are made up beziers */
101
cairo_move_to (cr, 0, 0);
102
cairo_rel_curve_to (cr,
103
petal_size, petal_size,
104
(pm2+2)*petal_size, petal_size,
105
(2*petal_size) + pm1, 0);
106
cairo_rel_curve_to (cr,
107
0 + (pm2*petal_size), -petal_size,
108
-petal_size, -petal_size,
109
-((2*petal_size) + pm1), 0);
110
cairo_close_path (cr);
115
petal_size -= rand() % (size/8);
120
/* Finally draw flower center */
122
idx = (rand() % (sizeof (colors) / sizeof (double) / 3)) * 3;
123
} while (idx == last_idx);
126
petal_size = rand() % 10;
128
cairo_set_source_rgba (cr, colors[idx], colors[idx+1], colors[idx+2], 0.5);
130
cairo_arc(cr, 0, 0, petal_size, 0, M_PI * 2);
136
static ClutterActor *
137
make_flower_actor (void)
139
gint petal_size = PETAL_MIN + rand() % PETAL_VAR;
140
gint size = petal_size * 8;
142
ClutterContent *canvas;
144
canvas = clutter_canvas_new ();
145
g_signal_connect (canvas, "draw",
146
G_CALLBACK (draw_flower), GINT_TO_POINTER (petal_size));
148
clutter_canvas_set_size (CLUTTER_CANVAS (canvas), size, size);
149
ctex = g_object_new (CLUTTER_TYPE_ACTOR,
151
"width", (gfloat) size,
152
"height", (gfloat) size,
155
g_object_unref (canvas);
161
tick (ClutterTimeline *timeline,
165
Flower **flowers = data;
168
for (i = 0; i < N_FLOWERS; i++)
170
flowers[i]->y += flowers[i]->v;
171
flowers[i]->rot += flowers[i]->rv;
173
if (flowers[i]->y > (gint) clutter_actor_get_height (stage))
174
flowers[i]->y = -clutter_actor_get_height (flowers[i]->ctex);
176
clutter_actor_set_position (flowers[i]->ctex,
177
flowers[i]->x, flowers[i]->y);
179
clutter_actor_set_rotation (flowers[i]->ctex,
182
clutter_actor_get_width (flowers[i]->ctex)/2,
183
clutter_actor_get_height (flowers[i]->ctex)/2,
189
stop_and_quit (ClutterActor *actor,
190
ClutterTimeline *timeline)
192
clutter_timeline_stop (timeline);
193
clutter_main_quit ();
197
test_cairo_flowers_main (int argc, char **argv)
199
Flower *flowers[N_FLOWERS];
200
ClutterTimeline *timeline;
205
if (clutter_init (&argc, &argv) != CLUTTER_INIT_SUCCESS)
208
/* Create a timeline to manage animation */
209
timeline = clutter_timeline_new (6000);
210
clutter_timeline_set_repeat_count (timeline, -1);
212
stage = clutter_stage_new ();
213
clutter_stage_set_title (CLUTTER_STAGE (stage), "Cairo Flowers");
214
g_signal_connect (stage, "destroy", G_CALLBACK (stop_and_quit), timeline);
216
clutter_actor_set_background_color (stage, CLUTTER_COLOR_Black);
218
for (i=0; i< N_FLOWERS; i++)
220
flowers[i] = g_new0(Flower, 1);
221
flowers[i]->ctex = make_flower_actor();
222
flowers[i]->x = rand() % (int) clutter_actor_get_width (stage)
223
- (PETAL_MIN + PETAL_VAR) * 2;
224
flowers[i]->y = rand() % (int) clutter_actor_get_height (stage);
225
flowers[i]->rv = rand() % 5 + 1;
226
flowers[i]->v = rand() % 10 + 2;
228
clutter_container_add_actor (CLUTTER_CONTAINER (stage),
230
clutter_actor_set_position (flowers[i]->ctex,
231
flowers[i]->x, flowers[i]->y);
234
/* fire a callback for frame change */
235
g_signal_connect (timeline, "new-frame", G_CALLBACK (tick), flowers);
237
clutter_actor_show (stage);
239
clutter_timeline_start (timeline);
241
g_signal_connect (stage, "key-press-event",
242
G_CALLBACK (clutter_main_quit),
247
g_object_unref (timeline);
252
G_MODULE_EXPORT const char *
253
test_cairo_flowers_describe (void)
255
return "Drawing pretty flowers with Cairo";