From 7c5ab64d4db75e4bb6dadedb578e10178554d0db Mon Sep 17 00:00:00 2001 From: Martin Kretzschmar Date: Tue, 01 Apr 2003 19:47:11 +0000 Subject: Merge with Xpdf 2.02 and make it build --- (limited to 'pdf/xpdf/PSOutputDev.cc') diff --git a/pdf/xpdf/PSOutputDev.cc b/pdf/xpdf/PSOutputDev.cc index 9844ab3..7bef193 100644 --- a/pdf/xpdf/PSOutputDev.cc +++ b/pdf/xpdf/PSOutputDev.cc @@ -2,7 +2,7 @@ // // PSOutputDev.cc // -// Copyright 1996-2002 Glyph & Cog, LLC +// Copyright 1996-2003 Glyph & Cog, LLC // //======================================================================== @@ -18,6 +18,7 @@ #include #include #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 || -- cgit v0.9.1