CIDFonts: look for external replacement.
[swftools.git] / pdf2swf / swfoutput.cc
index edb13a3..330c890 100644 (file)
@@ -35,6 +35,8 @@ int ignoredraworder=0;
 int drawonlyshapes=0;
 int jpegquality=85;
 int storeallcharacters=0;
+int enablezlib=0;
+int insertstoptag=0;
 static int flag_protected = 0;
 
 typedef unsigned char u8;
@@ -489,10 +491,10 @@ void swfoutput_drawpath(swfoutput*output, T1_OUTLINE*outline,
     if(textid>=0)
         endtext();
 
-    /* XXX the following is needed due to a bug in the SWF player.
-       Filled shapes consisting solely of curves don't get
-       filled correctly if they are in the same shape */
-    if(shapeid>=0 && fill) {
+    /* Multiple polygons in one shape don't overlap correctly, 
+       so we better start a new shape here if the polygon is filled
+     */
+    if(shapeid>=0 && fill && !ignoredraworder) {
        endshape();
     }
 
@@ -645,7 +647,7 @@ SWFFont::~SWFFont()
 
             swflastx=0;
             swflasty=0;
-            swf_SetU8(ftag,0x10); //0 fill bits, 0 linestyle bits
+            swf_SetU8(ftag,0x10); //1 fill bits, 0 linestyle bits
             SHAPE s;
             s.bits.fill = 1;
             s.bits.line = 0;
@@ -968,6 +970,14 @@ static void endpage(struct swfoutput*obj)
       endtext();
     while(clippos)
         swfoutput_endclip(obj);
+
+    if(insertstoptag) {
+       ActionTAG*atag=0;
+       atag = action_Stop(atag);
+       atag = action_End(atag);
+       tag = swf_InsertTag(tag,ST_DOACTION);
+       swf_ActionSet(tag,atag);
+    }
     tag = swf_InsertTag(tag,ST_SHOWFRAME);
 }
 
@@ -1013,8 +1023,14 @@ void swfoutput_destroy(struct swfoutput* obj)
  
     tag = swf_InsertTag(tag,ST_END);
 
-    if FAILED(swf_WriteSWF(fi,&swf)) 
-     logf("<error> WriteSWF() failed.\n");
+    if(enablezlib) {
+      if FAILED(swf_WriteSWC(fi,&swf)) 
+       logf("<error> WriteSWC() failed.\n");
+    } else {
+      if FAILED(swf_WriteSWF(fi,&swf)) 
+       logf("<error> WriteSWF() failed.\n");
+    }
+
     if(filename)
      close(fi);
     logf("<notice> SWF written\n");
@@ -1130,13 +1146,11 @@ void swfoutput_linktourl(struct swfoutput*obj, char*url, swfcoord*points)
     if(textid>=0)
      endtext();
     
-    actions = swf_ActionStart();
     if(opennewwindow)
-      action_GetUrl(url, "_parent");
+      actions = action_GetUrl(0, url, "_parent");
     else
-      action_GetUrl(url, "_this");
-      action_End();
-    swf_ActionEnd();
+      actions = action_GetUrl(0, url, "_this");
+    actions = action_End(actions);
     
     drawlink(obj, actions, 0, points,0);
 }
@@ -1149,10 +1163,8 @@ void swfoutput_linktopage(struct swfoutput*obj, int page, swfcoord*points)
     if(textid>=0)
      endtext();
    
-    actions = swf_ActionStart();
-      action_GotoFrame(page);
-      action_End();
-    swf_ActionEnd();
+      actions = action_GotoFrame(0, page);
+      actions = action_End(actions);
 
     drawlink(obj, actions, 0, points,0);
 }
@@ -1165,19 +1177,15 @@ void swfoutput_namedlink(struct swfoutput*obj, char*name, swfcoord*points)
     if(textid>=0)
      endtext();
    
-    actions1 = swf_ActionStart();
-      action_PushString("/:subtitle");
-      action_PushString(name);
-      action_SetVariable();
-      action_End();
-    swf_ActionEnd();
-
-    actions2 = swf_ActionStart();
-      action_PushString("/:subtitle");
-      action_PushString("");
-      action_SetVariable();
-      action_End();
-    swf_ActionEnd();
+      actions1 = action_PushString(0, "/:subtitle");
+      actions1 = action_PushString(actions1, name);
+      actions1 = action_SetVariable(actions1);
+      actions1 = action_End(actions1);
+
+      actions2 = action_PushString(0, "/:subtitle");
+      actions2 = action_PushString(actions2, "");
+      actions2 = action_SetVariable(actions2);
+      actions2 = action_End(actions2);
 
     drawlink(obj, actions1, actions2, points,1);
 
