* removed useGradients() method
[swftools.git] / pdf2swf / SWFOutputDev.cc
index 8226c66..0eac335 100644 (file)
 #include "Page.h"
 #include "PDFDoc.h"
 #include "Error.h"
+#include "Link.h"
 #include "OutputDev.h"
-#include "GfxState.h"
 #include "GfxFont.h"
+#include "GfxState.h"
 #include "CharCodeToUnicode.h"
 #include "NameToUnicodeTable.h"
 #include "GlobalParams.h"
-//#define XPDF_101
-#ifdef XPDF_101
-#include "FontFile.h"
-#else
 #include "FoFiType1C.h"
 #include "FoFiTrueType.h"
 #include "GHash.h"
-#endif
 #include "SWFOutputDev.h"
 
 //swftools header files
-#include "swfoutput.h"
+#include "../lib/devices/swf.h"
 #include "../lib/log.h"
 #include "../lib/gfxdevice.h"
 #include "../lib/gfxtools.h"
@@ -147,7 +143,7 @@ public:
   gfxdevice_t* output;
 
   // Constructor.
-  SWFOutputDev();
+  SWFOutputDev(gfxdevice_t*output);
 
   // Destructor.
   virtual ~SWFOutputDev() ;
@@ -157,15 +153,12 @@ public:
 
   void setInfo(InfoOutputDev*info) {this->info = info;}
   
-  int save(char*filename);
-    
   // Start a page.
   void startFrame(int width, int height);
 
   virtual void startPage(int pageNum, GfxState *state, double x1, double y1, double x2, double y2) ;
 
   void endframe();
-  void* get(char*name);
 
   //----- get info about output device
 
@@ -176,10 +169,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;}
+  
+  //virtual GBool useShadedFills() { return gTrue; }
 
   //----- initialization and control
 
@@ -227,7 +219,7 @@ public:
   virtual void drawChar(GfxState *state, double x, double y,
                        double dx, double dy,
                        double originX, double originY,
-                       CharCode code, Unicode *u, int uLen);
+                       CharCode code, int nBytes, Unicode *u, int uLen);
 
   //----- image drawing
   virtual void drawImageMask(GfxState *state, Object *ref, Stream *str,
@@ -236,6 +228,17 @@ public:
   virtual void drawImage(GfxState *state, Object *ref, Stream *str,
                         int width, int height, GfxImageColorMap *colorMap,
                         int *maskColors, GBool inlineImg);
+  virtual void drawMaskedImage(GfxState *state, Object *ref, Stream *str,
+                              int width, int height,
+                              GfxImageColorMap *colorMap,
+                              Stream *maskStr, int maskWidth, int maskHeight,
+                              GBool maskInvert);
+  virtual void drawSoftMaskedImage(GfxState *state, Object *ref, Stream *str,
+                                  int width, int height,
+                                  GfxImageColorMap *colorMap,
+                                  Stream *maskStr,
+                                  int maskWidth, int maskHeight,
+                                  GfxImageColorMap *maskColorMap);
   
   virtual GBool beginType3Char(GfxState *state, double x, double y, double dx, double dy, CharCode code, Unicode *u, int uLen);
   virtual void endType3Char(GfxState *state);
@@ -243,19 +246,18 @@ public:
   virtual void type3D0(GfxState *state, double wx, double wy);
   virtual void type3D1(GfxState *state, double wx, double wy, double llx, double lly, double urx, double ury);
 
+  void finish();
+
   private:
   void drawGeneralImage(GfxState *state, Object *ref, Stream *str,
                                   int width, int height, GfxImageColorMap*colorMap, GBool invert,
-                                  GBool inlineImg, int mask, int *maskColors);
-  int SWFOutputDev::setGfxFont(char*id, char*filename, double quality);
+                                  GBool inlineImg, int mask, int *maskColors,
+                                  Stream *maskStr, int maskWidth, int maskHeight, GBool maskInvert, GfxImageColorMap*maskColorMap);
+  int SWFOutputDev::setGfxFont(char*id, char*name, char*filename, double quality);
   void strokeGfxline(GfxState *state, gfxline_t*line);
   void clipToGfxLine(GfxState *state, gfxline_t*line);
   void fillGfxLine(GfxState *state, gfxline_t*line);
 
-  void finish();
-
-  gfxresult_t*result; //filled when complete
-
   char outer_clip_box; //whether the page clip box is still on
 
   InfoOutputDev*info;
@@ -303,7 +305,7 @@ public:
   int pagebuflen;
   int pagepos;
 
-  friend void swf_output_preparepage(swf_output_t*swf, int pdfpage, int outputpage);
+  friend void dev_output_preparepage(dev_output_t*swf, int pdfpage, int outputpage);
 };
 
 typedef struct _drawnchar
@@ -382,7 +384,6 @@ class InfoOutputDev:  public OutputDev
   }
   virtual GBool upsideDown() {return gTrue;}
   virtual GBool useDrawChar() {return gTrue;}
-  virtual GBool useGradients() {return gTrue;}
   virtual GBool interpretType3Chars() {return gTrue;}
   virtual void startPage(int pageNum, GfxState *state, double crop_x1, double crop_y1, double crop_x2, double crop_y2)
   {
@@ -429,10 +430,11 @@ class InfoOutputDev:  public OutputDev
       }
       currentfont = info;
   }
+  
   virtual void drawChar(GfxState *state, double x, double y,
                        double dx, double dy,
                        double originX, double originY,
-                       CharCode code, Unicode *u, int uLen)
+                       CharCode code, int nBytes, Unicode *u, int uLen)
   {
       int render = state->getRender();
       if (render == 3)
@@ -462,34 +464,33 @@ class InfoOutputDev:  public OutputDev
   }
 };
 
