summaryrefslogtreecommitdiff
path: root/src/lib/evas/common/evas_polygon_main.c
diff options
context:
space:
mode:
authorLeandro Pereira <leandro@profusion.mobi>2012-12-17 21:29:01 +0000
committerLeandro Pereira <leandro@profusion.mobi>2012-12-17 21:29:01 +0000
commit6ea27233227ee92afb21497a50f5224336f2489b (patch)
treeba261737289854102e02cd341e21672c5ffd3af5 /src/lib/evas/common/evas_polygon_main.c
parentb51ab5fc02581cbee3c26dcd7b9bfd3b142baa55 (diff)
evas/common: Prepare soil to land polygon drawing code for threaded render
SVN revision: 81187
Diffstat (limited to 'src/lib/evas/common/evas_polygon_main.c')
-rw-r--r--src/lib/evas/common/evas_polygon_main.c143
1 files changed, 143 insertions, 0 deletions
diff --git a/src/lib/evas/common/evas_polygon_main.c b/src/lib/evas/common/evas_polygon_main.c
index f82d245149..8635d1c16c 100644
--- a/src/lib/evas/common/evas_polygon_main.c
+++ b/src/lib/evas/common/evas_polygon_main.c
@@ -310,3 +310,146 @@ evas_common_polygon_draw(RGBA_Image *dst, RGBA_Draw_Context *dc, RGBA_Polygon_Po
310 } 310 }
311 } 311 }
312} 312}
313
314EAPI void
315evas_common_polygon_rgba_draw(RGBA_Image *dst, int ext_x, int ext_y, int ext_w, int ext_h, DATA32 col, int render_op, RGBA_Polygon_Point *points, int x, int y)
316{
317 RGBA_Gfx_Func func;
318 RGBA_Polygon_Point *pt;
319 RGBA_Vertex *point;
320 RGBA_Edge *edges;
321 Eina_Inlist *spans;
322 int num_active_edges;
323 int n;
324 int i, j, k;
325 int yy0, yy1, yi;
326 int *sorted_index;
327
328 if ((ext_w <= 0) || (ext_h <= 0)) return;
329
330 evas_common_cpu_end_opt();
331
332 n = 0; EINA_INLIST_FOREACH(points, pt) n++;
333 if (n < 3) return;
334 edges = malloc(sizeof(RGBA_Edge) * n);
335 if (!edges) return;
336 point = malloc(sizeof(RGBA_Vertex) * n);
337 if (!point)
338 {
339 free(edges);
340 return;
341 }
342 sorted_index = malloc(sizeof(int) * n);
343 if (!sorted_index)
344 {
345 free(edges);
346 free(point);
347 return;
348 }
349
350 k = 0;
351 EINA_INLIST_FOREACH(points, pt)
352 {
353 point[k].x = pt->x + x;
354 point[k].y = pt->y + y;
355 point[k].i = k;
356 k++;
357 }
358 qsort(point, n, sizeof(RGBA_Vertex), polygon_point_sorter);
359 for (k = 0; k < n; k++) sorted_index[k] = point[k].i;
360 k = 0;
361 EINA_INLIST_FOREACH(points, pt)
362 {
363 point[k].x = pt->x + x;
364 point[k].y = pt->y + y;
365 point[k].i = k;
366 k++;
367 }
368
369 yy0 = MAX(ext_y, ceil(point[sorted_index[0]].y - 0.5));
370 yy1 = MIN(ext_y + ext_h - 1, floor(point[sorted_index[n - 1]].y - 0.5));
371
372 k = 0;
373 num_active_edges = 0;
374 spans = NULL;
375
376 for (yi = yy0; yi <= yy1; yi++)
377 {
378 for (; (k < n) && (point[sorted_index[k]].y <= ((double)yi + 0.5)); k++)
379 {
380 i = sorted_index[k];
381
382 if (i > 0) j = i - 1;
383 else j = n - 1;
384 if (point[j].y <= ((double)yi - 0.5))
385 {
386 POLY_EDGE_DEL(j)
387 }
388 else if (point[j].y > ((double)yi + 0.5))
389 {
390 POLY_EDGE_ADD(j, yi)
391 }
392 if (i < (n - 1)) j = i + 1;
393 else j = 0;
394 if (point[j].y <= ((double)yi - 0.5))
395 {
396 POLY_EDGE_DEL(i)
397 }
398 else if (point[j].y > ((double)yi + 0.5))
399 {
400 POLY_EDGE_ADD(i, yi)
401 }
402 }
403
404 qsort(edges, num_active_edges, sizeof(RGBA_Edge), polygon_edge_sorter);
405
406 for (j = 0; j < num_active_edges; j += 2)
407 {
408 int x0, x1;
409
410 x0 = ceil(edges[j].x - 0.5);
411 if (j < (num_active_edges - 1))
412 x1 = floor(edges[j + 1].x - 0.5);
413 else
414 x1 = x0;
415 if ((x1 >= ext_x) && (x0 < (ext_x + ext_w)) && (x0 <= x1))
416 {
417 RGBA_Span *span;
418
419 if (x0 < ext_x) x0 = ext_x;
420 if (x1 >= (ext_x + ext_w)) x1 = ext_x + ext_w - 1;
421 span = malloc(sizeof(RGBA_Span));
422 spans = eina_inlist_append(spans, EINA_INLIST_GET(span));
423 span->y = yi;
424 span->x = x0;
425 span->w = (x1 - x0) + 1;
426 }
427 edges[j].x += edges[j].dx;
428 edges[j + 1].x += edges[j + 1].dx;
429 }
430 }
431
432 free(edges);
433 free(point);
434 free(sorted_index);
435
436 func = evas_common_gfx_func_composite_color_span_get(col, dst, 1, render_op);
437 if (spans)
438 {
439 RGBA_Span *span;
440
441 EINA_INLIST_FOREACH(spans, span)
442 {
443 DATA32 *ptr;
444
445 ptr = dst->image.data + (span->y * (dst->cache_entry.w)) + span->x;
446 func(NULL, NULL, col, ptr, span->w);
447 }
448 while (spans)
449 {
450 span = (RGBA_Span *)spans;
451 spans = eina_inlist_remove(spans, spans);
452 free(span);
453 }
454 }
455}