moved static variables into a structure.
[swftools.git] / pdf2swf / SWFOutputDev.cc
index 8d564a7..81a6211 100644 (file)
@@ -23,6 +23,9 @@
 #include <string.h>
 #include <unistd.h>
 #include "../config.h"
+#ifdef HAVE_FONTCONFIG_H
+#include <fontconfig.h>
+#endif
 //xpdf header files
 #include "config.h"
 #include "gfile.h"
 #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 "../lib/log.h"
@@ -55,7 +66,13 @@ static char* swffilename = 0;
 static int numpages;
 static int currentpage;
 
-static char*fonts[2048];
+typedef struct _fontfile
+{
+    char*filename;
+    int used;
+} fontfile_t;
+
+static fontfile_t fonts[2048];
 static int fontnum = 0;
 
 // swf <-> pdf pages
@@ -64,38 +81,11 @@ 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;
@@ -116,9 +106,6 @@ struct mapping {
 {"Symbol",                "s050000l"},
 {"ZapfDingbats",          "d050000l"}};
 
-class GfxState;
-class GfxImageColorMap;
-
 class SWFOutputDev:  public OutputDev {
   struct swfoutput output;
   int outputstarted;
@@ -139,6 +126,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
@@ -220,13 +210,45 @@ 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;
 };
 
-char*getFontName(GfxFont*font)
+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)
 {
     GString*gstr = font->getName();
     char* fontname = gstr==0?0:gstr->getCString();
@@ -236,14 +258,20 @@ char*getFontName(GfxFont*font)
        sprintf(buf, "UFONT%d", r->num);
        return strdup(buf);
     }
+    return fontname;
+}
+
+static char*getFontName(GfxFont*font)
+{
+    char*fontname = getFontID(font);
     char* plus = strchr(fontname, '+');
     if(plus && plus < &fontname[strlen(fontname)-1])
        fontname = plus+1;
     return fontname;
 }
 
-char mybuf[1024];
-char* gfxstate2str(GfxState *state)
+static char mybuf[1024];
+static char* gfxstate2str(GfxState *state)
 {
   char*bufpos = mybuf;
   GfxRGB rgb;
@@ -321,8 +349,8 @@ char* gfxstate2str(GfxState *state)
   if(state->getLineJoin()!=0)
   bufpos+=sprintf(bufpos,"ML%d ", state->getMiterLimit());
 
-  if(state->getFont() && getFontName(state->getFont()))
-  bufpos+=sprintf(bufpos,"F\"%s\" ",getFontName(state->getFont()));
+  if(state->getFont() && getFontID(state->getFont()))
+  bufpos+=sprintf(bufpos,"F\"%s\" ",getFontID(state->getFont()));
   bufpos+=sprintf(bufpos,"FS%.1f ", state->getFontSize());
   bufpos+=sprintf(bufpos,"MAT[%.1f/%.1f/%.1f/%.1f/%.1f/%.1f] ", state->getTextMat()[0],state->getTextMat()[1],state->getTextMat()[2],
                                   state->getTextMat()[3],state->getTextMat()[4],state->getTextMat()[5]);
@@ -349,16 +377,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;
@@ -378,11 +404,11 @@ void showFontError(GfxFont*font, int nr)
     dumpFontInfo("<warning>", font);
 }
 
-void dumpFontInfo(char*loglevel, GfxFont*font)
+static void dumpFontInfo(char*loglevel, GfxFont*font)
 {
-  char* name = getFontName(font);
+  char* name = getFontID(font);
   Ref* r=font->getID();
-  msg("%s=========== %s (ID:%d,%d) ==========\n", loglevel, name, r->num,r->gen);
+  msg("%s=========== %s (ID:%d,%d) ==========\n", loglevel, getFontName(font), r->num,r->gen);
 
   GString*gstr  = font->getTag();
    
@@ -440,20 +466,6 @@ 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() 
-{
-    jpeginfo = 0;
-    ttfinfo = 0;
-    linkinfo = 0;
-    pbminfo = 0;
-    type3active = 0;
-    clippos = 0;
-    clipping[clippos] = 0;
-    outputstarted = 0;
-    xref = 0;
-//    printf("SWFOutputDev::SWFOutputDev() \n");
-};
-
 SWF_OUTLINE* gfxPath_to_SWF_OUTLINE(GfxState*state, GfxPath*path)
 {
     int num = path->getNumSubpaths();
@@ -624,6 +636,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) 
 { 
@@ -654,11 +675,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) {
@@ -679,8 +700,11 @@ void SWFOutputDev::drawChar(GfxState *state, double x, double y,
           name = enc[c];
     }
     
-    msg("<debug> drawChar(%f,%f,c='%c' (%d),u=%d <%d>) CID=%d name=\"%s\"\n",x1,y1,(c&127)>=32?c:'?',c,u, uLen, font->isCIDFont(), FIXNULL(name));
+    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);*/
+    
     int ret = swfoutput_drawchar(&output, x1, y1, name, c, u);
 }
 
