From deecd8a137c1481504fa48bcf41566e51eb5100a Mon Sep 17 00:00:00 2001 From: Terseus Date: Tue, 1 Apr 2014 13:01:03 +0200 Subject: [PATCH] Refactored polygon functions to unify logic The functions `polygon8`, `polygon32` and `polygon32rgba` all have exactly the same logic in code, only changes the hline function called inside. Now all the logic is contained in `polygon_generic` which gets a function pointer to the hline handler, so there is no duplicated code anymore. --- libImaging/Draw.c | 132 +++++++--------------------------------------- 1 file changed, 20 insertions(+), 112 deletions(-) diff --git a/libImaging/Draw.c b/libImaging/Draw.c index f13ba4df0..1241c8d3b 100644 --- a/libImaging/Draw.c +++ b/libImaging/Draw.c @@ -61,6 +61,9 @@ typedef struct { float dx; } Edge; +/* Type used in "polygon*" functions */ +typedef void (*hline_handler)(Imaging, int, int, int, int); + static inline void point8(Imaging im, int x, int y, int ink) { @@ -403,8 +406,10 @@ x_cmp(const void *x0, const void *x1) return 0; } + static inline int -polygon8(Imaging im, int n, Edge *e, int ink, int eofill) +polygon_generic(Imaging im, int n, Edge *e, int ink, int eofill, + hline_handler handler) { int i, j; float *xx; @@ -436,22 +441,23 @@ polygon8(Imaging im, int n, Edge *e, int ink, int eofill) for (;ymin <= ymax; ymin++) { y = ymin+0.5F; - for (i = j = 0; i < n; i++) + for (i = j = 0; i < n; i++) { if (y >= e[i].ymin && y <= e[i].ymax) { if (e[i].d == 0) - hline8(im, e[i].xmin, ymin, e[i].xmax, ink); + (*handler)(im, e[i].xmin, ymin, e[i].xmax, ink); else xx[j++] = (y-e[i].y0) * e[i].dx + e[i].x0; } + } if (j == 2) { if (xx[0] < xx[1]) - hline8(im, CEIL(xx[0]-0.5), ymin, FLOOR(xx[1]+0.5), ink); + (*handler)(im, CEIL(xx[0]-0.5), ymin, FLOOR(xx[1]+0.5), ink); else - hline8(im, CEIL(xx[1]-0.5), ymin, FLOOR(xx[0]+0.5), ink); + (*handler)(im, CEIL(xx[1]-0.5), ymin, FLOOR(xx[0]+0.5), ink); } else { qsort(xx, j, sizeof(float), x_cmp); for (i = 0; i < j-1 ; i += 2) - hline8(im, CEIL(xx[i]-0.5), ymin, FLOOR(xx[i+1]+0.5), ink); + (*handler)(im, CEIL(xx[i]-0.5), ymin, FLOOR(xx[i+1]+0.5), ink); } } @@ -460,120 +466,22 @@ polygon8(Imaging im, int n, Edge *e, int ink, int eofill) return 0; } +static inline int +polygon8(Imaging im, int n, Edge *e, int ink, int eofill) +{ + return polygon_generic(im, n, e, ink, eofill, hline8); +} + static inline int polygon32(Imaging im, int n, Edge *e, int ink, int eofill) { - int i, j; - float *xx; - int ymin, ymax; - float y; - - if (n <= 0) - return 0; - - /* Find upper and lower polygon boundary (within image) */ - - ymin = e[0].ymin; - ymax = e[0].ymax; - for (i = 1; i < n; i++) { - if (e[i].ymin < ymin) ymin = e[i].ymin; - if (e[i].ymax > ymax) ymax = e[i].ymax; - } - - if (ymin < 0) - ymin = 0; - if (ymax >= im->ysize) - ymax = im->ysize-1; - - /* Process polygon edges */ - - xx = malloc(n * sizeof(float)); - if (!xx) - return -1; - - for (;ymin <= ymax; ymin++) { - y = ymin+0.5F; - for (i = j = 0; i < n; i++) { - if (y >= e[i].ymin && y <= e[i].ymax) { - if (e[i].d == 0) - hline32(im, e[i].xmin, ymin, e[i].xmax, ink); - else - xx[j++] = (y-e[i].y0) * e[i].dx + e[i].x0; - } - } - if (j == 2) { - if (xx[0] < xx[1]) - hline32(im, CEIL(xx[0]-0.5), ymin, FLOOR(xx[1]+0.5), ink); - else - hline32(im, CEIL(xx[1]-0.5), ymin, FLOOR(xx[0]+0.5), ink); - } else { - qsort(xx, j, sizeof(float), x_cmp); - for (i = 0; i < j-1 ; i += 2) - hline32(im, CEIL(xx[i]-0.5), ymin, FLOOR(xx[i+1]+0.5), ink); - } - } - - free(xx); - - return 0; + return polygon_generic(im, n, e, ink, eofill, hline32); } static inline int polygon32rgba(Imaging im, int n, Edge *e, int ink, int eofill) { - int i, j; - float *xx; - int ymin, ymax; - float y; - - if (n <= 0) - return 0; - - /* Find upper and lower polygon boundary (within image) */ - - ymin = e[0].ymin; - ymax = e[0].ymax; - for (i = 1; i < n; i++) { - if (e[i].ymin < ymin) ymin = e[i].ymin; - if (e[i].ymax > ymax) ymax = e[i].ymax; - } - - if (ymin < 0) - ymin = 0; - if (ymax >= im->ysize) - ymax = im->ysize-1; - - /* Process polygon edges */ - - xx = malloc(n * sizeof(float)); - if (!xx) - return -1; - - for (;ymin <= ymax; ymin++) { - y = ymin+0.5F; - for (i = j = 0; i < n; i++) { - if (y >= e[i].ymin && y <= e[i].ymax) { - if (e[i].d == 0) - hline32rgba(im, e[i].xmin, ymin, e[i].xmax, ink); - else - xx[j++] = (y-e[i].y0) * e[i].dx + e[i].x0; - } - } - if (j == 2) { - if (xx[0] < xx[1]) - hline32rgba(im, CEIL(xx[0]-0.5), ymin, FLOOR(xx[1]+0.5), ink); - else - hline32rgba(im, CEIL(xx[1]-0.5), ymin, FLOOR(xx[0]+0.5), ink); - } else { - qsort(xx, j, sizeof(float), x_cmp); - for (i = 0; i < j-1 ; i += 2) - hline32rgba(im, CEIL(xx[i]-0.5), ymin, FLOOR(xx[i+1]+0.5), ink); - } - } - - free(xx); - - return 0; + return polygon_generic(im, n, e, ink, eofill, hline32rgba); } static inline void