fixed memory leaks.
[swftools.git] / pdf2swf / SWFOutputDev.cc
index 0b06f8d..0992ed9 100644 (file)
 #include "GfxFont.h"
 #include "CharCodeToUnicode.h"
 #include "NameToUnicodeTable.h"
-#include "FontFile.h"
 #include "GlobalParams.h"
+//#define XPDF_101
+#ifdef XPDF_101
+#include "FontFile.h"
+#else
+#include "FoFiType1C.h"
+#include "FoFiTrueType.h"
+#endif
+#include "SWFOutputDev.h"
+
 //swftools header files
 #include "swfoutput.h"
-#include "SWFOutputDev.h"
 #include "../lib/log.h"
 
 #include <math.h>
@@ -74,42 +81,14 @@ static int pagebuflen = 0;
 static int pagepos = 0;
 
 static double caplinewidth = 3.0;
+static int zoom = 72; /* xpdf: 86 */
 
 static void printInfoString(Dict *infoDict, char *key, char *fmt);
 static void printInfoDate(Dict *infoDict, char *key, char *fmt);
 
-static double fontsizes[] = 
-{
- 0.833,0.833,0.889,0.889,
- 0.788,0.722,0.833,0.778,
- 0.600,0.600,0.600,0.600,
- 0.576,0.576,0.576,0.576,
- 0.733 //?
-};
-static char*fontnames[]={
-"Helvetica",             
-"Helvetica-Bold",        
-"Helvetica-BoldOblique", 
-"Helvetica-Oblique",     
-"Times-Roman",           
-"Times-Bold",            
-"Times-BoldItalic",      
-"Times-Italic",          
-"Courier",               
-"Courier-Bold",          
-"Courier-BoldOblique",   
-"Courier-Oblique",       
-"Symbol",                
-"Symbol",                
-"Symbol",                
-"Symbol",
-"ZapfDingBats"
-};
-
 struct mapping {
     char*pdffont;
     char*filename;
-    int id;
 } pdf2t1map[] ={
 {"Times-Roman",           "n021003l"},
 {"Times-Italic",          "n021023l"},
@@ -126,9 +105,6 @@ struct mapping {
 {"Symbol",                "s050000l"},
 {"ZapfDingbats",          "d050000l"}};
 
-class GfxState;
-class GfxImageColorMap;
-
 class SWFOutputDev:  public OutputDev {
   struct swfoutput output;
   int outputstarted;
@@ -149,6 +125,9 @@ public:
   // Does this device use drawChar() or drawString()?
   virtual GBool useDrawChar();
   
+  // Can this device draw gradients?
+  virtual GBool useGradients();
+  
   virtual GBool interpretType3Chars() {return gTrue;}
 
   //----- initialization and control
@@ -230,10 +209,42 @@ public:
   int pbminfo; // did we write "File contains jpegs" yet?
   int linkinfo; // did we write "File contains links" yet?
   int ttfinfo; // did we write "File contains TrueType Fonts" yet?
+  int gradientinfo; // did we write "File contains Gradients yet?
 
   int type3active; // are we between beginType3()/endType3()?
 
   GfxState *laststate;
+
+  int pic_xids[1024];
+  int pic_yids[1024];
+  int pic_ids[1024];
+  int pic_width[1024];
+  int pic_height[1024];
+  int picpos;
+  int pic_id;
+  char type3Warning;
+
+  char* substitutetarget[256];
+  char* substitutesource[256];
+  int substitutepos;
+};
+
+SWFOutputDev::SWFOutputDev()
+{
+    jpeginfo = 0;
+    ttfinfo = 0;
+    linkinfo = 0;
+    pbminfo = 0;
+    type3active = 0;
+    clippos = 0;
+    clipping[clippos] = 0;
+    outputstarted = 0;
+    xref = 0;
+    picpos = 0;
+    pic_id = 0;
+    substitutepos = 0;
+    type3Warning = 0;
+//    printf("SWFOutputDev::SWFOutputDev() \n");
 };
 
 static char*getFontID(GfxFont*font)
@@ -258,8 +269,8 @@ static char*getFontName(GfxFont*font)
     return fontname;
 }
 
