From: Matthias Kramm Date: Fri, 5 Jun 2009 19:51:43 +0000 (+0200) Subject: more bugfixes in stroke code X-Git-Tag: version-0-9-1~333 X-Git-Url: http://git.asbjorn.biz/?p=swftools.git;a=commitdiff_plain;h=3c6c2c2a98a273483285119b9cc0b782aa8a79c8 more bugfixes in stroke code --- diff --git a/lib/gfxpoly/convert.c b/lib/gfxpoly/convert.c index c6e365d..64cef43 100644 --- a/lib/gfxpoly/convert.c +++ b/lib/gfxpoly/convert.c @@ -264,6 +264,7 @@ typedef struct _polydraw_internal { double lx, ly; int32_t lastx, lasty; + int32_t x0, y0; double z; char last; polywriter_t writer; @@ -279,6 +280,8 @@ static void polydraw_moveTo(gfxdrawer_t*d, gfxcoord_t _x, gfxcoord_t _y) } i->lx = _x; i->ly = _y; + i->x0 = x; + i->y0 = y; i->lastx = x; i->lasty = y; i->last = 1; @@ -332,6 +335,21 @@ static void polydraw_splineTo(gfxdrawer_t*d, gfxcoord_t sx, gfxcoord_t sy, gfxco i->lasty = ny; i->last = 1; } +static void polydraw_close(gfxdrawer_t*d) +{ + polydraw_internal_t*i = (polydraw_internal_t*)d->internal; + assert(!(i->last && (i->x0 == INVALID_COORD || i->y0 == INVALID_COORD))); + if(!i->last) + return; + if(i->lastx != i->x0 || i->lasty != i->y0) { + i->writer.lineto(&i->writer, i->x0, i->y0); + i->lastx = i->x0; + i->lasty = i->y0; + } + i->last = 0; + i->x0 = INVALID_COORD; + i->y0 = INVALID_COORD; +} static void* polydraw_result(gfxdrawer_t*d) { polydraw_internal_t*i = (polydraw_internal_t*)d->internal; @@ -347,9 +365,12 @@ void gfxdrawer_target_poly(gfxdrawer_t*d, double gridsize) d->internal = i; i->lastx = INVALID_COORD; // convert_coord can never return this value i->lasty = INVALID_COORD; + i->x0 = INVALID_COORD; + i->y0 = INVALID_COORD; d->moveTo = polydraw_moveTo; d->lineTo = polydraw_lineTo; d->splineTo = polydraw_splineTo; + d->close = polydraw_close; d->result = polydraw_result; gfxpolywriter_init(&i->writer); i->writer.setgridsize(&i->writer, gridsize); @@ -393,6 +414,8 @@ gfxline_t*gfxline_from_gfxpoly(gfxpoly_t*poly) return 0; dict_t*d = dict_new2(&point_type); dict_t*todo = dict_new2(&ptr_type); + gfxpolystroke_t*stroke_min= poly->strokes; + int32_t y_min=stroke_min->points[0].y; for(stroke=poly->strokes;stroke;stroke=stroke->next) { dict_put(todo, stroke, stroke); assert(stroke->num_points>1); @@ -402,12 +425,18 @@ gfxline_t*gfxline_from_gfxpoly(gfxpoly_t*poly) } else { dict_put(d, &stroke->points[0], stroke); } + if(stroke->points[0].y < y_min) { + y_min = stroke->points[0].y; + stroke_min = stroke; + } } gfxpolystroke_t*next_todo = poly->strokes; gfxline_t*l = malloc(sizeof(gfxline_t)*count); count = 0; - stroke = poly->strokes; + stroke = stroke_min; + point_t last = {INVALID_COORD, INVALID_COORD}; + char should_connect = 0; while(stroke) { assert(dict_contains(todo, stroke)); int t; @@ -423,6 +452,7 @@ gfxline_t*gfxline_from_gfxpoly(gfxpoly_t*poly) l[count].type = gfx_moveTo; l[count].next = &l[count+1]; count++; + assert(!should_connect); } pos += incr; for(t=1;tnum_points;t++) { @@ -440,7 +470,9 @@ gfxline_t*gfxline_from_gfxpoly(gfxpoly_t*poly) /* try to find a poly which starts at the point we drew last */ stroke = dict_lookup(d, &last); + should_connect = 1; while(!dict_contains(todo, stroke)) { + should_connect = 0; stroke = next_todo; if(!next_todo) { stroke = 0; diff --git a/lib/gfxpoly/poly.c b/lib/gfxpoly/poly.c index efb51fe..9f7e8e8 100644 --- a/lib/gfxpoly/poly.c +++ b/lib/gfxpoly/poly.c @@ -167,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; diff --git a/lib/gfxpoly/poly.h b/lib/gfxpoly/poly.h index d1d5154..68eec9b 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 diff --git a/lib/gfxpoly/stroke.c b/lib/gfxpoly/stroke.c index 7d5c380..70a51d0 100644 --- a/lib/gfxpoly/stroke.c +++ b/lib/gfxpoly/stroke.c @@ -56,9 +56,6 @@ static void draw_arc(gfxdrawer_t*draw, double x, double y, double a1, double a2, static void draw_single_stroke(gfxpoint_t*p, int num, gfxdrawer_t*draw, double width, gfx_capType cap, gfx_joinType join, double limit) { - char do_draw=0; - leftright_t lastdir = LEFT; - width/=2; if(width<=0) width = 0.05; @@ -134,7 +131,7 @@ static void draw_single_stroke(gfxpoint_t*p, int num, gfxdrawer_t*draw, double w lastw = w; } /* draw stroke ends. We draw duplicates of some points here. The drawer - implementationshould be smart enough to remove them. */ + implementation should be smart enough to remove them. */ double c = cos(lastw-M_PI/2)*width; double s = sin(lastw-M_PI/2)*width; if(cap == gfx_capButt) { @@ -156,6 +153,7 @@ static void draw_single_stroke(gfxpoint_t*p, int num, gfxdrawer_t*draw, double w incr=-1; lastw += M_PI; // for dots } + draw->close(draw); } static void draw_stroke(gfxline_t*start, gfxdrawer_t*draw, double width, gfx_capType cap, gfx_joinType join, double miterLimit) @@ -191,7 +189,8 @@ static void draw_stroke(gfxline_t*start, gfxdrawer_t*draw, double width, gfx_cap pos = 0; while(line) { if(line->type == gfx_moveTo) { - if(pos) draw_single_stroke(points, pos, draw, width, cap, join, miterLimit); + if(pos) + draw_single_stroke(points, pos, draw, width, cap, join, miterLimit); pos = 0; } else if(line->type == gfx_splineTo) { int parts = (int)(sqrt(fabs(line->x-2*line->sx+lastx) + fabs(line->y-2*line->sy+lasty))*SUBFRACTION); diff --git a/lib/gfxpoly/test.c b/lib/gfxpoly/test.c index 6530340..b5c192a 100644 --- a/lib/gfxpoly/test.c +++ b/lib/gfxpoly/test.c @@ -6,6 +6,7 @@ #include "poly.h" #include "convert.h" #include "renderpoly.h" +#include "stroke.h" gfxline_t*mkstar(int x1, int y1, int x2, int y2) { @@ -172,6 +173,8 @@ int test0(int argn, char*argv[]) gfxline_t*box3 = gfxline_makerectangle(-100,-100,100,100); //gfxline_append(box2, box3); + gfxpoly_check(gfxpoly_from_stroke(box1, 2.0, gfx_capRound, gfx_joinRound, 0, 0.05)); + gfxmatrix_t matrix; memset(&matrix, 0, sizeof(gfxmatrix_t)); double ua=M_PI/4; diff --git a/lib/gfxpoly/test_stroke.c b/lib/gfxpoly/test_stroke.c index faaff03..b05d710 100644 --- a/lib/gfxpoly/test_stroke.c +++ b/lib/gfxpoly/test_stroke.c @@ -11,6 +11,7 @@ int main() gfxdevice_t dev; gfxdevice_swf_init(&dev); dev.setparameter(&dev, "framerate", "25.0"); + dev.setparameter(&dev, "disable_polygon_conversion", "1"); int t; for(t=0;t<300;t++) { dev.startpage(&dev, 700,700); @@ -80,14 +81,14 @@ int main() //gfxpoly_t*p2 = gfxpoly_from_fill(f, 0.05); gfxline_t*l2 = gfxline_clone(l); - double c = cos(t*M_PI/75); - double s = sin(t*M_PI/75); + double c = cos(t*M_PI/50.0); + double s = sin(t*M_PI/50.0); static int x1 = 0, xdir = 1; static int y1 = 0, ydir = 5; - x1+=xdir; if(x1>=150) {x1=300-x1;xdir=-xdir;} if(x1<-150) {x1=-300-x1;xdir=-xdir;} - y1+=ydir; if(y1>=150) {y1=300-y1;ydir=-ydir;} if(y1<-150) {y1=-300-y1;ydir=-ydir;} - gfxmatrix_t m = { c, s, -(350+x1)*c-350*s+350, - -s, c, 350*s-(350+x1)*c+350}; + x1 = sin(t*M_PI/60.0)*50; + y1 = -sin(t*M_PI/50.0)*50; + gfxmatrix_t m = { c, s, -(350+x1)*c-(350+y1)*s+350, + s, -c, -(350+x1)*s+(350+y1)*c+350}; gfxline_transform(l2, &m); gfxpoly_t*p2 = gfxpoly_from_stroke(l2, width, gfx_capRound, gfx_joinRound, 500, 0.05); assert(gfxpoly_check(p2)); diff --git a/lib/gfxtools.c b/lib/gfxtools.c index f754379..a206e57 100644 --- a/lib/gfxtools.c +++ b/lib/gfxtools.c @@ -33,6 +33,7 @@ typedef struct _linedraw_internal { gfxline_t*start; gfxline_t*next; + gfxcoord_t x0,y0; } linedraw_internal_t; static void linedraw_moveTo(gfxdrawer_t*d, gfxcoord_t x, gfxcoord_t y) @@ -46,6 +47,8 @@ static void linedraw_moveTo(gfxdrawer_t*d, gfxcoord_t x, gfxcoord_t y) return; } + i->x0 = x; + i->y0 = y; l->sx = l->sy = 0; d->x = l->x = x; d->y = l->y = y; @@ -102,6 +105,11 @@ static void linedraw_splineTo(gfxdrawer_t*d, gfxcoord_t sx, gfxcoord_t sy, gfxco if(!i->start) i->start = l; } +static void* linedraw_close(gfxdrawer_t*d) +{ + linedraw_internal_t*i = (linedraw_internal_t*)d->internal; + linedraw_lineTo(d, i->x0, i->y0); +} static void* linedraw_result(gfxdrawer_t*d) { linedraw_internal_t*i = (linedraw_internal_t*)d->internal; @@ -120,6 +128,7 @@ void gfxdrawer_target_gfxline(gfxdrawer_t*d) d->moveTo = linedraw_moveTo; d->lineTo = linedraw_lineTo; d->splineTo = linedraw_splineTo; + d->close = linedraw_close; d->result = linedraw_result; } diff --git a/lib/gfxtools.h b/lib/gfxtools.h index 7b7377d..a49a9b5 100644 --- a/lib/gfxtools.h +++ b/lib/gfxtools.h @@ -38,6 +38,7 @@ typedef struct _gfxdrawer void (*moveTo)(struct _gfxdrawer*d, gfxcoord_t x, gfxcoord_t y); void (*lineTo)(struct _gfxdrawer*d, gfxcoord_t x, gfxcoord_t y); void (*splineTo)(struct _gfxdrawer*d, gfxcoord_t sx, gfxcoord_t sy, gfxcoord_t x, gfxcoord_t y); + void (*close)(struct _gfxdrawer*d); void* (*result)(struct _gfxdrawer*d); } gfxdrawer_t;