@@ -713,8 +737,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
@@ -732,11 +754,11 @@ 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, swffilename);
     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) 
@@ -747,7 +769,11 @@ void SWFOutputDev::drawLink(Link *link, Catalog *catalog)
   swfcoord points[5];
   int x, y;
 
+#ifdef XPDF_101
   link->getBorder(&x1, &y1, &x2, &y2, &w);
+#else
+  link->getRect(&x1, &y1, &x2, &y2);
+#endif
 //  if (w > 0) 
   {
     rgb.r = 0;
@@ -905,14 +931,13 @@ void SWFOutputDev::restoreState(GfxState *state) {
   clippos--;
 }
 
-char type3Warning=0;
-
 char* SWFOutputDev::searchFont(char*name) 
 {      
     int i;
     char*filename=0;
+    int is_standard_font = 0;
        
-    msg("<verbose> SearchT1Font(%s)", name);
+    msg("<verbose> SearchFont(%s)", name);
 
     /* see if it is a pdf standard font */
     for(i=0;i<sizeof(pdf2t1map)/sizeof(mapping);i++) 
@@ -920,15 +945,22 @@ char* SWFOutputDev::searchFont(char*name)
        if(!strcmp(name, pdf2t1map[i].pdffont))
        {
            name = pdf2t1map[i].filename;
+           is_standard_font = 1;
            break;
        }
     }
     /* look in all font files */
     for(i=0;i<fontnum;i++) 
     {
-       if(strstr(fonts[i], name))
+       if(strstr(fonts[i].filename, name))
        {
-           return fonts[i];
+           if(!fonts[i].used) {
+
+               fonts[i].used = 1;
+               if(!is_standard_font)
+                   msg("<notice> Using %s for %s", fonts[i].filename, name);
+           }
+           return fonts[i].filename;
        }
     }
     return 0;
@@ -970,6 +1002,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;
@@ -996,6 +1033,13 @@ char*SWFOutputDev::writeEmbeddedFontToFile(XRef*ref, GfxFont*font)
       msg("<error> Couldn't create temporary Type 1 font file");
        return 0;
     }
