1 #include <evas_common_soft16.h>
2 #include "evas_soft16_scanline_fill.c"
5 typedef struct _RGBA_Edge RGBA_Edge;
6 typedef struct _RGBA_Vertex RGBA_Vertex;
20 #define POLY_EDGE_DEL(_i) \
24 for (_j = 0; (_j < num_active_edges) && (edges[_j].i != _i); _j++); \
25 if (_j < num_active_edges) \
28 memmove(&(edges[_j]), &(edges[_j + 1]), \
29 (num_active_edges - _j) * sizeof(RGBA_Edge)); \
33 #define POLY_EDGE_ADD(_i, _y) \
37 RGBA_Vertex *_p, *_q; \
38 if (_i < (n - 1)) _j = _i + 1; \
40 if (point[_i].y < point[_j].y) \
50 edges[num_active_edges].dx = _dx = (_q->x - _p->x) / (_q->y - _p->y); \
51 edges[num_active_edges].x = (_dx * ((float)_y + 0.5 - _p->y)) + _p->x; \
52 edges[num_active_edges].i = _i; \
57 polygon_point_sorter(const void *a, const void *b)
63 if (p->y <= q->y) return -1;
68 polygon_edge_sorter(const void *a, const void *b)
74 if (p->x <= q->x) return -1;
79 soft16_polygon_draw(Soft16_Image *dst, RGBA_Draw_Context *dc, RGBA_Polygon_Point *points)
81 RGBA_Polygon_Point *pt;
89 int ext_x, ext_y, ext_w, ext_h;
95 alpha = A_VAL(&dc->col.col) >> 3;
100 rgb565 = RGB_565_FROM_COMPONENTS(R_VAL(&dc->col.col),
102 B_VAL(&dc->col.col));
103 rgb565_unpack = RGB_565_UNPACK(rgb565);
107 ext_w = dst->cache_entry.w;
108 ext_h = dst->cache_entry.h;
110 RECTS_CLIP_TO_RECT(ext_x, ext_y, ext_w, ext_h,
111 dc->clip.x, dc->clip.y, dc->clip.w, dc->clip.h);
113 if ((ext_w <= 0) || (ext_h <= 0))
117 for (l = (Evas_Object_List *)points; l; l = l->next)
123 edges = malloc(sizeof(RGBA_Edge) * n);
127 point = malloc(sizeof(RGBA_Vertex) * n);
134 sorted_index = malloc(sizeof(int) * n);
142 for (k = 0, l = (Evas_Object_List *)points; l; k++, l = l->next)
144 pt = (RGBA_Polygon_Point *)l;
149 qsort(point, n, sizeof(RGBA_Vertex), polygon_point_sorter);
151 for (k = 0; k < n; k++)
152 sorted_index[k] = point[k].i;
154 for (k = 0, l = (Evas_Object_List *)points; l; k++, l = l->next)
156 pt = (RGBA_Polygon_Point *)l;
162 y0 = MAX(ext_y, ceil(point[sorted_index[0]].y - 0.5));
163 y1 = MIN(ext_y + ext_h - 1, floor(point[sorted_index[n - 1]].y - 0.5));
166 num_active_edges = 0;
168 for (y = y0; y <= y1; y++)
170 for (; (k < n) && (point[sorted_index[k]].y <= ((float)y + 0.5)); k++)
174 if (i > 0) j = i - 1;
176 if (point[j].y <= ((float)y - 0.5))
180 else if (point[j].y > ((float)y + 0.5))
184 if (i < (n - 1)) j = i + 1;
186 if (point[j].y <= ((float)y - 0.5))
190 else if (point[j].y > ((float)y + 0.5))
196 qsort(edges, num_active_edges, sizeof(RGBA_Edge), polygon_edge_sorter);
198 for (j = 0; j < num_active_edges; j += 2)
202 x0 = ceil(edges[j].x - 0.5);
203 if (j < (num_active_edges - 1))
204 x1 = floor(edges[j + 1].x - 0.5);
207 if ((x1 >= ext_x) && (x0 < (ext_x + ext_w)) && (x0 <= x1))
212 if (x0 < ext_x) x0 = ext_x;
213 if (x1 >= (ext_x + ext_w)) x1 = ext_x + ext_w - 1;
216 dst_itr = dst->pixels + (y * dst->stride) + x0;
219 _soft16_scanline_fill_solid_solid(dst_itr, w, rgb565);
221 _soft16_scanline_fill_transp_solid(dst_itr, w, rgb565_unpack, alpha);
223 edges[j].x += edges[j].dx;
224 edges[j + 1].x += edges[j + 1].dx;