From 9cef1b43083c70a5fb7c738e0aaae1b130d8038e Mon Sep 17 00:00:00 2001 From: Tom Gilbert Date: Fri, 15 Sep 2000 23:22:53 +0000 Subject: [PATCH] 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 --- src/rgbadraw.c | 161 +++++++++++++++++------------------------- src/rgbadraw.h | 185 ++++++++++++++++++++++++++++--------------------- 2 files changed, 169 insertions(+), 177 deletions(-) diff --git a/src/rgbadraw.c b/src/rgbadraw.c index 1a094ea..d1011d6 100644 --- a/src/rgbadraw.c +++ b/src/rgbadraw.c @@ -1848,9 +1848,9 @@ __imlib_fill_ellipse_clipped(ImlibImage * im, int xc, int yc, int aa, int bb, for (i = y1; i <= y2; i++) { 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) - __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) @@ -1871,9 +1871,9 @@ __imlib_fill_ellipse_clipped(ImlibImage * im, int xc, int yc, int aa, int bb, for (i = y1; i <= y2; i++) { 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) - __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) @@ -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 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, 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; ix2 = pt2->x; - idx = ix2 - ix1; - if (idx == 0) + if (ix1 == ix2) { return; } 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++; } 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 __imlib_draw_polygon_filled(ImlibImage * im, ImlibPoly poly, int clip_xmin, 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); + /* 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) + __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 */ - if (iy1 < clip_ymin) - iy1 = clip_ymin; - 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); + /* fill spans */ + span(im, iy1, &table1[iy1], &table2[iy1], r, g, b, a, op); + iy1++; } + while (iy1 < iy2); free(table1); 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 __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; } -/* 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 __imlib_point_delta_from_line(int p_x, int p_y, int s1_x, int s1_y, int s2_x, int s2_y) diff --git a/src/rgbadraw.h b/src/rgbadraw.h index 227d797..5427acd 100644 --- a/src/rgbadraw.h +++ b/src/rgbadraw.h @@ -14,26 +14,46 @@ \ if (y > py2) \ 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 -{ - int x,y; +{ + int x, y; }; -typedef struct _imlib_rectangle Imlib_Rectangle; +typedef struct _imlib_rectangle Imlib_Rectangle; struct _imlib_rectangle { - int x,y,w,h; + int x, y, w, h; }; typedef struct _imlib_polygon _ImlibPoly; -typedef _ImlibPoly * ImlibPoly; +typedef _ImlibPoly *ImlibPoly; struct _imlib_polygon { @@ -48,83 +68,88 @@ ImlibPoly __imlib_polygon_new(void); typedef unsigned int ImlibOutCode; enum { TOP = 0x1, BOTTOM = 0x2, RIGHT = 0x4, LEFT = 0x8 }; + #define TRUE 1 #define FALSE 0 -void __imlib_FlipImageHoriz(ImlibImage *im); -void __imlib_FlipImageVert(ImlibImage *im); -void __imlib_FlipImageBoth(ImlibImage *im); -void __imlib_FlipImageDiagonal(ImlibImage *im, int direction); -void __imlib_BlurImage(ImlibImage *im, int rad); -void __imlib_SharpenImage(ImlibImage *im, int rad); -void __imlib_TileImageHoriz(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); -void __imlib_draw_box(ImlibImage *im, int x, int y, int w, int h, DATA8 r, DATA8 g, DATA8 b, DATA8 a, ImlibOp op); -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_filled_box(ImlibImage *im, int x, int y, int w, int h, DATA8 r, DATA8 g, DATA8 b, DATA8 a, ImlibOp op); -void __imlib_copy_image_data(ImlibImage *im, int x, int y, int w, int h, int nx, int ny); -void __imlib_copy_alpha_data(ImlibImage *src, ImlibImage *dst, int x, int y, int w, int h, int nx, int ny); -ImlibOutCode __imlib_comp_outcode(double x, double y, double xmin, double xmax, - double ymin, double ymax); -void -__imlib_draw_polygon(ImlibImage * im, ImlibPoly poly, unsigned char closed, DATA8 r, DATA8 g, - DATA8 b, DATA8 a, ImlibOp op); -ImlibUpdate * -__imlib_draw_line_clipped(ImlibImage * im, int x1, int y1, int x2, int y2, - int clip_xmin, int clip_xmax, int clip_ymin, - int clip_ymax, DATA8 r, DATA8 g, DATA8 b, DATA8 a, - ImlibOp op, char make_updates); -void -__imlib_draw_box_clipped(ImlibImage * im, int x, int y, int w, int h, - int clip_xmin, int clip_xmax, int clip_ymin, - int clip_ymax, DATA8 r, DATA8 g, DATA8 b, DATA8 a, - ImlibOp op); -void -__imlib_draw_polygon_clipped(ImlibImage * im, ImlibPoly poly, unsigned char closed, int clip_xmin, - int clip_xmax, int clip_ymin, int clip_ymax, DATA8 r, DATA8 g, DATA8 b, - DATA8 a, ImlibOp op); -void __imlib_polygon_get_bounds(ImlibPoly poly, int *px1, int *py1, int *px2, int *py2); -void -__imlib_draw_set_point(ImlibImage * im, int x, int y, DATA8 r, DATA8 g, - DATA8 b, DATA8 a, ImlibOp op); -void -__imlib_draw_set_point_clipped(ImlibImage * im, int x, int y, int clip_xmin, - int clip_xmax, int clip_ymin, int clip_ymax, - DATA8 r, DATA8 g, DATA8 b, DATA8 a, ImlibOp op); -void -__imlib_draw_ellipse(ImlibImage * im, int xc, int yc, int aa, int bb, DATA8 r, - DATA8 g, DATA8 b, DATA8 a, ImlibOp op); -void -__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_ymax, DATA8 r, DATA8 g, DATA8 b, - DATA8 a, ImlibOp op); -void -__imlib_draw_polygon_filled(ImlibImage * im, ImlibPoly poly, +void __imlib_FlipImageHoriz(ImlibImage * im); +void __imlib_FlipImageVert(ImlibImage * im); +void __imlib_FlipImageBoth(ImlibImage * im); +void __imlib_FlipImageDiagonal(ImlibImage * im, int direction); +void __imlib_BlurImage(ImlibImage * im, int rad); +void __imlib_SharpenImage(ImlibImage * im, int rad); +void __imlib_TileImageHoriz(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); +void __imlib_draw_box(ImlibImage * im, int x, int y, int w, int h, DATA8 r, + DATA8 g, DATA8 b, DATA8 a, ImlibOp op); +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_filled_box(ImlibImage * im, int x, int y, int w, int h, + DATA8 r, DATA8 g, DATA8 b, DATA8 a, ImlibOp op); +void __imlib_copy_image_data(ImlibImage * im, int x, int y, int w, int h, + int nx, int ny); +void __imlib_copy_alpha_data(ImlibImage * src, ImlibImage * dst, int x, int y, + int w, int h, int nx, int ny); +ImlibOutCode __imlib_comp_outcode(double x, double y, double xmin, + double xmax, double ymin, double ymax); +void __imlib_draw_polygon(ImlibImage * im, ImlibPoly poly, + unsigned char closed, DATA8 r, DATA8 g, DATA8 b, + DATA8 a, ImlibOp op); +ImlibUpdate *__imlib_draw_line_clipped(ImlibImage * im, int x1, int y1, + int x2, int y2, int clip_xmin, + int clip_xmax, int clip_ymin, + int clip_ymax, DATA8 r, DATA8 g, + DATA8 b, DATA8 a, ImlibOp op, + + char make_updates); +void __imlib_draw_box_clipped(ImlibImage * im, int x, int y, int w, int h, + int clip_xmin, int clip_xmax, int clip_ymin, + int clip_ymax, DATA8 r, DATA8 g, DATA8 b, + DATA8 a, ImlibOp op); +void __imlib_draw_polygon_clipped(ImlibImage * im, ImlibPoly poly, + unsigned char closed, int clip_xmin, + int clip_xmax, int clip_ymin, int clip_ymax, + DATA8 r, DATA8 g, DATA8 b, DATA8 a, + + ImlibOp op); +void __imlib_polygon_get_bounds(ImlibPoly poly, int *px1, int *py1, int *px2, + + int *py2); +void __imlib_draw_set_point(ImlibImage * im, int x, int y, DATA8 r, DATA8 g, + DATA8 b, DATA8 a, ImlibOp op); +void __imlib_draw_set_point_clipped(ImlibImage * im, int x, int y, int clip_xmin, int clip_xmax, int clip_ymin, int clip_ymax, DATA8 r, DATA8 g, DATA8 b, DATA8 a, ImlibOp op); -void -__imlib_fill_ellipse(ImlibImage * im, int xc, int yc, int aa, int bb, DATA8 r, - DATA8 g, DATA8 b, DATA8 a, ImlibOp op); -void -__imlib_fill_ellipse_clipped(ImlibImage * im, int xc, int yc, int aa, int bb, - int clip_xmin, int clip_xmax, int clip_ymin, - int clip_ymax, DATA8 r, DATA8 g, DATA8 b, - DATA8 a, ImlibOp op); -unsigned char -__imlib_polygon_contains_point(ImlibPoly poly, int x, int y); -unsigned char -__imlib_point_on_segment(int p_x, int p_y, int s1_x, int s1_y, int s2_x, - int s2_y); -unsigned char -__imlib_segments_intersect(int r1_x, int r1_y, int r2_x, int r2_y, int s1_x, - int s1_y, int s2_x, int s2_y); -unsigned char -__imlib_point_inside_segment(int p_x, int p_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 __imlib_draw_ellipse(ImlibImage * im, int xc, int yc, int aa, int bb, + DATA8 r, DATA8 g, DATA8 b, DATA8 a, ImlibOp op); +void __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_ymax, DATA8 r, + DATA8 g, DATA8 b, DATA8 a, ImlibOp op); +void __imlib_draw_polygon_filled(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); +void __imlib_fill_ellipse(ImlibImage * im, int xc, int yc, int aa, int bb, + DATA8 r, DATA8 g, DATA8 b, DATA8 a, ImlibOp op); +void __imlib_fill_ellipse_clipped(ImlibImage * im, int xc, int yc, int aa, + int bb, int clip_xmin, int clip_xmax, + int clip_ymin, int clip_ymax, DATA8 r, + DATA8 g, DATA8 b, DATA8 a, ImlibOp op); +unsigned char __imlib_polygon_contains_point(ImlibPoly poly, int x, int y); +unsigned char __imlib_point_on_segment(int p_x, int p_y, int s1_x, int s1_y, + + int s2_x, int s2_y); +unsigned char __imlib_segments_intersect(int r1_x, int r1_y, int r2_x, + 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