X-Git-Url: http://git.asbjorn.biz/?p=swftools.git;a=blobdiff_plain;f=lib%2Fgfxpoly%2Fpoly.c;h=53b45e258c2fbe0587943d7de2d39d184f086bc2;hp=226584ad199921d1f79abd7d82ad1201ebeb4203;hb=05861649cece70d65e7ba84c3696039c0143ce9c;hpb=34ea6c36c2a3377546d0e8038f0d4f43b5e3cb6f diff --git a/lib/gfxpoly/poly.c b/lib/gfxpoly/poly.c index 226584a..53b45e2 100644 --- a/lib/gfxpoly/poly.c +++ b/lib/gfxpoly/poly.c @@ -3,7 +3,6 @@ #include #include "../mem.h" #include "../types.h" -#include "../q.h" #include "../MD5.h" #include "poly.h" #include "active.h" @@ -20,7 +19,7 @@ void gfxpoly_fail(char*expr, char*file, int line, const char*function) exit(1); } - void*md5 = init_md5(); + void*md5 = initialize_md5(); int s,t; gfxpolystroke_t*stroke = current_polygon->strokes; @@ -69,7 +68,7 @@ static void point_free(void*o) p->y = 0; free(p); } -static type_t point_type = { +type_t point_type = { equals: point_equals, hash: point_hash, dup: point_dup, @@ -146,6 +145,15 @@ typedef struct _status { } status_t; +int gfxpoly_num_segments(gfxpoly_t*poly) +{ + gfxpolystroke_t*stroke = poly->strokes; + int count = 0; + for(;stroke;stroke=stroke->next) { + count++; + } + return count; +} int gfxpoly_size(gfxpoly_t*poly) { int s,t; @@ -159,6 +167,7 @@ int gfxpoly_size(gfxpoly_t*poly) char gfxpoly_check(gfxpoly_t*poly) { + current_polygon = poly; dict_t*d = dict_new2(&point_type); int s,t; gfxpolystroke_t*stroke = poly->strokes; @@ -251,8 +260,8 @@ static void event_dump(event_t*e) } } -static inline max32(int32_t v1, int32_t v2) {return v1>v2?v1:v2;} -static inline min32(int32_t v1, int32_t v2) {return v1v2?v1:v2;} +static inline int32_t min32(int32_t v1, int32_t v2) {return v1nr = segment_count++; #ifdef CHECKS + /* notice: on some systems (with some compilers), for the line + (1073741823,-1073741824)->(1073741823,1073741823) + we get LINE_EQ(s->a, s) == 1. + That's why we now clamp to 26 bit. + */ assert(LINE_EQ(s->a, s) == 0); assert(LINE_EQ(s->b, s) == 0); @@ -371,10 +385,6 @@ static void advance_stroke(queue_t*queue, hqueue_t*hqueue, gfxpolystroke_t*strok } } if(s) { -#ifdef DEBUG - fprintf(stderr, "attaching contingency of stroke %08x to segment [%d] %s\n", - stroke, s, s->delta.y?"":"(horizontal)"); -#endif s->stroke = stroke; s->stroke_pos = pos; } @@ -935,7 +945,8 @@ static void recalculate_windings(status_t*status, segrange_t*range) s->fs_out = status->windrule->diff(&wind, &s->wind); #ifdef DEBUG - fprintf(stderr, "[%d] %s/%d/%s/%s %s\n", s->nr, s->dir==DIR_UP?"up":"down", s->wind.wind_nr, s->wind.is_filled?"fill":"nofill", s->fs_out?"draw":"omit", + fprintf(stderr, "[%d] dir=%s wind=%d wind.filled=%s fs_old/new=%s/%s %s\n", s->nr, s->dir==DIR_UP?"up":"down", s->wind.wind_nr, s->wind.is_filled?"fill":"nofill", + fs_old?"draw":"omit", s->fs_out?"draw":"omit", fs_old!=s->fs_out?"CHANGED":""); #endif assert(!(!s->changed && fs_old!=s->fs_out)); @@ -1202,21 +1213,28 @@ static void add_horizontals(gfxpoly_t*poly, windrule_t*windrule, windcontext_t*c e = hqueue_get(&hqueue); } while(e && y == e->p.y); - assert(!fill); // check that polygon is not bleeding +#ifdef CHECKS + char bleeding = fill; + assert(!bleeding); +#endif } actlist_destroy(actlist); hqueue_destroy(&hqueue); } -gfxpoly_t* gfxpoly_process(gfxpoly_t*poly, windrule_t*windrule, windcontext_t*context) +gfxpoly_t* gfxpoly_process(gfxpoly_t*poly1, gfxpoly_t*poly2, windrule_t*windrule, windcontext_t*context) { - current_polygon = poly; + current_polygon = poly1; status_t status; memset(&status, 0, sizeof(status_t)); queue_init(&status.queue); - gfxpoly_enqueue(poly, &status.queue, 0, /*polygon nr*/0); + gfxpoly_enqueue(poly1, &status.queue, 0, /*polygon nr*/0); + if(poly2) { + assert(poly1->gridsize == poly2->gridsize); + gfxpoly_enqueue(poly2, &status.queue, 0, /*polygon nr*/1); + } status.windrule = windrule; status.context = context; @@ -1279,10 +1297,19 @@ gfxpoly_t* gfxpoly_process(gfxpoly_t*poly, windrule_t*windrule, windcontext_t*co xrow_destroy(status.xrow); gfxpoly_t*p = (gfxpoly_t*)malloc(sizeof(gfxpoly_t)); - p->gridsize = poly->gridsize; + p->gridsize = poly1->gridsize; p->strokes = status.strokes; - gfxpoly_dump(p); add_horizontals(p, &windrule_evenodd, context); // output is always even/odd return p; } + +static windcontext_t twopolygons = {2}; +gfxpoly_t* gfxpoly_intersect(gfxpoly_t*p1, gfxpoly_t*p2) +{ + return gfxpoly_process(p1, p2, &windrule_intersect, &twopolygons); +} +gfxpoly_t* gfxpoly_union(gfxpoly_t*p1, gfxpoly_t*p2) +{ + return gfxpoly_process(p1, p2, &windrule_union, &twopolygons); +}