@@ -1344,23 +1352,28 @@ static void drawimage(struct swfoutput*obj, int bitid, int sizex,int sizey,
     if(y4>ymax) ymax=y4;
     if(x4<xmin) xmin=x4;
     if(y4<ymin) ymin=y4;
-    p1.x=x1;
-    p1.y=y1;
-    p2.x=x2;
-    p2.y=y2;
-    p3.x=x3;
-    p3.y=y3;
-    p4.x=x4;
-    p4.y=y4;
+    p1.x=x1; p1.y=y1;
+    p2.x=x2; p2.y=y2;
+    p3.x=x3; p3.y=y3;
+    p4.x=x4; p4.y=y4;
+
+    {p1.x = (int)(p1.x*20)/20.0;
+     p1.y = (int)(p1.y*20)/20.0;
+     p2.x = (int)(p2.x*20)/20.0;
+     p2.y = (int)(p2.y*20)/20.0;
+     p3.x = (int)(p3.x*20)/20.0;
+     p3.y = (int)(p3.y*20)/20.0;
+     p4.x = (int)(p4.x*20)/20.0;
+     p4.y = (int)(p4.y*20)/20.0;}
     
     MATRIX m;
-    m.sx = (int)(65536*20*(x4-x1))/sizex;
-    m.r1 = -(int)(65536*20*(y4-y1))/sizex;
-    m.r0 = (int)(65536*20*(x1-x2))/sizey;
-    m.sy = -(int)(65536*20*(y1-y2))/sizey;
+    m.sx = (int)(65536*20*(p4.x-p1.x)/sizex);
+    m.r1 = -(int)(65536*20*(p4.y-p1.y)/sizex);
+    m.r0 = (int)(65536*20*(p1.x-p2.x)/sizey);
+    m.sy = -(int)(65536*20*(p1.y-p2.y)/sizey);
 
-    m.tx = (int)(x1*20);
-    m.ty = (int)(y1*20);
+    m.tx = (int)(p1.x*20);
+    m.ty = (int)(p1.y*20);
   
     /* shape */
     myshapeid = ++currentswfid;
@@ -1368,7 +1381,7 @@ static void drawimage(struct swfoutput*obj, int bitid, int sizex,int sizey,
     swf_ShapeNew(&shape);
     //lsid = ShapeAddLineStyle(shape,obj->linewidth,&obj->strokergb);
     //fsid = ShapeAddSolidFillStyle(shape,&obj->fillrgb);
-    fsid = swf_ShapeAddBitmapFillStyle(shape,&m,bitid,0);
+    fsid = swf_ShapeAddBitmapFillStyle(shape,&m,bitid,1);
     swf_SetU16(tag, myshapeid);
     r.xmin = (int)(xmin*20);
     r.ymin = (int)(ymin*20);
@@ -1398,7 +1411,7 @@ static void drawimage(struct swfoutput*obj, int bitid, int sizex,int sizey,
     swf_ObjectPlace(tag,myshapeid,/*depth*/depth++,NULL,NULL,NULL);
 }
 
-int swfoutput_drawimagejpeg(struct swfoutput*obj, char*filename, int sizex,int sizey, 
+int swfoutput_drawimagejpeg_old(struct swfoutput*obj, char*filename, int sizex,int sizey, 
         double x1,double y1,
         double x2,double y2,
         double x3,double y3,
@@ -1424,6 +1437,29 @@ int swfoutput_drawimagejpeg(struct swfoutput*obj, char*filename, int sizex,int s
     return bitid;
 }
 
+int swfoutput_drawimagejpeg(struct swfoutput*obj, RGBA*mem, int sizex,int sizey, 
+        double x1,double y1,
+        double x2,double y2,
+        double x3,double y3,
+        double x4,double y4)
+{
+    TAG*oldtag;
+    JPEGBITS*jpeg;
+
+    if(shapeid>=0)
+     endshape();
+    if(textid>=0)
+     endtext();
+
+    int bitid = ++currentswfid;
+    oldtag = tag;
+    tag = swf_InsertTag(tag,ST_DEFINEBITSJPEG2);
+    swf_SetU16(tag, bitid);
+    swf_SetJPEGBits2(tag,sizex,sizey,mem,jpegquality);
+    drawimage(obj, bitid, sizex, sizey, x1,y1,x2,y2,x3,y3,x4,y4);
+    return bitid;
+}
+
 int swfoutput_drawimagelossless(struct swfoutput*obj, RGBA*mem, int sizex,int sizey, 
         double x1,double y1,
         double x2,double y2,
@@ -1450,27 +1486,46 @@ int swfoutput_drawimagelossless(struct swfoutput*obj, RGBA*mem, int sizex,int si
     return bitid;
 }
 
-int swfoutput_drawimagelossless256(struct swfoutput*obj, U8*mem, RGBA*pal, int sizex,int sizey, 
+int swfoutput_drawimagelosslessN(struct swfoutput*obj, U8*mem, RGBA*pal, int sizex,int sizey, 
         double x1,double y1,
         double x2,double y2,
         double x3,double y3,
-        double x4,double y4)
+        double x4,double y4, int n)
 {
     TAG*oldtag;
+    U8*mem2 = 0;
     if(shapeid>=0)
      endshape();
     if(textid>=0)
      endtext();
 
+    if(sizex&3)
+    { 
+       /* SWF expects scanlines to be 4 byte aligned */
+       int x,y;
+       U8*ptr;
+       mem2 = (U8*)malloc(BYTES_PER_SCANLINE(sizex)*sizey);
+       ptr = mem2;
+       for(y=0;y<sizey;y++)
+       {
+           for(x=0;x<sizex;x++)
+               *ptr++ = mem[y*sizex+x];
+           ptr+= BYTES_PER_SCANLINE(sizex)-sizex;
+       }
+       mem = mem2;
+    }
+
     int bitid = ++currentswfid;
     oldtag = tag;
     tag = swf_InsertTag(tag,ST_DEFINEBITSLOSSLESS2);
     swf_SetU16(tag, bitid);
-    if(swf_SetLosslessBitsIndexed(tag,sizex,sizey,mem, pal, 256)<0) {
+    if(swf_SetLosslessBitsIndexed(tag,sizex,sizey,mem, pal, n)<0) {
        swf_DeleteTag(tag);
        tag = oldtag;
        return -1;
     }
+    if(mem2)
+       free(mem2);
   
     drawimage(obj, bitid, sizex, sizey, x1,y1,x2,y2,x3,y3,x4,y4);
     return bitid;