aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/libraries/evas/src/lib/engines/common/evas_regionbuf.c
diff options
context:
space:
mode:
authorDavid Walter Seikel2012-01-04 18:41:13 +1000
committerDavid Walter Seikel2012-01-04 18:41:13 +1000
commitdd7595a3475407a7fa96a97393bae8c5220e8762 (patch)
treee341e911d7eb911a51684a7412ef7f7c7605d28e /libraries/evas/src/lib/engines/common/evas_regionbuf.c
parentAdd the skeleton. (diff)
downloadSledjHamr-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 '')
-rw-r--r--libraries/evas/src/lib/engines/common/evas_regionbuf.c357
1 files changed, 357 insertions, 0 deletions
diff --git a/libraries/evas/src/lib/engines/common/evas_regionbuf.c b/libraries/evas/src/lib/engines/common/evas_regionbuf.c
new file mode 100644
index 0000000..f381da5
--- /dev/null
+++ b/libraries/evas/src/lib/engines/common/evas_regionbuf.c
@@ -0,0 +1,357 @@
1#include "evas_common.h"
2
3#if 0
4Regionbuf *
5evas_common_regionbuf_new(int w, int h)
6{
7 Regionbuf *rb;
8
9 rb = calloc(1, sizeof(Regionbuf) + (h * sizeof(Regionspan)));
10 if (!rb) return NULL;
11 rb->spans = (Regionspan **)(rb + sizeof(Regionbuf));
12 rb->w = w;
13 rb->h = h;
14 return rb;
15}
16
17void
18evas_common_regionbuf_free(Regionbuf *rb)
19{
20 evas_common_regionbuf_clear(rb);
21 free(rb);
22}
23
24void
25evas_common_regionbuf_clear(Regionbuf *rb)
26{
27 int y;
28
29 for (y = 0; y < rb->h; y++)
30 {
31 while (rb->spans[y])
32 {
33 Regionspan *span;
34
35 span = rb->spans[y];
36 rb->spans[y] = eina_inlist_remove(rb->spans[y], rb->spans[y]);
37 free(span);
38 }
39 }
40}
41
42void
43evas_common_regionbuf_span_add(Regionbuf *rb, int x1, int x2, int y)
44{
45 Regionspan *span, *span2, *nspan, *sp_start, *sp_stop;
46
47 /* abort if outside */
48 if ((y < 0) ||
49 (y >= rb->h) ||
50 (x2 < 0) ||
51 (x1 >= rb->w)) return;
52 /* clip to horiz bounds */
53 if (x1 < 0) x1 = 0;
54 if (x2 < (rb->w - 1)) x2 = rb->w - 1;
55 sp_start = NULL;
56 sp_stop = NULL;
57 EINA_INLIST_FOREACH(rb->spans[y], span)
58 {
59 nspan = (Regionspan *)(EINA_INLIST_GET(span))->next;
60 /* we dont know what t do with the span yet */
61 if (!sp_start)
62 {
63 /* if new span starts before or on this span or just after
64 * with no gap */
65 if (x1 <= (span->x2 + 1))
66 sp_start = span;
67 /* if there is no next span */
68 if (!nspan)
69 {
70 sp_stop = span;
71 break;
72 }
73 /* if new span ends before the next span starts with a gap of
74 * 1 pixel (or more) */
75 else if (x2 < (nspan->x1 - 1))
76 {
77 sp_stop = span;
78 break;
79 }
80 }
81 /* we already know it already starts before or in sp_start */
82 else
83 {
84 /* there is no span after this one, so this has to be the stop */
85 if (!nspan)
86 {
87 sp_stop = span;
88 break;
89 }
90 /* if new span ends before the next span starts with a gap of
91 * 1 pixel (or more) */
92 else if (x2 < (nspan->x1 - 1))
93 {
94 sp_stop = span;
95 break;
96 }
97 }
98 }
99 /* sp_start is where the new span starts in or before */
100 /* sp_stop is where the new span stops in or after */
101 if ((sp_start) && (sp_stop))
102 {
103 /* same start and stop */
104 if (sp_start == sp_stop)
105 {
106 if (x2 < (sp_start->x1 - 1))
107 {
108 span2 = calloc(1, sizeof(Regionspan));
109 span2->x1 = x1;
110 span2->x2 = x2;
111 rb->spans[y] = eina_inlist_prepend_relative(rb->spans[y], span2, sp_start);
112 return;
113 }
114 if (x1 < sp_start->x1)
115 sp_start->x1 = x1;
116 if (x2 > sp_start->x2)
117 sp_start->x2 = x2;
118 return;
119 }
120 else
121 {
122 Eina_Inlist *l;
123
124 /* remove all nodes after sp_start and before_sp_stop because
125 * the new */
126 for (l = (EINA_INLIST_GET(sp_start))->next; l != EINA_INLIST_GET(sp_stop);)
127 {
128 span = (Regionspan *)l;
129 l = l->next;
130 rb->spans[y] = eina_inlist_remove(rb->spans[y], span);
131 free(span);
132 }
133 /* remove the end span */
134 rb->spans[y] = eina_inlist_remove(rb->spans[y], sp_stop);
135 /* if the new span is before the start span - extend */
136 if (x1 < sp_start->x1)
137 sp_start->x1 = x1;
138 /* if it goes beyond the stop span - extend stop span */
139 if (x2 > sp_stop->x2)
140 sp_stop->x2 = x2;
141 /* extend start span to stop span */
142 sp_start->x2 = sp_stop->x2;
143 /* don't need stop span anymore */
144 free(sp_stop);
145 return;
146 }
147 }
148 /* no start AND stop... just append */
149 span2 = calloc(1, sizeof(Regionspan));
150 span2->x1 = x1;
151 span2->x2 = x2;
152 rb->spans[y] = eina_inlist_append(rb->spans[y], span2);
153}
154
155void
156evas_common_regionbuf_span_del(Regionbuf *rb, int x1, int x2, int y)
157{
158 /* FIXME: del span */
159 Regionspan *span, *span2, *nspan, *sp_start, *sp_stop;
160
161 /* abort if outside */
162 if ((y < 0) ||
163 (y >= rb->h) ||
164 (x2 < 0) ||
165 (x1 >= rb->w)) return;
166 /* clip to horiz bounds */
167 if (x1 < 0) x1 = 0;
168 if (x2 < (rb->w - 1)) x2 = rb->w - 1;
169 sp_start = NULL;
170 sp_stop = NULL;
171 EINA_INLIST_FOREACH(rb->spans[y], span)
172 {
173 nspan = (Regionspan *)(EINA_INLIST_GET(l))->next;
174 /* we dont know what t do with the span yet */
175 if (!sp_start)
176 {
177 /* if new span starts before or on this span or just after
178 * with no gap */
179 if (x1 <= (span->x2))
180 sp_start = span;
181 /* if there is no next span */
182 if (!nspan)
183 {
184 sp_stop = span;
185 break;
186 }
187 /* if new span ends before the next span starts with a gap of
188 * 1 pixel (or more) */
189 else if (x2 < nspan->x1)
190 {
191 sp_stop = span;
192 break;
193 }
194 }
195 /* we already know it already starts before or in sp_start */
196 else
197 {
198 /* there is no span after this one, so this has to be the stop */
199 if (!nspan)
200 {
201 sp_stop = span;
202 break;
203 }
204 /* if new span ends before the next span starts with a gap of
205 * 1 pixel (or more) */
206 else if (x2 < nspan->x1)
207 {
208 sp_stop = span;
209 break;
210 }
211 }
212 }
213 /* sp_start is where the new span starts in or before */
214 /* sp_stop is where the new span stops in or after */
215 if ((sp_start) && (sp_stop))
216 {
217 /* same start and stop */
218 if (sp_start == sp_stop)
219 {
220 /* if it ends before this the span start starts... return */
221 if (x2 < sp_start->x1)
222 return;
223 /* it starts on or before this span */
224 else if (x1 <= sp_start->x1)
225 {
226 /* right edge is within the span */
227 if (x2 < sp_start->x2)
228 {
229 sp_start->x2 = x2;
230 return;
231 }
232 else
233 {
234 rb->spans[y] = eina_inlist_remove(rb->spans[y], sp_start);
235 return;
236 }
237 }
238 /* it ends on or after the end of this span */
239 else if (x2 >= sp_start->x2)
240 {
241 /* it starts after the start */
242 if (x1 > sp_start->x1)
243 {
244 sp_start->x1 = x1;
245 return;
246 }
247 /* remove it all */
248 else
249 {
250 rb->spans[y] = eina_inlist_remove(rb->spans[y], sp_start);
251 return;
252 }
253 return;
254 }
255 /* this breaks the span into 2 */
256 else
257 {
258 span2 = calloc(1, sizeof(Regionspan));
259 span2->x1 = sp_start->x1;
260 span2->x2 = x1 - 1;
261 rb->spans[y] = eina_inlist_prepend_relative(rb->spans[y], span2, sp_start);
262 sp_start->x1 = x2 + 1;
263 return;
264 }
265 }
266 else
267 {
268 Eina_Inlist *l;
269
270 /* remove all nodes after sp_start and before_sp_stop because
271 * the new */
272 for (l = (EINA_INLIST_GET(sp_start))->next; l != EINA_INLIST_GET(sp_stop);)
273 {
274 span = (Regionspan *)l;
275 l = l->next;
276 rb->spans[y] = eina_inlist_remove(rb->spans[y], span);
277 free(span);
278 }
279 /* all of the start span is cut out */
280 if (x1 <= sp_start->x1)
281 {
282 rb->spans[y] = eina_inlist_remove(rb->spans[y], sp_start);
283 free(sp_start);
284 }
285 /* chup it off at the new span start */
286 else
287 sp_start->x2 = x1 - 1;
288 /* all of the end span is cut out */
289 if (x2 >= sp_stop->x2)
290 {
291 rb->spans[y] = eina_inlist_remove(rb->spans[y], sp_stop);
292 free(sp_stop);
293 }
294 /* chop it up at the end */
295 else
296 sp_stop->x1 = x2 + 1;
297 return;
298 }
299 }
300}
301
302Tilebuf_Rect *
303evas_common_regionbuf_rects_get(Regionbuf *rb)
304{
305 Tilebuf_Rect *rects = NULL, *r;
306 int y;
307
308 /* FIXME: take spans, make rects */
309 for (y = 0; y < rb->h; y++)
310 {
311 Regionspan *sp_start;
312 Eina_Inlist *l, *ll;
313
314 for (l = EINA_INLIST_GET(rb->spans[y]); l;)
315 {
316 Regionspan *span;
317 int yy;
318
319 sp_start = (Regionspan *)l;
320 l = l->next;
321 rb->spans[y] = eina_inlist_remove(rb->spans[y], sp_start);
322 for (yy = y + 1; yy < rb->h; yy++)
323 {
324 int match = 0;
325
326 for (ll = EINA_INLIST_GET(rb->spans[yy]); ll;)
327 {
328 span = (Regionspan *)ll;
329 ll = ll->next;
330 if (span->x1 == sp_start->x1)
331 {
332 if ((span->x1 != sp_start->x1) ||
333 (span->x2 != sp_start->x2))
334 {
335 goto coallate;
336 }
337 match = 1;
338 rb->spans[yy] = eina_inlist_remove(rb->spans[yy], span);
339 free(span);
340 }
341 }
342 if (!match) goto coallate;
343 }
344 coallate:
345 r = calloc(1, sizeof(Tilebuf_Rect));
346 r->x = sp_start->x1;
347 r->y = y;
348 r->w = sp_start->x2 - sp_start->x1 + 1;
349 r->h = yy - y;
350 rects = eina_inlist_append(rects, r);
351 free(sp_start);
352 }
353 }
354 evas_common_regionbuf_clear(rb);
355 return rects;
356}
357#endif