more fiddling with edgestyles
[swftools.git] / lib / gfxpoly.c
index d251881..a687e63 100644 (file)
@@ -259,7 +259,7 @@ intbbox_t get_svp_bbox(ArtSVP*svp, double zoom)
             if(x1 < b.xmin) b.xmin = x1;
             if(y1 < b.ymin) b.ymin = y1;
             if(x2 > b.xmax) b.xmax = x2;
             if(x1 < b.xmin) b.xmin = x1;
             if(y1 < b.ymin) b.ymin = y1;
             if(x2 > b.xmax) b.xmax = x2;
-            if(y2 > b.xmax) b.ymax = y2;
+            if(y2 > b.ymax) b.ymax = y2;
         }
     }
     if(b.xmax > (int)(MAX_WIDTH*zoom))
         }
     }
     if(b.xmax > (int)(MAX_WIDTH*zoom))
@@ -296,51 +296,39 @@ intbbox_t get_svp_bbox(ArtSVP*svp, double zoom)
 #define B00000010 0x02
 #define B00000001 0x01
 
 #define B00000010 0x02
 #define B00000001 0x01
 
-int compare_bitmaps(intbbox_t*bbox, unsigned char*data1, unsigned char*data2)
+static int compare_bitmaps(intbbox_t*bbox, unsigned char*data1, unsigned char*data2)
 {
 {
-    int similar = 0;
+    if(!data1 || !data2) 
+        return 0;
     int x,y;
     int height = bbox->height;
     int width = bbox->width;
     int width8 = (width+7) >> 3;
     unsigned char*l1 = &data1[width8];
     unsigned char*l2 = &data2[width8];
     int x,y;
     int height = bbox->height;
     int width = bbox->width;
     int width8 = (width+7) >> 3;
     unsigned char*l1 = &data1[width8];
     unsigned char*l2 = &data2[width8];
-    int fail = 0;
     for(y=1;y<height-1;y++) {
         for(x=0;x<width8;x++) {
             unsigned a = l1[x-width8] & l1[x] & l1[x+width8];
             unsigned b = l2[x-width8] & l2[x] & l2[x+width8];
     for(y=1;y<height-1;y++) {
         for(x=0;x<width8;x++) {
             unsigned a = l1[x-width8] & l1[x] & l1[x+width8];
             unsigned b = l2[x-width8] & l2[x] & l2[x+width8];
-
-            if((a&B11100000) && !(l2[x]&B01000000))
-                fail == 1;
-            if((a&B01110000) && !(l2[x]&B00100000))
-                fail == 1;
-            if((a&B00111000) && !(l2[x]&B00010000))
-                fail == 1;
-            if((a&B00011100) && !(l2[x]&B00001000))
-                fail == 1;
-            if((a&B00001110) && !(l2[x]&B00000100))
-                fail == 1;
-            if((a&B00000111) && !(l2[x]&B00000010))
-                fail == 1;
-
-            if((b&B11100000) && !(l1[x]&B01000000))
-                fail == 1;
-            if((b&B01110000) && !(l1[x]&B00100000))
-                fail == 1;
-            if((b&B00111000) && !(l1[x]&B00010000))
-                fail == 1;
-            if((b&B00011100) && !(l1[x]&B00001000))
-                fail == 1;
-            if((b&B00001110) && !(l1[x]&B00000100))
-                fail == 1;
-            if((b&B00000111) && !(l1[x]&B00000010))
-                fail == 1;
+            
+            if((a&B11100000) && !(l2[x]&B01000000)) return 0;
+            if((a&B01110000) && !(l2[x]&B00100000)) return 0;
+            if((a&B00111000) && !(l2[x]&B00010000)) return 0;
+            if((a&B00011100) && !(l2[x]&B00001000)) return 0;
+            if((a&B00001110) && !(l2[x]&B00000100)) return 0;
+            if((a&B00000111) && !(l2[x]&B00000010)) return 0;
+
+            if((b&B11100000) && !(l1[x]&B01000000)) return 0;
+            if((b&B01110000) && !(l1[x]&B00100000)) return 0;
+            if((b&B00111000) && !(l1[x]&B00010000)) return 0;
+            if((b&B00011100) && !(l1[x]&B00001000)) return 0;
+            if((b&B00001110) && !(l1[x]&B00000100)) return 0;
+            if((b&B00000111) && !(l1[x]&B00000010)) return 0;
         }
         l1 += width8;
         l2 += width8;
     }
         }
         l1 += width8;
         l2 += width8;
     }
-    return !fail;
+    return 1;
 }
 
 
 }
 
 
