fixed handling of adjacent identical points, and use new arts intersector code
[swftools.git] / lib / gfxpoly.c
index 90c178e..293afc7 100644 (file)
@@ -25,6 +25,7 @@
 #include "gfxtools.h"
 #include "gfxpoly.h"
 #include "art/libart.h"
+#include "art/art_svp_intersect.h"
 #include <assert.h>
 #include <memory.h>
 #include <math.h>
@@ -114,23 +115,18 @@ static ArtVpath* gfxline_to_ArtVpath(gfxline_t*line, char fill)
     }
 
     /* Find adjacent identical points. If an ajdacent pair of identical
-       points is found, the moveto is removed (unless both are movetos).
-       So moveto x,y lineto x,y becomes lineto x,y
+       points is found, the second 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
           moveto x,y moveto x,y becomes moveto x,y
      */
-    int t;
+    int t = 1;
     while(t < pos)
     {
-       int t = 1;
        if ((vec[t-1].x == vec[t].x) && (vec[t-1].y == vec[t].y)) {
-           // adjacent identical points; remove one
-           int type = ART_MOVETO;
-           if(vec[t-1].code==ART_LINETO || vec[t].code==ART_LINETO)
-               type = ART_LINETO;
-           memcpy(&vec[t], &vec[t+1], sizeof(vec[0]) * (pos - t));
-           vec[t].code = type;
+           // adjacent identical points; remove the second
+           memcpy(&vec[t], &vec[t+1], sizeof(vec[0]) * (pos - t - 1));
            pos--;
        } else {
            t++;
@@ -324,10 +320,24 @@ gfxpoly_t* gfxpoly_fillToPoly(gfxline_t*line)
        }
        fprintf(stderr, "arts_fill abandonning shape with %d segments (%d line parts)\n", svp->n_segs, lineParts);
        art_svp_free(svp);
+
+       /* return empty shape */
        return (gfxpoly_t*)gfxpoly_strokeToPoly(0, 0, gfx_capButt, gfx_joinMiter, 0);
     }
-    ArtSVP* svp2 = art_svp_rewind_uncrossed(art_svp_uncross(svp),ART_WIND_RULE_ODDEVEN);
-    free(svp);svp=svp2;
+
+    /* for some reason, we need to rewind / self-intersect the polygons that gfxfillToSVP
+       returns- art probably uses a different fill mode (circular?) for vpaths */
+    ArtSVP*svp_uncrossed=0;
+#ifdef ART_USE_NEW_INTERSECTOR
+    ArtSvpWriter * swr = art_svp_writer_rewind_new(ART_WIND_RULE_ODDEVEN);
+    art_svp_intersector(svp, swr);
+    svp_uncrossed = art_svp_writer_rewind_reap(swr);
+#else
+    svp_uncrossed = art_svp_rewind_uncrossed(art_svp_uncross(svp),ART_WIND_RULE_ODDEVEN);
+#endif
+    art_svp_free(svp);
+    svp=svp_uncrossed;
+
     return (gfxpoly_t*)svp;
 }
 
@@ -352,7 +362,6 @@ gfxpoly_t* gfxpoly_union(gfxpoly_t*poly1, gfxpoly_t*poly2)
 gfxpoly_t* gfxpoly_strokeToPoly(gfxline_t*line, gfxcoord_t width, gfx_capType cap_style, gfx_joinType joint_style, double miterLimit)
 {
     ArtVpath* vec = gfxline_to_ArtVpath(line, 0);
-
     ArtSVP *svp = art_svp_vpath_stroke (vec,
                        (joint_style==gfx_joinMiter)?ART_PATH_STROKE_JOIN_MITER:
                        ((joint_style==gfx_joinRound)?ART_PATH_STROKE_JOIN_ROUND:
@@ -371,10 +380,20 @@ gfxpoly_t* gfxpoly_strokeToPoly(gfxline_t*line, gfxcoord_t width, gfx_capType ca
 gfxline_t* gfxline_circularToEvenOdd(gfxline_t*line)
 {
     ArtSVP* svp = gfxfillToSVP(line, 1);
-    ArtSVP* svp2 = art_svp_rewind_uncrossed(art_svp_uncross(svp),ART_WIND_RULE_POSITIVE);
-    gfxline_t* result = gfxpoly_to_gfxline((gfxpoly_t*)svp2);
+
+    ArtSVP* svp_rewinded;
+#ifdef ART_USE_NEW_INTERSECTOR
+    ArtSvpWriter * swr = art_svp_writer_rewind_new (ART_WIND_RULE_POSITIVE);
+    art_svp_intersector(svp, swr);
+    svp_rewinded = art_svp_writer_rewind_reap(swr);
+#else
+    jjj
+    svp_rewinded = art_svp_rewind_uncrossed(art_svp_uncross(svp),ART_WIND_RULE_POSITIVE);
+#endif
+
+    gfxline_t* result = gfxpoly_to_gfxline((gfxpoly_t*)svp_rewinded);
     art_svp_free(svp);
-    art_svp_free(svp2);
+    art_svp_free(svp_rewinded);
     return result;
 }
 
@@ -407,5 +426,5 @@ gfxpoly_t* gfxpoly_createbox(double x1, double y1,double x2, double y2)
 void gfxpoly_free(gfxpoly_t*poly)
 {
     ArtSVP*svp = (ArtSVP*)poly;
-    free(svp);
+    art_svp_free(svp);
 }