fixed bevel joins
[swftools.git] / lib / gfxtools.c
index e79e6fe..0862fd6 100644 (file)
@@ -33,6 +33,8 @@ typedef struct _linedraw_internal
 {
     gfxline_t*start;
     gfxline_t*next;
+    gfxcoord_t x0,y0;
+    char has_moveto;
 } linedraw_internal_t;
 
 static void linedraw_moveTo(gfxdrawer_t*d, gfxcoord_t x, gfxcoord_t y)
@@ -40,12 +42,9 @@ static void linedraw_moveTo(gfxdrawer_t*d, gfxcoord_t x, gfxcoord_t y)
     linedraw_internal_t*i = (linedraw_internal_t*)d->internal;
     gfxline_t*l = (gfxline_t*)rfx_alloc(sizeof(gfxline_t));
     l->type = gfx_moveTo;
-    if((int)((d->x * 5120) == (int)(x * 5120)) &&
-       (int)((d->y * 5120) == (int)(y * 5120))) {
-       /* never mind- we're already there */
-       return;
-
-    }
+    i->has_moveto = 1;
+    i->x0 = x;
+    i->y0 = y;
     l->sx = l->sy = 0;
     d->x = l->x = x;
     d->y = l->y = y;
@@ -61,10 +60,11 @@ static void linedraw_lineTo(gfxdrawer_t*d, gfxcoord_t x, gfxcoord_t y)
     linedraw_internal_t*i = (linedraw_internal_t*)d->internal;
     gfxline_t*l = (gfxline_t*)rfx_alloc(sizeof(gfxline_t));
 
-    if(!i->start) {
-       /* starts with a line, not with a moveto. That needs we first
-          need an explicit moveto to (0,0) */
-       linedraw_moveTo(d, 0, 0);
+    if(!i->has_moveto) {
+       /* starts with a line, not with a moveto. As this is the first
+          entry in the list, this is probably *meant* to be a moveto */
+       linedraw_moveTo(d, x, y);
+       return;
     }
 
     l->type = gfx_lineTo;
@@ -83,10 +83,9 @@ static void linedraw_splineTo(gfxdrawer_t*d, gfxcoord_t sx, gfxcoord_t sy, gfxco
     linedraw_internal_t*i = (linedraw_internal_t*)d->internal;
     gfxline_t*l = (gfxline_t*)rfx_alloc(sizeof(gfxline_t));
 
-    if(!i->start) {
-       /* starts with a line, not with a moveto. That needs we first
-          need an explicit moveto to (0,0) */
-       linedraw_moveTo(d, 0, 0);
+    if(!i->has_moveto) {
+       linedraw_moveTo(d, x, y);
+       return;
     }
 
     l->type = gfx_splineTo;
@@ -101,6 +100,16 @@ 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;
+    if(!i->has_moveto) 
+       return;
+    linedraw_lineTo(d, i->x0, i->y0);
+    i->has_moveto = 0;
+    i->x0 = 0;
+    i->y0 = 0;
+}
 static void* linedraw_result(gfxdrawer_t*d)
 {
     linedraw_internal_t*i = (linedraw_internal_t*)d->internal;
@@ -119,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;
 }
 
@@ -834,6 +844,42 @@ gfxline_t*gfxline_makerectangle(int x1,int y1,int x2, int y2)
     return line;
 }
 
+gfxline_t*gfxline_makecircle(double x,double y,double rx, double ry)
+{
+    double C1 = 0.2930;    
+    double C2 = 0.4140;   
+    double begin = 0.7070; 
+    gfxline_t** line = (gfxline_t**)rfx_calloc(sizeof(gfxline_t*)*9);
+    int t;
+    for(t=0;t<9;t++) {
+       line[t] = rfx_calloc(sizeof(gfxline_t));
+    }
+    line[0]->type = gfx_moveTo;
+    line[0]->x = x+begin*rx;
+    line[0]->y = y+begin*ry;
+    for(t=1;t<9;t++) {
+       line[t-1]->next = line[t];
+       line[t]->type = gfx_splineTo;
+    }
+    line[8]->next = 0;
+#define R(nr,cx,cy,mx,my) \
+    line[nr]->sx = line[nr-1]->x + (cx); \
+    line[nr]->sy = line[nr-1]->y + (cy); \
+    line[nr]->x = line[nr]->sx + (mx); \
+    line[nr]->y = line[nr]->sy + (my);
+    R(1, -C1*rx,  C1*ry, -C2*rx,      0);
+    R(2, -C2*rx,      0, -C1*rx, -C1*ry);
+    R(3, -C1*rx, -C1*ry,      0, -C2*ry);
+    R(4,      0, -C2*ry,  C1*rx, -C1*ry);
+    R(5,  C1*rx, -C1*ry,  C2*rx,      0);
+    R(6,  C2*rx,      0,  C1*rx,  C1*ry);
+    R(7,  C1*rx,  C1*ry,      0,  C2*ry);
+    R(8,      0,  C2*ry, -C1*rx,  C1*ry);
+    gfxline_t*l = line[0];
+    free(line);
+    return l;
+}
+
 gfxbbox_t* gfxline_isrectangle(gfxline_t*_l)
 {
     if(!_l)