summaryrefslogtreecommitdiff
path: root/src/examples
diff options
context:
space:
mode:
authorSubhransu Mohanty <sub.mohanty@samsung.com>2016-05-31 14:42:37 -0700
committerCedric BAIL <cedric@osg.samsung.com>2016-05-31 14:59:26 -0700
commitfbde2778af469c43311a8fb343f52cd2e1488ce4 (patch)
treefd29f49ce14fb45f5d95c76cf491fd71fc117f12 /src/examples
parentb43a7f51879ec86d959784e898857b95c8c24ce3 (diff)
evas: updated evas_vg_sample with the appen_arc() api as well as _shape_dup() api test.
Reviewers: Hermet, cedric Reviewed By: cedric Subscribers: cedric, jpeg Differential Revision: https://phab.enlightenment.org/D3966 Signed-off-by: Cedric BAIL <cedric@osg.samsung.com>
Diffstat (limited to 'src/examples')
-rw-r--r--src/examples/evas/evas-vg-simple.c365
1 files changed, 16 insertions, 349 deletions
diff --git a/src/examples/evas/evas-vg-simple.c b/src/examples/evas/evas-vg-simple.c
index 329e7a7..305df03 100644
--- a/src/examples/evas/evas-vg-simple.c
+++ b/src/examples/evas/evas-vg-simple.c
@@ -39,16 +39,6 @@
39#define PATH_KAPPA 0.5522847498 39#define PATH_KAPPA 0.5522847498
40#define PI 3.1415926535 40#define PI 3.1415926535
41 41
42typedef struct _Bezier
43{
44float x1, y1, x2, y2, x3, y3, x4, y4;
45}Bezier;
46
47typedef struct _Point
48{
49 int x;
50 int y;
51}Point;
52 42
53static Efl_VG *beginning = NULL; 43static Efl_VG *beginning = NULL;
54static Efl_VG *end = NULL; 44static Efl_VG *end = NULL;
@@ -56,337 +46,6 @@ static Efl_VG *root = NULL;
56static double start_time = 0; 46static double start_time = 0;
57static Ecore_Animator *anim = NULL; 47static Ecore_Animator *anim = NULL;
58 48
59static
60Bezier bezierFromPoints(Point p1, Point p2,
61 Point p3, Point p4)
62{
63 Bezier b;
64 b.x1 = p1.x;
65 b.y1 = p1.y;
66 b.x2 = p2.x;
67 b.y2 = p2.y;
68 b.x3 = p3.x;
69 b.y3 = p3.y;
70 b.x4 = p4.x;
71 b.y4 = p4.y;
72 return b;
73}
74
75static inline void
76parameterSplitLeft(Bezier *b, float t, Bezier *left)
77{
78 left->x1 = b->x1;
79 left->y1 = b->y1;
80
81 left->x2 = b->x1 + t * ( b->x2 - b->x1 );
82 left->y2 = b->y1 + t * ( b->y2 - b->y1 );
83
84 left->x3 = b->x2 + t * ( b->x3 - b->x2 ); // temporary holding spot
85 left->y3 = b->y2 + t * ( b->y3 - b->y2 ); // temporary holding spot
86
87 b->x3 = b->x3 + t * ( b->x4 - b->x3 );
88 b->y3 = b->y3 + t * ( b->y4 - b->y3 );
89
90 b->x2 = left->x3 + t * ( b->x3 - left->x3);
91 b->y2 = left->y3 + t * ( b->y3 - left->y3);
92
93 left->x3 = left->x2 + t * ( left->x3 - left->x2 );
94 left->y3 = left->y2 + t * ( left->y3 - left->y2 );
95
96 left->x4 = b->x1 = left->x3 + t * (b->x2 - left->x3);
97 left->y4 = b->y1 = left->y3 + t * (b->y2 - left->y3);
98}
99static
100Bezier bezierOnInterval(Bezier *b, float t0, float t1)
101{
102 if (t0 == 0 && t1 == 1)
103 return *b;
104
105 Bezier result;
106 parameterSplitLeft(b, t0, &result);
107 float trueT = (t1-t0)/(1-t0);
108 parameterSplitLeft(b, trueT, &result);
109
110 return result;
111}
112
113static inline void
114_bezier_coefficients(float t, float *ap, float *bp, float *cp, float *dp)
115{
116 float a,b,c,d;
117 float m_t = 1. - t;
118 b = m_t * m_t;
119 c = t * t;
120 d = c * t;
121 a = b * m_t;
122 b *= 3. * t;
123 c *= 3. * m_t;
124 *ap = a;
125 *bp = b;
126 *cp = c;
127 *dp = d;
128}
129
130static
131float _t_for_arc_angle(float angle)
132{
133 if (angle < 0.00001)
134 return 0;
135
136 if (angle == 90.0)
137 return 1;
138
139 float radians = PI * angle / 180;
140 float cosAngle = cos(radians);
141 float sinAngle = sin(radians);
142
143 // initial guess
144 float tc = angle / 90;
145 // do some iterations of newton's method to approximate cosAngle
146 // finds the zero of the function b.pointAt(tc).x() - cosAngle
147 tc -= ((((2-3*PATH_KAPPA) * tc + 3*(PATH_KAPPA-1)) * tc) * tc + 1 - cosAngle) // value
148 / (((6-9*PATH_KAPPA) * tc + 6*(PATH_KAPPA-1)) * tc); // derivative
149 tc -= ((((2-3*PATH_KAPPA) * tc + 3*(PATH_KAPPA-1)) * tc) * tc + 1 - cosAngle) // value
150 / (((6-9*PATH_KAPPA) * tc + 6*(PATH_KAPPA-1)) * tc); // derivative
151
152 // initial guess
153 float ts = tc;
154 // do some iterations of newton's method to approximate sinAngle
155 // finds the zero of the function b.pointAt(tc).y() - sinAngle
156 ts -= ((((3*PATH_KAPPA-2) * ts - 6*PATH_KAPPA + 3) * ts + 3*PATH_KAPPA) * ts - sinAngle)
157 / (((9*PATH_KAPPA-6) * ts + 12*PATH_KAPPA - 6) * ts + 3*PATH_KAPPA);
158 ts -= ((((3*PATH_KAPPA-2) * ts - 6*PATH_KAPPA + 3) * ts + 3*PATH_KAPPA) * ts - sinAngle)
159 / (((9*PATH_KAPPA-6) * ts + 12*PATH_KAPPA - 6) * ts + 3*PATH_KAPPA);
160
161 // use the average of the t that best approximates cosAngle
162 // and the t that best approximates sinAngle
163 float t = 0.5 * (tc + ts);
164 return t;
165}
166
167static void
168_find_ellipse_coords(int x, int y, int w, int h, float angle, float length,
169 Point* startPoint, Point *endPoint)
170{
171 if (!w || !h ) {
172 if (startPoint)
173 startPoint->x = 0 , startPoint->y = 0;
174 if (endPoint)
175 endPoint->x = 0 , endPoint->y = 0;
176 return;
177 }
178
179 int w2 = w / 2;
180 int h2 = h / 2;
181
182 float angles[2] = { angle, angle + length };
183 Point *points[2] = { startPoint, endPoint };
184 int i =0;
185 for (i = 0; i < 2; ++i) {
186 if (!points[i])
187 continue;
188
189 float theta = angles[i] - 360 * floor(angles[i] / 360);
190 float t = theta / 90;
191 // truncate
192 int quadrant = (int)t;
193 t -= quadrant;
194
195 t = _t_for_arc_angle(90 * t);
196
197 // swap x and y?
198 if (quadrant & 1)
199 t = 1 - t;
200
201 float a, b, c, d;
202 _bezier_coefficients(t, &a, &b, &c, &d);
203 float px = a + b + c*PATH_KAPPA;
204 float py = d + c + b*PATH_KAPPA;
205
206 // left quadrants
207 if (quadrant == 1 || quadrant == 2)
208 px = -px;
209
210 // top quadrants
211 if (quadrant == 0 || quadrant == 1)
212 py = -py;
213 int cx = x+w/2;
214 int cy = y+h/2;
215 points[i]->x = cx + w2 * px;
216 points[i]->y = cy + h2 * py;
217 }
218}
219
220
221//// The return value is the starting point of the arc
222static
223Point _curves_for_arc(int x, int y, int w, int h,
224 float startAngle, float sweepLength,
225 Point *curves, int *point_count)
226{
227 *point_count = 0;
228 int w2 = w / 2;
229 int w2k = w2 * PATH_KAPPA;
230
231 int h2 = h / 2;
232 int h2k = h2 * PATH_KAPPA;
233
234 Point points[16] =
235 {
236 // start point
237 { x + w, y + h2 },
238
239 // 0 -> 270 degrees
240 { x + w, y + h2 + h2k },
241 { x + w2 + w2k, y + h },
242 { x + w2, y + h },
243
244 // 270 -> 180 degrees
245 { x + w2 - w2k, y + h },
246 { x, y + h2 + h2k },
247 { x, y + h2 },
248
249 // 180 -> 90 degrees
250 { x, y + h2 - h2k },
251 { x + w2 - w2k, y },
252 { x + w2, y },
253
254 // 90 -> 0 degrees
255 { x + w2 + w2k, y },
256 { x + w, y + h2 - h2k },
257 { x + w, y + h2 }
258 };
259
260 if (sweepLength > 360) sweepLength = 360;
261 else if (sweepLength < -360) sweepLength = -360;
262
263 // Special case fast paths
264 if (startAngle == 0) {
265 if (sweepLength == 360) {
266 int i;
267 for (i = 11; i >= 0; --i)
268 curves[(*point_count)++] = points[i];
269 return points[12];
270 } else if (sweepLength == -360) {
271 int i ;
272 for (i = 1; i <= 12; ++i)
273 curves[(*point_count)++] = points[i];
274 return points[0];
275 }
276 }
277
278 int startSegment = (int)(floor(startAngle / 90));
279 int endSegment = (int)(floor((startAngle + sweepLength) / 90));
280
281 float startT = (startAngle - startSegment * 90) / 90;
282 float endT = (startAngle + sweepLength - endSegment * 90) / 90;
283
284 int delta = sweepLength > 0 ? 1 : -1;
285 if (delta < 0) {
286 startT = 1 - startT;
287 endT = 1 - endT;
288 }
289
290 // avoid empty start segment
291 if (startT == 1.0) {
292 startT = 0;
293 startSegment += delta;
294 }
295
296 // avoid empty end segment
297 if (endT == 0) {
298 endT = 1;
299 endSegment -= delta;
300 }
301
302 startT = _t_for_arc_angle(startT * 90);
303 endT = _t_for_arc_angle(endT * 90);
304
305 Eina_Bool splitAtStart = !(fabs(startT) <= 0.00001f);
306 Eina_Bool splitAtEnd = !(fabs(endT - 1.0) <= 0.00001f);
307
308 const int end = endSegment + delta;
309
310 // empty arc?
311 if (startSegment == end) {
312 const int quadrant = 3 - ((startSegment % 4) + 4) % 4;
313 const int j = 3 * quadrant;
314 return delta > 0 ? points[j + 3] : points[j];
315 }
316
317
318 Point startPoint, endPoint;
319 _find_ellipse_coords(x, y, w, h, startAngle, sweepLength, &startPoint, &endPoint);
320 int i;
321 for (i = startSegment; i != end; i += delta) {
322 const int quadrant = 3 - ((i % 4) + 4) % 4;
323 const int j = 3 * quadrant;
324
325 Bezier b;
326 if (delta > 0)
327 b = bezierFromPoints(points[j + 3], points[j + 2], points[j + 1], points[j]);
328 else
329 b = bezierFromPoints(points[j], points[j + 1], points[j + 2], points[j + 3]);
330
331 // empty arc?
332 if (startSegment == endSegment && (startT == endT))
333 return startPoint;
334
335 if (i == startSegment) {
336 if (i == endSegment && splitAtEnd)
337 b = bezierOnInterval(&b, startT, endT);
338 else if (splitAtStart)
339 b = bezierOnInterval(&b, startT, 1);
340 } else if (i == endSegment && splitAtEnd) {
341 b = bezierOnInterval(&b, 0, endT);
342 }
343
344 // push control points
345 curves[(*point_count)].x = b.x2;
346 curves[(*point_count)++].y = b.y2;
347 curves[(*point_count)].x = b.x3;
348 curves[(*point_count)++].y = b.y3;
349 curves[(*point_count)].x = b.x4;
350 curves[(*point_count)++].y = b.y4;
351 }
352
353 curves[*(point_count)-1] = endPoint;
354
355 return startPoint;
356}
357
358void _arcto(Efl_VG *obj, int x, int y, int width, int height, int startAngle, int sweepLength)
359{
360 int point_count;
361
362 Point pts[15];
363 Point curve_start = _curves_for_arc(x, y, width, height, startAngle, sweepLength, pts, &point_count);
364 int cx = x + (width)/2;
365 int cy = y + (height)/2;
366 int i;
367
368 evas_vg_shape_shape_append_move_to(obj, cx, cy);
369 evas_vg_shape_shape_append_line_to(obj, curve_start.x, curve_start.y);
370 for (i = 0; i < point_count; i += 3)
371 {
372 evas_vg_shape_shape_append_cubic_to(obj,
373 pts[i].x, pts[i].y,
374 pts[i+1].x, pts[i+1].y,
375 pts[i+2].x, pts[i+2].y);
376 }
377 evas_vg_shape_shape_append_close(obj);
378}
379
380void _rect_add(Efl_VG *obj, int x, int y, int w, int h)
381{
382 evas_vg_shape_shape_append_move_to(obj, x, y);
383 evas_vg_shape_shape_append_line_to(obj, x + w, y);
384 evas_vg_shape_shape_append_line_to(obj, x + w, y +h);
385 evas_vg_shape_shape_append_line_to(obj, x, y +h);
386 evas_vg_shape_shape_append_close(obj);
387}
388
389
390struct example_data 49struct example_data
391{ 50{
392 Ecore_Evas *ee; 51 Ecore_Evas *ee;
@@ -417,9 +76,9 @@ static void
417vector_set(int x, int y, int w, int h) 76vector_set(int x, int y, int w, int h)
418{ 77{
419 int vg_w = w, vg_h = h; 78 int vg_w = w, vg_h = h;
79 Efl_VG *root_node, *tmp_vg;
420 80
421 //Create VG Object 81 //Create VG Object
422
423 Evas_Object *tmp = evas_object_rectangle_add(d.evas); 82 Evas_Object *tmp = evas_object_rectangle_add(d.evas);
424 evas_object_resize(tmp, vg_w, vg_h); 83 evas_object_resize(tmp, vg_w, vg_h);
425 evas_object_color_set(tmp, 100, 100, 50, 100); 84 evas_object_color_set(tmp, 100, 100, 50, 100);
@@ -446,11 +105,11 @@ vector_set(int x, int y, int w, int h)
446 eina_matrix3_identity(&matrix); 105 eina_matrix3_identity(&matrix);
447 eina_matrix3_rotate(&matrix, radian); 106 eina_matrix3_rotate(&matrix, radian);
448 107
449 root = evas_object_vg_root_node_get(d.vg); 108 root = eo_add(EFL_VG_CONTAINER_CLASS, NULL);
450 //evas_vg_node_transformation_set(root, &matrix); 109 //evas_vg_node_transformation_set(root, &matrix);
451 110
452 Efl_VG *bg = eo_add(EFL_VG_SHAPE_CLASS, root, efl_vg_name_set(eo_self, "bg")); 111 Efl_VG *bg = eo_add(EFL_VG_SHAPE_CLASS, root, efl_vg_name_set(eo_self, "bg"));
453 _rect_add(bg, 0, 0 , vg_w, vg_h); 112 evas_vg_shape_shape_append_rect(bg, 0, 0 , vg_w, vg_h, 0, 0);
454 evas_vg_node_origin_set(bg, 0,0); 113 evas_vg_node_origin_set(bg, 0,0);
455 evas_vg_shape_stroke_width_set(bg, 1.0); 114 evas_vg_shape_stroke_width_set(bg, 1.0);
456 evas_vg_node_color_set(bg, 80, 80, 80, 80); 115 evas_vg_node_color_set(bg, 80, 80, 80, 80);
@@ -459,7 +118,7 @@ vector_set(int x, int y, int w, int h)
459 Efl_VG *rgradient = eo_add(EFL_VG_GRADIENT_RADIAL_CLASS, NULL, efl_vg_name_set(eo_self, "rgradient")); 118 Efl_VG *rgradient = eo_add(EFL_VG_GRADIENT_RADIAL_CLASS, NULL, efl_vg_name_set(eo_self, "rgradient"));
460 Efl_VG *lgradient = eo_add(EFL_VG_GRADIENT_LINEAR_CLASS, NULL, efl_vg_name_set(eo_self, "lgradient")); 119 Efl_VG *lgradient = eo_add(EFL_VG_GRADIENT_LINEAR_CLASS, NULL, efl_vg_name_set(eo_self, "lgradient"));
461 120
462 _arcto(shape, 0, 0, 100, 100, 25, 330); 121 evas_vg_shape_shape_append_arc(shape, 0, 0, 100, 100, 25, 330);
463 122
464 Efl_Gfx_Gradient_Stop stops[3]; 123 Efl_Gfx_Gradient_Stop stops[3];
465 stops[0].r = 255; 124 stops[0].r = 255;
@@ -499,7 +158,7 @@ vector_set(int x, int y, int w, int h)
499 evas_vg_shape_stroke_color_set(shape, 0, 0, 255, 128); 158 evas_vg_shape_stroke_color_set(shape, 0, 0, 255, 128);
500 159
501 Efl_VG *rect = eo_add(EFL_VG_SHAPE_CLASS, root, efl_vg_name_set(eo_self, "rect")); 160 Efl_VG *rect = eo_add(EFL_VG_SHAPE_CLASS, root, efl_vg_name_set(eo_self, "rect"));
502 _rect_add(rect, 0, 0, 100, 100); 161 evas_vg_shape_shape_append_rect(rect, 0, 0, 100, 100, 0, 0);
503 evas_vg_node_origin_set(rect, 100, 100); 162 evas_vg_node_origin_set(rect, 100, 100);
504 evas_vg_shape_fill_set(rect, lgradient); 163 evas_vg_shape_fill_set(rect, lgradient);
505 evas_vg_shape_stroke_width_set(rect, 2.0); 164 evas_vg_shape_stroke_width_set(rect, 2.0);
@@ -507,7 +166,7 @@ vector_set(int x, int y, int w, int h)
507 evas_vg_shape_stroke_color_set(rect, 255, 255, 255, 255); 166 evas_vg_shape_stroke_color_set(rect, 255, 255, 255, 255);
508 167
509 Efl_VG *rect1 = eo_add(EFL_VG_SHAPE_CLASS, root, efl_vg_name_set(eo_self, "rect1")); 168 Efl_VG *rect1 = eo_add(EFL_VG_SHAPE_CLASS, root, efl_vg_name_set(eo_self, "rect1"));
510 _rect_add(rect1, 0, 0, 70, 70); 169 evas_vg_shape_shape_append_rect(rect1, 0, 0, 70, 70, 0, 0);
511 evas_vg_node_origin_set(rect1, 50, 70); 170 evas_vg_node_origin_set(rect1, 50, 70);
512 evas_vg_shape_stroke_scale_set(rect1, 2); 171 evas_vg_shape_stroke_scale_set(rect1, 2);
513 evas_vg_shape_stroke_width_set(rect1, 8.0); 172 evas_vg_shape_stroke_width_set(rect1, 8.0);
@@ -515,7 +174,7 @@ vector_set(int x, int y, int w, int h)
515 evas_vg_shape_stroke_color_set(rect1, 0, 100, 80, 100); 174 evas_vg_shape_stroke_color_set(rect1, 0, 100, 80, 100);
516 175
517 Efl_VG *circle = eo_add(EFL_VG_SHAPE_CLASS, root, efl_vg_name_set(eo_self, "circle")); 176 Efl_VG *circle = eo_add(EFL_VG_SHAPE_CLASS, root, efl_vg_name_set(eo_self, "circle"));
518 _arcto(circle, 0, 0, 250, 100, 30, 300); 177 evas_vg_shape_shape_append_arc(circle, 0, 0, 250, 100, 30, 300);
519 evas_vg_shape_fill_set(circle, lgradient); 178 evas_vg_shape_fill_set(circle, lgradient);
520 //evas_vg_node_transformation_set(&matrix), 179 //evas_vg_node_transformation_set(&matrix),
521 evas_vg_node_origin_set(circle, 50,50); 180 evas_vg_node_origin_set(circle, 50,50);
@@ -523,7 +182,7 @@ vector_set(int x, int y, int w, int h)
523 182
524 // Foreground 183 // Foreground
525 Efl_VG *fg = eo_add(EFL_VG_SHAPE_CLASS, root, efl_vg_name_set(eo_self, "fg")); 184 Efl_VG *fg = eo_add(EFL_VG_SHAPE_CLASS, root, efl_vg_name_set(eo_self, "fg"));
526 _rect_add(fg, 0, 0, vg_w, vg_h); 185 evas_vg_shape_shape_append_rect(fg, 0, 0, vg_w, vg_h, 0, 0);
527 evas_vg_node_origin_set(fg, 0, 0); 186 evas_vg_node_origin_set(fg, 0, 0);
528 evas_vg_shape_stroke_width_set(fg, 5.0); 187 evas_vg_shape_stroke_width_set(fg, 5.0);
529 evas_vg_shape_stroke_join_set(fg, EFL_GFX_JOIN_ROUND); 188 evas_vg_shape_stroke_join_set(fg, EFL_GFX_JOIN_ROUND);
@@ -546,6 +205,14 @@ vector_set(int x, int y, int w, int h)
546 205
547 circle = efl_vg_container_child_get(end, "circle"); 206 circle = efl_vg_container_child_get(end, "circle");
548 efl_vg_transformation_set(circle, &matrix); 207 efl_vg_transformation_set(circle, &matrix);
208
209 root_node = evas_object_vg_root_node_get(d.vg);
210 // check if the dupe is working properly or not
211 eo_parent_set(beginning, root_node);
212
213 tmp_vg = root;
214 root = beginning;
215 beginning = tmp_vg;
549} 216}
550 217
551static Eina_Bool 218static Eina_Bool