]> www.fi.muni.cz Git - evince.git/blobdiff - pdf/xpdf/PSOutputDev.cc
(eog_hig_dialog_new): add terminating NULL in g_object_set.
[evince.git] / pdf / xpdf / PSOutputDev.cc
index 9844ab324fda9b63aabe0e1783fedaa711ce990f..7bef193e82db1581ffa804587ab41bc8e0c27941 100644 (file)
@@ -2,7 +2,7 @@
 //
 // PSOutputDev.cc
 //
-// Copyright 1996-2002 Glyph & Cog, LLC
+// Copyright 1996-2003 Glyph & Cog, LLC
 //
 //========================================================================
 
@@ -18,6 +18,7 @@
 #include <signal.h>
 #include <math.h>
 #include "GString.h"
+#include "GList.h"
 #include "config.h"
 #include "GlobalParams.h"
 #include "Object.h"
@@ -100,7 +101,7 @@ static char *prolog[] = {
   "  /customcolorimage {",
   "    gsave",
   "    [ exch /Separation exch dup 4 get exch /DeviceCMYK exch",
-  "      0 4 getinterval cvx",
+  "      0 4 getinterval",
   "      [ exch /dup load exch { mul exch dup } /forall load",
   "        /pop load dup ] cvx",
   "    ] setcolorspace",
@@ -328,11 +329,15 @@ static char *prolog[] = {
   "/pdfImSep {",
   "  findcmykcustomcolor exch",
   "  dup /Width get /pdfImBuf1 exch string def",
+  "  dup /Decode get aload pop 1 index sub /pdfImDecodeRange exch def",
+  "  /pdfImDecodeLow exch def",
   "  begin Width Height BitsPerComponent ImageMatrix DataSource end",
   "  /pdfImData exch def",
   "  { pdfImData pdfImBuf1 readstring pop",
   "    0 1 2 index length 1 sub {",
-  "      1 index exch 2 copy get 255 exch sub put",
+  "      1 index exch 2 copy get",
+  "      pdfImDecodeRange mul 255 div pdfImDecodeLow add round cvi",
+  "      255 exch sub put",
   "    } for }",
   "  6 5 roll customcolorimage",
   "  { currentfile pdfImBuf readline",
@@ -503,6 +508,7 @@ PSOutputDev::PSOutputDev(char *fileName, XRef *xrefA, Catalog *catalog,
   fontFileIDs = NULL;
   fontFileNames = NULL;
   font16Enc = NULL;
+  xobjStack = NULL;
   embFontList = NULL;
   customColors = NULL;
   t3String = NULL;
@@ -547,6 +553,7 @@ PSOutputDev::PSOutputDev(PSOutputFunc outputFuncA, void *outputStreamA,
   fontFileIDs = NULL;
   fontFileNames = NULL;
   font16Enc = NULL;
+  xobjStack = NULL;
   embFontList = NULL;
   customColors = NULL;
   t3String = NULL;
@@ -577,6 +584,11 @@ void PSOutputDev::init(PSOutputFunc outputFuncA, void *outputStreamA,
   mode = modeA;
   paperWidth = globalParams->getPSPaperWidth();
   paperHeight = globalParams->getPSPaperHeight();
+  if (paperWidth < 0 || paperHeight < 0) {
+    page = catalog->getPage(firstPage);
+    paperWidth = (int)(page->getWidth() + 0.5);
+    paperHeight = (int)(page->getHeight() + 0.5);
+  }
   if (mode == psModeForm) {
     lastPage = firstPage;
   }
@@ -601,6 +613,7 @@ void PSOutputDev::init(PSOutputFunc outputFuncA, void *outputStreamA,
   fontFileNames = (GString **)gmalloc(fontFileNameSize * sizeof(GString *));
   font16EncLen = 0;
   font16EncSize = 0;
+  xobjStack = new GList();
 
   // initialize embedded font resource comment list
   embFontList = new GString();
@@ -813,6 +826,9 @@ PSOutputDev::~PSOutputDev() {
     }
     gfree(font16Enc);
   }
+  if (xobjStack) {
+    delete xobjStack;
+  }
   while (customColors) {
     cc = customColors;
     customColors = cc->next;
@@ -821,8 +837,10 @@ PSOutputDev::~PSOutputDev() {
 }
 
 void PSOutputDev::setupResources(Dict *resDict) {
-  Object xObjDict, xObj, resObj;
-  int i;
+  Object xObjDict, xObjRef, xObj, resObj;
+  Ref ref0, ref1;
+  GBool skip;
+  int i, j;
 
   setupFonts(resDict);
   setupImages(resDict);
@@ -830,15 +848,40 @@ void PSOutputDev::setupResources(Dict *resDict) {
   resDict->lookup("XObject", &xObjDict);
   if (xObjDict.isDict()) {
     for (i = 0; i < xObjDict.dictGetLength(); ++i) {
-      xObjDict.dictGetVal(i, &xObj);
-      if (xObj.isStream()) {
-       xObj.streamGetDict()->lookup("Resources", &resObj);
-       if (resObj.isDict()) {
-         setupResources(resObj.getDict());
+
+      // avoid infinite recursion on XObjects
+      skip = gFalse;
+      if ((xObjDict.dictGetValNF(i, &xObjRef)->isRef())) {
+       ref0 = xObjRef.getRef();
+       for (j = 0; j < xobjStack->getLength(); ++j) {
+         ref1 = *(Ref *)xobjStack->get(j);
+         if (ref1.num == ref0.num && ref1.gen == ref0.gen) {
+           skip = gTrue;
+           break;
+         }
+       }
+       if (!skip) {
+         xobjStack->append(&ref0);
        }
-       resObj.free();
       }
-      xObj.free();
+      if (!skip) {
+
+       // process the XObject's resource dictionary
+       xObjDict.dictGetVal(i, &xObj);
+       if (xObj.isStream()) {
+         xObj.streamGetDict()->lookup("Resources", &resObj);
+         if (resObj.isDict()) {
+           setupResources(resObj.getDict());
+         }
+         resObj.free();
+       }
+       xObj.free();
+      }
+
+      if (xObjRef.isRef() && !skip) {
+       xobjStack->del(xobjStack->getLength() - 1);
+      }
+      xObjRef.free();
     }
   }
   xObjDict.free();
@@ -869,6 +912,7 @@ void PSOutputDev::setupFont(GfxFont *font, Dict *parentResDict) {
   GString *psNameStr;
   char *psName;
   char type3Name[64], buf[16];
+  GBool subst;
   UnicodeMap *uMap;
   char *charName;
   double xs, ys;
@@ -894,6 +938,7 @@ void PSOutputDev::setupFont(GfxFont *font, Dict *parentResDict) {
 
   xs = ys = 1;
   psNameStr = NULL;
+  subst = gFalse;
 
   // check for resident 8-bit font
   if (font->getName() &&
@@ -964,6 +1009,7 @@ void PSOutputDev::setupFont(GfxFont *font, Dict *parentResDict) {
 
   // do 8-bit font substitution
   } else if (!font->isCIDFont()) {
+    subst = gTrue;
     name = font->getName();
     psName = NULL;
     if (name) {
@@ -1025,6 +1071,7 @@ void PSOutputDev::setupFont(GfxFont *font, Dict *parentResDict) {
                getPSFont16(font->getName(),
                            ((GfxCIDFont *)font)->getCollection(),
                            font->getWMode()))) {
+    subst = gTrue;
     psName = fontParam->psFontName->getCString();
     if (font16EncLen >= font16EncSize) {
       font16EncSize += 16;
@@ -1069,6 +1116,7 @@ void PSOutputDev::setupFont(GfxFont *font, Dict *parentResDict) {
       writePSFmt((i == 0) ? "[ " : "  ");
       for (j = 0; j < 8; ++j) {
        if (font->getType() == fontTrueType &&
+           !subst &&
            !((Gfx8BitFont *)font)->getHasEncoding()) {
          sprintf(buf, "c%02x", i+j);
          charName = buf;
@@ -1288,7 +1336,9 @@ void PSOutputDev::setupEmbeddedType1CFont(GfxFont *font, Ref *id,
   // convert it to a Type 1 font
   fontBuf = font->readEmbFontFile(xref, &fontLen);
   t1cFile = new Type1CFontFile(fontBuf, fontLen);
-  t1cFile->convertToType1(outputFunc, outputStream);
+  if (t1cFile->isOk()) {
+    t1cFile->convertToType1(outputFunc, outputStream);
+  }
   delete t1cFile;
   gfree(fontBuf);
 
@@ -1330,6 +1380,7 @@ void PSOutputDev::setupEmbeddedTrueTypeFont(GfxFont *font, Ref *id,
   ctu = ((Gfx8BitFont *)font)->getToUnicode();
   ttFile->convertToType42(psName, ((Gfx8BitFont *)font)->getEncoding(),
                          ctu, ((Gfx8BitFont *)font)->getHasEncoding(),
+                         ((Gfx8BitFont *)font)->isSymbolic(),
                          outputFunc, outputStream);
   ctu->decRefCnt();
   delete ttFile;
@@ -1375,6 +1426,7 @@ void PSOutputDev::setupExternalTrueTypeFont(GfxFont *font, char *psName) {
   ctu = ((Gfx8BitFont *)font)->getToUnicode();
   ttFile->convertToType42(psName, ((Gfx8BitFont *)font)->getEncoding(),
                          ctu, ((Gfx8BitFont *)font)->getHasEncoding(),
+                         ((Gfx8BitFont *)font)->isSymbolic(),
                          outputFunc, outputStream);
   ctu->decRefCnt();
   delete ttFile;
@@ -1414,12 +1466,14 @@ void PSOutputDev::setupEmbeddedCIDType0Font(GfxFont *font, Ref *id,
   // convert it to a Type 0 font
   fontBuf = font->readEmbFontFile(xref, &fontLen);
   t1cFile = new Type1CFontFile(fontBuf, fontLen);
-  if (globalParams->getPSLevel() >= psLevel3) {
-    // Level 3: use a CID font
-    t1cFile->convertToCIDType0(psName, outputFunc, outputStream);
-  } else {
-    // otherwise: use a non-CID composite font
-    t1cFile->convertToType0(psName, outputFunc, outputStream);
+  if (t1cFile->isOk()) {
+    if (globalParams->getPSLevel() >= psLevel3) {
+      // Level 3: use a CID font
+      t1cFile->convertToCIDType0(psName, outputFunc, outputStream);
+    } else {
+      // otherwise: use a non-CID composite font
+      t1cFile->convertToType0(psName, outputFunc, outputStream);
+    }
   }
   delete t1cFile;
   gfree(fontBuf);
@@ -3309,6 +3363,15 @@ GString *PSOutputDev::filterPSName(GString *name) {
   char c;
 
   name2 = new GString();
+
+  // ghostscript chokes on names that begin with out-of-limits
+  // numbers, e.g., 1e4foo is handled correctly (as a name), but
+  // 1e999foo generates a limitcheck error
+  c = name->getChar(0);
+  if (c >= '0' && c <= '9') {
+    name2->append('f');
+  }
+
   for (i = 0; i < name->getLength(); ++i) {
     c = name->getChar(i);
     if (c <= (char)0x20 || c >= (char)0x7f ||