1 #include "evas_common.h"
5 evas_common_regionbuf_new(int w, int h)
9 rb = calloc(1, sizeof(Regionbuf) + (h * sizeof(Regionspan)));
11 rb->spans = (Regionspan **)(rb + sizeof(Regionbuf));
18 evas_common_regionbuf_free(Regionbuf *rb)
20 evas_common_regionbuf_clear(rb);
25 evas_common_regionbuf_clear(Regionbuf *rb)
29 for (y = 0; y < rb->h; y++)
36 rb->spans[y] = evas_object_list_remove(rb->spans[y], rb->spans[y]);
43 evas_common_regionbuf_span_add(Regionbuf *rb, int x1, int x2, int y)
46 Regionspan *span, *span2, *nspan, *sp_start, *sp_stop;
48 /* abort if outside */
52 (x1 >= rb->w)) return;
53 /* clip to horiz bounds */
55 if (x2 < (rb->w - 1)) x2 = rb->w - 1;
58 for (l = (Evas_Object_List *)rb->spans[y]; l; l = l->next)
60 span = (Regionspan *)l;
61 nspan = (Regionspan *)l->next;
62 /* we dont know what t do with the span yet */
65 /* if new span starts before or on this span or just after
67 if (x1 <= (span->x2 + 1))
69 /* if there is no next span */
75 /* if new span ends before the next span starts with a gap of
76 * 1 pixel (or more) */
77 else if (x2 < (nspan->x1 - 1))
83 /* we already know it already starts before or in sp_start */
86 /* there is no span after this one, so this has to be the stop */
92 /* if new span ends before the next span starts with a gap of
93 * 1 pixel (or more) */
94 else if (x2 < (nspan->x1 - 1))
101 /* sp_start is where the new span starts in or before */
102 /* sp_stop is where the new span stops in or after */
103 if ((sp_start) && (sp_stop))
105 /* same start and stop */
106 if (sp_start == sp_stop)
108 if (x2 < (sp_start->x1 - 1))
110 span2 = calloc(1, sizeof(Regionspan));
113 rb->spans[y] = evas_object_list_prepend_relative(rb->spans[y], span2, sp_start);
116 if (x1 < sp_start->x1)
118 if (x2 > sp_start->x2)
124 /* remove all nodes after sp_start and before_sp_stop because
126 for (l = ((Evas_Object_List *)sp_start)->next; l != (Evas_Object_List *)sp_stop;)
128 span = (Regionspan *)l;
130 rb->spans[y] = evas_object_list_remove(rb->spans[y], span);
133 /* remove the end span */
134 rb->spans[y] = evas_object_list_remove(rb->spans[y], sp_stop);
135 /* if the new span is before the start span - extend */
136 if (x1 < sp_start->x1)
138 /* if it goes beyond the stop span - extend stop span */
139 if (x2 > sp_stop->x2)
141 /* extend start span to stop span */
142 sp_start->x2 = sp_stop->x2;
143 /* don't need stop span anymore */
148 /* no start AND stop... just append */
149 span2 = calloc(1, sizeof(Regionspan));
152 rb->spans[y] = evas_object_list_append(rb->spans[y], span2);
156 evas_common_regionbuf_span_del(Regionbuf *rb, int x1, int x2, int y)
158 /* FIXME: del span */
160 Regionspan *span, *span2, *nspan, *sp_start, *sp_stop;
162 /* abort if outside */
166 (x1 >= rb->w)) return;
167 /* clip to horiz bounds */
169 if (x2 < (rb->w - 1)) x2 = rb->w - 1;
172 for (l = (Evas_Object_List *)rb->spans[y]; l; l = l->next)
174 span = (Regionspan *)l;
175 nspan = (Regionspan *)l->next;
176 /* we dont know what t do with the span yet */
179 /* if new span starts before or on this span or just after
181 if (x1 <= (span->x2))
183 /* if there is no next span */
189 /* if new span ends before the next span starts with a gap of
190 * 1 pixel (or more) */
191 else if (x2 < nspan->x1)
197 /* we already know it already starts before or in sp_start */
200 /* there is no span after this one, so this has to be the stop */
206 /* if new span ends before the next span starts with a gap of
207 * 1 pixel (or more) */
208 else if (x2 < nspan->x1)
215 /* sp_start is where the new span starts in or before */
216 /* sp_stop is where the new span stops in or after */
217 if ((sp_start) && (sp_stop))
219 /* same start and stop */
220 if (sp_start == sp_stop)
222 /* if it ends before this the span start starts... return */
223 if (x2 < sp_start->x1)
225 /* it starts on or before this span */
226 else if (x1 <= sp_start->x1)
228 /* right edge is within the span */
229 if (x2 < sp_start->x2)
236 rb->spans[y] = evas_object_list_remove(rb->spans[y], sp_start);
240 /* it ends on or after the end of thsi span */
241 else if (x2 >= sp_start->x2)
243 /* it starts after the start */
244 if (x1 > sp_start->x1)
252 rb->spans[y] = evas_object_list_remove(rb->spans[y], sp_start);
257 /* this breaks the span into 2 */
260 span2 = calloc(1, sizeof(Regionspan));
261 span2->x1 = sp_start->x1;
263 rb->spans[y] = evas_object_list_prepend_relative(rb->spans[y], span2, sp_start);
264 sp_start->x1 = x2 + 1;
270 /* remove all nodes after sp_start and before_sp_stop because
272 for (l = ((Evas_Object_List *)sp_start)->next; l != (Evas_Object_List *)sp_stop;)
274 span = (Regionspan *)l;
276 rb->spans[y] = evas_object_list_remove(rb->spans[y], span);
279 /* all of the start span is cut out */
280 if (x1 <= sp_start->x1)
282 rb->spans[y] = evas_object_list_remove(rb->spans[y], sp_start);
285 /* chup it off at the new span start */
287 sp_start->x2 = x1 - 1;
288 /* all of the end span is cut out */
289 if (x2 >= sp_stop->x2)
291 rb->spans[y] = evas_object_list_remove(rb->spans[y], sp_stop);
294 /* chop it up at the end */
296 sp_stop->x1 = x2 + 1;
303 evas_common_regionbuf_rects_get(Regionbuf *rb)
305 Tilebuf_Rect *rects = NULL, *r;
308 /* FIXME: take spans, make rects */
309 for (y = 0; y < rb->h; y++)
311 Evas_Object_List *l, *ll;
313 for (l = (Evas_Object_List *)rb->spans[y]; l;)
316 Regionspan *sp_start;
319 sp_start = (Regionspan *)l;
321 rb->spans[y] = evas_object_list_remove(rb->spans[y], sp_start);
322 for (yy = y + 1; yy < rb->h; yy++)
326 for (ll = (Evas_Object_List *)rb->spans[yy]; ll;)
328 span = (Regionspan *)ll;
330 if (span->x1 == sp_start->x1)
332 if ((span->x1 != sp_start->x1) ||
333 (span->x2 != sp_start->x2))
338 rb->spans[yy] = evas_object_list_remove(rb->spans[yy], span);
342 if (!match) goto coallate;
345 r = calloc(1, sizeof(Tilebuf_Rect));
348 r->w = sp_start->x2 - sp_start->x1 + 1;
350 rects = evas_object_list_append(rects, r);
354 evas_common_regionbuf_clear(rb);