-char mybuf[1024];
-char* gfxstate2str(GfxState *state)
+static char mybuf[1024];
+static char* gfxstate2str(GfxState *state)
 {
   char*bufpos = mybuf;
   GfxRGB rgb;
@@ -365,16 +376,14 @@ char* gfxstate2str(GfxState *state)
   return mybuf;
 }
 
-
-
-void dumpFontInfo(char*loglevel, GfxFont*font);
-int lastdumps[1024];
-int lastdumppos = 0;
+static void dumpFontInfo(char*loglevel, GfxFont*font);
+static int lastdumps[1024];
+static int lastdumppos = 0;
 /* nr = 0  unknown
    nr = 1  substituting
    nr = 2  type 3
  */
-void showFontError(GfxFont*font, int nr) 
+static void showFontError(GfxFont*font, int nr) 
 {  
     Ref*r=font->getID();
     int t;
@@ -394,7 +403,7 @@ void showFontError(GfxFont*font, int nr)
     dumpFontInfo("<warning>", font);
 }
 
-void dumpFontInfo(char*loglevel, GfxFont*font)
+static void dumpFontInfo(char*loglevel, GfxFont*font)
 {
   char* name = getFontID(font);
   Ref* r=font->getID();
@@ -456,19 +465,14 @@ void dumpFontInfo(char*loglevel, GfxFont*font)
 //void SWFOutputDev::drawImageMask(GfxState *state, Object *ref, Stream *str, int width, int height, GBool invert, GBool inlineImg) {printf("void SWFOutputDev::drawImageMask(GfxState *state, Object *ref, Stream *str, int width, int height, GBool invert, GBool inlineImg) \n");}
 //void SWFOutputDev::drawImage(GfxState *state, Object *ref, Stream *str, int width, int height, GfxImageColorMap *colorMap, GBool inlineImg) {printf("void SWFOutputDev::drawImage(GfxState *state, Object *ref, Stream *str, int width, int height, GfxImageColorMap *colorMap, GBool inlineImg) \n");}
 
-SWFOutputDev::SWFOutputDev() 
+static void free_outline(SWF_OUTLINE*outline)
 {
-    jpeginfo = 0;
-    ttfinfo = 0;
-    linkinfo = 0;
-    pbminfo = 0;
-    type3active = 0;
-    clippos = 0;
-    clipping[clippos] = 0;
-    outputstarted = 0;
-    xref = 0;
-//    printf("SWFOutputDev::SWFOutputDev() \n");
-};
+    while(outline) {
+        SWF_OUTLINE*next = outline->link;
+        free(outline);
+        outline = next;
+    }
+}
 
 SWF_OUTLINE* gfxPath_to_SWF_OUTLINE(GfxState*state, GfxPath*path)
 {
@@ -579,6 +583,7 @@ void SWFOutputDev::stroke(GfxState *state)
        updateStrokeColor(state); //reset
        updateFillColor(state);  //reset
     }
