Lots of changes. Macro-ised the point_on_segment code.

Implemented a span-list clipper.

Inlined the drawing code for span().

Cleaned up and speeded up a couple of drawing funcs.

Polygons filled much faster now. More to do though.


SVN revision: 3480
This commit is contained in:
Tom Gilbert 2000-09-15 23:22:53 +00:00
parent 220207d492
commit 9cef1b4308
2 changed files with 169 additions and 177 deletions

View File

@ -1848,9 +1848,9 @@ __imlib_fill_ellipse_clipped(ImlibImage * im, int xc, int yc, int aa, int bb,
for (i = y1; i <= y2; i++) for (i = y1; i <= y2; i++)
{ {
if ((xc - x) >= clip_xmin && (xc - x) <= clip_xmax) if ((xc - x) >= clip_xmin && (xc - x) <= clip_xmax)
__imlib_draw_set_point(im, xc - x, i, r, g, b, a, op); __imlib_draw_set_point(im, xc - x, i, r, g, b, a, op);
if ((xc + x) >= clip_xmin && (xc + x) <= clip_xmax) if ((xc + x) >= clip_xmin && (xc + x) <= clip_xmax)
__imlib_draw_set_point(im, xc + x, i, r, g, b, a, op); __imlib_draw_set_point(im, xc + x, i, r, g, b, a, op);
} }
if (dec >= 0) if (dec >= 0)
@ -1871,9 +1871,9 @@ __imlib_fill_ellipse_clipped(ImlibImage * im, int xc, int yc, int aa, int bb,
for (i = y1; i <= y2; i++) for (i = y1; i <= y2; i++)
{ {
if ((xc + x) >= clip_xmin && (xc + x) <= clip_xmax) if ((xc + x) >= clip_xmin && (xc + x) <= clip_xmax)
__imlib_draw_set_point(im, xc + x, i, r, g, b, a, op); __imlib_draw_set_point(im, xc + x, i, r, g, b, a, op);
if ((xc - x) >= clip_xmin && (xc - x) <= clip_xmax) if ((xc - x) >= clip_xmin && (xc - x) <= clip_xmax)
__imlib_draw_set_point(im, xc - x, i, r, g, b, a, op); __imlib_draw_set_point(im, xc - x, i, r, g, b, a, op);
} }
if (dec >= 0) if (dec >= 0)
@ -1996,20 +1996,6 @@ __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 static void
edge(edgeRec * table, ImlibPoint * pt1, ImlibPoint * pt2) edge(edgeRec * table, ImlibPoint * pt1, ImlibPoint * pt2)
{ {
@ -2042,59 +2028,42 @@ static void
span(ImlibImage * im, int y, edgeRec * pt1, edgeRec * pt2, DATA8 r, DATA8 g, span(ImlibImage * im, int y, edgeRec * pt1, edgeRec * pt2, DATA8 r, DATA8 g,
DATA8 b, DATA8 a, ImlibOp op) DATA8 b, DATA8 a, ImlibOp op)
{ {
int idx, ix1, ix2; int ix1, ix2;
DATA32 *p;
int tmp;
if (pt2->x < pt1->x)
{
exchange(edgeRec *, pt1, pt2);
}
ix1 = pt1->x; ix1 = pt1->x;
ix2 = pt2->x; ix2 = pt2->x;
idx = ix2 - ix1; if (ix1 == ix2)
if (idx == 0)
{ {
return; return;
} }
do do
{ {
__imlib_draw_set_point(im, ix1, y, r, g, b, a, op); p = &(im->data[(im->w * y) + ix1]);
switch (op)
{
case OP_RESHADE:
BLEND_RE(r, g, b, a, p);
break;
case OP_SUBTRACT:
BLEND_SUB(r, g, b, a, p);
break;
case OP_ADD:
BLEND_ADD(r, g, b, a, p);
break;
case OP_COPY:
BLEND(r, g, b, a, p);
break;
default:
break;
}
ix1++; ix1++;
} }
while (ix1 < ix2); 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;
/* clip x, y is clipped for us by the caller */
if (ix1 < clip_xmin)
ix1 = clip_xmin;
if (ix2 > clip_xmax)
ix2 = clip_xmax;
do
{
__imlib_draw_set_point(im, ix1, y, r, g, b, a, op);
ix1++;
}
while (ix1 < ix2);
}
void void
__imlib_draw_polygon_filled(ImlibImage * im, ImlibPoly poly, int clip_xmin, __imlib_draw_polygon_filled(ImlibImage * im, ImlibPoly poly, int clip_xmin,
int clip_xmax, int clip_ymin, int clip_ymax, int clip_xmax, int clip_ymin, int clip_ymax,
@ -2171,35 +2140,51 @@ __imlib_draw_polygon_filled(ImlibImage * im, ImlibPoly poly, int clip_xmin,
} }
while (pnt1 != iminy); while (pnt1 != iminy);
/* clip spans to screen */
__spanlist_clip(table1, table2, &iy1, &iy2, 0, im->w, 0, im->h);
/* clip to clip rect if it's there */
if (clip_xmin != clip_xmax) if (clip_xmin != clip_xmax)
__spanlist_clip(table1, table2, &iy1, &iy2, clip_xmin, clip_xmax,
clip_ymin, clip_ymax);
do
{ {
/* there is a cliprect, don't bother with y outside of it */ /* fill spans */
if (iy1 < clip_ymin) span(im, iy1, &table1[iy1], &table2[iy1], r, g, b, a, op);
iy1 = clip_ymin; iy1++;
if (iy2 > clip_ymax)
iy2 = clip_ymax;
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);
}
else
{
do
{
span(im, iy1, &table1[iy1], &table2[iy1], r, g, b, a, op);
iy1++;
}
while (iy1 < iy2);
} }
while (iy1 < iy2);
free(table1); free(table1);
free(table2); free(table2);
} }
void
__spanlist_clip(edgeRec * table1, edgeRec * table2, int *sy, int *ey,
int xmin, int xmax, int ymin, int ymax)
{
edgeRec *pt1, *pt2;
int iy1, iy2;
iy1 = MAX(*sy, ymin);
iy2 = MIN(*ey, ymax);
*sy = iy1;
*ey = iy2;
do
{
pt1 = &(table1)[iy1];
pt2 = &(table2)[iy1];
if (pt2->x < pt1->x)
SWAP(pt2->x, pt1->x);
pt1->x = MAX(pt1->x, xmin);
pt2->x = MIN(pt2->x, xmax);
iy1++;
}
while (iy1 < iy2);
}
unsigned char unsigned char
__imlib_polygon_contains_point(ImlibPoly poly, int x, int y) __imlib_polygon_contains_point(ImlibPoly poly, int x, int y)
@ -2307,24 +2292,6 @@ __imlib_segments_intersect(int r1_x, int r1_y, int r2_x, int r2_y, int s1_x,
return FALSE; return FALSE;
} }
/* TODO this could prolly be a macro */
unsigned char
__imlib_point_inside_segment(int p_x, int p_y, int s1_x, int s1_y, int s2_x,
int s2_y)
{
/* Check if p lies on segment [ s1, s2 ] given that
it lies on the line defined by s1 and s2. */
if (s1_y != s2_y)
{
if (p_y <= MAX(s1_y, s2_y) && p_y >= MIN(s1_y, s2_y))
return TRUE;
}
else if (p_x <= MAX(s1_x, s2_x) && p_x >= MIN(s1_x, s2_x))
return TRUE;
return FALSE;
}
double double
__imlib_point_delta_from_line(int p_x, int p_y, int s1_x, int s1_y, int s2_x, __imlib_point_delta_from_line(int p_x, int p_y, int s1_x, int s1_y, int s2_x,
int s2_y) int s2_y)

View File

@ -14,26 +14,46 @@
\ \
if (y > py2) \ if (y > py2) \
py2 = y; \ py2 = y; \
} }
#define exchange(type, a, b) \
{ \
type _t_; \
_t_ = a; \
a = b; \
b = _t_; \
}
typedef struct _imlib_point ImlibPoint; /* Check if p lies on segment [ s1, s2 ] given that
it lies on the line defined by s1 and s2. */
#define __imlib_point_inside_segment(p_x, p_y, s1_x, s1_y, s2_x,s2_y) \
(s1_y != s2_y) ? (p_y <= MAX(s1_y, s2_y) && p_y >= MIN(s1_y, s2_y)) : (p_x <= MAX(s1_x, s2_x) && p_x >= MIN(s1_x, s2_x))
#define SWAP(a,b) {int _tmp_; _tmp_ = a; a = b; b = _tmp_;}
typedef struct _edgerec
{
int x;
}
edgeRec;
typedef struct _imlib_point ImlibPoint;
struct _imlib_point struct _imlib_point
{ {
int x,y; int x, y;
}; };
typedef struct _imlib_rectangle Imlib_Rectangle; typedef struct _imlib_rectangle Imlib_Rectangle;
struct _imlib_rectangle struct _imlib_rectangle
{ {
int x,y,w,h; int x, y, w, h;
}; };
typedef struct _imlib_polygon _ImlibPoly; typedef struct _imlib_polygon _ImlibPoly;
typedef _ImlibPoly * ImlibPoly; typedef _ImlibPoly *ImlibPoly;
struct _imlib_polygon struct _imlib_polygon
{ {
@ -48,83 +68,88 @@ ImlibPoly __imlib_polygon_new(void);
typedef unsigned int ImlibOutCode; typedef unsigned int ImlibOutCode;
enum enum
{ TOP = 0x1, BOTTOM = 0x2, RIGHT = 0x4, LEFT = 0x8 }; { TOP = 0x1, BOTTOM = 0x2, RIGHT = 0x4, LEFT = 0x8 };
#define TRUE 1 #define TRUE 1
#define FALSE 0 #define FALSE 0
void __imlib_FlipImageHoriz(ImlibImage *im); void __imlib_FlipImageHoriz(ImlibImage * im);
void __imlib_FlipImageVert(ImlibImage *im); void __imlib_FlipImageVert(ImlibImage * im);
void __imlib_FlipImageBoth(ImlibImage *im); void __imlib_FlipImageBoth(ImlibImage * im);
void __imlib_FlipImageDiagonal(ImlibImage *im, int direction); void __imlib_FlipImageDiagonal(ImlibImage * im, int direction);
void __imlib_BlurImage(ImlibImage *im, int rad); void __imlib_BlurImage(ImlibImage * im, int rad);
void __imlib_SharpenImage(ImlibImage *im, int rad); void __imlib_SharpenImage(ImlibImage * im, int rad);
void __imlib_TileImageHoriz(ImlibImage *im); void __imlib_TileImageHoriz(ImlibImage * im);
void __imlib_TileImageVert(ImlibImage *im); void __imlib_TileImageVert(ImlibImage * im);
ImlibUpdate * __imlib_draw_line(ImlibImage *im, int x1, int y1, int x2, int y2, DATA8 r, DATA8 g, DATA8 b, DATA8 a, ImlibOp op, char make_updates); ImlibUpdate *__imlib_draw_line(ImlibImage * im, int x1, int y1, int x2,
void __imlib_draw_box(ImlibImage *im, int x, int y, int w, int h, DATA8 r, DATA8 g, DATA8 b, DATA8 a, ImlibOp op); int y2, DATA8 r, DATA8 g, DATA8 b, DATA8 a,
void __imlib_draw_filled_box(ImlibImage *im, int x, int y, int w, int h, DATA8 r, DATA8 g, DATA8 b, DATA8 a, ImlibOp op); ImlibOp op, char make_updates);
void __imlib_draw_filled_box(ImlibImage *im, int x, int y, int w, int h, DATA8 r, DATA8 g, DATA8 b, DATA8 a, ImlibOp op); void __imlib_draw_box(ImlibImage * im, int x, int y, int w, int h, DATA8 r,
void __imlib_copy_image_data(ImlibImage *im, int x, int y, int w, int h, int nx, int ny); DATA8 g, DATA8 b, DATA8 a, ImlibOp op);
void __imlib_copy_alpha_data(ImlibImage *src, ImlibImage *dst, int x, int y, int w, int h, int nx, int ny); void __imlib_draw_filled_box(ImlibImage * im, int x, int y, int w, int h,
ImlibOutCode __imlib_comp_outcode(double x, double y, double xmin, double xmax, DATA8 r, DATA8 g, DATA8 b, DATA8 a, ImlibOp op);
double ymin, double ymax); void __imlib_draw_filled_box(ImlibImage * im, int x, int y, int w, int h,
void DATA8 r, DATA8 g, DATA8 b, DATA8 a, ImlibOp op);
__imlib_draw_polygon(ImlibImage * im, ImlibPoly poly, unsigned char closed, DATA8 r, DATA8 g, void __imlib_copy_image_data(ImlibImage * im, int x, int y, int w, int h,
DATA8 b, DATA8 a, ImlibOp op); int nx, int ny);
ImlibUpdate * void __imlib_copy_alpha_data(ImlibImage * src, ImlibImage * dst, int x, int y,
__imlib_draw_line_clipped(ImlibImage * im, int x1, int y1, int x2, int y2, int w, int h, int nx, int ny);
int clip_xmin, int clip_xmax, int clip_ymin, ImlibOutCode __imlib_comp_outcode(double x, double y, double xmin,
int clip_ymax, DATA8 r, DATA8 g, DATA8 b, DATA8 a, double xmax, double ymin, double ymax);
ImlibOp op, char make_updates); void __imlib_draw_polygon(ImlibImage * im, ImlibPoly poly,
void unsigned char closed, DATA8 r, DATA8 g, DATA8 b,
__imlib_draw_box_clipped(ImlibImage * im, int x, int y, int w, int h, DATA8 a, ImlibOp op);
int clip_xmin, int clip_xmax, int clip_ymin, ImlibUpdate *__imlib_draw_line_clipped(ImlibImage * im, int x1, int y1,
int clip_ymax, DATA8 r, DATA8 g, DATA8 b, DATA8 a, int x2, int y2, int clip_xmin,
ImlibOp op); int clip_xmax, int clip_ymin,
void int clip_ymax, DATA8 r, DATA8 g,
__imlib_draw_polygon_clipped(ImlibImage * im, ImlibPoly poly, unsigned char closed, int clip_xmin, DATA8 b, DATA8 a, ImlibOp op,
int clip_xmax, int clip_ymin, int clip_ymax, DATA8 r, DATA8 g, DATA8 b,
DATA8 a, ImlibOp op); char make_updates);
void __imlib_polygon_get_bounds(ImlibPoly poly, int *px1, int *py1, int *px2, int *py2); void __imlib_draw_box_clipped(ImlibImage * im, int x, int y, int w, int h,
void int clip_xmin, int clip_xmax, int clip_ymin,
__imlib_draw_set_point(ImlibImage * im, int x, int y, DATA8 r, DATA8 g, int clip_ymax, DATA8 r, DATA8 g, DATA8 b,
DATA8 b, DATA8 a, ImlibOp op); DATA8 a, ImlibOp op);
void void __imlib_draw_polygon_clipped(ImlibImage * im, ImlibPoly poly,
__imlib_draw_set_point_clipped(ImlibImage * im, int x, int y, int clip_xmin, unsigned char closed, int clip_xmin,
int clip_xmax, int clip_ymin, int clip_ymax, int clip_xmax, int clip_ymin, int clip_ymax,
DATA8 r, DATA8 g, DATA8 b, DATA8 a, ImlibOp op); DATA8 r, DATA8 g, DATA8 b, DATA8 a,
void
__imlib_draw_ellipse(ImlibImage * im, int xc, int yc, int aa, int bb, DATA8 r, ImlibOp op);
DATA8 g, DATA8 b, DATA8 a, ImlibOp op); void __imlib_polygon_get_bounds(ImlibPoly poly, int *px1, int *py1, int *px2,
void
__imlib_draw_ellipse_clipped(ImlibImage * im, int xc, int yc, int aa, int bb, int *py2);
int clip_xmin, int clip_xmax, int clip_ymin, void __imlib_draw_set_point(ImlibImage * im, int x, int y, DATA8 r, DATA8 g,
int clip_ymax, DATA8 r, DATA8 g, DATA8 b, DATA8 b, DATA8 a, ImlibOp op);
DATA8 a, ImlibOp op); void __imlib_draw_set_point_clipped(ImlibImage * im, int x, int y,
void
__imlib_draw_polygon_filled(ImlibImage * im, ImlibPoly poly,
int clip_xmin, int clip_xmax, int clip_xmin, int clip_xmax,
int clip_ymin, int clip_ymax, DATA8 r, int clip_ymin, int clip_ymax, DATA8 r,
DATA8 g, DATA8 b, DATA8 a, ImlibOp op); DATA8 g, DATA8 b, DATA8 a, ImlibOp op);
void void __imlib_draw_ellipse(ImlibImage * im, int xc, int yc, int aa, int bb,
__imlib_fill_ellipse(ImlibImage * im, int xc, int yc, int aa, int bb, DATA8 r, DATA8 r, DATA8 g, DATA8 b, DATA8 a, ImlibOp op);
DATA8 g, DATA8 b, DATA8 a, ImlibOp op); void __imlib_draw_ellipse_clipped(ImlibImage * im, int xc, int yc, int aa,
void int bb, int clip_xmin, int clip_xmax,
__imlib_fill_ellipse_clipped(ImlibImage * im, int xc, int yc, int aa, int bb, int clip_ymin, int clip_ymax, DATA8 r,
int clip_xmin, int clip_xmax, int clip_ymin, DATA8 g, DATA8 b, DATA8 a, ImlibOp op);
int clip_ymax, DATA8 r, DATA8 g, DATA8 b, void __imlib_draw_polygon_filled(ImlibImage * im, ImlibPoly poly,
DATA8 a, ImlibOp op); int clip_xmin, int clip_xmax, int clip_ymin,
unsigned char int clip_ymax, DATA8 r, DATA8 g, DATA8 b,
__imlib_polygon_contains_point(ImlibPoly poly, int x, int y); DATA8 a, ImlibOp op);
unsigned char void __imlib_fill_ellipse(ImlibImage * im, int xc, int yc, int aa, int bb,
__imlib_point_on_segment(int p_x, int p_y, int s1_x, int s1_y, int s2_x, DATA8 r, DATA8 g, DATA8 b, DATA8 a, ImlibOp op);
int s2_y); void __imlib_fill_ellipse_clipped(ImlibImage * im, int xc, int yc, int aa,
unsigned char int bb, int clip_xmin, int clip_xmax,
__imlib_segments_intersect(int r1_x, int r1_y, int r2_x, int r2_y, int s1_x, int clip_ymin, int clip_ymax, DATA8 r,
int s1_y, int s2_x, int s2_y); DATA8 g, DATA8 b, DATA8 a, ImlibOp op);
unsigned char unsigned char __imlib_polygon_contains_point(ImlibPoly poly, int x, int y);
__imlib_point_inside_segment(int p_x, int p_y, int s1_x, int s1_y, int s2_x, unsigned char __imlib_point_on_segment(int p_x, int p_y, int s1_x, int s1_y,
int s2_y);
double int s2_x, int s2_y);
__imlib_point_delta_from_line(int p_x, int p_y, int s1_x, int s1_y, int s2_x, unsigned char __imlib_segments_intersect(int r1_x, int r1_y, int r2_x,
int s2_y); int r2_y, int s1_x, int s1_y,
int s2_x, int s2_y);
double __imlib_point_delta_from_line(int p_x, int p_y, int s1_x, int s1_y,
int s2_x, int s2_y);
void __spanlist_clip(edgeRec * table1, edgeRec * table2, int *sy, int *ey,
int xmin, int xmax, int ymin, int ymax);
#endif #endif