diff options
author | David Walter Seikel | 2012-01-04 18:41:13 +1000 |
---|---|---|
committer | David Walter Seikel | 2012-01-04 18:41:13 +1000 |
commit | dd7595a3475407a7fa96a97393bae8c5220e8762 (patch) | |
tree | e341e911d7eb911a51684a7412ef7f7c7605d28e /libraries/evas/src/lib/engines/common_16/evas_soft16_polygon.c | |
parent | Add the skeleton. (diff) | |
download | SledjHamr-dd7595a3475407a7fa96a97393bae8c5220e8762.zip SledjHamr-dd7595a3475407a7fa96a97393bae8c5220e8762.tar.gz SledjHamr-dd7595a3475407a7fa96a97393bae8c5220e8762.tar.bz2 SledjHamr-dd7595a3475407a7fa96a97393bae8c5220e8762.tar.xz |
Add the base Enlightenment Foundation Libraries - eina, eet, evas, ecore, embryo, and edje.
Note that embryo wont be used, but I'm not sure yet if you can build edje without it.
Diffstat (limited to 'libraries/evas/src/lib/engines/common_16/evas_soft16_polygon.c')
-rw-r--r-- | libraries/evas/src/lib/engines/common_16/evas_soft16_polygon.c | 231 |
1 files changed, 231 insertions, 0 deletions
diff --git a/libraries/evas/src/lib/engines/common_16/evas_soft16_polygon.c b/libraries/evas/src/lib/engines/common_16/evas_soft16_polygon.c new file mode 100644 index 0000000..ca18bef --- /dev/null +++ b/libraries/evas/src/lib/engines/common_16/evas_soft16_polygon.c | |||
@@ -0,0 +1,231 @@ | |||
1 | #include <math.h> | ||
2 | #include <evas_common_soft16.h> | ||
3 | #include "evas_soft16_scanline_fill.c" | ||
4 | |||
5 | typedef struct _RGBA_Edge RGBA_Edge; | ||
6 | typedef struct _RGBA_Vertex RGBA_Vertex; | ||
7 | |||
8 | struct _RGBA_Edge | ||
9 | { | ||
10 | float x, dx; | ||
11 | int i; | ||
12 | }; | ||
13 | |||
14 | struct _RGBA_Vertex | ||
15 | { | ||
16 | float x, y; | ||
17 | int i; | ||
18 | }; | ||
19 | |||
20 | #define POLY_EDGE_DEL(_i) \ | ||
21 | { \ | ||
22 | int _j; \ | ||
23 | \ | ||
24 | for (_j = 0; (_j < num_active_edges) && (edges[_j].i != _i); _j++); \ | ||
25 | if (_j < num_active_edges) \ | ||
26 | { \ | ||
27 | num_active_edges--; \ | ||
28 | memmove(&(edges[_j]), &(edges[_j + 1]), \ | ||
29 | (num_active_edges - _j) * sizeof(RGBA_Edge)); \ | ||
30 | } \ | ||
31 | } | ||
32 | |||
33 | #define POLY_EDGE_ADD(_i, _y) \ | ||
34 | { \ | ||
35 | int _j; \ | ||
36 | float _dx; \ | ||
37 | RGBA_Vertex *_p, *_q; \ | ||
38 | if (_i < (n - 1)) _j = _i + 1; \ | ||
39 | else _j = 0; \ | ||
40 | if (point[_i].y < point[_j].y) \ | ||
41 | { \ | ||
42 | _p = &(point[_i]); \ | ||
43 | _q = &(point[_j]); \ | ||
44 | } \ | ||
45 | else \ | ||
46 | { \ | ||
47 | _p = &(point[_j]); \ | ||
48 | _q = &(point[_i]); \ | ||
49 | } \ | ||
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; \ | ||
53 | num_active_edges++; \ | ||
54 | } | ||
55 | |||
56 | static int | ||
57 | polygon_point_sorter(const void *a, const void *b) | ||
58 | { | ||
59 | RGBA_Vertex *p, *q; | ||
60 | |||
61 | p = (RGBA_Vertex *)a; | ||
62 | q = (RGBA_Vertex *)b; | ||
63 | if (p->y <= q->y) return -1; | ||
64 | return 1; | ||
65 | } | ||
66 | |||
67 | static int | ||
68 | polygon_edge_sorter(const void *a, const void *b) | ||
69 | { | ||
70 | RGBA_Edge *p, *q; | ||
71 | |||
72 | p = (RGBA_Edge *)a; | ||
73 | q = (RGBA_Edge *)b; | ||
74 | if (p->x <= q->x) return -1; | ||
75 | return 1; | ||
76 | } | ||
77 | |||
78 | void | ||
79 | evas_common_soft16_polygon_draw(Soft16_Image *dst, RGBA_Draw_Context *dc, RGBA_Polygon_Point *points, int x, int y) | ||
80 | { | ||
81 | RGBA_Polygon_Point *pt; | ||
82 | RGBA_Vertex *point; | ||
83 | RGBA_Edge *edges; | ||
84 | int num_active_edges; | ||
85 | int n; | ||
86 | int i, j, k; | ||
87 | int y0, y1, yi; | ||
88 | int ext_x, ext_y, ext_w, ext_h; | ||
89 | int *sorted_index; | ||
90 | DATA8 alpha; | ||
91 | DATA16 rgb565; | ||
92 | DATA32 rgb565_unpack; | ||
93 | |||
94 | alpha = A_VAL(&dc->col.col) >> 3; | ||
95 | if (alpha == 0) | ||
96 | return; | ||
97 | alpha++; | ||
98 | |||
99 | rgb565 = RGB_565_FROM_COMPONENTS(R_VAL(&dc->col.col), | ||
100 | G_VAL(&dc->col.col), | ||
101 | B_VAL(&dc->col.col)); | ||
102 | rgb565_unpack = RGB_565_UNPACK(rgb565); | ||
103 | |||
104 | ext_x = 0; | ||
105 | ext_y = 0; | ||
106 | ext_w = dst->cache_entry.w; | ||
107 | ext_h = dst->cache_entry.h; | ||
108 | if (dc->clip.use) | ||
109 | RECTS_CLIP_TO_RECT(ext_x, ext_y, ext_w, ext_h, | ||
110 | dc->clip.x, dc->clip.y, dc->clip.w, dc->clip.h); | ||
111 | |||
112 | if ((ext_w <= 0) || (ext_h <= 0)) | ||
113 | return; | ||
114 | |||
115 | n = 0; | ||
116 | EINA_INLIST_FOREACH(points, pt) n++; | ||
117 | |||
118 | if (n < 3) | ||
119 | return; | ||
120 | |||
121 | edges = malloc(sizeof(RGBA_Edge) * n); | ||
122 | if (!edges) | ||
123 | return; | ||
124 | |||
125 | point = malloc(sizeof(RGBA_Vertex) * n); | ||
126 | if (!point) | ||
127 | { | ||
128 | free(edges); | ||
129 | return; | ||
130 | } | ||
131 | |||
132 | sorted_index = malloc(sizeof(int) * n); | ||
133 | if (!sorted_index) | ||
134 | { | ||
135 | free(edges); | ||
136 | free(point); | ||
137 | return; | ||
138 | } | ||
139 | |||
140 | k = 0; | ||
141 | EINA_INLIST_FOREACH(points, pt) | ||
142 | { | ||
143 | point[k].x = pt->x + x; | ||
144 | point[k].y = pt->y + y; | ||
145 | point[k].i = k; | ||
146 | k++; | ||
147 | } | ||
148 | qsort(point, n, sizeof(RGBA_Vertex), polygon_point_sorter); | ||
149 | |||
150 | for (k = 0; k < n; k++) | ||
151 | sorted_index[k] = point[k].i; | ||
152 | |||
153 | k = 0; | ||
154 | EINA_INLIST_FOREACH(points, pt) | ||
155 | { | ||
156 | point[k].x = pt->x + x; | ||
157 | point[k].y = pt->y + y; | ||
158 | point[k].i = k; | ||
159 | k++; | ||
160 | } | ||
161 | |||
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)); | ||
164 | |||
165 | k = 0; | ||
166 | num_active_edges = 0; | ||
167 | |||
168 | for (yi = y0; yi <= y1; yi++) | ||
169 | { | ||
170 | for (; (k < n) && (point[sorted_index[k]].y <= ((float)yi + 0.5)); k++) | ||
171 | { | ||
172 | i = sorted_index[k]; | ||
173 | |||
174 | if (i > 0) j = i - 1; | ||
175 | else j = n - 1; | ||
176 | if (point[j].y <= ((float)yi - 0.5)) | ||
177 | { | ||
178 | POLY_EDGE_DEL(j) | ||
179 | } | ||
180 | else if (point[j].y > ((float)yi + 0.5)) | ||
181 | { | ||
182 | POLY_EDGE_ADD(j, yi) | ||
183 | } | ||
184 | if (i < (n - 1)) j = i + 1; | ||
185 | else j = 0; | ||
186 | if (point[j].y <= ((float)yi - 0.5)) | ||
187 | { | ||
188 | POLY_EDGE_DEL(i) | ||
189 | } | ||
190 | else if (point[j].y > ((float)yi + 0.5)) | ||
191 | { | ||
192 | POLY_EDGE_ADD(i, yi) | ||
193 | } | ||
194 | } | ||
195 | |||
196 | qsort(edges, num_active_edges, sizeof(RGBA_Edge), polygon_edge_sorter); | ||
197 | |||
198 | for (j = 0; j < num_active_edges; j += 2) | ||
199 | { | ||
200 | int x0, x1; | ||
201 | |||
202 | x0 = ceil(edges[j].x - 0.5); | ||
203 | if (j < (num_active_edges - 1)) | ||
204 | x1 = floor(edges[j + 1].x - 0.5); | ||
205 | else | ||
206 | x1 = x0; | ||
207 | if ((x1 >= ext_x) && (x0 < (ext_x + ext_w)) && (x0 <= x1)) | ||
208 | { | ||
209 | DATA16 *dst_itr; | ||
210 | int w; | ||
211 | |||
212 | if (x0 < ext_x) x0 = ext_x; | ||
213 | if (x1 >= (ext_x + ext_w)) x1 = ext_x + ext_w - 1; | ||
214 | |||
215 | w = (x1 - x0) + 1; | ||
216 | dst_itr = dst->pixels + (yi * dst->stride) + x0; | ||
217 | |||
218 | if (alpha == 32) | ||
219 | _soft16_scanline_fill_solid_solid(dst_itr, w, rgb565); | ||
220 | else | ||
221 | _soft16_scanline_fill_transp_solid(dst_itr, w, rgb565_unpack, alpha); | ||
222 | } | ||
223 | edges[j].x += edges[j].dx; | ||
224 | edges[j + 1].x += edges[j + 1].dx; | ||
225 | } | ||
226 | } | ||
227 | |||
228 | free(edges); | ||
229 | free(point); | ||
230 | free(sorted_index); | ||
231 | } | ||