//
// PSOutputDev.cc
//
-// Copyright 1996-2002 Glyph & Cog, LLC
+// Copyright 1996-2003 Glyph & Cog, LLC
//
//========================================================================
#include <signal.h>
#include <math.h>
#include "GString.h"
+#include "GList.h"
#include "config.h"
#include "GlobalParams.h"
#include "Object.h"
" /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",
"/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",
fontFileIDs = NULL;
fontFileNames = NULL;
font16Enc = NULL;
+ xobjStack = NULL;
embFontList = NULL;
customColors = NULL;
t3String = NULL;
fontFileIDs = NULL;
fontFileNames = NULL;
font16Enc = NULL;
+ xobjStack = NULL;
embFontList = NULL;
customColors = NULL;
t3String = NULL;
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;
}
fontFileNames = (GString **)gmalloc(fontFileNameSize * sizeof(GString *));
font16EncLen = 0;
font16EncSize = 0;
+ xobjStack = new GList();
// initialize embedded font resource comment list
embFontList = new GString();
}
gfree(font16Enc);
}
+ if (xobjStack) {
+ delete xobjStack;
+ }
while (customColors) {
cc = customColors;
customColors = cc->next;
}
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);
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();
GString *psNameStr;
char *psName;
char type3Name[64], buf[16];
+ GBool subst;
UnicodeMap *uMap;
char *charName;
double xs, ys;
xs = ys = 1;
psNameStr = NULL;
+ subst = gFalse;
// check for resident 8-bit font
if (font->getName() &&
// do 8-bit font substitution
} else if (!font->isCIDFont()) {
+ subst = gTrue;
name = font->getName();
psName = NULL;
if (name) {
getPSFont16(font->getName(),
((GfxCIDFont *)font)->getCollection(),
font->getWMode()))) {
+ subst = gTrue;
psName = fontParam->psFontName->getCString();
if (font16EncLen >= font16EncSize) {
font16EncSize += 16;
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;
// 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);
ctu = ((Gfx8BitFont *)font)->getToUnicode();
ttFile->convertToType42(psName, ((Gfx8BitFont *)font)->getEncoding(),
ctu, ((Gfx8BitFont *)font)->getHasEncoding(),
+ ((Gfx8BitFont *)font)->isSymbolic(),
outputFunc, outputStream);
ctu->decRefCnt();
delete ttFile;
ctu = ((Gfx8BitFont *)font)->getToUnicode();
ttFile->convertToType42(psName, ((Gfx8BitFont *)font)->getEncoding(),
ctu, ((Gfx8BitFont *)font)->getHasEncoding(),
+ ((Gfx8BitFont *)font)->isSymbolic(),
outputFunc, outputStream);
ctu->decRefCnt();
delete ttFile;
// 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);
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 ||