@@ -378,11 +366,13 @@ static ArtVpath* gfxline_to_ArtVpath(gfxline_t*line, char fill)
 
     pos = 0;
     l2 = line;
 
     pos = 0;
     l2 = line;
+    int lastmove=-1;
     while(l2) {
        if(l2->type == gfx_moveTo) {
            vec[pos].code = ART_MOVETO_OPEN;
            vec[pos].x = l2->x;
            vec[pos].y = l2->y;
     while(l2) {
        if(l2->type == gfx_moveTo) {
            vec[pos].code = ART_MOVETO_OPEN;
            vec[pos].x = l2->x;
            vec[pos].y = l2->y;
+            lastmove=pos;
            pos++; 
            assert(pos<=len);
        } else if(l2->type == gfx_lineTo) {
            pos++; 
            assert(pos<=len);
        } else if(l2->type == gfx_lineTo) {
@@ -407,6 +397,16 @@ static ArtVpath* gfxline_to_ArtVpath(gfxline_t*line, char fill)
        }
        x = l2->x;
        y = l2->y;
        }
        x = l2->x;
        y = l2->y;
+       
+        /* let closed line segments start w/ MOVETO instead of MOVETO_OPEN */
+        if(lastmove>=0 && l2->type!=gfx_moveTo && (!l2->next || l2->next->type == gfx_moveTo)) {
+            if(vec[lastmove].x == l2->x &&
+               vec[lastmove].y == l2->y) {
+                assert(vec[lastmove].code == ART_MOVETO_OPEN);
+                vec[lastmove].code = ART_MOVETO;
+            }
+        }
+
        l2 = l2->next;
     }
     vec[pos++].code = ART_END;
        l2 = l2->next;
     }
     vec[pos++].code = ART_END;
