From: Matthias Kramm Date: Fri, 29 May 2009 03:19:32 +0000 (-0700) Subject: implemented stroke merging X-Git-Tag: version-0-9-1~342 X-Git-Url: http://git.asbjorn.biz/?p=swftools.git;a=commitdiff_plain;h=34ea6c36c2a3377546d0e8038f0d4f43b5e3cb6f implemented stroke merging --- diff --git a/lib/gfxpoly/convert.c b/lib/gfxpoly/convert.c index 9cd560c..9f54542 100644 --- a/lib/gfxpoly/convert.c +++ b/lib/gfxpoly/convert.c @@ -133,7 +133,7 @@ void finish_segment(compactpoly_t*data) gfxpolystroke_t*s = rfx_calloc(sizeof(gfxpolystroke_t)); s->next = data->poly->strokes; data->poly->strokes = s; - s->num_points = data->num_points; + s->num_points = s->points_size = data->num_points; s->dir = data->dir; s->points = p; assert(data->dir != DIR_UNKNOWN); diff --git a/lib/gfxpoly/poly.c b/lib/gfxpoly/poly.c index 2b55041..226584a 100644 --- a/lib/gfxpoly/poly.c +++ b/lib/gfxpoly/poly.c @@ -136,7 +136,8 @@ typedef struct _status { windrule_t*windrule; windcontext_t*context; segment_t*ending_segments; - polywriter_t writer; + + gfxpolystroke_t*strokes; #ifdef CHECKS dict_t*seen_crossings; //list of crossing we saw so far dict_t*intersecting_segs; //list of segments intersecting in this scanline @@ -647,13 +648,38 @@ static void insert_point_into_segment(status_t*status, segment_t*s, point_t p) fprintf(stderr, "[%d] receives next point (%d,%d)->(%d,%d) (drawing)\n", s->nr, s->pos.x, s->pos.y, p.x, p.y); #endif + /* XXX we probably will never output circular/anticircular polygons, but if + we do, we would need to set the segment direction here */ + fillstyle_t*fs = s->fs_out; + // omit horizontal lines if(s->pos.y != p.y) { point_t a = s->pos; point_t b = p; assert(a.y != b.y); - status->writer.moveto(&status->writer, a.x, a.y); - status->writer.lineto(&status->writer, b.x, b.y); + + gfxpolystroke_t*stroke = status->strokes; + while(stroke) { + point_t p = stroke->points[stroke->num_points-1]; + if(p.x == a.x && p.y == a.y && stroke->fs == fs) + break; + stroke = stroke->next; + } + if(!stroke) { + stroke = rfx_calloc(sizeof(gfxpolystroke_t)); + stroke->dir = DIR_DOWN; + stroke->fs = fs; + stroke->next = status->strokes; + status->strokes = stroke; + stroke->points_size = 2; + stroke->points = rfx_calloc(sizeof(point_t)*stroke->points_size); + stroke->points[0] = a; + stroke->num_points = 1; + } else if(stroke->num_points == stroke->points_size) { + stroke->points_size *= 2; + stroke->points = rfx_realloc(stroke->points, sizeof(point_t)*stroke->points_size); + } + stroke->points[stroke->num_points++] = b; } } else { #ifdef DEBUG @@ -1195,8 +1221,6 @@ gfxpoly_t* gfxpoly_process(gfxpoly_t*poly, windrule_t*windrule, windcontext_t*co status.windrule = windrule; status.context = context; status.actlist = actlist_new(); - gfxpolywriter_init(&status.writer); - status.writer.setgridsize(&status.writer, poly->gridsize); #ifdef CHECKS status.seen_crossings = dict_new2(&point_type); @@ -1254,8 +1278,11 @@ gfxpoly_t* gfxpoly_process(gfxpoly_t*poly, windrule_t*windrule, windcontext_t*co queue_destroy(&status.queue); xrow_destroy(status.xrow); - gfxpoly_t*p = (gfxpoly_t*)status.writer.finish(&status.writer); + gfxpoly_t*p = (gfxpoly_t*)malloc(sizeof(gfxpoly_t)); + p->gridsize = poly->gridsize; + p->strokes = status.strokes; + gfxpoly_dump(p); add_horizontals(p, &windrule_evenodd, context); // output is always even/odd return p; } diff --git a/lib/gfxpoly/poly.h b/lib/gfxpoly/poly.h index fc825b4..186075a 100644 --- a/lib/gfxpoly/poly.h +++ b/lib/gfxpoly/poly.h @@ -6,7 +6,7 @@ #include "../types.h" //#define DEBUG -#define CHECKS +//#define CHECKS /* features */ #define SPLAY @@ -48,6 +48,7 @@ typedef struct _windrule typedef struct _gfxpolystroke { segment_dir_t dir; + int points_size; int num_points; point_t*points; fillstyle_t*fs; diff --git a/lib/gfxpoly/test.c b/lib/gfxpoly/test.c index a6a5ab5..c58c3d5 100644 --- a/lib/gfxpoly/test.c +++ b/lib/gfxpoly/test.c @@ -139,7 +139,7 @@ int test_speed() { //gfxline_t* b = mkchessboard(); //gfxline_t* b = mkrandomshape(100,7); - gfxline_t* b = make_circles(100); + gfxline_t* b = make_circles(30); gfxmatrix_t m; memset(&m, 0, sizeof(gfxmatrix_t)); @@ -439,21 +439,33 @@ void test4(int argn, char*argv[]) #include "../gfxdevice.h" #include "../pdf/pdf.h" +static int max_segments = 0; +static int max_any_segments = 0; void extract_polygons_fill(gfxdevice_t*dev, gfxline_t*line, gfxcolor_t*color) { //gfxpoly_t*c = gfxpoly_from_gfxline(line, 0.05); //gfxpoly_free(c); + //gfxpoly_t*poly1 = gfxpoly_from_gfxline(line, 0.05); gfxpoly_t*poly1 = gfxpoly_from_gfxline(line, 0.05); //gfxline_dump(line, stderr, ""); //gfxpoly_dump(poly); - if(gfxpoly_size(poly1)>100000) { - fprintf(stderr, "%d segments (skipping)\n", gfxpoly_size(poly1)); + int size = gfxpoly_size(poly1); + if(size == 4) { + //rectangles are boring. + gfxpoly_destroy(poly1); + return; + } + + max_any_segments = size > max_any_segments? size : max_any_segments; + if(size>100000) { + fprintf(stderr, "%d segments (skipping)\n", size); return; } else { - //fprintf(stderr, "%d segments\n", gfxpoly_size(poly)); + max_segments = size > max_segments? size : max_segments; + fprintf(stderr, "%d segments (max so far: %d/%d)\n", size, max_segments, max_any_segments); } if(!gfxpoly_check(poly1)) {