fixed "triangle problem"- corrected bounding boxes are now correct
[swftools.git] / pdf2swf / swfoutput.cc
index eed7fad..36d5d40 100644 (file)
@@ -48,6 +48,7 @@ int flashversion=5;
 int splinemaxerror=1;
 int fontsplinemaxerror=1;
 int filloverlap=0;
+float minlinewidth=0.1;
 
 static char storefont = 0;
 static int flag_protected = 0;
@@ -120,7 +121,13 @@ static int moveto(TAG*tag, plotxy p0)
     }
     return 0;
 }
-
+static int moveto(TAG*tag, float x, float y)
+{
+    plotxy p;
+    p.x = x;
+    p.y = y;
+    return moveto(tag, p);
+}
 static void addPointToBBox(int px, int py) 
 {
     SPOINT p;
@@ -151,6 +158,14 @@ static void lineto(TAG*tag, plotxy p0)
     swflastx+=rx;
     swflasty+=ry;
 }
+static void lineto(TAG*tag, double x, double y)
+{
+    plotxy p;
+    p.x = x;
+    p.y = y;
+    lineto(tag, p);
+}
+
 
 // write a spline-to command into the swf
 static void splineto(TAG*tag, plotxy control,plotxy end)
@@ -760,7 +775,7 @@ static inline int colorcompare(RGBA*a,RGBA*b)
 static const int CHARDATAMAX = 8192;
 struct chardata {
     int charid;
-    int fontid;
+    int fontid; /* TODO: use a SWFFONT instead */
     int x;
     int y;
     int size;
@@ -1150,12 +1165,14 @@ int getCharID(SWFFONT *font, int charnr, char *charname, int u)
        return charnr;
     }
 
-    /* the following is technically wrong, and only works if the font encoding
-       is US-ASCII based. It's needed for fonts which return broken unicode
-       indices */
-/*    if(charnr>=0 && charnr<font->maxascii && font->ascii2glyph[charnr]>=0) {
-       return font->ascii2glyph[charnr];
-    }*/
+    if(font->encoding != FONT_ENCODING_UNICODE) {
+       /* the following only works if the font encoding
+          is US-ASCII based. It's needed for fonts which return broken unicode
+          indices */
+       if(charnr>=0 && charnr<font->maxascii && font->ascii2glyph[charnr]>=0) {
+           return font->ascii2glyph[charnr];
+       }
+    }
 
     return -1;
 }
@@ -1219,6 +1236,11 @@ void swfoutput_setfont(struct swfoutput*obj, char*fontid, char*filename)
                    swffont->layout->bounds[iii].xmax/20.0,
                    swffont->layout->bounds[iii].ymax/20.0
                    );
+           int t;
+           for(t=0;t<swffont->maxascii;t++) {
+               if(swffont->ascii2glyph[t] == iii)
+                   msg("<debug> | - maps to %d",t);
+           }
        }
     }
 
@@ -1432,13 +1454,48 @@ void changeRect(TAG*tag, int pos, SRECT*newrect)
     tag->pos = tag->readBit = 0;
 }
 
+void fixAreas()
+{
+    if(!shapeisempty && fill &&
+       (bboxrect.xmin == bboxrect.xmax ||
+        bboxrect.ymin == bboxrect.ymax) &&
+        minlinewidth >= 0.001
+       ) {
+       SRECT r = bboxrect;
+       msg("<debug> Shape has size 0");
+    
+       if(r.xmin == r.xmax && r.ymin == r.ymax) {
+           /* this thing comes down to a single dot- nothing to fix here */
+           return;
+       }
+
+       double x=0,y=0;
+       if(r.xmin == r.xmax) {
+           x = minlinewidth;
+       } else {
+           y = minlinewidth;
+       }
+       /* warning: doing this inside endshape() is dangerous */
+       moveto(tag, r.xmin/20.0    , r.ymin/20.0);
+       lineto(tag, r.xmax/20.0 + x, r.ymin/20.0);
+       lineto(tag, r.xmax/20.0 + x, r.ymax/20.0 + y);
+       lineto(tag, r.xmin/20.0    , r.ymax/20.0 + y);
+       lineto(tag, r.xmin/20.0    , r.ymin/20.0);
+    }
+    
+}
+
 static void endshape(int clipdepth)
 {
     if(shapeid<0) 
         return;
-    swf_ShapeSetEnd(tag);
 
-    if(shapeisempty) {
+    if(!clipdepth)
+       fixAreas();
+       
+    if(shapeisempty ||
+       (bboxrect.xmin == bboxrect.xmax && bboxrect.ymin == bboxrect.ymax)) 
+    {
        // delete the tag again, we didn't do anything
        TAG*todel = tag;
        tag = tag->prev;
@@ -1447,6 +1504,8 @@ static void endshape(int clipdepth)
        bboxrectpos = -1;
        return;
     }
+    
+    swf_ShapeSetEnd(tag);
 
     changeRect(tag, bboxrectpos, &bboxrect);
 
@@ -1583,14 +1642,14 @@ void swfoutput_setstrokecolor(swfoutput* obj, u8 r, u8 g, u8 b, u8 a)
     obj->strokergb.a = a;
 }
 
-void swfoutput_setlinewidth(struct swfoutput*obj, double linewidth)
+void swfoutput_setlinewidth(struct swfoutput*obj, double _linewidth)
 {
-    if(linewidth == (u16)(linewidth*20))
+    if(linewidth == (u16)(_linewidth*20))
         return;
 
     if(shapeid>=0)
        endshape(0);
-    linewidth = (u16)(linewidth*20);
+    linewidth = (u16)(_linewidth*20);
 }
 
 
@@ -2104,6 +2163,8 @@ void swfoutput_setparameter(char*name, char*value)
        insertstoptag = atoi(value);
     } else if(!strcmp(name, "flashversion")) {
        flashversion = atoi(value);
+    } else if(!strcmp(name, "minlinewidth")) {
+       minlinewidth = atof(value);
     } else if(!strcmp(name, "jpegquality")) {
        int val = atoi(value);
        if(val<0) val=0;