+    free_outline(outline);
 }
 void SWFOutputDev::fill(GfxState *state) 
 {
@@ -628,6 +633,7 @@ void SWFOutputDev::eoClip(GfxState *state)
 
 SWFOutputDev::~SWFOutputDev() 
 {
+    swfoutput_save(&output, swffilename);
     swfoutput_destroy(&output);
     outputstarted = 0;
 };
@@ -640,6 +646,15 @@ GBool SWFOutputDev::useDrawChar()
 {
     return gTrue;
 }
+GBool SWFOutputDev::useGradients()
+{
+    if(!gradientinfo)
+    {
+       msg("<notice> File contains gradients");
+       gradientinfo = 1;
+    }
+    return gTrue;
+}
 
 void SWFOutputDev::beginString(GfxState *state, GString *s) 
 { 
@@ -649,9 +664,6 @@ void SWFOutputDev::beginString(GfxState *state, GString *s)
     m11 *= state->getHorizScaling();
     m21 *= state->getHorizScaling();
     swfoutput_setfontmatrix(&output, m11, -m21, m12, -m22);
-    
-    msg("<debug> fontmatrix %7.3f %7.3f\n", m11,-m21);
-    msg("<debug> fontmatrix %7.3f %7.3f\n", m12,-m22);
 }
 
 void SWFOutputDev::drawChar(GfxState *state, double x, double y,
@@ -673,11 +685,11 @@ void SWFOutputDev::drawChar(GfxState *state, double x, double y,
     x1 = x;
     y1 = y;
     state->transform(x, y, &x1, &y1);
-       
+    
     Unicode u=0;
-    if(_u) 
+    if(_u && uLen) 
        u = *_u;
-    
+
     /* find out the character name */
     char*name=0;
     if(font->isCIDFont() && u) {
@@ -700,9 +712,9 @@ void SWFOutputDev::drawChar(GfxState *state, double x, double y,
     
     msg("<debug> drawChar(%f,%f,c='%c' (%d),u=%d <%d>) CID=%d name=\"%s\"\n",x,y,(c&127)>=32?c:'?',c,u, uLen, font->isCIDFont(), FIXNULL(name));
 
-    x1 = (int)(x1+0.5);
-    y1 = (int)(y1+0.5);
-
+    /*x1 = (int)(x1+0.5);
+    y1 = (int)(y1+0.5);*/
+    
     int ret = swfoutput_drawchar(&output, x1, y1, name, c, u);
 }
 
@@ -735,8 +747,6 @@ void SWFOutputDev::startPage(int pageNum, GfxState *state, double crop_x1, doubl
   if(rot!=0)
     msg("<verbose> page is rotated %d degrees\n", rot);
 
-  msg("<notice> processing page %d", pageNum);
-
   /* state->transform(state->getX1(),state->getY1(),&x1,&y1);
   state->transform(state->getX2(),state->getY2(),&x2,&y2);
   Use CropBox, not MediaBox, as page size
@@ -754,24 +764,26 @@ void SWFOutputDev::startPage(int pageNum, GfxState *state, double crop_x1, doubl
 
   if(!outputstarted) {
     msg("<verbose> Bounding box is (%f,%f)-(%f,%f)", x1,y1,x2,y2);
-    swfoutput_init(&output, swffilename,(int)x1,(int)y1,(int)x2,(int)y2);
+    swfoutput_init(&output);
     outputstarted = 1;
   }
-  else
-    swfoutput_newpage(&output);
+    
+  swfoutput_newpage(&output, pageNum, (int)x1, (int)y1, (int)x2, (int)y2);
 }
 
 void SWFOutputDev::drawLink(Link *link, Catalog *catalog) 
 {
-  msg("<debug> drawlink\n");
-  double x1, y1, x2, y2, w;
-  GfxRGB rgb;
-  swfcoord points[5];
-  int x, y;
+    msg("<debug> drawlink\n");
+    double x1, y1, x2, y2, w;
+    GfxRGB rgb;
+    swfcoord points[5];
+    int x, y;
 
-  link->getBorder(&x1, &y1, &x2, &y2, &w);
-//  if (w > 0) 
-  {
+#ifdef XPDF_101
+    link->getBorder(&x1, &y1, &x2, &y2, &w);
+#else
+    link->getRect(&x1, &y1, &x2, &y2);
+#endif
     rgb.r = 0;
     rgb.g = 0;
     rgb.b = 1;
@@ -790,121 +802,124 @@ void SWFOutputDev::drawLink(Link *link, Catalog *catalog)
 
     LinkAction*action=link->getAction();
     char buf[128];
-    char*s = "-?-";
+    char*s = 0;
     char*type = "-?-";
     char*url = 0;
     char*named = 0;
     int page = -1;
     switch(action->getKind())
     {
-       case actionGoTo: {
-           type = "GoTo";
-           LinkGoTo *ha=(LinkGoTo *)link->getAction();
-           LinkDest *dest=NULL;
-           if (ha->getDest()==NULL) 
-               dest=catalog->findDest(ha->getNamedDest());
-           else dest=ha->getDest();
-           if (dest){ 
-             if (dest->isPageRef()){
-               Ref pageref=dest->getPageRef();
-               page=catalog->findPage(pageref.num,pageref.gen);
-             }
-             else  page=dest->getPageNum();
-             sprintf(buf, "%d", page);
-             s = buf;
-           }
-       }
+        case actionGoTo: {
+            type = "GoTo";
+            LinkGoTo *ha=(LinkGoTo *)link->getAction();
+            LinkDest *dest=NULL;
+            if (ha->getDest()==NULL) 
+                dest=catalog->findDest(ha->getNamedDest());
+            else dest=ha->getDest();
+            if (dest){ 
+              if (dest->isPageRef()){
+                Ref pageref=dest->getPageRef();
+                page=catalog->findPage(pageref.num,pageref.gen);
+              }
+              else  page=dest->getPageNum();
+              sprintf(buf, "%d", page);
+              s = strdup(buf);
+            }
+        }
         break;
-       case actionGoToR: {
-           type = "GoToR";
-           LinkGoToR*l = (LinkGoToR*)action;
-           GString*g = l->getNamedDest();
-           if(g)
-            s = g->getCString();
-       }
+        case actionGoToR: {
+            type = "GoToR";
+            LinkGoToR*l = (LinkGoToR*)action;
+            GString*g = l->getNamedDest();
+            if(g)
+             s = strdup(g->getCString());
+        }
         break;
-       case actionNamed: {
-           type = "Named";
-           LinkNamed*l = (LinkNamed*)action;
-           GString*name = l->getName();
-           if(name) {
-               s = name->lowerCase()->getCString();
-               named = name->getCString();
-               if(!strchr(s,':')) 
-               {
-                   if(strstr(s, "next") || strstr(s, "forward"))
-                   {
-                       page = currentpage + 1;
-                   }
-                   else if(strstr(s, "prev") || strstr(s, "back"))
-                   {
-                       page = currentpage - 1;
-                   }
-                   else if(strstr(s, "last") || strstr(s, "end"))
-                   {
-                       page = pages[pagepos-1]; //:)
-                   }
-                   else if(strstr(s, "first") || strstr(s, "top"))
-                   {
-                       page = 1;
-                   }
-               }
-           }
-       }
+        case actionNamed: {
+            type = "Named";
+            LinkNamed*l = (LinkNamed*)action;
+            GString*name = l->getName();
+            if(name) {
+                s = strdup(name->lowerCase()->getCString());
+                named = name->getCString();
+                if(!strchr(s,':')) 
+                {
+                    if(strstr(s, "next") || strstr(s, "forward"))
+                    {
+                        page = currentpage + 1;
+                    }
+                    else if(strstr(s, "prev") || strstr(s, "back"))
+                    {
+                        page = currentpage - 1;
+                    }
+                    else if(strstr(s, "last") || strstr(s, "end"))
+                    {
+                        page = pages[pagepos-1]; //:)
+                    }
+                    else if(strstr(s, "first") || strstr(s, "top"))
+                    {
+                        page = 1;
+                    }
+                }
+            }
+        }
         break;
-       case actionLaunch: {
-           type = "Launch";
-           LinkLaunch*l = (LinkLaunch*)action;
-           GString * str = new GString(l->getFileName());
-           str->append(l->getParams());
-           s = str->getCString();
-       }
+        case actionLaunch: {
+            type = "Launch";
+            LinkLaunch*l = (LinkLaunch*)action;
+            GString * str = new GString(l->getFileName());
+            str->append(l->getParams());
+            s = strdup(str->getCString());
+            delete str;
+        }
         break;
-       case actionURI: {
-           type = "URI";
-           LinkURI*l = (LinkURI*)action;
-           GString*g = l->getURI();
-           if(g) {
-            url = g->getCString();
-            s = url;
-           }
-       }
+        case actionURI: {
+            type = "URI";
+            LinkURI*l = (LinkURI*)action;
+            GString*g = l->getURI();
+            if(g) {
+             url = g->getCString();
+             s = strdup(url);
+            }
+        }
         break;
-       case actionUnknown: {
-           type = "Unknown";
-           LinkUnknown*l = (LinkUnknown*)action;
-           s = "";
-       }
+        case actionUnknown: {
+            type = "Unknown";
+            LinkUnknown*l = (LinkUnknown*)action;
+            s = strdup("");
+        }
         break;
-       default: {
-           msg("<error> Unknown link type!\n");
-           break;
-       }
+        default: {
+            msg("<error> Unknown link type!\n");
+            break;
+        }
     }
+    if(!s) s = strdup("-?-");
+
     if(!linkinfo && (page || url))
     {
-       msg("<notice> File contains links");
-       linkinfo = 1;
+        msg("<notice> File contains links");
+        linkinfo = 1;
     }
     if(page>0)
     {
-       int t;
-       for(t=0;t<pagepos;t++)
-           if(pages[t]==page)
-               break;
-       if(t!=pagepos)
-       swfoutput_linktopage(&output, t, points);
+        int t;
+        for(t=0;t<pagepos;t++)
+            if(pages[t]==page)
+                break;
+        if(t!=pagepos)
+        swfoutput_linktopage(&output, t, points);
     }
     else if(url)
     {
-       swfoutput_linktourl(&output, url, points);
+        swfoutput_linktourl(&output, url, points);
     }
     else if(named)
     {
-       swfoutput_namedlink(&output, named, points);
+        swfoutput_namedlink(&output, named, points);
     }
     msg("<verbose> \"%s\" link to \"%s\" (%d)\n", type, FIXNULL(s), page);
-  }
+    free(s);s=0;
 }
 
 void SWFOutputDev::saveState(GfxState *state) {
@@ -927,8 +942,6 @@ void SWFOutputDev::restoreState(GfxState *state) {
   clippos--;
 }
 
-char type3Warning=0;
-
 char* SWFOutputDev::searchFont(char*name) 
 {      
     int i;
@@ -1000,6 +1013,11 @@ void SWFOutputDev::updateStrokeColor(GfxState *state)
                                      (char)(rgb.b*255), (char)(opaq*255));
 }
 
+void FoFiWrite(void *stream, char *data, int len)
+{
+   fwrite(data, len, 1, (FILE*)stream);
+}
+
 char*SWFOutputDev::writeEmbeddedFontToFile(XRef*ref, GfxFont*font)
 {
     char*tmpFileName = NULL;
@@ -1040,8 +1058,13 @@ char*SWFOutputDev::writeEmbeddedFontToFile(XRef*ref, GfxFont*font)
        msg("<error> Couldn't read embedded font file");
        return 0;
       }
+#ifdef XPDF_101
       Type1CFontFile *cvt = new Type1CFontFile(fontBuf, fontLen);
       cvt->convertToType1(f);
+#else
+      FoFiType1C *cvt = FoFiType1C::make(fontBuf, fontLen);
+      cvt->convertToType1(NULL, gTrue, FoFiWrite, f);
+#endif
       //cvt->convertToCIDType0("test", f);
       //cvt->convertToType0("test", f);
       delete cvt;
@@ -1053,8 +1076,13 @@ char*SWFOutputDev::writeEmbeddedFontToFile(XRef*ref, GfxFont*font)
        msg("<error> Couldn't read embedded font file");
        return 0;
       }
+#ifdef XPDF_101
       TrueTypeFontFile *cvt = new TrueTypeFontFile(fontBuf, fontLen);
       cvt->writeTTF(f);
+#else
+      FoFiTrueType *cvt = FoFiTrueType::make(fontBuf, fontLen);
+      cvt->writeTTF(FoFiWrite, f);
+#endif
       delete cvt;
       gfree(fontBuf);
     } else {
@@ -1096,11 +1124,6 @@ char*SWFOutputDev::writeEmbeddedFontToFile(XRef*ref, GfxFont*font)
     return strdup(tmpFileName);
 }
 
-
-char* substitutetarget[256];
-char* substitutesource[256];
-int substitutepos = 0;
-
 char* searchForSuitableFont(GfxFont*gfxFont)
 {
     char*name = getFontName(gfxFont);
@@ -1334,14 +1357,6 @@ void SWFOutputDev::updateFont(GfxState *state)
        unlinkfont(fileName);
 }
 
-int pic_xids[1024];
-int pic_yids[1024];
-int pic_ids[1024];
-int pic_width[1024];
-int pic_height[1024];
-int picpos = 0;
-int pic_id = 0;
-
 #define SQR(x) ((x)*(x))
 
 unsigned char* antialize(unsigned char*data, int width, int height, int newwidth, int newheight, int palettesize)
@@ -1711,66 +1726,70 @@ static void printInfoDate(Dict *infoDict, char *key, char *fmt) {
 
 void pdfswf_init(char*filename, char*userPassword) 
 {
-  GString *fileName = new GString(filename);
-  GString *userPW;
-  Object info;
-
-  // read config file
-  globalParams = new GlobalParams("");
-
-  // open PDF file
-  if (userPassword && userPassword[0]) {
-    userPW = new GString(userPassword);
-  } else {
-    userPW = NULL;
-  }
-  doc = new PDFDoc(fileName, userPW);
-  if (userPW) {
-    delete userPW;
-  }
-  if (!doc->isOk()) {
-    exit(1);
-  }
+    GString *fileName = new GString(filename);
+    GString *userPW;
+    Object info;
 
-  // print doc info
-  doc->getDocInfo(&info);
-  if (info.isDict() &&
-    (screenloglevel>=LOGLEVEL_NOTICE)) {
-    printInfoString(info.getDict(), "Title",        "Title:        %s\n");
-    printInfoString(info.getDict(), "Subject",      "Subject:      %s\n");
-    printInfoString(info.getDict(), "Keywords",     "Keywords:     %s\n");
-    printInfoString(info.getDict(), "Author",       "Author:       %s\n");
-    printInfoString(info.getDict(), "Creator",      "Creator:      %s\n");
-    printInfoString(info.getDict(), "Producer",     "Producer:     %s\n");
-    printInfoDate(info.getDict(),   "CreationDate", "CreationDate: %s\n");
-    printInfoDate(info.getDict(),   "ModDate",      "ModDate:      %s\n");
-    printf("Pages:        %d\n", doc->getNumPages());
-    printf("Linearized:   %s\n", doc->isLinearized() ? "yes" : "no");
-    printf("Encrypted:    ");
-    if (doc->isEncrypted()) {
-      printf("yes (print:%s copy:%s change:%s addNotes:%s)\n",
-            doc->okToPrint() ? "yes" : "no",
-            doc->okToCopy() ? "yes" : "no",
-            doc->okToChange() ? "yes" : "no",
-            doc->okToAddNotes() ? "yes" : "no");
+    // read config file
+    globalParams = new GlobalParams("");
+
+    // open PDF file
+    if (userPassword && userPassword[0]) {
+      userPW = new GString(userPassword);
     } else {
-      printf("no\n");
+      userPW = NULL;
     }
-  }
-  info.free();
-                
-  numpages = doc->getNumPages();
-  if (doc->isEncrypted()) {
-       if(!doc->okToCopy()) {
-           printf("PDF disallows copying. Bailing out.\n");
-           exit(1); //bail out
-       }
-       if(!doc->okToChange() || !doc->okToAddNotes())
-           swfoutput_setprotected();
-  }
+    doc = new PDFDoc(fileName, userPW);
+    if (userPW) {
+      delete userPW;
+    }
+    if (!doc->isOk()) {
+      exit(1);
+    }
+
+    // print doc info
+    doc->getDocInfo(&info);
+    if (info.isDict() &&
+      (screenloglevel>=LOGLEVEL_NOTICE)) {
+      printInfoString(info.getDict(), "Title",        "Title:        %s\n");
+      printInfoString(info.getDict(), "Subject",      "Subject:      %s\n");
+      printInfoString(info.getDict(), "Keywords",     "Keywords:     %s\n");
+      printInfoString(info.getDict(), "Author",       "Author:       %s\n");
+      printInfoString(info.getDict(), "Creator",      "Creator:      %s\n");
+      printInfoString(info.getDict(), "Producer",     "Producer:     %s\n");
+      printInfoDate(info.getDict(),   "CreationDate", "CreationDate: %s\n");
+      printInfoDate(info.getDict(),   "ModDate",      "ModDate:      %s\n");
+      printf("Pages:        %d\n", doc->getNumPages());
+      printf("Linearized:   %s\n", doc->isLinearized() ? "yes" : "no");
+      printf("Encrypted:    ");
+      if (doc->isEncrypted()) {
+        printf("yes (print:%s copy:%s change:%s addNotes:%s)\n",
+               doc->okToPrint() ? "yes" : "no",
+               doc->okToCopy() ? "yes" : "no",
+               doc->okToChange() ? "yes" : "no",
+               doc->okToAddNotes() ? "yes" : "no");
+      } else {
+        printf("no\n");
+      }
+    }
+    info.free();
+                   
+    numpages = doc->getNumPages();
+    int protect = 0;
+    if (doc->isEncrypted()) {
+          if(!doc->okToCopy()) {
+              printf("PDF disallows copying. Terminating.\n");
+              exit(1); //bail out
+          }
+          if(!doc->okToChange() || !doc->okToAddNotes())
+              protect = 1;
+    }
+   
+    if(protect)
+        swfoutput_setparameter("protect", "1");
 
-  output = new SWFOutputDev();
-  output->startDoc(doc->getXRef());
+    output = new SWFOutputDev();
+    output->startDoc(doc->getXRef());
 }
 
 void pdfswf_setparameter(char*name, char*value)
@@ -1779,6 +1798,8 @@ void pdfswf_setparameter(char*name, char*value)
        swffilename = value;
     } else if(!strcmp(name, "caplinewidth")) {
        caplinewidth = atof(value);
+    } else if(!strcmp(name, "zoom")) {
+       zoom = atoi(value);
     } else {
        swfoutput_setparameter(name, value);
     }
@@ -1792,26 +1813,7 @@ void pdfswf_addfont(char*filename)
     fonts[fontnum++] = f;
 }
 
-/* TODO: get rid of this */
-void pdfswf_drawonlyshapes() { pdfswf_setparameter("drawonlyshapes", "1"); }
-void pdfswf_ignoredraworder() { pdfswf_setparameter("ignoredraworder", "1"); }
-void pdfswf_linksopennewwindow() { pdfswf_setparameter("opennewwindow", "1"); }
-void pdfswf_storeallcharacters() { pdfswf_setparameter("storeallcharacters", "1"); }
-void pdfswf_enablezlib() { pdfswf_setparameter("enablezlib", "1"); }
 void pdfswf_setoutputfilename(char*_filename) { swffilename = _filename; }
-void pdfswf_insertstop() { pdfswf_setparameter("insertstoptag", "1"); }
-void pdfswf_jpegquality(int val) {
-    char tmp[32];
-    sprintf(tmp, "%d", val);
-    pdfswf_setparameter("jpegquality", tmp);
-}
-void pdfswf_setversion(int n) {
-    char tmp[32];
-    sprintf(tmp, "%d", n);
-    pdfswf_setparameter("flashversion", tmp);
-}
-
-
 
 void pdfswf_convertpage(int page)
 {
@@ -1835,19 +1837,23 @@ void pdfswf_performconversion()
     for(t=0;t<pagepos;t++)
     {
        currentpage = pages[t];
-       doc->displayPage((OutputDev*)output, currentpage, /*dpi*/72, /*rotate*/0, /*doLinks*/(int)1);
+#ifdef XPDF_101
+       doc->displayPage((OutputDev*)output, currentpage, /*zoom*/zoom, /*rotate*/0, /*doLinks*/(int)1);
+#else
+       doc->displayPage((OutputDev*)output, currentpage, zoom, zoom, /*rotate*/0, true, /*doLinks*/(int)1);
+#endif
     }
 }
 int pdfswf_numpages()
 {
   return doc->getNumPages();
 }
-int closed=0;
 void pdfswf_close()
 {
     msg("<debug> pdfswf.cc: pdfswf_close()");
-    delete output;
-    delete doc;
+    delete output; output=0;
+    delete doc; doc=0;
+    free(pages); pages = 0;
     //freeParams();
     // check for memory leaks
     Object::memCheck(stderr);