aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/libraries/evas/src/lib/canvas/evas_map.c
diff options
context:
space:
mode:
Diffstat (limited to 'libraries/evas/src/lib/canvas/evas_map.c')
-rw-r--r--libraries/evas/src/lib/canvas/evas_map.c1037
1 files changed, 0 insertions, 1037 deletions
diff --git a/libraries/evas/src/lib/canvas/evas_map.c b/libraries/evas/src/lib/canvas/evas_map.c
deleted file mode 100644
index 5dcb760..0000000
--- a/libraries/evas/src/lib/canvas/evas_map.c
+++ /dev/null
@@ -1,1037 +0,0 @@
1#include "evas_common.h"
2#include "evas_private.h"
3#include <math.h>
4
5static void
6_evas_map_calc_geom_change(Evas_Object *obj)
7{
8 int is, was = 0, pass = 0;
9
10 evas_object_change(obj);
11 evas_object_clip_dirty(obj);
12 if (obj->layer->evas->events_frozen <= 0)
13 {
14 evas_object_recalc_clippees(obj);
15 if (!pass)
16 {
17 if (!obj->smart.smart)
18 {
19 is = evas_object_is_in_output_rect(obj,
20 obj->layer->evas->pointer.x,
21 obj->layer->evas->pointer.y, 1, 1);
22 if ((is ^ was) && obj->cur.visible)
23 evas_event_feed_mouse_move(obj->layer->evas,
24 obj->layer->evas->pointer.x,
25 obj->layer->evas->pointer.y,
26 obj->layer->evas->last_timestamp,
27 NULL);
28 }
29 }
30 }
31 evas_object_inform_call_move(obj);
32 evas_object_inform_call_resize(obj);
33}
34
35static void
36_evas_map_calc_map_geometry(Evas_Object *obj)
37{
38 Evas_Coord x1, x2, yy1, yy2;
39 const Evas_Map_Point *p, *p_end;
40 Eina_Bool ch = EINA_FALSE;
41
42 if (!obj->cur.map) return;
43
44 // WARN: Do not merge below code to SLP until it is fixed.
45 // It has an infinite loop bug.
46 if (obj->prev.map)
47 {
48 // FIXME: this causes an infinite loop somewhere... hard to debug
49 if (obj->prev.map->count == obj->cur.map->count)
50 {
51 const Evas_Map_Point *p2;
52
53 p = obj->cur.map->points;
54 p_end = p + obj->cur.map->count;
55 p2 = obj->prev.map->points;
56
57 for (; p < p_end; p++, p2++)
58 {
59 if ((p->a != p2->a) ||
60 (p->r != p2->r) ||
61 (p->g != p2->g) ||
62 (p->b != p2->b))
63 {
64 ch = 1;
65 break;
66 }
67 if ((p->x != p2->x) ||
68 (p->y != p2->y) ||
69 (p->z != p2->z))
70 {
71 ch = 1;
72 break;
73 }
74 }
75 }
76 else
77 ch = 1;
78 }
79 else
80 ch = 1;
81
82 p = obj->cur.map->points;
83 p_end = p + obj->cur.map->count;
84 x1 = x2 = lround(p->x);
85 yy1 = yy2 = lround(p->y);
86 p++;
87 for (; p < p_end; p++)
88 {
89 Evas_Coord x, y;
90
91 x = lround(p->x);
92 y = lround(p->y);
93 if (x < x1) x1 = x;
94 if (x > x2) x2 = x;
95 if (y < yy1) yy1 = y;
96 if (y > yy2) yy2 = y;
97 }
98// this causes clip-out bugs now mapped objs canbe opaque!!!
99// // add 1 pixel of fuzz around the map region to ensure updates are correct
100// x1 -= 1; yy1 -= 1;
101// x2 += 1; yy2 += 1;
102 if (obj->cur.map->normal_geometry.x != x1) ch = 1;
103 if (obj->cur.map->normal_geometry.y != yy1) ch = 1;
104 if (obj->cur.map->normal_geometry.w != (x2 - x1)) ch = 1;
105 if (obj->cur.map->normal_geometry.h != (yy2 - yy1)) ch = 1;
106 obj->cur.map->normal_geometry.x = x1;
107 obj->cur.map->normal_geometry.y = yy1;
108 obj->cur.map->normal_geometry.w = (x2 - x1);
109 obj->cur.map->normal_geometry.h = (yy2 - yy1);
110 if (ch) _evas_map_calc_geom_change(obj);
111}
112
113static inline Evas_Map *
114_evas_map_new(int count)
115{
116 int i;
117 int alloc;
118 Evas_Map *m;
119
120 /* Adjust allocation such that: at least 4 points, and always an even
121 * number: this allows the software engine to work efficiently */
122 alloc = (count < 4) ? 4 : count;
123 if (alloc & 0x1) alloc ++;
124
125 m = calloc(1, sizeof(Evas_Map) + (alloc * sizeof(Evas_Map_Point)));
126 if (!m) return NULL;
127 m->count = count;
128 m->persp.foc = 0;
129 m->alpha = 1;
130 m->smooth = 1;
131 m->magic = MAGIC_MAP;
132 for (i = 0; i < count; i++)
133 {
134 m->points[i].r = 255;
135 m->points[i].g = 255;
136 m->points[i].b = 255;
137 m->points[i].a = 255;
138 }
139 return m;
140}
141
142static inline Eina_Bool
143_evas_map_copy(Evas_Map *dst, const Evas_Map *src)
144{
145 if (dst->count != src->count)
146 {
147 ERR("cannot copy map of different sizes: dst=%i, src=%i", dst->count, src->count);
148 return EINA_FALSE;
149 }
150 memcpy(dst->points, src->points, src->count * sizeof(Evas_Map_Point));
151 dst->smooth = src->smooth;
152 dst->alpha = src->alpha;
153 dst->persp = src->persp;
154 return EINA_TRUE;
155}
156
157static inline Evas_Map *
158_evas_map_dup(const Evas_Map *orig)
159{
160 Evas_Map *copy = _evas_map_new(orig->count);
161 if (!copy) return NULL;
162 memcpy(copy->points, orig->points, orig->count * sizeof(Evas_Map_Point));
163 copy->smooth = orig->smooth;
164 copy->alpha = orig->alpha;
165 copy->persp = orig->persp;
166 return copy;
167}
168
169static inline void
170_evas_map_free(Evas_Object *obj, Evas_Map *m)
171{
172 if (obj)
173 {
174 if (m->surface)
175 obj->layer->evas->engine.func->image_map_surface_free
176 (obj->layer->evas->engine.data.output, m->surface);
177 }
178 m->magic = 0;
179 free(m);
180}
181
182/****************************************************************************/
183/* util functions for manipulating maps, so you don't need to know the math */
184/****************************************************************************/
185static inline void
186_evas_map_util_points_populate(Evas_Map *m, const Evas_Coord x, const Evas_Coord y, const Evas_Coord w, const Evas_Coord h, const Evas_Coord z)
187{
188 Evas_Map_Point *p = m->points;
189 int i;
190
191 p[0].x = x;
192 p[0].y = y;
193 p[0].z = z;
194 p[0].u = 0.0;
195 p[0].v = 0.0;
196
197 p[1].x = x + w;
198 p[1].y = y;
199 p[1].z = z;
200 p[1].u = w;
201 p[1].v = 0.0;
202
203 p[2].x = x + w;
204 p[2].y = y + h;
205 p[2].z = z;
206 p[2].u = w;
207 p[2].v = h;
208
209 p[3].x = x;
210 p[3].y = y + h;
211 p[3].z = z;
212 p[3].u = 0.0;
213 p[3].v = h;
214
215 for (i = 0; i < 4; i++)
216 {
217 p[i].px = p[i].x;
218 p[i].py = p[i].y;
219 }
220}
221
222Eina_Bool
223evas_map_coords_get(const Evas_Map *m, Evas_Coord x, Evas_Coord y,
224 Evas_Coord *mx, Evas_Coord *my, int grab)
225{
226 MAGIC_CHECK(m, Evas_Map, MAGIC_MAP);
227 return EINA_FALSE;
228 MAGIC_CHECK_END();
229
230 int i, j, edges, edge[m->count][2], douv;
231 Evas_Coord xe[2];
232 double u[2] = { 0.0, 0.0 };
233 double v[2] = { 0.0, 0.0 };
234
235 if (m->count < 4) return 0;
236 // FIXME need to handle grab mode and extrapolte coords outside
237 // map
238 if (grab)
239 {
240 Evas_Coord ymin, ymax;
241
242 ymin = m->points[0].y;
243 ymax = m->points[0].y;
244 for (i = 1; i < m->count; i++)
245 {
246 if (m->points[i].y < ymin) ymin = m->points[i].y;
247 else if (m->points[i].y > ymax) ymax = m->points[i].y;
248 }
249 if (y <= ymin) y = ymin + 1;
250 if (y >= ymax) y = ymax - 1;
251 }
252 edges = 0;
253 for (i = 0; i < m->count; i++)
254 {
255 j = (i + 1) % m->count;
256 if ((m->points[i].y <= y) && (m->points[j].y > y))
257 {
258 edge[edges][0] = i;
259 edge[edges][1] = j;
260 edges++;
261 }
262 else if ((m->points[j].y <= y) && (m->points[i].y > y))
263 {
264 edge[edges][0] = j;
265 edge[edges][1] = i;
266 edges++;
267 }
268 }
269 douv = 0;
270 if ((mx) || (my)) douv = 1;
271 for (i = 0; i < (edges - 1); i+= 2)
272 {
273 Evas_Coord yp, yd;
274
275 j = i + 1;
276 yd = m->points[edge[i][1]].y - m->points[edge[i][0]].y;
277 if (yd > 0)
278 {
279 yp = y - m->points[edge[i][0]].y;
280 xe[0] = m->points[edge[i][1]].x - m->points[edge[i][0]].x;
281 xe[0] = m->points[edge[i][0]].x + ((xe[0] * yp) / yd);
282 if (douv)
283 {
284 u[0] = m->points[edge[i][1]].u - m->points[edge[i][0]].u;
285 u[0] = m->points[edge[i][0]].u + ((u[0] * yp) / yd);
286 v[0] = m->points[edge[i][1]].v - m->points[edge[i][0]].v;
287 v[0] = m->points[edge[i][0]].v + ((v[0] * yp) / yd);
288 }
289 }
290 else
291 {
292 xe[0] = m->points[edge[i][0]].x;
293 if (douv)
294 {
295 u[0] = m->points[edge[i][0]].u;
296 v[0] = m->points[edge[i][0]].v;
297 }
298 }
299 yd = m->points[edge[j][1]].y - m->points[edge[j][0]].y;
300 if (yd > 0)
301 {
302 yp = y - m->points[edge[j][0]].y;
303 xe[1] = m->points[edge[j][1]].x - m->points[edge[j][0]].x;
304 xe[1] = m->points[edge[j][0]].x + ((xe[1] * yp) / yd);
305 if (douv)
306 {
307 u[1] = m->points[edge[j][1]].u - m->points[edge[j][0]].u;
308 u[1] = m->points[edge[j][0]].u + ((u[1] * yp) / yd);
309 v[1] = m->points[edge[j][1]].v - m->points[edge[j][0]].v;
310 v[1] = m->points[edge[j][0]].v + ((v[1] * yp) / yd);
311 }
312 }
313 else
314 {
315 xe[1] = m->points[edge[j][0]].x;
316 if (douv)
317 {
318 u[1] = m->points[edge[j][0]].u;
319 v[1] = m->points[edge[j][0]].v;
320 }
321 }
322 if (xe[0] > xe[1])
323 {
324 int ti;
325
326 ti = xe[0]; xe[0] = xe[1]; xe[1] = ti;
327 if (douv)
328 {
329 double td;
330
331 td = u[0]; u[0] = u[1]; u[1] = td;
332 td = v[0]; v[0] = v[1]; v[1] = td;
333 }
334 }
335 if ((x >= xe[0]) && (x < xe[1]))
336 {
337 if (douv)
338 {
339 if (mx)
340 *mx = u[0] + (((x - xe[0]) * (u[1] - u[0])) /
341 (xe[1] - xe[0]));
342 if (my)
343 *my = v[0] + (((x - xe[0]) * (v[1] - v[0])) /
344 (xe[1] - xe[0]));
345 }
346 return EINA_TRUE;
347 }
348 if (grab)
349 {
350 if (douv)
351 {
352 if (mx)
353 *mx = u[0] + (((x - xe[0]) * (u[1] - u[0])) /
354 (xe[1] - xe[0]));
355 if (my)
356 *my = v[0] + (((x - xe[0]) * (v[1] - v[0])) /
357 (xe[1] - xe[0]));
358 }
359 return EINA_TRUE;
360 }
361 }
362 return EINA_FALSE;
363}
364
365Eina_Bool
366evas_map_inside_get(const Evas_Map *m, Evas_Coord x, Evas_Coord y)
367{
368 return evas_map_coords_get(m, x, y, NULL, NULL, 0);
369}
370
371EAPI void
372evas_object_map_enable_set(Evas_Object *obj, Eina_Bool enabled)
373{
374 MAGIC_CHECK(obj, Evas_Object, MAGIC_OBJ);
375 return;
376 MAGIC_CHECK_END();
377 Eina_Bool pchange = EINA_FALSE;
378
379 enabled = !!enabled;
380 if (obj->cur.usemap == enabled) return;
381 pchange = obj->changed;
382 obj->cur.usemap = enabled;
383 if (enabled)
384 {
385 if (!obj->cur.map)
386 obj->cur.map = _evas_map_new(4);
387 evas_object_mapped_clip_across_mark(obj);
388// obj->cur.map->normal_geometry = obj->cur.geometry;
389 }
390 else
391 {
392 if (obj->cur.map)
393 {
394 _evas_map_calc_geom_change(obj);
395 evas_object_mapped_clip_across_mark(obj);
396 //FIXME: Since the last frame is not updated when map is
397 //disabled, afterimage problem is happened in s/w rendering.
398 //Need to find out the fundamental reason then fix it.
399 evas_damage_rectangle_add(obj->layer->evas,
400 0,
401 0,
402 obj->layer->evas->output.w,
403 obj->layer->evas->output.h);
404 }
405 }
406 _evas_map_calc_map_geometry(obj);
407 /* This is a bit heavy handed, but it fixes the case of same geometry, but
408 * changed colour or UV settings. */
409 evas_object_change(obj);
410 if (!obj->changed_pchange) obj->changed_pchange = pchange;
411 obj->changed_map = EINA_TRUE;
412}
413
414EAPI Eina_Bool
415evas_object_map_enable_get(const Evas_Object *obj)
416{
417 MAGIC_CHECK(obj, Evas_Object, MAGIC_OBJ);
418 return EINA_FALSE;
419 MAGIC_CHECK_END();
420 return obj->cur.usemap;
421}
422
423
424EAPI void
425evas_object_map_source_set(Evas_Object *obj, Evas_Object *src)
426{
427 MAGIC_CHECK(obj, Evas_Object, MAGIC_OBJ);
428 return;
429 MAGIC_CHECK_END();
430 (void)src; /* method still needs to be implemented. */
431}
432
433EAPI Evas_Object *
434evas_object_map_source_get(const Evas_Object *obj)
435{
436 MAGIC_CHECK(obj, Evas_Object, MAGIC_OBJ);
437 return NULL;
438 MAGIC_CHECK_END();
439 return NULL;
440}
441
442EAPI void
443evas_object_map_set(Evas_Object *obj, const Evas_Map *map)
444{
445 MAGIC_CHECK(obj, Evas_Object, MAGIC_OBJ);
446 return;
447 MAGIC_CHECK_END();
448
449 if (!map)
450 {
451 if (obj->cur.map)
452 {
453 if (obj->cur.map->surface)
454 {
455 obj->layer->evas->engine.func->image_map_surface_free
456 (obj->layer->evas->engine.data.output,
457 obj->cur.map->surface);
458 obj->cur.map->surface = NULL;
459 }
460 obj->prev.geometry = obj->cur.map->normal_geometry;
461 if (!obj->prev.map)
462 {
463 _evas_map_free(obj, obj->cur.map);
464 obj->cur.map = NULL;
465 evas_object_mapped_clip_across_mark(obj);
466 return;
467 }
468 _evas_map_free(obj, obj->cur.map);
469 obj->cur.map = NULL;
470 if (!obj->cur.usemap) _evas_map_calc_geom_change(obj);
471 else _evas_map_calc_map_geometry(obj);
472 if (obj->cur.usemap)
473 {
474 evas_object_mapped_clip_across_mark(obj);
475 //FIXME: Since the last frame is not updated when map is
476 //disabled, afterimage problem is happened in s/w
477 //rendering. Need to find out the fundamental reason
478 //then fix it.
479 evas_damage_rectangle_add(obj->layer->evas,
480 0,
481 0,
482 obj->layer->evas->output.w,
483 obj->layer->evas->output.h);
484 }
485 }
486 return;
487 }
488
489 if ((obj->cur.map) && (obj->cur.map->count == map->count))
490 {
491 Evas_Map *omap = obj->cur.map;
492 obj->cur.map = _evas_map_new(map->count);
493 memcpy(obj->cur.map, omap, sizeof(Evas_Map) + (map->count * sizeof(Evas_Map_Point)));
494 _evas_map_copy(obj->cur.map, map);
495 if (obj->prev.map == omap) obj->prev.map = NULL;
496 free(omap);
497 }
498 else
499 {
500 if (obj->cur.map) evas_map_free(obj->cur.map);
501 obj->cur.map = _evas_map_dup(map);
502 if (obj->cur.usemap)
503 evas_object_mapped_clip_across_mark(obj);
504 }
505 _evas_map_calc_map_geometry(obj);
506}
507
508EAPI const Evas_Map *
509evas_object_map_get(const Evas_Object *obj)
510{
511 MAGIC_CHECK(obj, Evas_Object, MAGIC_OBJ);
512 return NULL;
513 MAGIC_CHECK_END();
514
515 return obj->cur.map;
516}
517
518EAPI Evas_Map *
519evas_map_new(int count)
520{
521 if (count != 4)
522 {
523 ERR("map point count (%i) != 4 is unsupported!", count);
524 return NULL;
525 }
526
527 return _evas_map_new(count);
528}
529
530EAPI void
531evas_map_smooth_set(Evas_Map *m, Eina_Bool enabled)
532{
533 MAGIC_CHECK(m, Evas_Map, MAGIC_MAP);
534 return;
535 MAGIC_CHECK_END();
536
537 m->smooth = enabled;
538}
539
540EAPI Eina_Bool
541evas_map_smooth_get(const Evas_Map *m)
542{
543 MAGIC_CHECK(m, Evas_Map, MAGIC_MAP);
544 return EINA_FALSE;
545 MAGIC_CHECK_END();
546
547 return m->smooth;
548}
549
550EAPI void
551evas_map_alpha_set(Evas_Map *m, Eina_Bool enabled)
552{
553 MAGIC_CHECK(m, Evas_Map, MAGIC_MAP);
554 return;
555 MAGIC_CHECK_END();
556
557 m->alpha = enabled;
558}
559
560EAPI Eina_Bool
561evas_map_alpha_get(const Evas_Map *m)
562{
563 MAGIC_CHECK(m, Evas_Map, MAGIC_MAP);
564 return EINA_FALSE;
565 MAGIC_CHECK_END();
566
567 return m->alpha;
568}
569
570EAPI Evas_Map *
571evas_map_dup(const Evas_Map *m)
572{
573 MAGIC_CHECK(m, Evas_Map, MAGIC_MAP);
574 return NULL;
575 MAGIC_CHECK_END();
576
577 return _evas_map_dup(m);
578}
579
580EAPI void
581evas_map_free(Evas_Map *m)
582{
583 MAGIC_CHECK(m, Evas_Map, MAGIC_MAP);
584 return;
585 MAGIC_CHECK_END();
586
587 _evas_map_free(NULL, m);
588}
589
590EAPI int
591evas_map_count_get(const Evas_Map *m)
592{
593 MAGIC_CHECK(m, Evas_Map, MAGIC_MAP);
594 return -1;
595 MAGIC_CHECK_END();
596
597 return m->count;
598}
599
600EAPI void
601evas_map_point_coord_set(Evas_Map *m, int idx, Evas_Coord x, Evas_Coord y, Evas_Coord z)
602{
603 MAGIC_CHECK(m, Evas_Map, MAGIC_MAP);
604 return;
605 MAGIC_CHECK_END();
606
607 Evas_Map_Point *p;
608
609 if (idx >= m->count) return;
610 p = m->points + idx;
611 p->x = p->px = x;
612 p->y = p->py = y;
613 p->z = z;
614}
615
616EAPI void
617evas_map_point_coord_get(const Evas_Map *m, int idx, Evas_Coord *x, Evas_Coord *y, Evas_Coord *z)
618{
619 MAGIC_CHECK(m, Evas_Map, MAGIC_MAP);
620 goto error;
621 MAGIC_CHECK_END();
622
623 const Evas_Map_Point *p;
624
625 if (idx >= m->count) goto error;
626 p = m->points + idx;
627 if (x) *x = p->x;
628 if (y) *y = p->y;
629 if (z) *z = p->z;
630 return;
631
632 error:
633 if (x) *x = 0;
634 if (y) *y = 0;
635 if (z) *z = 0;
636}
637
638EAPI void
639evas_map_point_image_uv_set(Evas_Map *m, int idx, double u, double v)
640{
641 MAGIC_CHECK(m, Evas_Map, MAGIC_MAP);
642 return;
643 MAGIC_CHECK_END();
644
645 Evas_Map_Point *p;
646
647 if (idx >= m->count) return;
648 p = m->points + idx;
649 p->u = u;
650 p->v = v;
651}
652
653EAPI void
654evas_map_point_image_uv_get(const Evas_Map *m, int idx, double *u, double *v)
655{
656 MAGIC_CHECK(m, Evas_Map, MAGIC_MAP);
657 goto error;
658 MAGIC_CHECK_END();
659
660 const Evas_Map_Point *p;
661
662 if (idx >= m->count) goto error;
663 p = m->points + idx;
664 if (u) *u = p->u;
665 if (v) *v = p->v;
666 return;
667
668 error:
669 if (u) *u = 0.0;
670 if (v) *v = 0.0;
671}
672
673EAPI void
674evas_map_point_color_set(Evas_Map *m, int idx, int r, int g, int b, int a)
675{
676 MAGIC_CHECK(m, Evas_Map, MAGIC_MAP);
677 return;
678 MAGIC_CHECK_END();
679
680 Evas_Map_Point *p;
681
682 if (idx >= m->count) return;
683 p = m->points + idx;
684 p->r = r;
685 p->g = g;
686 p->b = b;
687 p->a = a;
688}
689
690EAPI void
691evas_map_point_color_get(const Evas_Map *m, int idx, int *r, int *g, int *b, int *a)
692{
693 MAGIC_CHECK(m, Evas_Map, MAGIC_MAP);
694 return;
695 MAGIC_CHECK_END();
696
697 const Evas_Map_Point *p;
698
699 if (idx >= m->count) return;
700 p = m->points + idx;
701 if (r) *r = p->r;
702 if (g) *g = p->g;
703 if (b) *b = p->b;
704 if (a) *a = p->a;
705}
706
707EAPI void
708evas_map_util_points_populate_from_object_full(Evas_Map *m, const Evas_Object *obj, Evas_Coord z)
709{
710 MAGIC_CHECK(obj, Evas_Object, MAGIC_OBJ);
711 return;
712 MAGIC_CHECK_END();
713
714 if (m->count != 4)
715 {
716 ERR("map has count=%d where 4 was expected.", m->count);
717 return;
718 }
719 _evas_map_util_points_populate(m, obj->cur.geometry.x, obj->cur.geometry.y,
720 obj->cur.geometry.w, obj->cur.geometry.h, z);
721}
722
723EAPI void
724evas_map_util_points_populate_from_object(Evas_Map *m, const Evas_Object *obj)
725{
726 MAGIC_CHECK(m, Evas_Map, MAGIC_MAP);
727 return;
728 MAGIC_CHECK_END();
729
730 MAGIC_CHECK(obj, Evas_Object, MAGIC_OBJ);
731 return;
732 MAGIC_CHECK_END();
733
734 if (m->count != 4)
735 {
736 ERR("map has count=%d where 4 was expected.", m->count);
737 return;
738 }
739 _evas_map_util_points_populate(m, obj->cur.geometry.x, obj->cur.geometry.y,
740 obj->cur.geometry.w, obj->cur.geometry.h, 0);
741}
742
743EAPI void
744evas_map_util_points_populate_from_geometry(Evas_Map *m, Evas_Coord x, Evas_Coord y, Evas_Coord w, Evas_Coord h, Evas_Coord z)
745{
746 MAGIC_CHECK(m, Evas_Map, MAGIC_MAP);
747 return;
748 MAGIC_CHECK_END();
749
750 if (m->count != 4)
751 {
752 ERR("map has count=%d where 4 was expected.", m->count);
753 return;
754 }
755 _evas_map_util_points_populate(m, x, y, w, h, z);
756}
757
758EAPI void
759evas_map_util_points_color_set(Evas_Map *m, int r, int g, int b, int a)
760{
761 MAGIC_CHECK(m, Evas_Map, MAGIC_MAP);
762 return;
763 MAGIC_CHECK_END();
764
765 Evas_Map_Point *p, *p_end;
766
767 p = m->points;
768 p_end = p + m->count;
769 for (; p < p_end; p++)
770 {
771 p->r = r;
772 p->g = g;
773 p->b = b;
774 p->a = a;
775 }
776}
777
778EAPI void
779evas_map_util_rotate(Evas_Map *m, double degrees, Evas_Coord cx, Evas_Coord cy)
780{
781 MAGIC_CHECK(m, Evas_Map, MAGIC_MAP);
782 return;
783 MAGIC_CHECK_END();
784
785 double r = (degrees * M_PI) / 180.0;
786 Evas_Map_Point *p, *p_end;
787
788 p = m->points;
789 p_end = p + m->count;
790
791 for (; p < p_end; p++)
792 {
793 double x, y, xx, yy;
794
795 x = p->x - cx;
796 y = p->y - cy;
797
798 xx = x * cos(r);
799 yy = x * sin(r);
800 x = xx - (y * sin(r));
801 y = yy + (y * cos(r));
802
803 p->px = p->x = x + cx;
804 p->py = p->y = y + cy;
805 }
806}
807
808EAPI void
809evas_map_util_zoom(Evas_Map *m, double zoomx, double zoomy, Evas_Coord cx, Evas_Coord cy)
810{
811 MAGIC_CHECK(m, Evas_Map, MAGIC_MAP);
812 return;
813 MAGIC_CHECK_END();
814
815 Evas_Map_Point *p, *p_end;
816
817 p = m->points;
818 p_end = p + m->count;
819
820 for (; p < p_end; p++)
821 {
822 double x, y;
823
824 x = p->x - cx;
825 y = p->y - cy;
826
827 x = (((double)x) * zoomx);
828 y = (((double)y) * zoomy);
829
830 p->px = p->x = x + cx;
831 p->py = p->y = y + cy;
832 }
833}
834
835EAPI void
836evas_map_util_3d_rotate(Evas_Map *m, double dx, double dy, double dz,
837 Evas_Coord cx, Evas_Coord cy, Evas_Coord cz)
838{
839 MAGIC_CHECK(m, Evas_Map, MAGIC_MAP);
840 return;
841 MAGIC_CHECK_END();
842
843 double rz = (dz * M_PI) / 180.0;
844 double rx = (dx * M_PI) / 180.0;
845 double ry = (dy * M_PI) / 180.0;
846 Evas_Map_Point *p, *p_end;
847
848 p = m->points;
849 p_end = p + m->count;
850
851 for (; p < p_end; p++)
852 {
853 double x, y, z, xx, yy, zz;
854
855 x = p->x - cx;
856 y = p->y - cy;
857 z = p->z - cz;
858
859 if (rz != 0.0)
860 {
861 xx = x * cos(rz);
862 yy = x * sin(rz);
863 x = xx - (y * sin(rz));
864 y = yy + (y * cos(rz));
865 }
866
867 if (ry != 0.0)
868 {
869 xx = x * cos(ry);
870 zz = x * sin(ry);
871 x = xx - (z * sin(ry));
872 z = zz + (z * cos(ry));
873 }
874
875 if (rx != 0.0)
876 {
877 zz = z * cos(rx);
878 yy = z * sin(rx);
879 z = zz - (y * sin(rx));
880 y = yy + (y * cos(rx));
881 }
882
883 p->px = p->x = x + cx;
884 p->py = p->y = y + cy;
885 p->z = z + cz;
886 }
887}
888
889EAPI void
890evas_map_util_3d_lighting(Evas_Map *m,
891 Evas_Coord lx, Evas_Coord ly, Evas_Coord lz,
892 int lr, int lg, int lb, int ar, int ag, int ab)
893{
894 MAGIC_CHECK(m, Evas_Map, MAGIC_MAP);
895 return;
896 MAGIC_CHECK_END();
897
898 int i;
899
900 for (i = 0; i < m->count; i++)
901 {
902 double x, y, z;
903 double nx, ny, nz, x1, yy1, z1, x2, yy2, z2, ln, br;
904 int h, j, mr, mg, mb;
905
906 x = m->points[i].x;
907 y = m->points[i].y;
908 z = m->points[i].z;
909 // calc normal
910 h = (i - 1 + 4) % 4 + (i & ~0x3); // prev point
911 j = (i + 1) % 4 + (i & ~0x3); // next point
912
913 x1 = m->points[h].x - x;
914 yy1 = m->points[h].y - y;
915 z1 = m->points[h].z - z;
916
917 x2 = m->points[j].x - x;
918 yy2 = m->points[j].y - y;
919 z2 = m->points[j].z - z;
920 nx = (yy1 * z2) - (z1 * yy2);
921 ny = (z1 * x2) - (x1 * z2);
922 nz = (x1 * yy2) - (yy1 * x2);
923
924 ln = (nx * nx) + (ny * ny) + (nz * nz);
925 ln = sqrt(ln);
926
927 if (ln != 0.0)
928 {
929 nx /= ln;
930 ny /= ln;
931 nz /= ln;
932 }
933
934 // calc point -> light vector
935 x = lx - x;
936 y = ly - y;
937 z = lz - z;
938
939 ln = (x * x) + (y * y) + (z * z);
940 ln = sqrt(ln);
941
942 if (ln != 0.0)
943 {
944 x /= ln;
945 y /= ln;
946 z /= ln;
947 }
948
949 // brightness - tan (0.0 -> 1.0 brightness really)
950 br = (nx * x) + (ny * y) + (nz * z);
951 if (br < 0.0) br = 0.0;
952
953 mr = ar + ((lr - ar) * br);
954 mg = ag + ((lg - ag) * br);
955 mb = ab + ((lb - ab) * br);
956 if (m->points[i].a != 255)
957 {
958 mr = (mr * m->points[i].a) / 255;
959 mg = (mg * m->points[i].a) / 255;
960 mb = (mb * m->points[i].a) / 255;
961 }
962 m->points[i].r = (m->points[i].r * mr) / 255;
963 m->points[i].g = (m->points[i].g * mg) / 255;
964 m->points[i].b = (m->points[i].b * mb) / 255;
965 }
966}
967
968EAPI void
969evas_map_util_3d_perspective(Evas_Map *m,
970 Evas_Coord px, Evas_Coord py,
971 Evas_Coord z0, Evas_Coord foc)
972{
973 MAGIC_CHECK(m, Evas_Map, MAGIC_MAP);
974 return;
975 MAGIC_CHECK_END();
976
977 Evas_Map_Point *p, *p_end;
978
979 p = m->points;
980 p_end = p + m->count;
981
982 m->persp.px = px;
983 m->persp.py = py;
984 m->persp.z0 = z0;
985 m->persp.foc = foc;
986
987 if (foc <= 0) return;
988
989 for (; p < p_end; p++)
990 {
991 double x, y, zz;
992
993 x = p->x - px;
994 y = p->y - py;
995
996 zz = ((p->z - z0) + foc);
997
998 if (zz > 0)
999 {
1000 x = (x * foc) / zz;
1001 y = (y * foc) / zz;
1002 }
1003
1004 p->x = px + x;
1005 p->y = py + y;
1006 }
1007}
1008
1009EAPI Eina_Bool
1010evas_map_util_clockwise_get(Evas_Map *m)
1011{
1012 MAGIC_CHECK(m, Evas_Map, MAGIC_MAP);
1013 return EINA_FALSE;
1014 MAGIC_CHECK_END();
1015
1016 int i, j, k, count;
1017 long long c;
1018
1019 if (m->count < 3) return EINA_FALSE;
1020
1021 count = 0;
1022 for (i = 0; i < m->count; i++)
1023 {
1024 j = (i + 1) % m->count;
1025 k = (i + 2) % m->count;
1026 c =
1027 ((m->points[j].x - m->points[i].x) *
1028 (m->points[k].y - m->points[j].y))
1029 -
1030 ((m->points[j].y - m->points[i].y) *
1031 (m->points[k].x - m->points[j].x));
1032 if (c < 0) count--;
1033 else if (c > 0) count++;
1034 }
1035 if (count > 0) return EINA_TRUE;
1036 return EINA_FALSE;
1037}