From 7a5914b9815f05bef144c989cf932af5434d62f8 Mon Sep 17 00:00:00 2001 From: Tony Cook Date: Fri, 24 Jan 2014 21:47:08 +1100 Subject: [PATCH] C level support for filling multiple polygons in one call --- imdatatypes.h | 6 ++ polygon.c | 159 ++++++++++++++++++++++++++++++++++---------------- 2 files changed, 115 insertions(+), 50 deletions(-) diff --git a/imdatatypes.h b/imdatatypes.h index 9d5cf747..c684e58c 100644 --- a/imdatatypes.h +++ b/imdatatypes.h @@ -442,6 +442,12 @@ enum bounding_box_index_t { BOUNDING_BOX_COUNT }; +typedef struct i_polygon_tag { + const double *x; + const double *y; + size_t count; +} i_polygon_t; + /* Generic fills */ struct i_fill_tag; diff --git a/polygon.c b/polygon.c index 38c8f5c0..2a84c8c2 100644 --- a/polygon.c +++ b/polygon.c @@ -20,12 +20,12 @@ typedef i_img_dim pcord; typedef struct { - int n; + size_t n; pcord x,y; } p_point; typedef struct { - int n; + size_t n; pcord x1,y1; pcord x2,y2; pcord miny,maxy; @@ -34,7 +34,7 @@ typedef struct { } p_line; typedef struct { - int n; + size_t n; double x; } p_slice; @@ -81,34 +81,63 @@ p_eval_atx(p_line *l, pcord x) { static p_line * -line_set_new(const double *x, const double *y, int l) { - int i; - p_line *lset = mymalloc(sizeof(p_line) * l); - - for(i=0; icount; j++) { + line->n = n++; + line->x1 = IMTRUNC(p->x[j]); + line->y1 = IMTRUNC(p->y[j]); + line->x2 = IMTRUNC(p->x[(j + 1) % p->count]); + line->y2 = IMTRUNC(p->y[(j + 1) % p->count]); + line->miny = i_min(line->y1, line->y2); + line->maxy = i_max(line->y1, line->y2); + line->minx = i_min(line->x1, line->x2); + line->maxx = i_max(line->x1, line->x2); + ++line; + } } + return lset; } static p_point * -point_set_new(const double *x, const double *y, int l) { - int i; - p_point *pset = mymalloc(sizeof(p_point) * l); +point_set_new(const i_polygon_t *polys, size_t count, size_t *point_count) { + size_t i, j, n; + p_point *pset, *pt; + size_t points = 0; - for(i=0; icount; j++) { + pt->n = n++; + pt->x = IMTRUNC(p->x[j]); + pt->y = IMTRUNC(p->y[j]); + ++pt; + } } return pset; } @@ -209,8 +238,6 @@ mark_updown_slices(p_line *lset, p_slice *tllist, int count) { } } - - static unsigned char saturate(int in) { @@ -404,8 +431,9 @@ render_slice_scanline(ss_scanline *ss, int y, p_line *l, p_line *r, pcord miny, */ -static void -i_poly_aa_low(i_img *im, int l, const double *x, const double *y, void *ctx, scanline_flusher flusher) { +static int +i_poly_poly_aa_low(i_img *im, int count, const i_polygon_t *polys, + void *ctx, scanline_flusher flusher) { int i ,k; /* Index variables */ i_img_dim clc; /* Lines inside current interval */ /* initialize to avoid compiler warnings */ @@ -416,11 +444,16 @@ i_poly_aa_low(i_img *im, int l, const double *x, const double *y, void *ctx, sca p_point *pset; /* List of points in polygon */ p_line *lset; /* List of lines in polygon */ p_slice *tllist; /* List of slices */ + size_t pcount, lcount; - mm_log((1, "i_poly_aa(im %p, l %d, x %p, y %p, ctx %p, flusher %p)\n", im, l, x, y, ctx, flusher)); + mm_log((1, "i_poly_poly_aa_low(im %p, count %d, polys %p, ctx %p, flusher %p)\n", im, count, polys, ctx, flusher)); - for(i=0; icount; i++) { + mm_log((2, " (%.2f, %.2f)\n", p->x[i], p->y[i])); + } } @@ -429,18 +462,17 @@ i_poly_aa_low(i_img *im, int l, const double *x, const double *y, void *ctx, sca setbuf(stdout, NULL); ); - tllist = mymalloc(sizeof(p_slice)*l); - - ss_scanline_init(&templine, im->xsize, l); + pset = point_set_new(polys, count, &pcount); + lset = line_set_new(polys, count, &lcount); - pset = point_set_new(x, y, l); - lset = line_set_new(x, y, l); + ss_scanline_init(&templine, im->xsize, lcount); - - qsort(pset, l, sizeof(p_point), (int(*)(const void *,const void *))p_compy); + tllist = mymalloc(sizeof(p_slice) * lcount); + + qsort(pset, pcount, sizeof(p_point), (int(*)(const void *,const void *))p_compy); POLY_DEB( - for(i=0;i (%d , %d) yspan ( %d , %d )\n", i, lset[i].n, lset[i].x1, lset[i].y1, lset[i].x2, lset[i].y2, lset[i].miny, lset[i].maxy); } @@ -449,7 +481,7 @@ i_poly_aa_low(i_img *im, int l, const double *x, const double *y, void *ctx, sca /* loop on intervals */ - for(i=0; iysize); pcord miny, maxy; /* y bounds in fine coordinates */ @@ -466,7 +498,7 @@ i_poly_aa_low(i_img *im, int l, const double *x, const double *y, void *ctx, sca continue; } - clc = lines_in_interval(lset, l, tllist, pset[i].y, pset[i+1].y); + clc = lines_in_interval(lset, lcount, tllist, pset[i].y, pset[i+1].y); qsort(tllist, clc, sizeof(p_slice), (int(*)(const void *,const void *))p_compx); mark_updown_slices(lset, tllist, clc); @@ -530,14 +562,25 @@ i_poly_aa_low(i_img *im, int l, const double *x, const double *y, void *ctx, sca myfree(pset); myfree(lset); myfree(tllist); - -} /* Function */ + + return 1; +} int -i_poly_aa(i_img *im, int l, const double *x, const double *y, const i_color *val) { +i_poly_poly_aa(i_img *im, int count, const i_polygon_t *polys, + const i_color *val) { i_color c = *val; - i_poly_aa_low(im, l, x, y, &c, scanline_flush); - return 1; + return i_poly_poly_aa_low(im, count, polys, &c, scanline_flush); +} + +int +i_poly_aa(i_img *im, int l, const double *x, const double *y, const i_color *val) { + i_polygon_t poly; + + poly.count = l; + poly.x = x; + poly.y = y; + return i_poly_poly_aa(im, 1, &poly, val); } struct poly_render_state { @@ -572,15 +615,31 @@ scanline_flush_render(i_img *im, ss_scanline *ss, int y, void *ctx) { } int -i_poly_aa_cfill(i_img *im, int l, const double *x, const double *y, - i_fill_t *fill) { +i_poly_poly_aa_cfill(i_img *im, int count, const i_polygon_t *polys, + i_fill_t *fill) { struct poly_render_state ctx; + int result; i_render_init(&ctx.render, im, im->xsize); ctx.fill = fill; ctx.cover = mymalloc(im->xsize); - i_poly_aa_low(im, l, x, y, &ctx, scanline_flush_render); + + result = i_poly_poly_aa_low(im, count, polys, &ctx, scanline_flush_render); + myfree(ctx.cover); i_render_done(&ctx.render); - return 1; + + return result; +} + +int +i_poly_aa_cfill(i_img *im, int l, const double *x, const double *y, + i_fill_t *fill) { + i_polygon_t poly; + + poly.count = l; + poly.x = x; + poly.y = y; + + return i_poly_poly_aa_cfill(im, 1, &poly, fill); } -- 2.39.5