forked from old/legacy-imlib2
Polygon filling. Right now only works for convex polygons. Works with a
clipping rect, but highly suboptimally (I'm not doing proper polygon clipping here yet, just clipping slowly on each point drawn - really nasty). There are probably some rounding errors in here. I need to work more on this, but I have *so* little time for the next few weeks. Please don't kill me for this code. It's not finished, but I'm about to move house, and I have to get something working before I pack my PC away. SVN revision: 3303
This commit is contained in:
parent
f640137020
commit
222e1b5f32
285
src/rgbadraw.c
285
src/rgbadraw.c
|
@ -12,6 +12,8 @@
|
||||||
#define XY_IN_RECT(x, y, rx, ry, rw, rh) \
|
#define XY_IN_RECT(x, y, rx, ry, rw, rh) \
|
||||||
(((x) >= (rx)) && ((y) >= (ry)) && ((x) <= ((rx) + (rw))) && ((y) <= ((ry) + (rh))))
|
(((x) >= (rx)) && ((y) >= (ry)) && ((x) <= ((rx) + (rw))) && ((y) <= ((ry) + (rh))))
|
||||||
|
|
||||||
|
#define MAX(a,b) (((a) > (b)) ? (a) : (b))
|
||||||
|
|
||||||
void
|
void
|
||||||
__imlib_FlipImageHoriz(ImlibImage * im)
|
__imlib_FlipImageHoriz(ImlibImage * im)
|
||||||
{
|
{
|
||||||
|
@ -1683,6 +1685,12 @@ __imlib_draw_polygon(ImlibImage * im, ImlibPoly poly, DATA8 r, DATA8 g,
|
||||||
if (!poly || !poly->points || (poly->pointcount < 2))
|
if (!poly || !poly->points || (poly->pointcount < 2))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
if (poly->filled)
|
||||||
|
{
|
||||||
|
__imlib_draw_polygon_filled(im, poly, r, g, b, a, op);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
for (i = 0; i < poly->pointcount; i++)
|
for (i = 0; i < poly->pointcount; i++)
|
||||||
{
|
{
|
||||||
if (i < poly->pointcount - 1)
|
if (i < poly->pointcount - 1)
|
||||||
|
@ -1708,6 +1716,14 @@ __imlib_draw_polygon_clipped(ImlibImage * im, ImlibPoly poly, int clip_xmin,
|
||||||
if (!poly || !poly->points || (poly->pointcount < 2))
|
if (!poly || !poly->points || (poly->pointcount < 2))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
if (poly->filled)
|
||||||
|
{
|
||||||
|
__imlib_draw_polygon_filled_clipped(im, poly, clip_xmin, clip_xmax,
|
||||||
|
clip_ymin, clip_ymax, r, g, b, a,
|
||||||
|
op);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
for (i = 0; i < poly->pointcount; i++)
|
for (i = 0; i < poly->pointcount; i++)
|
||||||
{
|
{
|
||||||
if (i < poly->pointcount - 1)
|
if (i < poly->pointcount - 1)
|
||||||
|
@ -1869,7 +1885,8 @@ __imlib_draw_set_point_clipped(ImlibImage * im, int x, int y, int clip_xmin,
|
||||||
if ((x >= 0 && x < im->w) && (y >= 0 && y <= im->h))
|
if ((x >= 0 && x < im->w) && (y >= 0 && y <= im->h))
|
||||||
{
|
{
|
||||||
if (XY_IN_RECT
|
if (XY_IN_RECT
|
||||||
(x, y, clip_xmin, clip_ymin, clip_xmax - clip_xmin, clip_ymax - clip_ymin))
|
(x, y, clip_xmin, clip_ymin, clip_xmax - clip_xmin,
|
||||||
|
clip_ymax - clip_ymin))
|
||||||
{
|
{
|
||||||
p = &(im->data[(im->w * y) + x]);
|
p = &(im->data[(im->w * y) + x]);
|
||||||
switch (op)
|
switch (op)
|
||||||
|
@ -1892,3 +1909,269 @@ __imlib_draw_set_point_clipped(ImlibImage * im, int x, int y, int clip_xmin,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#define exchange(type, a, b) \
|
||||||
|
{ \
|
||||||
|
type _t_; \
|
||||||
|
_t_ = a; \
|
||||||
|
a = b; \
|
||||||
|
b = _t_; \
|
||||||
|
}
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
int x;
|
||||||
|
}
|
||||||
|
edgeRec;
|
||||||
|
|
||||||
|
static void
|
||||||
|
edge(edgeRec * table, ImlibPoint * pt1, ImlibPoint * pt2)
|
||||||
|
{
|
||||||
|
long x, dx;
|
||||||
|
int idy, iy1, iy2;
|
||||||
|
|
||||||
|
if (pt2->y < pt1->y)
|
||||||
|
{
|
||||||
|
exchange(ImlibPoint *, pt1, pt2)}
|
||||||
|
iy1 = pt1->y;
|
||||||
|
iy2 = pt2->y;
|
||||||
|
idy = iy2 - iy1;
|
||||||
|
if (idy == 0)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
idy = MAX(2, idy - 1);
|
||||||
|
x = pt1->x;
|
||||||
|
dx = (pt2->x - pt1->x) / idy;
|
||||||
|
do
|
||||||
|
{
|
||||||
|
table[iy1].x = x;
|
||||||
|
x += dx;
|
||||||
|
iy1++;
|
||||||
|
}
|
||||||
|
while (iy1 < iy2);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
span(ImlibImage * im, int y, edgeRec * pt1, edgeRec * pt2, DATA8 r, DATA8 g,
|
||||||
|
DATA8 b, DATA8 a, ImlibOp op)
|
||||||
|
{
|
||||||
|
int idx, ix1, ix2;
|
||||||
|
|
||||||
|
if (pt2->x < pt1->x)
|
||||||
|
{
|
||||||
|
exchange(edgeRec *, pt1, pt2);
|
||||||
|
}
|
||||||
|
ix1 = pt1->x;
|
||||||
|
ix2 = pt2->x;
|
||||||
|
idx = ix2 - ix1;
|
||||||
|
if (idx == 0)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
do
|
||||||
|
{
|
||||||
|
__imlib_draw_set_point(im, ix1, y, r, g, b, a, op);
|
||||||
|
ix1++;
|
||||||
|
}
|
||||||
|
while (ix1 < ix2);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
span_clipped(ImlibImage * im, int y, edgeRec * pt1, edgeRec * pt2,
|
||||||
|
int clip_xmin, int clip_xmax, int clip_ymin, int clip_ymax,
|
||||||
|
DATA8 r, DATA8 g, DATA8 b, DATA8 a, ImlibOp op)
|
||||||
|
{
|
||||||
|
int idx, ix1, ix2;
|
||||||
|
|
||||||
|
if (pt2->x < pt1->x)
|
||||||
|
{
|
||||||
|
exchange(edgeRec *, pt1, pt2);
|
||||||
|
}
|
||||||
|
ix1 = pt1->x;
|
||||||
|
ix2 = pt2->x;
|
||||||
|
idx = ix2 - ix1;
|
||||||
|
if (idx == 0)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
do
|
||||||
|
{
|
||||||
|
__imlib_draw_set_point_clipped(im, ix1, y, clip_xmin, clip_xmax,
|
||||||
|
clip_ymin, clip_ymax, r, g, b, a, op);
|
||||||
|
ix1++;
|
||||||
|
}
|
||||||
|
while (ix1 < ix2);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
__imlib_draw_polygon_filled(ImlibImage * im, ImlibPoly poly, DATA8 r, DATA8 g,
|
||||||
|
DATA8 b, DATA8 a, ImlibOp op)
|
||||||
|
{
|
||||||
|
long maxy, miny;
|
||||||
|
int iy1, iy2;
|
||||||
|
int imaxy, iminy;
|
||||||
|
int pnt1, pnt2;
|
||||||
|
int i;
|
||||||
|
edgeRec *table1, *table2;
|
||||||
|
|
||||||
|
if (poly->pointcount < 3)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
table1 = malloc(sizeof(edgeRec) * im->h);
|
||||||
|
table2 = malloc(sizeof(edgeRec) * im->h);
|
||||||
|
|
||||||
|
maxy = miny = poly->points[0].y;
|
||||||
|
imaxy = iminy = 0;
|
||||||
|
for (i = 1; i < poly->pointcount; i++)
|
||||||
|
{
|
||||||
|
if (poly->points[i].y > maxy)
|
||||||
|
{
|
||||||
|
maxy = poly->points[i].y;
|
||||||
|
imaxy = i;
|
||||||
|
}
|
||||||
|
if (poly->points[i].y < miny)
|
||||||
|
{
|
||||||
|
miny = poly->points[i].y;
|
||||||
|
iminy = i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
iy1 = miny;
|
||||||
|
iy2 = maxy;
|
||||||
|
if (iy1 == iy2)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
pnt1 = iminy;
|
||||||
|
pnt2 = iminy + 1;
|
||||||
|
if (pnt2 >= poly->pointcount)
|
||||||
|
{
|
||||||
|
pnt2 = 0;
|
||||||
|
}
|
||||||
|
do
|
||||||
|
{
|
||||||
|
edge(table1, &poly->points[pnt1], &poly->points[pnt2]);
|
||||||
|
pnt1 = pnt2;
|
||||||
|
pnt2 = pnt2 + 1;
|
||||||
|
if (pnt2 >= poly->pointcount)
|
||||||
|
{
|
||||||
|
pnt2 = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
while (pnt1 != imaxy);
|
||||||
|
pnt1 = imaxy;
|
||||||
|
pnt2 = imaxy + 1;
|
||||||
|
if (pnt2 >= poly->pointcount)
|
||||||
|
{
|
||||||
|
pnt2 = 0;
|
||||||
|
}
|
||||||
|
do
|
||||||
|
{
|
||||||
|
edge(table2, &poly->points[pnt1], &poly->points[pnt2]);
|
||||||
|
pnt1 = pnt2;
|
||||||
|
pnt2 = pnt2 + 1;
|
||||||
|
if (pnt2 >= poly->pointcount)
|
||||||
|
{
|
||||||
|
pnt2 = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
while (pnt1 != iminy);
|
||||||
|
do
|
||||||
|
{
|
||||||
|
span(im, iy1, &table1[iy1], &table2[iy1], r, g, b, a, op);
|
||||||
|
iy1++;
|
||||||
|
}
|
||||||
|
while (iy1 < iy2);
|
||||||
|
free(table1);
|
||||||
|
free(table2);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
__imlib_draw_polygon_filled_clipped(ImlibImage * im, ImlibPoly poly,
|
||||||
|
int clip_xmin, int clip_xmax,
|
||||||
|
int clip_ymin, int clip_ymax, DATA8 r,
|
||||||
|
DATA8 g, DATA8 b, DATA8 a, ImlibOp op)
|
||||||
|
{
|
||||||
|
long maxy, miny;
|
||||||
|
int iy1, iy2;
|
||||||
|
int imaxy, iminy;
|
||||||
|
int pnt1, pnt2;
|
||||||
|
int i;
|
||||||
|
edgeRec *table1, *table2;
|
||||||
|
|
||||||
|
if (poly->pointcount < 3)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
table1 = malloc(sizeof(edgeRec) * im->h);
|
||||||
|
table2 = malloc(sizeof(edgeRec) * im->h);
|
||||||
|
|
||||||
|
maxy = miny = poly->points[0].y;
|
||||||
|
imaxy = iminy = 0;
|
||||||
|
for (i = 1; i < poly->pointcount; i++)
|
||||||
|
{
|
||||||
|
if (poly->points[i].y > maxy)
|
||||||
|
{
|
||||||
|
maxy = poly->points[i].y;
|
||||||
|
imaxy = i;
|
||||||
|
}
|
||||||
|
if (poly->points[i].y < miny)
|
||||||
|
{
|
||||||
|
miny = poly->points[i].y;
|
||||||
|
iminy = i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
iy1 = miny;
|
||||||
|
iy2 = maxy;
|
||||||
|
if (iy1 == iy2)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
pnt1 = iminy;
|
||||||
|
pnt2 = iminy + 1;
|
||||||
|
if (pnt2 >= poly->pointcount)
|
||||||
|
{
|
||||||
|
pnt2 = 0;
|
||||||
|
}
|
||||||
|
do
|
||||||
|
{
|
||||||
|
edge(table1, &poly->points[pnt1], &poly->points[pnt2]);
|
||||||
|
pnt1 = pnt2;
|
||||||
|
pnt2 = pnt2 + 1;
|
||||||
|
if (pnt2 >= poly->pointcount)
|
||||||
|
{
|
||||||
|
pnt2 = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
while (pnt1 != imaxy);
|
||||||
|
pnt1 = imaxy;
|
||||||
|
pnt2 = imaxy + 1;
|
||||||
|
if (pnt2 >= poly->pointcount)
|
||||||
|
{
|
||||||
|
pnt2 = 0;
|
||||||
|
}
|
||||||
|
do
|
||||||
|
{
|
||||||
|
edge(table2, &poly->points[pnt1], &poly->points[pnt2]);
|
||||||
|
pnt1 = pnt2;
|
||||||
|
pnt2 = pnt2 + 1;
|
||||||
|
if (pnt2 >= poly->pointcount)
|
||||||
|
{
|
||||||
|
pnt2 = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
while (pnt1 != iminy);
|
||||||
|
do
|
||||||
|
{
|
||||||
|
span_clipped(im, iy1, &table1[iy1], &table2[iy1], clip_xmin, clip_xmax,
|
||||||
|
clip_ymin, clip_ymax, r, g, b, a, op);
|
||||||
|
iy1++;
|
||||||
|
}
|
||||||
|
while (iy1 < iy2);
|
||||||
|
free(table1);
|
||||||
|
free(table2);
|
||||||
|
}
|
||||||
|
|
|
@ -108,4 +108,12 @@ __imlib_draw_ellipse_clipped(ImlibImage * im, int xc, int yc, int aa, int bb,
|
||||||
int clip_xmin, int clip_xmax, int clip_ymin,
|
int clip_xmin, int clip_xmax, int clip_ymin,
|
||||||
int clip_ymax, DATA8 r, DATA8 g, DATA8 b,
|
int clip_ymax, DATA8 r, DATA8 g, DATA8 b,
|
||||||
DATA8 a, ImlibOp op);
|
DATA8 a, ImlibOp op);
|
||||||
|
void
|
||||||
|
__imlib_draw_polygon_filled(ImlibImage * im, ImlibPoly poly, DATA8 r, DATA8 g,
|
||||||
|
DATA8 b, DATA8 a, ImlibOp op);
|
||||||
|
void
|
||||||
|
__imlib_draw_polygon_filled_clipped(ImlibImage * im, ImlibPoly poly,
|
||||||
|
int clip_xmin, int clip_xmax,
|
||||||
|
int clip_ymin, int clip_ymax, DATA8 r,
|
||||||
|
DATA8 g, DATA8 b, DATA8 a, ImlibOp op);
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -295,7 +295,7 @@ int main (int argc, char **argv)
|
||||||
sec1=(int)timev.tv_sec; /* and stores it so we can time outselves */
|
sec1=(int)timev.tv_sec; /* and stores it so we can time outselves */
|
||||||
usec1=(int)timev.tv_usec; /* we will use this to vary speed of rot */
|
usec1=(int)timev.tv_usec; /* we will use this to vary speed of rot */
|
||||||
|
|
||||||
poly = imlib_polygon_new(POLY_CLOSED);
|
poly = imlib_polygon_new(POLY_FILLED);
|
||||||
imlib_polygon_add_point(poly, 400,50);
|
imlib_polygon_add_point(poly, 400,50);
|
||||||
imlib_polygon_add_point(poly, 450,100);
|
imlib_polygon_add_point(poly, 450,100);
|
||||||
imlib_polygon_add_point(poly, 350,100);
|
imlib_polygon_add_point(poly, 350,100);
|
||||||
|
@ -309,7 +309,7 @@ int main (int argc, char **argv)
|
||||||
imlib_polygon_add_point(poly3, 400,250);
|
imlib_polygon_add_point(poly3, 400,250);
|
||||||
imlib_polygon_add_point(poly3, 450,300);
|
imlib_polygon_add_point(poly3, 450,300);
|
||||||
imlib_polygon_add_point(poly3, 350,300);
|
imlib_polygon_add_point(poly3, 350,300);
|
||||||
|
|
||||||
if (loop)
|
if (loop)
|
||||||
{
|
{
|
||||||
printf("loop\n");
|
printf("loop\n");
|
||||||
|
@ -848,8 +848,9 @@ int main (int argc, char **argv)
|
||||||
imlib_context_set_cliprect(0,0,0,0);
|
imlib_context_set_cliprect(0,0,0,0);
|
||||||
|
|
||||||
/* test polygons */
|
/* test polygons */
|
||||||
imlib_context_set_color(255, 255, 255, 255);
|
imlib_context_set_color(255, 0, 0, 255);
|
||||||
imlib_image_draw_polygon(poly);
|
imlib_image_draw_polygon(poly);
|
||||||
|
imlib_context_set_color(255, 255, 255, 255);
|
||||||
imlib_image_draw_polygon(poly2);
|
imlib_image_draw_polygon(poly2);
|
||||||
imlib_image_draw_polygon(poly3);
|
imlib_image_draw_polygon(poly3);
|
||||||
imlib_image_draw_rectangle(380,260,50,50);
|
imlib_image_draw_rectangle(380,260,50,50);
|
||||||
|
|
Loading…
Reference in New Issue