more bugfixes in stroke code
authorMatthias Kramm <kramm@quiss.org>
Fri, 5 Jun 2009 19:51:43 +0000 (21:51 +0200)
committerMatthias Kramm <kramm@quiss.org>
Fri, 5 Jun 2009 19:51:43 +0000 (21:51 +0200)
lib/gfxpoly/convert.c
lib/gfxpoly/poly.c
lib/gfxpoly/poly.h
lib/gfxpoly/stroke.c
lib/gfxpoly/test.c
lib/gfxpoly/test_stroke.c
lib/gfxtools.c
lib/gfxtools.h

index c6e365d..64cef43 100644 (file)
@@ -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;t<stroke->num_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;
index efb51fe..9f7e8e8 100644 (file)
@@ -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;
index d1d5154..68eec9b 100644 (file)
@@ -6,7 +6,7 @@
 #include "../types.h"
 
 //#define DEBUG
-#define CHECKS
+//#define CHECKS
 
 /* features */
 #define SPLAY
index 7d5c380..70a51d0 100644 (file)
@@ -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);
index 6530340..b5c192a 100644 (file)
@@ -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;
index faaff03..b05d710 100644 (file)
@@ -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));
index f754379..a206e57 100644 (file)
@@ -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;
 }
 
index 7b7377d..a49a9b5 100644 (file)
@@ -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;