+
+    /*if(font->isCIDFont()) {
+       GfxCIDFont* cidFont = (GfxCIDFont *)font;
+       GString c = cidFont->getCollection();
+       msg("<notice> Collection: %s", c.getCString());
+    }*/
+
     if (font->getType() == fontType1C ||
        font->getType() == fontCIDType0C) {
       if (!(fontBuf = font->readEmbFontFile(xref, &fontLen))) {
@@ -1003,8 +1047,15 @@ 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;
       gfree(fontBuf);
     } else if(font->getType() == fontTrueType) {
@@ -1014,8 +1065,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 {
@@ -1057,16 +1113,106 @@ char*SWFOutputDev::writeEmbeddedFontToFile(XRef*ref, GfxFont*font)
     return strdup(tmpFileName);
 }
 
+char* searchForSuitableFont(GfxFont*gfxFont)
+{
+    char*name = getFontName(gfxFont);
+    char*fontname = 0;
+    char*filename = 0;
+    
+#ifdef HAVE_FONTCONFIG
+    FcPattern *pattern, *match;
+    FcResult result;
+    FcChar8 *v;
+
+    // call init ony once
+    static int fcinitcalled = false; 
+    if (!fcinitcalled) {
+        fcinitcalled = true;
+       FcInit();
+    }
+   
+    pattern = FcPatternBuild(NULL, FC_FAMILY, FcTypeString, name, NULL);
+    if (gfxFont->isItalic()) // check for italic
+       FcPatternAddInteger(pattern, FC_SLANT, FC_SLANT_ITALIC);
+    if (gfxFont->isBold()) // check for bold
+        FcPatternAddInteger(pattern, FC_WEIGHT, FC_WEIGHT_BOLD);
+
+    // configure and match using the original font name 
+    FcConfigSubstitute(0, pattern, FcMatchPattern); 
+    FcDefaultSubstitute(pattern);
+    match = FcFontMatch(0, pattern, &result);
+    
+    if (FcPatternGetString(match, "family", 0, &v) == FcResultMatch) {
+        // if we get an exact match
+        if (strcmp((char *)v, name) == 0) {
+           if (FcPatternGetString(match, "file", 0, &v) == FcResultMatch) {
+               filename = strdup((char*)v);
+               char *nfn = strrchr(filename, '/');
+               if(nfn) fontname = strdup(nfn+1);
+               else    fontname = filename;
+            }
+        } else {
+            // initialize patterns
+            FcPatternDestroy(pattern);
+           FcPatternDestroy(match);
+
+            // now match against serif etc.
+           if (gfxFont->isSerif()) {
+                pattern = FcPatternBuild (NULL, FC_FAMILY, FcTypeString, "serif", NULL);
+            } else if (gfxFont->isFixedWidth()) {
+                pattern = FcPatternBuild (NULL, FC_FAMILY, FcTypeString, "monospace", NULL);
+            } else {
+                pattern = FcPatternBuild (NULL, FC_FAMILY, FcTypeString, "sans", NULL);
+            }
+
+            // check for italic
+            if (gfxFont->isItalic()) {
+                int bb = FcPatternAddInteger(pattern, FC_SLANT, FC_SLANT_ITALIC);
+            }
+            // check for bold
+            if (gfxFont->isBold()) {
+                int bb = FcPatternAddInteger(pattern, FC_WEIGHT, FC_WEIGHT_BOLD);
+            }
+
+            // configure and match using serif etc
+           FcConfigSubstitute (0, pattern, FcMatchPattern);
+            FcDefaultSubstitute (pattern);
+            match = FcFontMatch (0, pattern, &result);
+            
+            if (FcPatternGetString(match, "file", 0, &v) == FcResultMatch) {
+               filename = strdup((char*)v);
+               char *nfn = strrchr(filename, '/');
+               if(nfn) fontname = strdup(nfn+1);
+               else    fontname = filename;
+           }
+        }        
+    }
 
-char* substitutetarget[256];
-char* substitutesource[256];
-int substitutepos = 0;
+    //printf("FONTCONFIG: pattern");
+    //FcPatternPrint(pattern);
+    //printf("FONTCONFIG: match");
+    //FcPatternPrint(match);
+    FcPatternDestroy(pattern);
+    FcPatternDestroy(match);
+
+    pdfswf_addfont(filename);
+    return fontname;
+#else
+    return 0;
+#endif
+}
 
 char* SWFOutputDev::substituteFont(GfxFont*gfxFont, char* oldname)
 {
-    char*fontname = "Times-Roman";
-    msg("<verbose> substituteFont(,%s)", FIXNULL(oldname));
-    char*filename = searchFont(fontname);
+    char*fontname = 0, *filename = 0;
+    msg("<notice> subsituteFont(%s)", oldname);
+
+    if(!(fontname = searchForSuitableFont(gfxFont))) {
+       fontname = "Times-Roman";
+    }
+    filename = searchFont(fontname);
+
     if(substitutepos>=sizeof(substitutesource)/sizeof(char*)) {
        msg("<fatal> Too many fonts in file.");
        exit(1);
@@ -1122,33 +1268,36 @@ void SWFOutputDev::updateFont(GfxState *state)
     if (!gfxFont) {
        return;
     }  
-    char * fontname = getFontName(gfxFont);
+    char * fontid = getFontID(gfxFont);
     
     int t;
     /* first, look if we substituted this font before-
        this way, we don't initialize the T1 Fonts
        too often */
     for(t=0;t<substitutepos;t++) {
-       if(!strcmp(fontname, substitutesource[t])) {
-           fontname = substitutetarget[t];
+       if(!strcmp(fontid, substitutesource[t])) {
+           fontid = substitutetarget[t];
            break;
        }
     }
 
     /* second, see if swfoutput already has this font
        cached- if so, we are done */
-    if(swfoutput_queryfont(&output, fontname))
+    if(swfoutput_queryfont(&output, fontid))
     {
-       swfoutput_setfont(&output, fontname, 0);
+       swfoutput_setfont(&output, fontid, 0);
        
-       msg("<debug> updateFont(%s) [cached]", fontname);
+       msg("<debug> updateFont(%s) [cached]", fontid);
        return;
     }
 
     // look for Type 3 font
-    if (!type3Warning && gfxFont->getType() == fontType3) {
-       type3Warning = gTrue;
-       showFontError(gfxFont, 2);
+    if (gfxFont->getType() == fontType3) {
+       if(!type3Warning) {
+           type3Warning = gTrue;
+           showFontError(gfxFont, 2);
+       }
+       return;
     }
 
     /* now either load the font, or find a substitution */
@@ -1160,8 +1309,8 @@ void SWFOutputDev::updateFont(GfxState *state)
     int del = 0;
     if(embedded &&
        (gfxFont->getType() == fontType1 ||
-       //gfxFont->getType() == fontCIDType0C ||
        gfxFont->getType() == fontType1C ||
+       //gfxFont->getType() == fontCIDType0C ||
        gfxFont->getType() == fontTrueType ||
        gfxFont->getType() == fontCIDType2
        ))
@@ -1170,37 +1319,33 @@ void SWFOutputDev::updateFont(GfxState *state)
       if(!fileName) showFontError(gfxFont,0);
       else del = 1;
     } else {
+      char * fontname = getFontName(gfxFont);
       fileName = searchFont(fontname);
       if(!fileName) showFontError(gfxFont,0);
     }
     if(!fileName) {
-       msg("<warning> Font %s could not be loaded.", fontname);
+       char * fontname = getFontName(gfxFont);
+       msg("<warning> Font %s %scould not be loaded.", fontname, embedded?"":"(not embedded) ");
        msg("<warning> Try putting a TTF version of that font (named \"%s.ttf\") into /swftools/fonts", fontname);
-       fileName = substituteFont(gfxFont, fontname);
+       fileName = substituteFont(gfxFont, fontid);
+       if(fontid) { fontid = substitutetarget[substitutepos-1]; /*ugly hack*/};
+       msg("<notice> Font is now %s (%s)", fontid, fileName);
     }
 
     if(!fileName) {
-       msg("<error> Couldn't set font %s\n", fontname);
+       msg("<error> Couldn't set font %s\n", fontid);
        return;
     }
        
-    msg("<verbose> updateFont(%s) -> %s", fontname, fileName);
+    msg("<verbose> updateFont(%s) -> %s", fontid, fileName);
     dumpFontInfo("<verbose>", gfxFont);
 
-    swfoutput_setfont(&output, fontname, fileName);
+    swfoutput_setfont(&output, fontid, fileName);
    
     if(fileName && del)
        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)
@@ -1570,160 +1715,94 @@ 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;
+    }
+    doc = new PDFDoc(fileName, userPW);
+    if (userPW) {
+      delete userPW;
+    }
+    if (!doc->isOk()) {
+      exit(1);
     }
-  }
-  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();
-  }
 
-  output = new SWFOutputDev();
-  output->startDoc(doc->getXRef());
+    // 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());
 }
 
 void pdfswf_setparameter(char*name, char*value)
 {
-    if(!strcmp(name, "drawonlyshapes")) {
-       drawonlyshapes = atoi(value);
-    } else if(!strcmp(name, "ignoredraworder")) {
-       ignoredraworder = atoi(value);
-    } else if(!strcmp(name, "linksopennewwindow")) {
-       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, "outputfilename")) {
+    if(!strcmp(name, "outputfilename")) {
        swffilename = value;
     } else if(!strcmp(name, "caplinewidth")) {
        caplinewidth = atof(value);
-    } 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 if(!strcmp(name, "zoom")) {
+       zoom = atoi(value);
     } else {
-       fprintf(stderr, "unknown parameter: %s (=%s)\n", name, value);
+       swfoutput_setparameter(name, value);
     }
 }
 
 void pdfswf_addfont(char*filename)
 {
-    fonts[fontnum++] = filename;
-}
-
-void pdfswf_drawonlyshapes()
-{
-    drawonlyshapes = 1;
-}
-
-void pdfswf_ignoredraworder()
-{
-    ignoredraworder = 1;
-}
-
-void pdfswf_linksopennewwindow()
-{
-    opennewwindow = 1;
-}
-
-void pdfswf_storeallcharacters()
-{
-    storeallcharacters = 1;
-}
-
-void pdfswf_enablezlib()
-{
-    enablezlib = 1;
-}
-
-void pdfswf_jpegquality(int val)
-{
-    if(val<0) val=0;
-    if(val>100) val=100;
-    jpegquality = val;
-}
-
-void pdfswf_setoutputfilename(char*_filename)
-{
-    swffilename = _filename;
-}
-
-void pdfswf_insertstop()
-{
-    insertstoptag = 1;
-}
-
-void pdfswf_setversion(int n)
-{
-    flashversion = n;
+    fontfile_t f;
+    memset(&f, 0, sizeof(fontfile_t));
+    f.filename = filename;
+    fonts[fontnum++] = f;
 }
 
+void pdfswf_setoutputfilename(char*_filename) { swffilename = _filename; }
 
 void pdfswf_convertpage(int page)
 {
@@ -1747,15 +1826,17 @@ 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()");