mirror of
https://github.com/python-pillow/Pillow.git
synced 2025-07-10 16:22:22 +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;
|
float dx;
|
||||||
} Edge;
|
} Edge;
|
||||||
|
|
||||||
|
/* Type used in "polygon*" functions */
|
||||||
|
typedef void (*hline_handler)(Imaging, int, int, int, int);
|
||||||
|
|
||||||
static inline void
|
static inline void
|
||||||
point8(Imaging im, int x, int y, int ink)
|
point8(Imaging im, int x, int y, int ink)
|
||||||
{
|
{
|
||||||
|
@ -403,8 +406,10 @@ x_cmp(const void *x0, const void *x1)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static inline int
|
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;
|
int i, j;
|
||||||
float *xx;
|
float *xx;
|
||||||
|
@ -436,22 +441,23 @@ polygon8(Imaging im, int n, Edge *e, int ink, int eofill)
|
||||||
|
|
||||||
for (;ymin <= ymax; ymin++) {
|
for (;ymin <= ymax; ymin++) {
|
||||||
y = ymin+0.5F;
|
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 (y >= e[i].ymin && y <= e[i].ymax) {
|
||||||
if (e[i].d == 0)
|
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
|
else
|
||||||
xx[j++] = (y-e[i].y0) * e[i].dx + e[i].x0;
|
xx[j++] = (y-e[i].y0) * e[i].dx + e[i].x0;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
if (j == 2) {
|
if (j == 2) {
|
||||||
if (xx[0] < xx[1])
|
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
|
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 {
|
} else {
|
||||||
qsort(xx, j, sizeof(float), x_cmp);
|
qsort(xx, j, sizeof(float), x_cmp);
|
||||||
for (i = 0; i < j-1 ; i += 2)
|
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;
|
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
|
static inline int
|
||||||
polygon32(Imaging im, int n, Edge *e, int ink, int eofill)
|
polygon32(Imaging im, int n, Edge *e, int ink, int eofill)
|
||||||
{
|
{
|
||||||
int i, j;
|
return polygon_generic(im, n, e, ink, eofill, hline32);
|
||||||
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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline int
|
static inline int
|
||||||
polygon32rgba(Imaging im, int n, Edge *e, int ink, int eofill)
|
polygon32rgba(Imaging im, int n, Edge *e, int ink, int eofill)
|
||||||
{
|
{
|
||||||
int i, j;
|
return polygon_generic(im, n, e, ink, eofill, hline32rgba);
|
||||||
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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void
|
static inline void
|
||||||
|
|
Loading…
Reference in New Issue
Block a user