mirror of
https://github.com/python-pillow/Pillow.git
synced 2024-12-26 01:46:18 +03:00
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.
This commit is contained in:
parent
6e2075e25d
commit
deecd8a137
|
@ -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
|
||||
|
|
Loading…
Reference in New Issue
Block a user