polygon intersector: improved test routines
[swftools.git] / lib / gfxpoly / convert.c
index f71a096..5615612 100644 (file)
@@ -1,6 +1,7 @@
 #include <stdlib.h>
 #include <math.h>
 #include <assert.h>
+#include <string.h>
 #include "../gfxdevice.h"
 #include "poly.h"
 
@@ -15,32 +16,36 @@ static edge_t*edge_new(int x1, int y1, int x2, int y2)
     return s;
 }
 
-static inline void gfxpoly_add_edge(edge_t**list, double _x1, double _y1, double _x2, double _y2)
+static inline void gfxpoly_add_edge(gfxpoly_t*poly, double _x1, double _y1, double _x2, double _y2)
 {
     int x1 = ceil(_x1);
     int y1 = ceil(_y1);
     int x2 = ceil(_x2);
     int y2 = ceil(_y2);
-    if(y1!=y2) {
+    if(x1!=x2 || y1!=y2) {
         edge_t*s = edge_new(x1, y1, x2, y2);
-        s->next = *list;
-        *list = s;
+        s->next = poly->edges;
+        poly->edges = s;
     }
 }
 
-gfxpoly_t* gfxpoly_fillToPoly(gfxline_t*line)
+gfxpoly_t* gfxpoly_fillToPoly(gfxline_t*line, double gridsize)
 {
-    edge_t*s = 0;
+    gfxpoly_t*p = gfxpoly_new(gridsize);
 
     /* factor that determines into how many line fragments a spline is converted */
     double subfraction = 2.4;//0.3
 
+    double z = 1.0 / gridsize;
+
     double lastx=0, lasty=0;
     assert(!line || line[0].type == gfx_moveTo);
     while(line) {
+        double x = line->x*z;
+        double y = line->y*z;
         if(line->type == gfx_moveTo) {
         } else if(line->type == gfx_lineTo) {
-            gfxpoly_add_edge(&s, lastx, lasty, line->x, line->y);
+            gfxpoly_add_edge(p, lastx, lasty, x, y);
        } 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);
@@ -49,20 +54,81 @@ gfxpoly_t* gfxpoly_fillToPoly(gfxline_t*line)
             int i;
            for(i=0;i<parts;i++) {
                double t = (double)i*stepsize;
-               double x = line->x*t*t + 2*line->sx*t*(1-t) + x*(1-t)*(1-t);
-               double y = line->y*t*t + 2*line->sy*t*(1-t) + y*(1-t)*(1-t);
-                gfxpoly_add_edge(&s, lastx, lasty, x, y);
-                lastx = x;
-                lasty = y;
+               double sx = (line->x*t*t + 2*line->sx*t*(1-t) + x*(1-t)*(1-t))*z;
+               double sy = (line->y*t*t + 2*line->sy*t*(1-t) + y*(1-t)*(1-t))*z;
+                gfxpoly_add_edge(p, lastx, lasty, sx, sy);
+                lastx = sx;
+                lasty = sy;
            }
-            gfxpoly_add_edge(&s, lastx, lasty, line->x, line->y);
+            gfxpoly_add_edge(p, lastx, lasty, x, y);
         }
-        lastx = line->x;
-        lasty = line->y;
+        lastx = x;
+        lasty = y;
         line = line->next;
     }
 
     gfxline_free(line);
-    return s;
+    return p;
+}
+
+static char* readline(FILE*fi)
+{
+    char c;
+    while(1) {
+        int l = fread(&c, 1, 1, fi);
+        if(!l)
+            return 0;
+        if(c!=10 || c!=13)
+            break;
+    }
+    char line[256];
+    int pos = 0;
+    while(1) {
+        line[pos++] = c;
+        line[pos] = 0;
+        int l = fread(&c, 1, 1, fi);
+        if(!l || c==10 || c==13) {
+            return strdup(line);
+        }
+    }
 }
 
+gfxpoly_t* gfxpoly_from_file(const char*filename, double gridsize)
+{
+    gfxpoly_t*p = gfxpoly_new(gridsize);
+
+    double z = 1.0 / gridsize;
+
+    FILE*fi = fopen(filename, "rb");
+    if(!fi) {
+        perror(filename);
+        return 0;
+    }
+    int count = 0;
+    double lastx=0,lasty=0;
+    while(1) {
+        char*line = readline(fi);
+        if(!line)
+            break;
+        double x,y;
+        char s[256];
+        if(sscanf(line, "%lf %lf %s", &x, &y, &s) == 3) {
+            x*=z;
+            y*=z;
+            if(s && !strcmp(s,"moveto")) {
+                count++;
+            } else if(s && !strcmp(s,"lineto")) {
+                gfxpoly_add_edge(p, lastx, lasty, x, y);
+                count++;
+            } else {
+                printf("invalid command: %s\n", s);
+            }
+            lastx = x;
+            lasty = y;
+        }
+        free(line);
+    }
+    fclose(fi);
+    printf("loaded %d points from %s\n", count, filename);
+    return p;
+}