@@ -431,7 +431,7 @@ static ArtVpath* gfxline_to_ArtVpath(gfxline_t*line, char fill)
     }
 
     /* Find adjacent identical points. If an ajdacent pair of identical
     }
 
     /* Find adjacent identical points. If an ajdacent pair of identical
-       points is found, the second is removed.
+       points is found, the second one is removed.
        So moveto x,y lineto x,y becomes moveto x,y
           lineto x,y lineto x,y becomes lineto x,y
           lineto x,y moveto x,y becomes lineto x,y
        So moveto x,y lineto x,y becomes moveto x,y
           lineto x,y lineto x,y becomes lineto x,y
           lineto x,y moveto x,y becomes lineto x,y
@@ -523,7 +523,13 @@ static double find_shear_value(ArtSVP*svp)
         }
         if(!fail) 
             break;
         }
         if(!fail) 
             break;
-        v = lrand48() / 2000000000.0;
+#ifdef HAVE_LRAND48
+       v = lrand48() / 2000000000.0;;
+#elif HAVE_RAND
+        v = rand() / 2000000000.0;
+#else
+#error "no lrand48()/rand() implementation found"
+#endif
         tries++;
     }
     return v;
         tries++;
     }
     return v;
@@ -905,7 +911,7 @@ static ArtSVP* gfxfillToSVP(gfxline_t*line, int perturb)
 
 //#ifdef SHEAR
 //    double shear = find_shear_value(svp);
 
 //#ifdef SHEAR
 //    double shear = find_shear_value(svp);
-//    gfxline_t*line =  gfxpoly_to_gfxline((gfxpoly_t*)svp);
+//    gfxline_t*line =  gfxline_from_gfxpoly((gfxpoly_t*)svp);
 //    gfxline_t*l = line;
 //    while(l) {
 //        l->y += l->x*shear;
 //    gfxline_t*l = line;
 //    while(l) {
 //        l->y += l->x*shear;
@@ -957,7 +963,7 @@ ArtSVP* run_intersector(ArtSVP*svp, ArtWindRule rule)
     return result;
 }
 
     return result;
 }
 
-gfxline_t* gfxpoly_to_gfxline(gfxpoly_t*poly)
+gfxline_t* gfxline_from_gfxpoly(gfxpoly_t*poly)
 {
     ArtSVP*svp = (ArtSVP*)poly;
     int size = 0;
 {
     ArtSVP*svp = (ArtSVP*)poly;
     int size = 0;
@@ -992,7 +998,7 @@ gfxline_t* gfxpoly_to_gfxline(gfxpoly_t*poly)
     }
 }
 
     }
 }
 
-gfxpoly_t* gfxpoly_fillToPoly(gfxline_t*line)
+gfxpoly_t* gfxpoly_from_fill(gfxline_t*line, double gridsize)
 {
     /* I'm not sure whether doing perturbation here is actually
        a good idea- if that line has been run through the machinery
 {
     /* I'm not sure whether doing perturbation here is actually
        a good idea- if that line has been run through the machinery
@@ -1092,7 +1098,7 @@ gfxpoly_t* gfxpoly_union(gfxpoly_t*poly1, gfxpoly_t*poly2)
     return (gfxpoly_t*)svp;
 }
 
     return (gfxpoly_t*)svp;
 }
 
-gfxpoly_t* gfxpoly_strokeToPoly(gfxline_t*line, gfxcoord_t width, gfx_capType cap_style, gfx_joinType joint_style, double miterLimit)
+gfxpoly_t* gfxpoly_from_stroke(gfxline_t*line, gfxcoord_t width, gfx_capType cap_style, gfx_joinType joint_style, double miterLimit, double gridsize)
 {
     ArtVpath* vec = gfxline_to_ArtVpath(line, 0);
     msg("<verbose> Casting gfxline of %d segments to a stroke-polygon", gfxline_len(line));
 {
     ArtVpath* vec = gfxline_to_ArtVpath(line, 0);
     msg("<verbose> Casting gfxline of %d segments to a stroke-polygon", gfxline_len(line));
@@ -1116,31 +1122,26 @@ gfxpoly_t* gfxpoly_strokeToPoly(gfxline_t*line, gfxcoord_t width, gfx_capType ca
     return (gfxpoly_t*)svp;
 }
 
     return (gfxpoly_t*)svp;
 }
 
-gfxline_t* gfxline_circularToEvenOdd(gfxline_t*line)
+gfxline_t* gfxpoly_circular_to_evenodd(gfxline_t*line, double gridsize)
 {
     msg("<verbose> Converting circular-filled gfxline of %d segments to even-odd filled gfxline", gfxline_len(line));
     ArtSVP* svp = gfxfillToSVP(line, 1);
 
 {
     msg("<verbose> Converting circular-filled gfxline of %d segments to even-odd filled gfxline", gfxline_len(line));
     ArtSVP* svp = gfxfillToSVP(line, 1);
 
-    /* TODO: ART_WIND_RULE_POSITIVE means that a shape is visible if
-             positive and negative line segments add up to something positive.
-             I *think* that clockwise fill in PDF is defined in a way, however,
-             that the *last* shape's direction will determine whether something
-             is filled */
     ArtSVP* svp_rewinded;
     
     ArtSVP* svp_rewinded;
     
-    svp_rewinded = run_intersector(svp, ART_WIND_RULE_POSITIVE);
+    svp_rewinded = run_intersector(svp, ART_WIND_RULE_NONZERO);
     if(!svp_rewinded) {
        art_svp_free(svp);
        return 0;
     }
 
     if(!svp_rewinded) {
        art_svp_free(svp);
        return 0;
     }
 
-    gfxline_t* result = gfxpoly_to_gfxline((gfxpoly_t*)svp_rewinded);
+    gfxline_t* result = gfxline_from_gfxpoly((gfxpoly_t*)svp_rewinded);
     art_svp_free(svp);
     art_svp_free(svp_rewinded);
     return result;
 }
 
     art_svp_free(svp);
     art_svp_free(svp_rewinded);
     return result;
 }
 
-gfxpoly_t* gfxpoly_createbox(double x1, double y1,double x2, double y2)
+gfxpoly_t* gfxpoly_createbox(double x1, double y1,double x2, double y2, double gridsize)
 {
     ArtVpath *vec = art_new (ArtVpath, 5+1);
     vec[0].code = ART_MOVETO;
 {
     ArtVpath *vec = art_new (ArtVpath, 5+1);
     vec[0].code = ART_MOVETO;
@@ -1166,7 +1167,7 @@ gfxpoly_t* gfxpoly_createbox(double x1, double y1,double x2, double y2)
     return (gfxpoly_t*)svp;
 }
 
     return (gfxpoly_t*)svp;
 }
 
-void gfxpoly_free(gfxpoly_t*poly)
+void gfxpoly_destroy(gfxpoly_t*poly)
 {
     ArtSVP*svp = (ArtSVP*)poly;
     art_svp_free(svp);
 {
     ArtSVP*svp = (ArtSVP*)poly;
     art_svp_free(svp);