2 * vim:ts=8:sw=3:sts=8:noexpandtab:cino=>5n-3f0^-2{2
7 #include "evas_common.h"
8 #include "evas_blend_private.h"
10 typedef struct _RGBA_Span RGBA_Span;
11 typedef struct _RGBA_Edge RGBA_Edge;
12 typedef struct _RGBA_Vertex RGBA_Vertex;
16 Evas_Object_List _list_data;
32 #define POLY_EDGE_DEL(_i) \
36 for (_j = 0; (_j < num_active_edges) && (edges[_j].i != _i); _j++); \
37 if (_j < num_active_edges) \
40 memmove(&(edges[_j]), &(edges[_j + 1]), \
41 (num_active_edges - _j) * sizeof(RGBA_Edge)); \
45 #define POLY_EDGE_ADD(_i, _y) \
49 RGBA_Vertex *_p, *_q; \
50 if (_i < (n - 1)) _j = _i + 1; \
52 if (point[_i].y < point[_j].y) \
62 edges[num_active_edges].dx = _dx = (_q->x - _p->x) / (_q->y - _p->y); \
63 edges[num_active_edges].x = (_dx * ((float)_y + 0.5 - _p->y)) + _p->x; \
64 edges[num_active_edges].i = _i; \
69 evas_common_polygon_init(void)
73 EAPI RGBA_Polygon_Point *
74 evas_common_polygon_point_add(RGBA_Polygon_Point *points, int x, int y)
76 RGBA_Polygon_Point *pt;
78 pt = malloc(sizeof(RGBA_Polygon_Point));
79 if (!pt) return points;
82 points = evas_object_list_append(points, pt);
86 EAPI RGBA_Polygon_Point *
87 evas_common_polygon_points_clear(RGBA_Polygon_Point *points)
93 RGBA_Polygon_Point *old_p;
96 points = evas_object_list_remove(points, points);
104 polygon_point_sorter(const void *a, const void *b)
108 p = (RGBA_Vertex *)a;
109 q = (RGBA_Vertex *)b;
110 if (p->y <= q->y) return -1;
115 polygon_edge_sorter(const void *a, const void *b)
121 if (p->x <= q->x) return -1;
126 evas_common_polygon_draw(RGBA_Image *dst, RGBA_Draw_Context *dc, RGBA_Polygon_Point *points)
129 RGBA_Polygon_Point *pt;
132 Evas_Object_List *spans, *l;
133 int num_active_edges;
137 int ext_x, ext_y, ext_w, ext_h;
142 ext_w = dst->cache_entry.w;
143 ext_h = dst->cache_entry.h;
146 if (dc->clip.x > ext_x)
148 ext_w += ext_x - dc->clip.x;
151 if ((ext_x + ext_w) > (dc->clip.x + dc->clip.w))
153 ext_w = (dc->clip.x + dc->clip.w) - ext_x;
155 if (dc->clip.y > ext_y)
157 ext_h += ext_y - dc->clip.y;
160 if ((ext_y + ext_h) > (dc->clip.y + dc->clip.h))
162 ext_h = (dc->clip.y + dc->clip.h) - ext_y;
165 if ((ext_w <= 0) || (ext_h <= 0)) return;
167 evas_common_cpu_end_opt();
169 n = 0; for (l = (Evas_Object_List *)points; l; l = l->next) n++;
171 edges = malloc(sizeof(RGBA_Edge) * n);
173 point = malloc(sizeof(RGBA_Vertex) * n);
179 sorted_index = malloc(sizeof(int) * n);
188 for (l = (Evas_Object_List *)points; l; l = l->next)
190 pt = (RGBA_Polygon_Point *)l;
196 qsort(point, n, sizeof(RGBA_Vertex), polygon_point_sorter);
197 for (k = 0; k < n; k++) sorted_index[k] = point[k].i;
199 for (l = (Evas_Object_List *)points; l; l = l->next)
201 pt = (RGBA_Polygon_Point *)l;
208 y0 = MAX(ext_y, ceil(point[sorted_index[0]].y - 0.5));
209 y1 = MIN(ext_y + ext_h - 1, floor(point[sorted_index[n - 1]].y - 0.5));
212 num_active_edges = 0;
215 for (y = y0; y <= y1; y++)
217 for (; (k < n) && (point[sorted_index[k]].y <= ((double)y + 0.5)); k++)
221 if (i > 0) j = i - 1;
223 if (point[j].y <= ((double)y - 0.5))
227 else if (point[j].y > ((double)y + 0.5))
231 if (i < (n - 1)) j = i + 1;
233 if (point[j].y <= ((double)y - 0.5))
237 else if (point[j].y > ((double)y + 0.5))
243 qsort(edges, num_active_edges, sizeof(RGBA_Edge), polygon_edge_sorter);
245 for (j = 0; j < num_active_edges; j += 2)
249 x0 = ceil(edges[j].x - 0.5);
250 if (j < (num_active_edges - 1))
251 x1 = floor(edges[j + 1].x - 0.5);
254 if ((x1 >= ext_x) && (x0 < (ext_x + ext_w)) && (x0 <= x1))
258 if (x0 < ext_x) x0 = ext_x;
259 if (x1 >= (ext_x + ext_w)) x1 = ext_x + ext_w - 1;
260 span = malloc(sizeof(RGBA_Span));
261 spans = evas_object_list_append(spans, span);
264 span->w = (x1 - x0) + 1;
266 edges[j].x += edges[j].dx;
267 edges[j + 1].x += edges[j + 1].dx;
275 func = evas_common_gfx_func_composite_color_span_get(dc->col.col, dst, 1, dc->render_op);
278 for (l = spans; l; l = l->next)
283 span = (RGBA_Span *)l;
285 if (((span->y) % dc->sli.h) == dc->sli.y)
288 ptr = dst->image.data + (span->y * (dst->cache_entry.w)) + span->x;
289 func(NULL, NULL, dc->col.col, ptr, span->w);
296 span = (RGBA_Span *)spans;
297 spans = evas_object_list_remove(spans, spans);