-SWFOutputDev::SWFOutputDev()
-{
-    jpeginfo = 0;
-    textmodeinfo = 0;
-    ttfinfo = 0;
-    linkinfo = 0;
-    pbminfo = 0;
-    type3active = 0;
-    statepos = 0;
-    xref = 0;
-    substitutepos = 0;
-    type3Warning = 0;
-    user_movex = 0;
-    user_movey = 0;
-    user_clipx1 = 0;
-    user_clipy1 = 0;
-    user_clipx2 = 0;
-    user_clipy2 = 0;
-    current_text_stroke = 0;
-    current_text_clip = 0;
-    fontlist = 0;
-    result = 0;
-    outer_clip_box = 0;
-    pages = 0;
-    pagebuflen = 0;
-    pagepos = 0;
-    output = (gfxdevice_t*)malloc(sizeof(gfxdevice_t));
-    gfxdevice_swf_init(output);
+SWFOutputDev::SWFOutputDev(gfxdevice_t*output)
+{
+    this->output = output;
+    this->jpeginfo = 0;
+    this->textmodeinfo = 0;
+    this->ttfinfo = 0;
+    this->linkinfo = 0;
+    this->pbminfo = 0;
+    this->type3active = 0;
+    this->statepos = 0;
+    this->xref = 0;
+    this->substitutepos = 0;
+    this->type3Warning = 0;
+    this->user_movex = 0;
+    this->user_movey = 0;
+    this->user_clipx1 = 0;
+    this->user_clipy1 = 0;
+    this->user_clipx2 = 0;
+    this->user_clipy2 = 0;
+    this->current_text_stroke = 0;
+    this->current_text_clip = 0;
+    this->fontlist = 0;
+    this->outer_clip_box = 0;
+    this->pages = 0;
+    this->pagebuflen = 0;
+    this->pagepos = 0;
+
     /* configure device */
     parameter_t*p = device_config;
     while(p) {
@@ -517,20 +518,31 @@ void SWFOutputDev::setClip(int x1,int y1,int x2,int y2)
 
 static char*getFontID(GfxFont*font)
 {
+    Ref*ref = font->getID();
     GString*gstr = font->getName();
-    char* fontname = gstr==0?0:gstr->getCString();
-    if(fontname==0) {
-       char buf[32];
-       Ref*r=font->getID();
-       sprintf(buf, "UFONT%d", r->num);
-       return strdup(buf);
+    char* fname = gstr==0?0:gstr->getCString();
+    char buf[128];
+    if(fname==0) {
+       sprintf(buf, "font-%d-%d", ref->num, ref->gen);
+    } else {
+       sprintf(buf, "%s-%d-%d", fname, ref->num, ref->gen);
     }
-    return strdup(fontname);
+    return strdup(buf);
 }
 
 static char*getFontName(GfxFont*font)
 {
-    char*fontid = getFontID(font);
+    char*fontid;
+    GString*gstr = font->getName();
+    char* fname = gstr==0?0:gstr->getCString();
+    if(fname==0) {
+       char buf[32];
+       Ref*r=font->getID();
+       sprintf(buf, "UFONT%d", r->num);
+       fontid = strdup(buf);
+    }
+    fontid = strdup(fname);
+
     char*fontname= 0;
     char* plus = strchr(fontid, '+');
     if(plus && plus < &fontid[strlen(fontid)-1]) {
@@ -849,9 +861,9 @@ void SWFOutputDev::strokeGfxline(GfxState *state, gfxline_t*line)
     else
        state->getStrokeRGB(&rgb);
     gfxcolor_t col;
-    col.r = (unsigned char)(rgb.r*255);
-    col.g = (unsigned char)(rgb.g*255);
-    col.b = (unsigned char)(rgb.b*255);
+    col.r = colToByte(rgb.r);
+    col.g = colToByte(rgb.g);
+    col.b = colToByte(rgb.b);
     col.a = (unsigned char)(opaq*255);
    
     gfx_capType capType = gfx_capRound;
@@ -894,15 +906,12 @@ void SWFOutputDev::strokeGfxline(GfxState *state, gfxline_t*line)
     }
     
     if(getLogLevel() >= LOGLEVEL_TRACE)  {
-       double gray;
-       state->getStrokeGray(&gray);
-        msg("<trace> stroke width=%f join=%s cap=%s dashes=%d color=%02x%02x%02x%02x gray=%f\n",
+        msg("<trace> stroke width=%f join=%s cap=%s dashes=%d color=%02x%02x%02x%02x\n",
                width,
                lineJoin==0?"miter": (lineJoin==1?"round":"bevel"),
                lineCap==0?"butt": (lineJoin==1?"round":"square"),
                dashnum,
-               col.r,col.g,col.b,col.a,
-               gray
+               col.r,col.g,col.b,col.a
                );
         dump_outline(line);
     }
@@ -914,15 +923,19 @@ void SWFOutputDev::strokeGfxline(GfxState *state, gfxline_t*line)
        gfxline_free(line2);
 }
 
+void convertRGB()
+{
+}
+
 gfxcolor_t getFillColor(GfxState * state)
 {
     GfxRGB rgb;
     double opaq = state->getFillOpacity();
     state->getFillRGB(&rgb);
     gfxcolor_t col;
-    col.r = (unsigned char)(rgb.r*255);
-    col.g = (unsigned char)(rgb.g*255);
-    col.b = (unsigned char)(rgb.b*255);
+    col.r = colToByte(rgb.r);
+    col.g = colToByte(rgb.g);
+    col.b = colToByte(rgb.b);
     col.a = (unsigned char)(opaq*255);
     return col;
 }
@@ -1011,32 +1024,12 @@ void SWFOutputDev::finish()
        }
        outer_clip_box = 0;
     }
-    if(output) {
-       this->result = output->finish(output);
-       free(output);output=0;
-    }
-}
-
-int SWFOutputDev::save(char*filename)
-{
-    finish();
-    return result->save(result, filename);
-}
-void* SWFOutputDev::get(char*name)
-{
-    finish();
-    return result->get(result, name);
 }
 
 SWFOutputDev::~SWFOutputDev() 
 {
     finish();
 
-    if(this->result) {
-       this->result->destroy(this->result);
-       this->result = 0;
-    }
-    
     if(this->pages) {
        free(this->pages); this->pages = 0;
     }
@@ -1046,8 +1039,8 @@ SWFOutputDev::~SWFOutputDev()
        fontlist_t*next = l->next;
        l->next = 0;
        gfxfont_free(l->font);
-       free(l->id);
-       free(l->filename);
+       free(l->id);l->id=0;
+       free(l->filename);l->filename=0;
        free(l);
        l = next;
     }
@@ -1061,15 +1054,6 @@ GBool SWFOutputDev::useDrawChar()
 {
     return gTrue;
 }
-GBool SWFOutputDev::useGradients()
-{
-    if(!gradientinfo)
-    {
-       msg("<notice> File contains gradients");
-       gradientinfo = 1;
-    }
-    return gTrue;
-}
 
 char*renderModeDesc[]= {"fill", "stroke", "fill+stroke", "invisible",
                       "clip+fill", "stroke+clip", "fill+stroke+clip", "clip"};
@@ -1109,8 +1093,22 @@ char* makeStringPrintable(char*str)
 
 int getGfxCharID(gfxfont_t*font, int charnr, char *charname, int u)
 {
-    int t;
+    char*uniname = 0;
+    if(u>0) {
+       int t;
+       /* find out char name from unicode index 
+          TODO: should be precomputed
+        */
+       for(t=0;t<sizeof(nameToUnicodeTab)/sizeof(nameToUnicodeTab[0]);t++) {
+           if(nameToUnicodeTab[t].u == u) {
+               uniname = nameToUnicodeTab[t].name;
+               break;
+           }
+       }
+    }
+
     if(charname) {
+       int t;
        for(t=0;t<font->num_glyphs;t++) {
            if(font->glyphs[t].name && !strcmp(font->glyphs[t].name,charname)) {
                msg("<debug> Char [%d,>%s<,%d] maps to %d\n", charnr, charname, u, t);
@@ -1127,17 +1125,30 @@ int getGfxCharID(gfxfont_t*font, int charnr, char *charname, int u)
        }
     }
 
+    if(uniname) {
+       int t;
+       for(t=0;t<font->num_glyphs;t++) {
+           if(font->glyphs[t].name && !strcmp(font->glyphs[t].name,uniname)) {
+               msg("<debug> Char [%d,%s,>%d(%s)<] maps to %d\n", charnr, charname, u, uniname, t);
+               return t;
+           }
+       }
+       /* if we didn't find the character, maybe
+          we can find the capitalized version */
+       for(t=0;t<font->num_glyphs;t++) {
+           if(font->glyphs[t].name && !strcasecmp(font->glyphs[t].name,uniname)) {
+               msg("<debug> Char [%d,%s,>>%d(%s)<<] maps to %d\n", charnr, charname, u, uniname, t);
+               return t;
+           }
+       }
+    }
+
     /* try to use the unicode id */
     if(u>=0 && u<font->max_unicode && font->unicode2glyph[u]>=0) {
        msg("<debug> Char [%d,%s,>%d<] maps to %d\n", charnr, charname, u, font->unicode2glyph[u]);
        return font->unicode2glyph[u];
     }
 
-    /* we don't need to "draw" space characters, so don't overdo the search
-       for a matching glyph */
-    if(charname && !strcasecmp(charname, "space"))
-       return -1;
-
     if(charnr>=0 && charnr<font->num_glyphs) {
        msg("<debug> Char [>%d<,%s,%d] maps to %d\n", charnr, charname, u, charnr);
        return charnr;
@@ -1178,7 +1189,7 @@ void SWFOutputDev::beginString(GfxState *state, GString *s)
 void SWFOutputDev::drawChar(GfxState *state, double x, double y,
                        double dx, double dy,
                        double originX, double originY,
-                       CharCode c, Unicode *_u, int uLen)
+                       CharCode c, int nBytes, Unicode *_u, int uLen)
 {
     int render = state->getRender();
     // check for invisible text -- this is used by Acrobat Capture
@@ -1204,21 +1215,8 @@ void SWFOutputDev::drawChar(GfxState *state, double x, double y,
     Unicode u=0;
     char*name=0;
 
-    if(_u && uLen) {
-       u = *_u;
-       if (u) {
-           int t;
-           /* find out char name from unicode index 
-              TODO: should be precomputed
-            */
-           for(t=0;t<sizeof(nameToUnicodeTab)/sizeof(nameToUnicodeTab[0]);t++) {
-               if(nameToUnicodeTab[t].u == u) {
-                   name = nameToUnicodeTab[t].name;
-                   break;
-               }
-           }
-       }
-    }
+    if(uLen)
+       u = _u[0];
 
     if(font->isCIDFont()) {
        GfxCIDFont*cfont = (GfxCIDFont*)font;
@@ -1229,9 +1227,7 @@ void SWFOutputDev::drawChar(GfxState *state, double x, double y,
        Gfx8BitFont*font8;
        font8 = (Gfx8BitFont*)font;
        char**enc=font8->getEncoding();
-       if(enc && enc[c] && strcasecmp(enc[c], "space")) {
-          name = enc[c];
-       }
+       name = enc[c];
     }
     if (CIDToGIDMap) {
        msg("<debug> drawChar(%f, %f, c='%c' (%d), GID=%d, u=%d <%d>) CID=%d name=\"%s\" render=%d\n", x, y, (c&127)>=32?c:'?', c, CIDToGIDMap[c], u, uLen, font->isCIDFont(), FIXNULL(name), render);
@@ -1245,7 +1241,8 @@ void SWFOutputDev::drawChar(GfxState *state, double x, double y,
     if(uLen<=1) {
        charid = getGfxCharID(current_gfxfont, c, name, u);
     } else {
-       charid = getGfxCharID(current_gfxfont, c, 0, -1);
+       charid = getGfxCharID(current_gfxfont, c, name, -1);
+
        if(charid < 0) {
            /* multiple unicodes- should usually map to a ligature.
               if the ligature doesn't exist, we need to draw
@@ -1253,17 +1250,14 @@ void SWFOutputDev::drawChar(GfxState *state, double x, double y,
            int t;
            msg("<warning> ligature %d missing in font %s\n", c, current_font_id);
            for(t=0;t<uLen;t++) {
-               drawChar(state, x, y, dx, dy, originX, originY, c, _u+t, 1);
+               drawChar(state, x, y, dx, dy, originX, originY, c, nBytes, _u+t, 1);
            }
            return;
        }
     }
-
-    if(charid<0 && name) {
-       if(strcasecmp(name, "space")) {
-           msg("<warning> Didn't find character '%s' (c=%d,u=%d) in current charset (%s, %d characters)", 
-                   FIXNULL(name),c, u, FIXNULL((char*)current_font_id), current_gfxfont->num_glyphs);
-       }
+    if(charid<0) {
+       msg("<warning> Didn't find character '%s' (c=%d,u=%d) in current charset (%s, %d characters)", 
+               FIXNULL(name),c, u, FIXNULL((char*)current_font_id), current_gfxfont->num_glyphs);
        return;
     }
 
@@ -1307,6 +1301,7 @@ void SWFOutputDev::endString(GfxState *state)
           now (as there may be texts of other rendering modes in this
           text object)- clipping objects have to wait until endTextObject,
           however */
+       output->setparameter(output, "mark","TXT");
        if((render&3) == RENDER_FILL) {
            fillGfxLine(state, current_text_stroke);
            gfxline_free(current_text_stroke);
@@ -1321,6 +1316,7 @@ void SWFOutputDev::endString(GfxState *state)
            gfxline_free(current_text_stroke);
            current_text_stroke = 0;
        }
+       output->setparameter(output, "mark","");
     }
 }    
 
@@ -1332,7 +1328,9 @@ void SWFOutputDev::endTextObject(GfxState *state)
        msg("<error> Internal error: drawChar.render!=beginString.render");
     
     if(current_text_clip) {
+       output->setparameter(output, "mark","TXT");
        clipToGfxLine(state, current_text_clip);
+       output->setparameter(output, "mark","");
        gfxline_free(current_text_clip);
        current_text_clip = 0;
     }
@@ -1433,20 +1431,13 @@ void SWFOutputDev::startPage(int pageNum, GfxState *state, double crop_x1, doubl
 
 void SWFOutputDev::drawLink(Link *link, Catalog *catalog) 
 {
-    msg("<debug> drawlink\n");
     double x1, y1, x2, y2, w;
-    GfxRGB rgb;
     gfxline_t points[5];
     int x, y;
+    
+    msg("<debug> drawlink\n");
 
-#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;
     cvtUserToDev(x1, y1, &x, &y);
     points[0].type = gfx_moveTo;
     points[0].x = points[4].x = x + user_movex;
@@ -1542,7 +1533,9 @@ void SWFOutputDev::drawLink(Link *link, Catalog *catalog)
             type = "Launch";
             LinkLaunch*l = (LinkLaunch*)action;
             GString * str = new GString(l->getFileName());
-            str->append(l->getParams());
+           GString * params = l->getParams();
+           if(params)
+               str->append(params);
             s = strdup(str->getCString());
             delete str;
         }
@@ -1568,6 +1561,7 @@ void SWFOutputDev::drawLink(Link *link, Catalog *catalog)
             break;
         }
     }
+
     if(!s) s = strdup("-?-");
 
     if(!linkinfo && (page || url))
@@ -1586,13 +1580,12 @@ void SWFOutputDev::drawLink(Link *link, Catalog *catalog)
                 break;
            }
        }
-        if(lpage>=0) {
-           char buf[80];
-           sprintf(buf, "page%d", t);
-            output->drawlink(output, points, buf);
-       } else {
-           msg("<warning> Invalid link to page %d", page);
+        if(lpage<0) {
+           lpage = page;
        }
+       char buf[80];
+       sprintf(buf, "page%d", lpage);
+       output->drawlink(output, points, buf);
     }
     else if(url)
     {
@@ -1738,15 +1731,9 @@ 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);
-      if(!cvt) return 0;
-      cvt->convertToType1(f);
-#else
       FoFiType1C *cvt = FoFiType1C::make(fontBuf, fontLen);
       if(!cvt) return 0;
       cvt->convertToType1(NULL, gTrue, FoFiWrite, f);
-#endif
       //cvt->convertToCIDType0("test", f);
       //cvt->convertToType0("test", f);
       delete cvt;
@@ -1758,13 +1745,8 @@ 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 {
@@ -1983,7 +1965,7 @@ void SWFOutputDev::setXRef(PDFDoc*doc, XRef *xref)
     this->xref = xref;
 }
 
-int SWFOutputDev::setGfxFont(char*id, char*filename, double maxSize)
+int SWFOutputDev::setGfxFont(char*id, char*name, char*filename, double maxSize)
 {
     gfxfont_t*font = 0;
     fontlist_t*last=0,*l = this->fontlist;
@@ -2007,8 +1989,11 @@ int SWFOutputDev::setGfxFont(char*id, char*filename, double maxSize)
        we have to divide 0.05 by (fontsize/1024)
      */
     double quality = (1024 * 0.05) / maxSize;
-    
+   
+    msg("<verbose> Loading %s...", filename);
     font = gfxfont_load(filename, quality);
+    msg("<verbose> Font %s loaded successfully", filename);
+
     l = new fontlist_t;
     l->font = font;
     l->filename = strdup(filename);
@@ -2032,7 +2017,10 @@ void SWFOutputDev::updateFont(GfxState *state)
     if (!gfxFont) {
        return;
     }  
+    
     char * fontid = getFontID(gfxFont);
+    char * fontname = getFontName(gfxFont);
+
     double maxSize = 1.0;
 
     if(this->info) {
@@ -2053,8 +2041,9 @@ void SWFOutputDev::updateFont(GfxState *state)
 
     /* second, see if this is a font which was used before-
        if so, we are done */
-    if(setGfxFont(fontid, 0, 0)) {
+    if(setGfxFont(fontid, fontname, 0, 0)) {
        free(fontid);
+       free(fontname);
        return;
     }
 /*    if(swfoutput_queryfont(&output, fontid))
@@ -2071,6 +2060,7 @@ void SWFOutputDev::updateFont(GfxState *state)
            showFontError(gfxFont, 2);
        }
        free(fontid);
+       free(fontname);
        return;
     }
 
@@ -2093,21 +2083,21 @@ 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);
-      free(fontname);
     }
     if(!fileName) {
        char * fontname = getFontName(gfxFont);
        msg("<warning> Font %s %scould not be loaded.", fontname, embedded?"":"(not embedded) ");
        
        if(lastfontdir)
-           msg("<warning> Try putting a TTF version of that font (named \"%s.ttf\") into %s/swftools/fonts", fontname, lastfontdir);
+           msg("<warning> Try putting a TTF version of that font (named \"%s.ttf\") into %s", fontname, lastfontdir);
        else
            msg("<warning> Try specifying one or more font directories");
 
        fileName = substituteFont(gfxFont, fontid);
+       if(!fileName)
+           exit(1);
        if(fontid) { free(fontid);fontid = strdup(substitutetarget[substitutepos-1]); /*ugly hack*/};
        msg("<notice> Font is now %s (%s)", fontid, fileName);
     }
@@ -2115,6 +2105,7 @@ void SWFOutputDev::updateFont(GfxState *state)
     if(!fileName) {
        msg("<error> Couldn't set font %s\n", fontid);
        free(fontid);
+       free(fontname);
        return;
     }
        
@@ -2123,15 +2114,19 @@ void SWFOutputDev::updateFont(GfxState *state)
 
     //swfoutput_setfont(&output, fontid, fileName);
     
-    if(!setGfxFont(fontid, 0, 0)) {
-       setGfxFont(fontid, fileName, maxSize);
+    if(!setGfxFont(fontid, fontname, 0, 0)) {
+       setGfxFont(fontid, fontname, fileName, maxSize);
     }
    
     if(fileName && del)
        unlinkfont(fileName);
+
     if(fileName)
         free(fileName);
     free(fontid);
+    free(fontname);
+
+    msg("<verbose> |");
 }
 
 #define SQR(x) ((x)*(x))
@@ -2187,13 +2182,13 @@ unsigned char* antialize(unsigned char*data, int width, int height, int newwidth
 #define IMAGE_TYPE_JPEG 0
 #define IMAGE_TYPE_LOSSLESS 1
 
-static void drawimage(gfxdevice_t*dev, RGBA* data, int sizex,int sizey, 
+static void drawimage(gfxdevice_t*dev, gfxcolor_t* data, int sizex,int sizey, 
         double x1,double y1,
         double x2,double y2,
         double x3,double y3,
         double x4,double y4, int type)
 {
-    RGBA*newpic=0;
+    gfxcolor_t*newpic=0;
     
     double l1 = sqrt((x4-x1)*(x4-x1) + (y4-y1)*(y4-y1));
     double l2 = sqrt((x2-x1)*(x2-x1) + (y2-y1)*(y2-y1));
@@ -2238,13 +2233,13 @@ static void drawimage(gfxdevice_t*dev, RGBA* data, int sizex,int sizey,
     dev->fillbitmap(dev, &p1, &img, &m, 0);
 }
 
-void drawimagejpeg(gfxdevice_t*dev, RGBA*mem, int sizex,int sizey, 
+void drawimagejpeg(gfxdevice_t*dev, gfxcolor_t*mem, int sizex,int sizey, 
         double x1,double y1, double x2,double y2, double x3,double y3, double x4,double y4)
 {
     drawimage(dev,mem,sizex,sizey,x1,y1,x2,y2,x3,y3,x4,y4, IMAGE_TYPE_JPEG);
 }
 
-void drawimagelossless(gfxdevice_t*dev, RGBA*mem, int sizex,int sizey, 
+void drawimagelossless(gfxdevice_t*dev, gfxcolor_t*mem, int sizex,int sizey, 
         double x1,double y1, double x2,double y2, double x3,double y3, double x4,double y4)
 {
     drawimage(dev,mem,sizex,sizey,x1,y1,x2,y2,x3,y3,x4,y4, IMAGE_TYPE_LOSSLESS);
@@ -2253,22 +2248,60 @@ void drawimagelossless(gfxdevice_t*dev, RGBA*mem, int sizex,int sizey,
 
 void SWFOutputDev::drawGeneralImage(GfxState *state, Object *ref, Stream *str,
                                   int width, int height, GfxImageColorMap*colorMap, GBool invert,
-                                  GBool inlineImg, int mask, int*maskColors)
+                                  GBool inlineImg, int mask, int*maskColors,
+                                  Stream *maskStr, int maskWidth, int maskHeight, GBool maskInvert, GfxImageColorMap*maskColorMap)
 {
-  FILE *fi;
-  int c;
-  char fileName[128];
   double x1,y1,x2,y2,x3,y3,x4,y4;
   ImageStream *imgStr;
   Guchar pixBuf[4];
   GfxRGB rgb;
   int ncomps = 1;
   int bits = 1;
+  unsigned char* maskbitmap = 0;
                                 
   if(colorMap) {
     ncomps = colorMap->getNumPixelComps();
     bits = colorMap->getBits();
   }
+      
+  if(maskStr) {
+      int x,y;
+      unsigned char buf[8];
+      maskbitmap = (unsigned char*)malloc(maskHeight*maskWidth);
+      if(maskColorMap) {
+         ImageStream*imgMaskStr = new ImageStream(maskStr, maskWidth, maskColorMap->getNumPixelComps(), maskColorMap->getBits());
+         imgMaskStr->reset();
+         unsigned char pal[256];
+         int n = 1 << colorMap->getBits();
+         int t;
+         for(t=0;t<n;t++) {
+             GfxGray gray;
+             pixBuf[0] = t;
+             maskColorMap->getGray(pixBuf, &gray);
+             pal[t] = colToByte(gray);
+         }
+         for (y = 0; y < maskHeight; y++) {
+             for (x = 0; x < maskWidth; x++) {
+                 imgMaskStr->getPixel(buf);
+                 maskbitmap[y*maskWidth+x] = pal[buf[0]];
+             }
+         }
+         delete imgMaskStr;
+      } else {
+         ImageStream*imgMaskStr = new ImageStream(maskStr, maskWidth, 1, 1);
+         imgMaskStr->reset();
+         for (y = 0; y < maskHeight; y++) {
+             for (x = 0; x < maskWidth; x++) {
+                 imgMaskStr->getPixel(buf);
+                 buf[0]^=maskInvert;
+                 maskbitmap[y*maskWidth+x] = (buf[0]^1)*255;
+             }
+         }
+         delete imgMaskStr;
+      }
+      maskStr->close();
+  }
+  
   imgStr = new ImageStream(str, width, ncomps,bits);
   imgStr->reset();
 
@@ -2282,13 +2315,16 @@ void SWFOutputDev::drawGeneralImage(GfxState *state, Object *ref, Stream *str,
          imgStr->getPixel(buf);
       }
       delete imgStr;
+      if(maskbitmap)
+         free(maskbitmap);
       return;
   }
-  
-  state->transform(0, 1, &x1, &y1); x1 += user_movex; y1+= user_movey;
-  state->transform(0, 0, &x2, &y2); x2 += user_movex; y2+= user_movey;
-  state->transform(1, 0, &x3, &y3); x3 += user_movex; y3+= user_movey;
-  state->transform(1, 1, &x4, &y4); x4 += user_movex; y4+= user_movey;
+
+  state->transform(0, 1, &x1, &y1); x1 += user_movex; y1 += user_movey;
+  state->transform(0, 0, &x2, &y2); x2 += user_movex; y2 += user_movey;
+  state->transform(1, 0, &x3, &y3); x3 += user_movex; y3 += user_movey;
+  state->transform(1, 1, &x4, &y4); x4 += user_movex; y4 += user_movey;
+
 
   if(!pbminfo && !(str->getKind()==strDCT)) {
       if(!type3active) {
@@ -2308,16 +2344,16 @@ void SWFOutputDev::drawGeneralImage(GfxState *state, Object *ref, Stream *str,
       unsigned char buf[8];
       int x,y;
       unsigned char*pic = new unsigned char[width*height];
-      RGBA pal[256];
+      gfxcolor_t pal[256];
       GfxRGB rgb;
       state->getFillRGB(&rgb);
 
       memset(pal,255,sizeof(pal));
-      pal[0].r = (int)(rgb.r*255); pal[1].r = 0;
-      pal[0].g = (int)(rgb.g*255); pal[1].g = 0;
-      pal[0].b = (int)(rgb.b*255); pal[1].b = 0;
+      pal[0].r = (int)(colToByte(rgb.r)); pal[1].r = 0;
+      pal[0].g = (int)(colToByte(rgb.g)); pal[1].g = 0;
+      pal[0].b = (int)(colToByte(rgb.b)); pal[1].b = 0;
       pal[0].a = 255;              pal[1].a = 0;
-
+    
       int numpalette = 2;
       int realwidth = (int)sqrt(SQR(x2-x3) + SQR(y2-y3));
       int realheight = (int)sqrt(SQR(x1-x2) + SQR(y1-y2));
@@ -2352,21 +2388,18 @@ void SWFOutputDev::drawGeneralImage(GfxState *state, Object *ref, Stream *str,
          pic = pic2;
          
          /* make a black/white palette */
-         GfxRGB rgb2;
-         rgb2.r = 1 - rgb.r;
-         rgb2.g = 1 - rgb.g;
-         rgb2.b = 1 - rgb.b;
+
          float r = 255/(numpalette-1);
          int t;
          for(t=0;t<numpalette;t++) {
-             pal[t].r = (U8)(255*rgb.r);
-             pal[t].g = (U8)(255*rgb.g);
-             pal[t].b = (U8)(255*rgb.b);
-             pal[t].a = (U8)(t*r);
+             pal[t].r = colToByte(rgb.r);
+             pal[t].g = colToByte(rgb.g);
+             pal[t].b = colToByte(rgb.b);
+             pal[t].a = (unsigned char)(t*r);
          }
       }
 
-      RGBA*pic2 = new RGBA[width*height];
+      gfxcolor_t*pic2 = new gfxcolor_t[width*height];
       for (y = 0; y < height; ++y) {
        for (x = 0; x < width; ++x) {
          pic2[width*y+x] = pal[pic[y*width+x]];
@@ -2376,21 +2409,25 @@ void SWFOutputDev::drawGeneralImage(GfxState *state, Object *ref, Stream *str,
       free(pic2);
       free(pic);
       delete imgStr;
+      if(maskbitmap) free(maskbitmap);
       return;
-  } 
+  }
 
   int x,y;
 
   if(colorMap->getNumPixelComps()!=1 || str->getKind()==strDCT) {
-      RGBA*pic=new RGBA[width*height];
+      gfxcolor_t*pic=new gfxcolor_t[width*height];
       for (y = 0; y < height; ++y) {
        for (x = 0; x < width; ++x) {
          imgStr->getPixel(pixBuf);
          colorMap->getRGB(pixBuf, &rgb);
-         pic[width*y+x].r = (U8)(rgb.r * 255 + 0.5);
-         pic[width*y+x].g = (U8)(rgb.g * 255 + 0.5);
-         pic[width*y+x].b = (U8)(rgb.b * 255 + 0.5);
+         pic[width*y+x].r = (unsigned char)(colToByte(rgb.r));
+         pic[width*y+x].g = (unsigned char)(colToByte(rgb.g));
+         pic[width*y+x].b = (unsigned char)(colToByte(rgb.b));
          pic[width*y+x].a = 255;//(U8)(rgb.a * 255 + 0.5);
+         if(maskbitmap) {
+             pic[width*y+x].a = maskbitmap[(y*maskHeight/height)*maskWidth+(x*maskWidth/width)];
+         }
        }
       }
       if(str->getKind()==strDCT)
@@ -2399,15 +2436,18 @@ void SWFOutputDev::drawGeneralImage(GfxState *state, Object *ref, Stream *str,
          drawimagelossless(output, pic, width, height, x1,y1,x2,y2,x3,y3,x4,y4);
       delete pic;
       delete imgStr;
+      if(maskbitmap) free(maskbitmap);
       return;
   } else {
-      RGBA*pic=new RGBA[width*height];
-      RGBA pal[256];
+      gfxcolor_t*pic=new gfxcolor_t[width*height];
+      gfxcolor_t pal[256];
+      int n = 1 << colorMap->getBits();
       int t;
       for(t=0;t<256;t++) {
          pixBuf[0] = t;
          colorMap->getRGB(pixBuf, &rgb);
-         /*if(maskColors && *maskColors==t) {
+
+         {/*if(maskColors && *maskColors==t) {
              msg("<notice> Color %d is transparent", t);
              if (imgData->maskColors) {
                *alpha = 0;
@@ -2427,10 +2467,10 @@ void SWFOutputDev::drawGeneralImage(GfxState *state, Object *ref, Stream *str,
                    pal[t].b = 0;
                    pal[t].a = 0;
              }
-         } else*/ {
-             pal[t].r = (U8)(rgb.r * 255 + 0.5);
-             pal[t].g = (U8)(rgb.g * 255 + 0.5);
-             pal[t].b = (U8)(rgb.b * 255 + 0.5);
+         } else {*/
+             pal[t].r = (unsigned char)(colToByte(rgb.r));
+             pal[t].g = (unsigned char)(colToByte(rgb.g));
+             pal[t].b = (unsigned char)(colToByte(rgb.b));
              pal[t].a = 255;//(U8)(rgb.b * 255 + 0.5);
          }
       }
@@ -2438,12 +2478,16 @@ void SWFOutputDev::drawGeneralImage(GfxState *state, Object *ref, Stream *str,
        for (x = 0; x < width; ++x) {
          imgStr->getPixel(pixBuf);
          pic[width*y+x] = pal[pixBuf[0]];
+         if(maskbitmap) {
+             pic[width*y+x].a = maskbitmap[(y*maskHeight/height)*maskWidth+(x*maskWidth/width)];
+         }
        }
       }
       drawimagelossless(output, pic, width, height, x1,y1,x2,y2,x3,y3,x4,y4);
 
       delete pic;
       delete imgStr;
+      if(maskbitmap) free(maskbitmap);
       return;
   }
 }
@@ -2455,7 +2499,7 @@ void SWFOutputDev::drawImageMask(GfxState *state, Object *ref, Stream *str,
   if(states[statepos].textRender & 4) //clipped
       return;
   msg("<verbose> drawImageMask %dx%d, invert=%d inline=%d", width, height, invert, inlineImg);
-  drawGeneralImage(state,ref,str,width,height,0,invert,inlineImg,1, 0);
+  drawGeneralImage(state,ref,str,width,height,0,invert,inlineImg,1, 0, 0,0,0,0, 0);
 }
 
 void SWFOutputDev::drawImage(GfxState *state, Object *ref, Stream *str,
@@ -2465,14 +2509,51 @@ void SWFOutputDev::drawImage(GfxState *state, Object *ref, Stream *str,
   if(states[statepos].textRender & 4) //clipped
       return;
 
-  msg("<verbose> drawImage %dx%d, %s %s, inline=%d", width, height, 
+  msg("<verbose> drawImage %dx%d, %s, %s, inline=%d", width, height, 
          colorMap?"colorMap":"no colorMap", 
          maskColors?"maskColors":"no maskColors",
          inlineImg);
   if(colorMap)
       msg("<verbose> colorMap pixcomps:%d bits:%d mode:%d\n", colorMap->getNumPixelComps(),
              colorMap->getBits(),colorMap->getColorSpace()->getMode());
-  drawGeneralImage(state,ref,str,width,height,colorMap,0,inlineImg,0,maskColors);
+  drawGeneralImage(state,ref,str,width,height,colorMap,0,inlineImg,0,maskColors, 0,0,0,0, 0);
+}
+  
+void SWFOutputDev::drawMaskedImage(GfxState *state, Object *ref, Stream *str,
+                              int width, int height,
+                              GfxImageColorMap *colorMap,
+                              Stream *maskStr, int maskWidth, int maskHeight,
+                              GBool maskInvert)
+{
+  if(states[statepos].textRender & 4) //clipped
+      return;
+
+  msg("<verbose> drawMaskedImage %dx%d, %s, %dx%d mask", width, height, 
+         colorMap?"colorMap":"no colorMap", 
+         maskWidth, maskHeight);
+  if(colorMap)
+      msg("<verbose> colorMap pixcomps:%d bits:%d mode:%d\n", colorMap->getNumPixelComps(),
+             colorMap->getBits(),colorMap->getColorSpace()->getMode());
+  drawGeneralImage(state,ref,str,width,height,colorMap,0,0,0,0, maskStr, maskWidth, maskHeight, maskInvert, 0);
+}
+
+void SWFOutputDev::drawSoftMaskedImage(GfxState *state, Object *ref, Stream *str,
+                                  int width, int height,
+                                  GfxImageColorMap *colorMap,
+                                  Stream *maskStr,
+                                  int maskWidth, int maskHeight,
+                                  GfxImageColorMap *maskColorMap)
+{
+  if(states[statepos].textRender & 4) //clipped
+      return;
+
+  msg("<verbose> drawSoftMaskedImage %dx%d, %s, %dx%d mask", width, height, 
+         colorMap?"colorMap":"no colorMap", 
+         maskWidth, maskHeight);
+  if(colorMap)
+      msg("<verbose> colorMap pixcomps:%d bits:%d mode:%d\n", colorMap->getNumPixelComps(),
+             colorMap->getBits(),colorMap->getColorSpace()->getMode());
+  drawGeneralImage(state,ref,str,width,height,colorMap,0,0,0,0, maskStr, maskWidth, maskHeight, 0, maskColorMap);
 }
 
 //SWFOutputDev*output = 0; 
@@ -2561,9 +2642,9 @@ void pdfswf_setparameter(char*name, char*value)
        storeDeviceParameter("ppmsubpixels", buf);
     } else if(!strcmp(name, "forceType0Fonts")) {
        forceType0Fonts = atoi(value);
-    } else if(!strcmp(name, "fontdir")) {
+    } else if(!strncmp(name, "fontdir", strlen("fontdir"))) {
         pdfswf_addfontdir(value);
-    } else if(!strcmp(name, "languagedir")) {
+    } else if(!strncmp(name, "languagedir", strlen("languagedir"))) {
         pdfswf_addlanguagedir(value);
     } else if(!strcmp(name, "fontconfig")) {
         config_use_fontconfig = atoi(value);
@@ -2601,7 +2682,7 @@ void pdfswf_addlanguagedir(char*dir)
 
     int l;
     FILE*fi = 0;
-    char* config_file = (char*)malloc(strlen(dir) + 1 + sizeof("add-to-xpdfrc"));
+    char* config_file = (char*)malloc(strlen(dir) + 1 + sizeof("add-to-xpdfrc") + 1);
     strcpy(config_file, dir);
     strcat(config_file, dirseparator());
     strcat(config_file, "add-to-xpdfrc");
@@ -2669,10 +2750,10 @@ typedef struct _pdf_doc_internal
 typedef struct _pdf_page_internal
 {
 } pdf_page_internal_t;
-typedef struct _swf_output_internal
+typedef struct _dev_output_internal
 {
     SWFOutputDev*outputDev;
-} swf_output_internal_t;
+} dev_output_internal_t;
 
 pdf_doc_t* pdf_init(char*filename, char*userPassword)
 {
@@ -2745,11 +2826,7 @@ pdf_doc_t* pdf_init(char*filename, char*userPassword)
     InfoOutputDev*io = new InfoOutputDev();
     int t;
     for(t=1;t<=pdf_doc->num_pages;t++) {
-#ifdef XPDF_101
-       i->doc->displayPage((OutputDev*)io, t, /*zoom*/zoom, /*rotate*/0, /*doLinks*/(int)1);
-#else
-       i->doc->displayPage((OutputDev*)io, t, zoom, zoom, /*rotate*/0, true, /*doLinks*/(int)1);
-#endif
+       i->doc->displayPage((OutputDev*)io, t, zoom, zoom, /*rotate*/0, /*usemediabox*/true, /*crop*/true, /*doLinks*/(int)1);
     }
     i->info = io;
 
@@ -2804,38 +2881,44 @@ void pdf_page_destroy(pdf_page_t*pdf_page)
     free(pdf_page);pdf_page=0;
 }
 
-swf_output_t* swf_output_init() 
+dev_output_t* dev_output_init(gfxdevice_t*dev) 
 {
-    swf_output_t*swf_output = (swf_output_t*)malloc(sizeof(swf_output_t));
-    memset(swf_output, 0, sizeof(swf_output_t));
-    swf_output_internal_t*i= (swf_output_internal_t*)malloc(sizeof(swf_output_internal_t));
-    memset(i, 0, sizeof(swf_output_internal_t));
-    swf_output->internal = i;
+    dev_output_t*dev_output = (dev_output_t*)malloc(sizeof(dev_output_t));
+    memset(dev_output, 0, sizeof(dev_output_t));
+    dev_output_internal_t*i= (dev_output_internal_t*)malloc(sizeof(dev_output_internal_t));
+    memset(i, 0, sizeof(dev_output_internal_t));
+    dev_output->internal = i;
 
-    i->outputDev = new SWFOutputDev();
-    return swf_output;
+    i->outputDev = new SWFOutputDev(dev);
+    return dev_output;
 }
 
-void swf_output_setparameter(swf_output_t*swf, char*name, char*value)
+void dev_output_setparameter(dev_output_t*swf, char*name, char*value)
 {
     pdfswf_setparameter(name, value);
 }
 
-void swf_output_startframe(swf_output_t*swf, int width, int height)
+void dev_output_startframe(dev_output_t*swf, int width, int height)
 {
-    swf_output_internal_t*i= (swf_output_internal_t*)swf->internal;
+    dev_output_internal_t*i= (dev_output_internal_t*)swf->internal;
     i->outputDev->startFrame(width, height);
 }
 
-void swf_output_endframe(swf_output_t*swf)
+void dev_output_endframe(dev_output_t*swf)
 {
-    swf_output_internal_t*i= (swf_output_internal_t*)swf->internal;
+    dev_output_internal_t*i= (dev_output_internal_t*)swf->internal;
     i->outputDev->endframe();
 }
 
-void swf_output_preparepage(swf_output_t*swf, int pdfpage, int outputpage)
+void dev_output_finish(dev_output_t*swf)
 {
-    swf_output_internal_t*i= (swf_output_internal_t*)swf->internal;
+    dev_output_internal_t*i= (dev_output_internal_t*)swf->internal;
+    i->outputDev->finish();
+}
+
+void dev_output_preparepage(dev_output_t*swf, int pdfpage, int outputpage)
+{
+    dev_output_internal_t*i= (dev_output_internal_t*)swf->internal;
     SWFOutputDev*o = i->outputDev;
 
     if(pdfpage < 0)
@@ -2859,32 +2942,18 @@ void swf_output_preparepage(swf_output_t*swf, int pdfpage, int outputpage)
        o->pagepos = pdfpage;
 }
 
-int swf_output_save(swf_output_t*swf, char*filename)
+void dev_output_destroy(dev_output_t*output)
 {
-    swf_output_internal_t*i= (swf_output_internal_t*)swf->internal;
-    int ret = i->outputDev->save(filename);
-    return ret;
-}
-
-void* swf_output_get(swf_output_t*swf,char*name)
-{
-    swf_output_internal_t*i= (swf_output_internal_t*)swf->internal;
-    void* ret = i->outputDev->get(name);
-    return ret;
-}
-
-void swf_output_destroy(swf_output_t*output)
-{
-    swf_output_internal_t*i = (swf_output_internal_t*)output->internal;
+    dev_output_internal_t*i = (dev_output_internal_t*)output->internal;
     delete i->outputDev; i->outputDev=0;
     free(output->internal);output->internal=0;
     free(output);
 }
 
-void pdf_page_render2(pdf_page_t*page, swf_output_t*swf)
+void pdf_page_render2(pdf_page_t*page, dev_output_t*swf)
 {
     pdf_doc_internal_t*pi = (pdf_doc_internal_t*)page->parent->internal;
-    swf_output_internal_t*si = (swf_output_internal_t*)swf->internal;
+    dev_output_internal_t*si = (dev_output_internal_t*)swf->internal;
 
     if(!pi) {
        msg("<fatal> pdf_page_render: Parent PDF this page belongs to doesn't exist yet/anymore");
@@ -2897,17 +2966,13 @@ void pdf_page_render2(pdf_page_t*page, swf_output_t*swf)
     }
     si->outputDev->setInfo(pi->info);
     si->outputDev->setXRef(pi->doc, pi->doc->getXRef());
-#ifdef XPDF_101
-    pi->doc->displayPage((OutputDev*)si->outputDev, page->nr, /*zoom*/zoom, /*rotate*/0, /*doLinks*/(int)1);
-#else
-    pi->doc->displayPage((OutputDev*)si->outputDev, page->nr, zoom, zoom, /*rotate*/0, true, /*doLinks*/(int)1);
-#endif
+    pi->doc->displayPage((OutputDev*)si->outputDev, page->nr, zoom, zoom, /*rotate*/0, true, true, /*doLinks*/(int)1);
 }
 
-void pdf_page_rendersection(pdf_page_t*page, swf_output_t*output, int x, int y, int x1, int y1, int x2, int y2)
+void pdf_page_rendersection(pdf_page_t*page, dev_output_t*output, int x, int y, int x1, int y1, int x2, int y2)
 {
     pdf_doc_internal_t*pi = (pdf_doc_internal_t*)page->parent->internal;
-    swf_output_internal_t*si = (swf_output_internal_t*)output->internal;
+    dev_output_internal_t*si = (dev_output_internal_t*)output->internal;
 
     si->outputDev->setMove(x,y);
     if((x1|y1|x2|y2)==0) x2++;
@@ -2915,10 +2980,10 @@ void pdf_page_rendersection(pdf_page_t*page, swf_output_t*output, int x, int y,
 
     pdf_page_render2(page, output);
 }
-void pdf_page_render(pdf_page_t*page, swf_output_t*output)
+void pdf_page_render(pdf_page_t*page, dev_output_t*output)
 {
     pdf_doc_internal_t*pi = (pdf_doc_internal_t*)page->parent->internal;
-    swf_output_internal_t*si = (swf_output_internal_t*)output->internal;
+    dev_output_internal_t*si = (dev_output_internal_t*)output->internal;
     
     si->outputDev->setMove(0,0);
     si->outputDev->setClip(0,0,0,0);
@@ -2936,11 +3001,7 @@ pdf_page_info_t* pdf_page_getinfo(pdf_page_t*page)
 
     InfoOutputDev*output = new InfoOutputDev;
     
-#ifdef XPDF_101
-    pi->doc->displayPage((OutputDev*)output, page->nr, /*zoom*/zoom, /*rotate*/0, /*doLinks*/(int)1);
-#else
-    pi->doc->displayPage((OutputDev*)output, page->nr, zoom, zoom, /*rotate*/0, true, /*doLinks*/(int)1);
-#endif
+    pi->doc->displayPage((OutputDev*)output, page->nr, zoom, zoom, /*rotate*/0, true, true, /*doLinks*/(int)1);
 
     info->xMin = output->x1;
     info->yMin = output->y1;