* added rectangle correction.
[swftools.git] / pdf2swf / swfoutput.cc
index 9125528..189f3ec 100644 (file)
@@ -47,6 +47,7 @@ int insertstoptag=0;
 int flashversion=5;
 int splinemaxerror=1;
 int fontsplinemaxerror=1;
+int filloverlap=0;
 
 static char storefont = 0;
 static int flag_protected = 0;
@@ -119,7 +120,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;
@@ -150,6 +157,14 @@ static void lineto(TAG*tag, plotxy p0)
     swflastx+=rx;
     swflasty+=ry;
 }
+static void lineto(TAG*tag, float x, float 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)
@@ -264,7 +279,8 @@ void drawpath(struct swfoutput*output, SWF_OUTLINE*outline, struct swfmatrix*m,
         y += (outline->dest.y/(float)0xffff);
         if(outline->type == SWF_PATHTYPE_MOVE)
         {
-           if(!init && fill && output->drawmode != DRAWMODE_EOFILL && !ignoredraworder) {
+           //if(!init && fill && output->drawmode != DRAWMODE_EOFILL && !ignoredraworder) {
+           if(filloverlap && !init && fill && output->drawmode != DRAWMODE_EOFILL) {
                /* drawmode=FILL (not EOFILL) means that
                   seperate shapes do not cancel each other out.
                   On SWF side, we need to start a new shape for each
@@ -1148,12 +1164,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;
 }
@@ -1217,6 +1235,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);
+           }
        }
     }
 
@@ -1430,13 +1453,45 @@ 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)) {
+       msg("<debug> Shape has size 0");
+    
+       if(bboxrect.xmin == bboxrect.xmax && bboxrect.ymin == bboxrect.ymax) {
+           /* this thing comes down to a single dot- nothing to fix here */
+           return;
+       }
+
+       float x=0,y=0;
+       if(bboxrect.xmin == bboxrect.xmax) {
+           x = 0.05;
+       } else {
+           y = 0.05;
+       }
+       /* warning: doing this inside endshape() is dangerous */
+       moveto(tag, bboxrect.xmin/20.0, bboxrect.ymin/20.0);
+       lineto(tag, bboxrect.xmax/20.0 + x, bboxrect.ymin/20.0);
+       lineto(tag, bboxrect.xmax/20.0 + x, bboxrect.ymax/20.0 + y);
+       lineto(tag, bboxrect.xmin/20.0, bboxrect.ymax/20.0 + y);
+       lineto(tag, bboxrect.xmin/20.0, bboxrect.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;
@@ -1445,6 +1500,8 @@ static void endshape(int clipdepth)
        bboxrectpos = -1;
        return;
     }
+    
+    swf_ShapeSetEnd(tag);
 
     changeRect(tag, bboxrectpos, &bboxrect);
 
@@ -1581,14 +1638,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);
 }
 
 
@@ -2082,3 +2139,43 @@ void swfoutput_drawimageagain(struct swfoutput*obj, int id, int sizex,int sizey,
     drawimage(obj, id, sizex, sizey, x1,y1,x2,y2,x3,y3,x4,y4);
 }
 
+void swfoutput_setparameter(char*name, char*value)
+{
+    if(!strcmp(name, "drawonlyshapes")) {
+       drawonlyshapes = atoi(value);
+    } else if(!strcmp(name, "ignoredraworder")) {
+       ignoredraworder = atoi(value);
+    } else if(!strcmp(name, "filloverlap")) {
+       filloverlap = atoi(value);
+    } else if(!strcmp(name, "linksopennewwindow")) {
+       opennewwindow = atoi(value);
+    } else if(!strcmp(name, "opennewwindow")) {
+       opennewwindow = atoi(value);
+    } else if(!strcmp(name, "storeallcharacters")) {
+       storeallcharacters = atoi(value);
+    } else if(!strcmp(name, "enablezlib")) {
+       enablezlib = atoi(value);
+    } else if(!strcmp(name, "insertstop")) {
+       insertstoptag = atoi(value);
+    } else if(!strcmp(name, "flashversion")) {
+       flashversion = atoi(value);
+    } else if(!strcmp(name, "jpegquality")) {
+       int val = atoi(value);
+       if(val<0) val=0;
+       if(val>100) val=100;
+       jpegquality = val;
+    } else if(!strcmp(name, "splinequality")) {
+       int v = atoi(value);
+       v = 500-(v*5); // 100% = 0.25 pixel, 0% = 25 pixel
+       if(v<1) v = 1;
+       splinemaxerror = v;
+    } else if(!strcmp(name, "fontquality")) {
+       int v = atoi(value);
+       v = 500-(v*5); // 100% = 0.25 pixel, 0% = 25 pixel
+       if(v<1) v = 1;
+       fontsplinemaxerror = v;
+    } else {
+       fprintf(stderr, "unknown parameter: %s (=%s)\n", name, value);
+    }
+}
+