diff options
Diffstat (limited to 'filters/kword/pdf/xpdf/xpdf/PSOutputDev.cc')
-rw-r--r-- | filters/kword/pdf/xpdf/xpdf/PSOutputDev.cc | 3325 |
1 files changed, 0 insertions, 3325 deletions
diff --git a/filters/kword/pdf/xpdf/xpdf/PSOutputDev.cc b/filters/kword/pdf/xpdf/xpdf/PSOutputDev.cc deleted file mode 100644 index 111d8717b..000000000 --- a/filters/kword/pdf/xpdf/xpdf/PSOutputDev.cc +++ /dev/null @@ -1,3325 +0,0 @@ -//======================================================================== -// -// PSOutputDev.cc -// -// Copyright 1996-2002 Glyph & Cog, LLC -// -//======================================================================== - -#include <aconf.h> - -#ifdef USE_GCC_PRAGMAS -#pragma implementation -#endif - -#include <stdio.h> -#include <stddef.h> -#include <stdarg.h> -#include <signal.h> -#include <math.h> -#include "GString.h" -#include "config.h" -#include "GlobalParams.h" -#include "Object.h" -#include "Error.h" -#include "Function.h" -#include "Gfx.h" -#include "GfxState.h" -#include "GfxFont.h" -#include "CharCodeToUnicode.h" -#include "UnicodeMap.h" -#include "FontFile.h" -#include "Catalog.h" -#include "Page.h" -#include "Stream.h" -#include "Annot.h" -#include "PSOutputDev.h" - -#ifdef MACOS -// needed for setting type/creator of MacOS files -#include "ICSupport.h" -#endif - -//------------------------------------------------------------------------ -// PostScript prolog and setup -//------------------------------------------------------------------------ - -static char *prolog[] = { - "/xpdf 75 dict def xpdf begin", - "% PDF special state", - "/pdfDictSize 14 def", - "/pdfSetup {", - " 3 1 roll 2 array astore", - " /setpagedevice where {", - " pop 3 dict begin", - " /PageSize exch def", - " /ImagingBBox null def", - " /Policies 1 dict dup begin /PageSize 3 def end def", - " { /Duplex true def } if", - " currentdict end setpagedevice", - " } {", - " pop pop", - " } ifelse", - "} def", - "/pdfStartPage {", - " pdfDictSize dict begin", - " /pdfFill [0] def", - " /pdfStroke [0] def", - " /pdfLastFill false def", - " /pdfLastStroke false def", - " /pdfTextMat [1 0 0 1 0 0] def", - " /pdfFontSize 0 def", - " /pdfCharSpacing 0 def", - " /pdfTextRender 0 def", - " /pdfTextRise 0 def", - " /pdfWordSpacing 0 def", - " /pdfHorizScaling 1 def", - "} def", - "/pdfEndPage { end } def", - "% separation convention operators", - "/findcmykcustomcolor where {", - " pop", - "}{", - " /findcmykcustomcolor { 5 array astore } def", - "} ifelse", - "/setcustomcolor where {", - " pop", - "}{", - " /setcustomcolor {", - " exch", - " [ exch /Separation exch dup 4 get exch /DeviceCMYK exch", - " 0 4 getinterval cvx", - " [ exch /dup load exch { mul exch dup } /forall load", - " /pop load dup ] cvx", - " ] setcolorspace setcolor", - " } def", - "} ifelse", - "/customcolorimage where {", - " pop", - "}{", - " /customcolorimage {", - " gsave", - " [ exch /Separation exch dup 4 get exch /DeviceCMYK exch", - " 0 4 getinterval cvx", - " [ exch /dup load exch { mul exch dup } /forall load", - " /pop load dup ] cvx", - " ] setcolorspace", - " 10 dict begin", - " /ImageType 1 def", - " /DataSource exch def", - " /ImageMatrix exch def", - " /BitsPerComponent exch def", - " /Height exch def", - " /Width exch def", - " /Decode [1 0] def", - " currentdict end", - " image", - " grestore", - " } def", - "} ifelse", - "% PDF color state", - "/sCol {", - " pdfLastStroke not {", - " pdfStroke aload length", - " dup 1 eq {", - " pop setgray", - " }{", - " dup 3 eq {", - " pop setrgbcolor", - " }{", - " 4 eq {", - " setcmykcolor", - " }{", - " findcmykcustomcolor exch setcustomcolor", - " } ifelse", - " } ifelse", - " } ifelse", - " /pdfLastStroke true def /pdfLastFill false def", - " } if", - "} def", - "/fCol {", - " pdfLastFill not {", - " pdfFill aload length", - " dup 1 eq {", - " pop setgray", - " }{", - " dup 3 eq {", - " pop setrgbcolor", - " }{", - " 4 eq {", - " setcmykcolor", - " }{", - " findcmykcustomcolor exch setcustomcolor", - " } ifelse", - " } ifelse", - " } ifelse", - " /pdfLastFill true def /pdfLastStroke false def", - " } if", - "} def", - "% build a font", - "/pdfMakeFont {", - " 4 3 roll findfont", - " 4 2 roll matrix scale makefont", - " dup length dict begin", - " { 1 index /FID ne { def } { pop pop } ifelse } forall", - " /Encoding exch def", - " currentdict", - " end", - " definefont pop", - "} def", - "/pdfMakeFont16 {", - " exch findfont", - " dup length dict begin", - " { 1 index /FID ne { def } { pop pop } ifelse } forall", - " /WMode exch def", - " currentdict", - " end", - " definefont pop", - "} def", - "/pdfMakeFont16L3 {", - " 1 index /CIDFont resourcestatus {", - " pop pop 1 index /CIDFont findresource /CIDFontType known", - " } {", - " false", - " } ifelse", - " {", - " 0 eq { /Identity-H } { /Identity-V } ifelse", - " exch 1 array astore composefont pop", - " } {", - " pdfMakeFont16", - " } ifelse", - "} def", - "% graphics state operators", - "/q { gsave pdfDictSize dict begin } def", - "/Q { end grestore } def", - "/cm { concat } def", - "/d { setdash } def", - "/i { setflat } def", - "/j { setlinejoin } def", - "/J { setlinecap } def", - "/M { setmiterlimit } def", - "/w { setlinewidth } def", - "% color operators", - "/g { dup 1 array astore /pdfFill exch def setgray", - " /pdfLastFill true def /pdfLastStroke false def } def", - "/G { dup 1 array astore /pdfStroke exch def setgray", - " /pdfLastStroke true def /pdfLastFill false def } def", - "/rg { 3 copy 3 array astore /pdfFill exch def setrgbcolor", - " /pdfLastFill true def /pdfLastStroke false def } def", - "/RG { 3 copy 3 array astore /pdfStroke exch def setrgbcolor", - " /pdfLastStroke true def /pdfLastFill false def } def", - "/k { 4 copy 4 array astore /pdfFill exch def setcmykcolor", - " /pdfLastFill true def /pdfLastStroke false def } def", - "/K { 4 copy 4 array astore /pdfStroke exch def setcmykcolor", - " /pdfLastStroke true def /pdfLastFill false def } def", - "/ck { 6 copy 6 array astore /pdfFill exch def", - " findcmykcustomcolor exch setcustomcolor", - " /pdfLastFill true def /pdfLastStroke false def } def", - "/CK { 6 copy 6 array astore /pdfStroke exch def", - " findcmykcustomcolor exch setcustomcolor", - " /pdfLastStroke true def /pdfLastFill false def } def", - "% path segment operators", - "/m { moveto } def", - "/l { lineto } def", - "/c { curveto } def", - "/re { 4 2 roll moveto 1 index 0 rlineto 0 exch rlineto", - " neg 0 rlineto closepath } def", - "/h { closepath } def", - "% path painting operators", - "/S { sCol stroke } def", - "/Sf { fCol stroke } def", - "/f { fCol fill } def", - "/f* { fCol eofill } def", - "% clipping operators", - "/W { clip newpath } def", - "/W* { eoclip newpath } def", - "% text state operators", - "/Tc { /pdfCharSpacing exch def } def", - "/Tf { dup /pdfFontSize exch def", - " dup pdfHorizScaling mul exch matrix scale", - " pdfTextMat matrix concatmatrix dup 4 0 put dup 5 0 put", - " exch findfont exch makefont setfont } def", - "/Tr { /pdfTextRender exch def } def", - "/Ts { /pdfTextRise exch def } def", - "/Tw { /pdfWordSpacing exch def } def", - "/Tz { /pdfHorizScaling exch def } def", - "% text positioning operators", - "/Td { pdfTextMat transform moveto } def", - "/Tm { /pdfTextMat exch def } def", - "% text string operators", - "/awcp { % awidthcharpath", - " exch {", - " 1 string dup 0 3 index put 2 index charpath", - " 3 index 3 index rmoveto", - " 4 index eq { 5 index 5 index rmoveto } if", - " } forall", - " 6 {pop} repeat", - "} def", - "/Tj { fCol", // because stringwidth has to draw Type 3 chars - " 0 pdfTextRise pdfTextMat dtransform rmoveto", - " 1 index stringwidth pdfTextMat idtransform pop", - " sub 1 index length dup 0 ne { div } { pop pop 0 } ifelse", - " pdfWordSpacing pdfHorizScaling mul 0 pdfTextMat dtransform 32", - " 4 3 roll pdfCharSpacing pdfHorizScaling mul add 0", - " pdfTextMat dtransform", - " 6 5 roll", - " currentpoint 8 2 roll", - " pdfTextRender 1 and 0 eq {", - " 6 copy awidthshow", - " } if", - " pdfTextRender 3 and dup 1 eq exch 2 eq or {", - " 8 6 roll moveto", - " currentfont /FontType get 3 eq { fCol } { sCol } ifelse", - " false awcp currentpoint stroke moveto", - " } {", - " 8 {pop} repeat", - " } ifelse", - " 0 pdfTextRise neg pdfTextMat dtransform rmoveto } def", - "/Tj16 { pdfTextRender 1 and 0 eq { fCol } { sCol } ifelse", - " 0 pdfTextRise pdfTextMat dtransform rmoveto", - " 2 index stringwidth pdfTextMat idtransform pop", - " sub exch div", - " pdfWordSpacing pdfHorizScaling mul 0 pdfTextMat dtransform 32", - " 4 3 roll pdfCharSpacing pdfHorizScaling mul add 0", - " pdfTextMat dtransform", - " 6 5 roll awidthshow", - " 0 pdfTextRise neg pdfTextMat dtransform rmoveto } def", - "/Tj16V { pdfTextRender 1 and 0 eq { fCol } { sCol } ifelse", - " 0 pdfTextRise pdfTextMat dtransform rmoveto", - " 2 index stringwidth pdfTextMat idtransform exch pop", - " sub exch div", - " 0 pdfWordSpacing pdfTextMat dtransform 32", - " 4 3 roll pdfCharSpacing add 0 exch", - " pdfTextMat dtransform", - " 6 5 roll awidthshow", - " 0 pdfTextRise neg pdfTextMat dtransform rmoveto } def", - "/TJm { pdfFontSize 0.001 mul mul neg 0", - " pdfTextMat dtransform rmoveto } def", - "/TJmV { pdfFontSize 0.001 mul mul neg 0 exch", - " pdfTextMat dtransform rmoveto } def", - "% Level 1 image operators", - "/pdfIm1 {", - " /pdfImBuf1 4 index string def", - " { currentfile pdfImBuf1 readhexstring pop } image", - "} def", - "/pdfIm1Sep {", - " /pdfImBuf1 4 index string def", - " /pdfImBuf2 4 index string def", - " /pdfImBuf3 4 index string def", - " /pdfImBuf4 4 index string def", - " { currentfile pdfImBuf1 readhexstring pop }", - " { currentfile pdfImBuf2 readhexstring pop }", - " { currentfile pdfImBuf3 readhexstring pop }", - " { currentfile pdfImBuf4 readhexstring pop }", - " true 4 colorimage", - "} def", - "/pdfImM1 {", - " /pdfImBuf1 4 index 7 add 8 idiv string def", - " { currentfile pdfImBuf1 readhexstring pop } imagemask", - "} def", - "% Level 2 image operators", - "/pdfImBuf 100 string def", - "/pdfIm {", - " image", - " { currentfile pdfImBuf readline", - " not { pop exit } if", - " (%-EOD-) eq { exit } if } loop", - "} def", - "/pdfImSep {", - " findcmykcustomcolor exch", - " dup /Width get /pdfImBuf1 exch string 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", - " } for }", - " 6 5 roll customcolorimage", - " { currentfile pdfImBuf readline", - " not { pop exit } if", - " (%-EOD-) eq { exit } if } loop", - "} def", - "/pdfImM {", - " fCol imagemask", - " { currentfile pdfImBuf readline", - " not { pop exit } if", - " (%-EOD-) eq { exit } if } loop", - "} def", - "end", - NULL -}; - -static char *cmapProlog[] = { - "/CIDInit /ProcSet findresource begin", - "10 dict begin", - " begincmap", - " /CMapType 1 def", - " /CMapName /Identity-H def", - " /CIDSystemInfo 3 dict dup begin", - " /Registry (Adobe) def", - " /Ordering (Identity) def", - " /Supplement 0 def", - " end def", - " 1 begincodespacerange", - " <0000> <ffff>", - " endcodespacerange", - " 0 usefont", - " 1 begincidrange", - " <0000> <ffff> 0", - " endcidrange", - " endcmap", - " currentdict CMapName exch /CMap defineresource pop", - "end", - "10 dict begin", - " begincmap", - " /CMapType 1 def", - " /CMapName /Identity-V def", - " /CIDSystemInfo 3 dict dup begin", - " /Registry (Adobe) def", - " /Ordering (Identity) def", - " /Supplement 0 def", - " end def", - " /WMode 1 def", - " 1 begincodespacerange", - " <0000> <ffff>", - " endcodespacerange", - " 0 usefont", - " 1 begincidrange", - " <0000> <ffff> 0", - " endcidrange", - " endcmap", - " currentdict CMapName exch /CMap defineresource pop", - "end", - "end", - NULL -}; - -//------------------------------------------------------------------------ -// Fonts -//------------------------------------------------------------------------ - -struct PSSubstFont { - char *psName; // PostScript name - double mWidth; // width of 'm' character -}; - -static char *psFonts[] = { - "Courier", - "Courier-Bold", - "Courier-Oblique", - "Courier-BoldOblique", - "Helvetica", - "Helvetica-Bold", - "Helvetica-Oblique", - "Helvetica-BoldOblique", - "Symbol", - "Times-Roman", - "Times-Bold", - "Times-Italic", - "Times-BoldItalic", - "ZapfDingbats", - NULL -}; - -static PSSubstFont psSubstFonts[] = { - {"Helvetica", 0.833}, - {"Helvetica-Oblique", 0.833}, - {"Helvetica-Bold", 0.889}, - {"Helvetica-BoldOblique", 0.889}, - {"Times-Roman", 0.788}, - {"Times-Italic", 0.722}, - {"Times-Bold", 0.833}, - {"Times-BoldItalic", 0.778}, - {"Courier", 0.600}, - {"Courier-Oblique", 0.600}, - {"Courier-Bold", 0.600}, - {"Courier-BoldOblique", 0.600} -}; - -// Encoding info for substitute 16-bit font -struct PSFont16Enc { - Ref fontID; - GString *enc; -}; - -//------------------------------------------------------------------------ -// process colors -//------------------------------------------------------------------------ - -#define psProcessCyan 1 -#define psProcessMagenta 2 -#define psProcessYellow 4 -#define psProcessBlack 8 -#define psProcessCMYK 15 - -//------------------------------------------------------------------------ -// PSOutCustomColor -//------------------------------------------------------------------------ - -class PSOutCustomColor { -public: - - PSOutCustomColor(double cA, double mA, - double yA, double kA, GString *nameA); - ~PSOutCustomColor(); - - double c, m, y, k; - GString *name; - PSOutCustomColor *next; -}; - -PSOutCustomColor::PSOutCustomColor(double cA, double mA, - double yA, double kA, GString *nameA) { - c = cA; - m = mA; - y = yA; - k = kA; - name = nameA; - next = NULL; -} - -PSOutCustomColor::~PSOutCustomColor() { - delete name; -} - -//------------------------------------------------------------------------ -// PSOutputDev -//------------------------------------------------------------------------ - -extern "C" { -typedef void (*SignalFunc)(int); -} - -static void outputToFile(void *stream, char *data, int len) { - fwrite(data, 1, len, (FILE *)stream); -} - -PSOutputDev::PSOutputDev(char *fileName, XRef *xrefA, Catalog *catalog, - int firstPage, int lastPage, PSOutMode modeA) { - FILE *f; - PSFileType fileTypeA; - - fontIDs = NULL; - fontFileIDs = NULL; - fontFileNames = NULL; - font16Enc = NULL; - embFontList = NULL; - customColors = NULL; - t3String = NULL; - - // open file or pipe - if (!strcmp(fileName, "-")) { - fileTypeA = psStdout; - f = stdout; - } else if (fileName[0] == '|') { - fileTypeA = psPipe; -#ifdef HAVE_POPEN -#ifndef WIN32 - signal(SIGPIPE, (SignalFunc)SIG_IGN); -#endif - if (!(f = popen(fileName + 1, "w"))) { - error(-1, "Couldn't run print command '%s'", fileName); - ok = gFalse; - return; - } -#else - error(-1, "Print commands are not supported ('%s')", fileName); - ok = gFalse; - return; -#endif - } else { - fileTypeA = psFile; - if (!(f = fopen(fileName, "w"))) { - error(-1, "Couldn't open PostScript file '%s'", fileName); - ok = gFalse; - return; - } - } - - init(outputToFile, f, fileTypeA, - xrefA, catalog, firstPage, lastPage, modeA); -} - -PSOutputDev::PSOutputDev(PSOutputFunc outputFuncA, void *outputStreamA, - XRef *xrefA, Catalog *catalog, - int firstPage, int lastPage, PSOutMode modeA) { - fontIDs = NULL; - fontFileIDs = NULL; - fontFileNames = NULL; - font16Enc = NULL; - embFontList = NULL; - customColors = NULL; - t3String = NULL; - - init(outputFuncA, outputStreamA, psGeneric, - xrefA, catalog, firstPage, lastPage, modeA); -} - -void PSOutputDev::init(PSOutputFunc outputFuncA, void *outputStreamA, - PSFileType fileTypeA, XRef *xrefA, Catalog *catalog, - int firstPage, int lastPage, PSOutMode modeA) { - Page *page; - PDFRectangle *box; - Dict *resDict; - Annots *annots; - char **p; - int pg; - Object obj1, obj2; - int i; - - // initialize - ok = gTrue; - outputFunc = outputFuncA; - outputStream = outputStreamA; - fileType = fileTypeA; - xref = xrefA; - level = globalParams->getPSLevel(); - mode = modeA; - paperWidth = globalParams->getPSPaperWidth(); - paperHeight = globalParams->getPSPaperHeight(); - if (mode == psModeForm) { - lastPage = firstPage; - } - processColors = 0; - inType3Char = gFalse; - -#if OPI_SUPPORT - // initialize OPI nesting levels - opi13Nest = 0; - opi20Nest = 0; -#endif - - // initialize fontIDs, fontFileIDs, and fontFileNames lists - fontIDSize = 64; - fontIDLen = 0; - fontIDs = (Ref *)gmalloc(fontIDSize * sizeof(Ref)); - fontFileIDSize = 64; - fontFileIDLen = 0; - fontFileIDs = (Ref *)gmalloc(fontFileIDSize * sizeof(Ref)); - fontFileNameSize = 64; - fontFileNameLen = 0; - fontFileNames = (GString **)gmalloc(fontFileNameSize * sizeof(GString *)); - font16EncLen = 0; - font16EncSize = 0; - - // initialize embedded font resource comment list - embFontList = new GString(); - - // write header - switch (mode) { - case psModePS: - writePS("%!PS-Adobe-3.0\n"); - writePSFmt("%%%%Creator: xpdf/pdftops %s\n", xpdfVersion); - writePSFmt("%%%%LanguageLevel: %d\n", - (level == psLevel1 || level == psLevel1Sep) ? 1 : - (level == psLevel2 || level == psLevel2Sep) ? 2 : 3); - if (level == psLevel1Sep || level == psLevel2Sep || level == psLevel3Sep) { - writePS("%%DocumentProcessColors: (atend)\n"); - writePS("%%DocumentCustomColors: (atend)\n"); - } - writePS("%%DocumentSuppliedResources: (atend)\n"); - writePSFmt("%%%%DocumentMedia: plain %d %d 0 () ()\n", - paperWidth, paperHeight); - writePSFmt("%%%%Pages: %d\n", lastPage - firstPage + 1); - writePS("%%EndComments\n"); - writePS("%%BeginDefaults\n"); - writePS("%%PageMedia: plain\n"); - writePS("%%EndDefaults\n"); - break; - case psModeEPS: - writePS("%!PS-Adobe-3.0 EPSF-3.0\n"); - writePSFmt("%%%%Creator: xpdf/pdftops %s\n", xpdfVersion); - writePSFmt("%%%%LanguageLevel: %d\n", - (level == psLevel1 || level == psLevel1Sep) ? 1 : - (level == psLevel2 || level == psLevel2Sep) ? 2 : 3); - if (level == psLevel1Sep || level == psLevel2Sep || level == psLevel3Sep) { - writePS("%%DocumentProcessColors: (atend)\n"); - writePS("%%DocumentCustomColors: (atend)\n"); - } - page = catalog->getPage(firstPage); - box = page->getBox(); - writePSFmt("%%%%BoundingBox: %d %d %d %d\n", - (int)floor(box->x1), (int)floor(box->y1), - (int)ceil(box->x2), (int)ceil(box->y2)); - if (floor(box->x1) != ceil(box->x1) || - floor(box->y1) != ceil(box->y1) || - floor(box->x2) != ceil(box->x2) || - floor(box->y2) != ceil(box->y2)) { - writePSFmt("%%%%HiResBoundingBox: %g %g %g %g\n", - box->x1, box->y1, box->x2, box->y2); - } - writePS("%%DocumentSuppliedResources: (atend)\n"); - writePS("%%EndComments\n"); - break; - case psModeForm: - writePS("%!PS-Adobe-3.0 Resource-Form\n"); - writePSFmt("%%%%Creator: xpdf/pdftops %s\n", xpdfVersion); - writePSFmt("%%%%LanguageLevel: %d\n", - (level == psLevel1 || level == psLevel1Sep) ? 1 : - (level == psLevel2 || level == psLevel2Sep) ? 2 : 3); - if (level == psLevel1Sep || level == psLevel2Sep || level == psLevel3Sep) { - writePS("%%DocumentProcessColors: (atend)\n"); - writePS("%%DocumentCustomColors: (atend)\n"); - } - writePS("%%DocumentSuppliedResources: (atend)\n"); - writePS("%%EndComments\n"); - page = catalog->getPage(firstPage); - box = page->getBox(); - writePS("32 dict dup begin\n"); - writePSFmt("/BBox [%d %d %d %d] def\n", - (int)box->x1, (int)box->y1, (int)box->x2, (int)box->y2); - writePS("/FormType 1 def\n"); - writePS("/Matrix [1 0 0 1 0 0] def\n"); - break; - } - - // write prolog - if (mode != psModeForm) { - writePS("%%BeginProlog\n"); - } - writePSFmt("%%%%BeginResource: procset xpdf %s 0\n", xpdfVersion); - for (p = prolog; *p; ++p) { - writePSFmt("%s\n", *p); - } - writePS("%%EndResource\n"); - if (level >= psLevel3) { - for (p = cmapProlog; *p; ++p) { - writePSFmt("%s\n", *p); - } - } - if (mode != psModeForm) { - writePS("%%EndProlog\n"); - } - - // set up fonts and images - if (mode == psModeForm) { - // swap the form and xpdf dicts - writePS("xpdf end begin dup begin\n"); - } else { - writePS("%%BeginSetup\n"); - writePS("xpdf begin\n"); - } - for (pg = firstPage; pg <= lastPage; ++pg) { - page = catalog->getPage(pg); - if ((resDict = page->getResourceDict())) { - setupResources(resDict); - } - annots = new Annots(xref, page->getAnnots(&obj1)); - obj1.free(); - for (i = 0; i < annots->getNumAnnots(); ++i) { - if (annots->getAnnot(i)->getAppearance(&obj1)->isStream()) { - obj1.streamGetDict()->lookup("Resources", &obj2); - if (obj2.isDict()) { - setupResources(obj2.getDict()); - } - obj2.free(); - } - obj1.free(); - } - delete annots; - } - if (mode != psModeForm) { - if (mode != psModeEPS) { - writePSFmt("%d %d %s pdfSetup\n", - paperWidth, paperHeight, - globalParams->getPSDuplex() ? "true" : "false"); - } -#if OPI_SUPPORT - if (globalParams->getPSOPI()) { - writePS("/opiMatrix matrix currentmatrix def\n"); - } -#endif - writePS("%%EndSetup\n"); - } - - // initialize sequential page number - seqPage = 1; -} - -PSOutputDev::~PSOutputDev() { - PSOutCustomColor *cc; - int i; - - if (ok) { - if (mode == psModeForm) { - writePS("/Foo exch /Form defineresource pop\n"); - } else { - writePS("%%Trailer\n"); - writePS("end\n"); - writePS("%%DocumentSuppliedResources:\n"); - writePS(embFontList->getCString()); - if (level == psLevel1Sep || level == psLevel2Sep || - level == psLevel3Sep) { - writePS("%%DocumentProcessColors:"); - if (processColors & psProcessCyan) { - writePS(" Cyan"); - } - if (processColors & psProcessMagenta) { - writePS(" Magenta"); - } - if (processColors & psProcessYellow) { - writePS(" Yellow"); - } - if (processColors & psProcessBlack) { - writePS(" Black"); - } - writePS("\n"); - writePS("%%DocumentCustomColors:"); - for (cc = customColors; cc; cc = cc->next) { - writePSFmt(" (%s)", cc->name->getCString()); - } - writePS("\n"); - writePS("%%CMYKCustomColor:\n"); - for (cc = customColors; cc; cc = cc->next) { - writePSFmt("%%%%+ %g %g %g %g (%s)\n", - cc->c, cc->m, cc->y, cc->k, cc->name->getCString()); - } - } - writePS("%%EOF\n"); - } - if (fileType == psFile) { -#ifdef MACOS - ICS_MapRefNumAndAssign((short)((FILE *)outputStream)->handle); -#endif - fclose((FILE *)outputStream); - } -#ifdef HAVE_POPEN - else if (fileType == psPipe) { - pclose((FILE *)outputStream); -#ifndef WIN32 - signal(SIGPIPE, (SignalFunc)SIG_DFL); -#endif - } -#endif - } - if (embFontList) { - delete embFontList; - } - if (fontIDs) { - gfree(fontIDs); - } - if (fontFileIDs) { - gfree(fontFileIDs); - } - if (fontFileNames) { - for (i = 0; i < fontFileNameLen; ++i) { - delete fontFileNames[i]; - } - gfree(fontFileNames); - } - if (font16Enc) { - for (i = 0; i < font16EncLen; ++i) { - delete font16Enc[i].enc; - } - gfree(font16Enc); - } - while (customColors) { - cc = customColors; - customColors = cc->next; - delete cc; - } -} - -void PSOutputDev::setupResources(Dict *resDict) { - Object xObjDict, xObj, resObj; - int i; - - 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()); - } - resObj.free(); - } - xObj.free(); - } - } - xObjDict.free(); -} - -void PSOutputDev::setupFonts(Dict *resDict) { - Object fontDict; - GfxFontDict *gfxFontDict; - GfxFont *font; - int i; - - resDict->lookup("Font", &fontDict); - if (fontDict.isDict()) { - gfxFontDict = new GfxFontDict(xref, fontDict.getDict()); - for (i = 0; i < gfxFontDict->getNumFonts(); ++i) { - font = gfxFontDict->getFont(i); - setupFont(font, resDict); - } - delete gfxFontDict; - } - fontDict.free(); -} - -void PSOutputDev::setupFont(GfxFont *font, Dict *parentResDict) { - Ref fontFileID; - GString *name; - PSFontParam *fontParam; - GString *psNameStr; - char *psName; - char type3Name[64], buf[16]; - UnicodeMap *uMap; - char *charName; - double xs, ys; - int code; - double w1, w2; - double *fm; - int i, j; - - // check if font is already set up - for (i = 0; i < fontIDLen; ++i) { - if (fontIDs[i].num == font->getID()->num && - fontIDs[i].gen == font->getID()->gen) { - return; - } - } - - // add entry to fontIDs list - if (fontIDLen >= fontIDSize) { - fontIDSize += 64; - fontIDs = (Ref *)grealloc(fontIDs, fontIDSize * sizeof(Ref)); - } - fontIDs[fontIDLen++] = *font->getID(); - - xs = ys = 1; - psNameStr = NULL; - - // check for resident 8-bit font - if (font->getName() && - (fontParam = globalParams->getPSFont(font->getName()))) { - psName = fontParam->psFontName->getCString(); - - // check for embedded Type 1 font - } else if (globalParams->getPSEmbedType1() && - font->getType() == fontType1 && - font->getEmbeddedFontID(&fontFileID)) { - psNameStr = filterPSName(font->getEmbeddedFontName()); - psName = psNameStr->getCString(); - setupEmbeddedType1Font(&fontFileID, psName); - - // check for embedded Type 1C font - } else if (globalParams->getPSEmbedType1() && - font->getType() == fontType1C && - font->getEmbeddedFontID(&fontFileID)) { - psNameStr = filterPSName(font->getEmbeddedFontName()); - psName = psNameStr->getCString(); - setupEmbeddedType1CFont(font, &fontFileID, psName); - - // check for external Type 1 font file - } else if (globalParams->getPSEmbedType1() && - font->getType() == fontType1 && - font->getExtFontFile()) { - // this assumes that the PS font name matches the PDF font name - psName = font->getName()->getCString(); - setupExternalType1Font(font->getExtFontFile(), psName); - - // check for embedded TrueType font - } else if (globalParams->getPSEmbedTrueType() && - font->getType() == fontTrueType && - font->getEmbeddedFontID(&fontFileID)) { - psNameStr = filterPSName(font->getEmbeddedFontName()); - psName = psNameStr->getCString(); - setupEmbeddedTrueTypeFont(font, &fontFileID, psName); - - // check for external TrueType font file - } else if (globalParams->getPSEmbedTrueType() && - font->getType() == fontTrueType && - font->getExtFontFile()) { - psNameStr = filterPSName(font->getName()); - psName = psNameStr->getCString(); - setupExternalTrueTypeFont(font, psName); - - // check for embedded CID PostScript font - } else if (globalParams->getPSEmbedCIDPostScript() && - font->getType() == fontCIDType0C && - font->getEmbeddedFontID(&fontFileID)) { - psNameStr = filterPSName(font->getEmbeddedFontName()); - psName = psNameStr->getCString(); - setupEmbeddedCIDType0Font(font, &fontFileID, psName); - - // check for embedded CID TrueType font - } else if (globalParams->getPSEmbedCIDTrueType() && - font->getType() == fontCIDType2 && - font->getEmbeddedFontID(&fontFileID)) { - psNameStr = filterPSName(font->getEmbeddedFontName()); - psName = psNameStr->getCString(); - setupEmbeddedCIDTrueTypeFont(font, &fontFileID, psName); - - } else if (font->getType() == fontType3) { - sprintf(type3Name, "T3_%d_%d", - font->getID()->num, font->getID()->gen); - psName = type3Name; - setupType3Font(font, psName, parentResDict); - - // do 8-bit font substitution - } else if (!font->isCIDFont()) { - name = font->getName(); - psName = NULL; - if (name) { - for (i = 0; psFonts[i]; ++i) { - if (name->cmp(psFonts[i]) == 0) { - psName = psFonts[i]; - break; - } - } - } - if (!psName) { - if (font->isFixedWidth()) { - i = 8; - } else if (font->isSerif()) { - i = 4; - } else { - i = 0; - } - if (font->isBold()) { - i += 2; - } - if (font->isItalic()) { - i += 1; - } - psName = psSubstFonts[i].psName; - for (code = 0; code < 256; ++code) { - if ((charName = ((Gfx8BitFont *)font)->getCharName(code)) && - charName[0] == 'm' && charName[1] == '\0') { - break; - } - } - if (code < 256) { - w1 = ((Gfx8BitFont *)font)->getWidth(code); - } else { - w1 = 0; - } - w2 = psSubstFonts[i].mWidth; - xs = w1 / w2; - if (xs < 0.1) { - xs = 1; - } - if (font->getType() == fontType3) { - // This is a hack which makes it possible to substitute for some - // Type 3 fonts. The problem is that it's impossible to know what - // the base coordinate system used in the font is without actually - // rendering the font. - ys = xs; - fm = font->getFontMatrix(); - if (fm[0] != 0) { - ys *= fm[3] / fm[0]; - } - } else { - ys = 1; - } - } - - // do 16-bit font substitution - } else if ((fontParam = globalParams-> - getPSFont16(font->getName(), - ((GfxCIDFont *)font)->getCollection(), - font->getWMode()))) { - psName = fontParam->psFontName->getCString(); - if (font16EncLen >= font16EncSize) { - font16EncSize += 16; - font16Enc = (PSFont16Enc *)grealloc(font16Enc, - font16EncSize * sizeof(PSFont16Enc)); - } - font16Enc[font16EncLen].fontID = *font->getID(); - font16Enc[font16EncLen].enc = fontParam->encoding->copy(); - if ((uMap = globalParams->getUnicodeMap(font16Enc[font16EncLen].enc))) { - uMap->decRefCnt(); - ++font16EncLen; - } else { - error(-1, "Couldn't find Unicode map for 16-bit font encoding '%s'", - font16Enc[font16EncLen].enc->getCString()); - } - - // give up - can't do anything with this font - } else { - error(-1, "Couldn't find a font to substitute for '%s' ('%s' character collection)", - font->getName() ? font->getName()->getCString() : "(unnamed)", - ((GfxCIDFont *)font)->getCollection() - ? ((GfxCIDFont *)font)->getCollection()->getCString() - : "(unknown)"); - return; - } - - // generate PostScript code to set up the font - if (font->isCIDFont()) { - if (level == psLevel3 || level == psLevel3Sep) { - writePSFmt("/F%d_%d /%s %d pdfMakeFont16L3\n", - font->getID()->num, font->getID()->gen, psName, - font->getWMode()); - } else { - writePSFmt("/F%d_%d /%s %d pdfMakeFont16\n", - font->getID()->num, font->getID()->gen, psName, - font->getWMode()); - } - } else { - writePSFmt("/F%d_%d /%s %g %g\n", - font->getID()->num, font->getID()->gen, psName, xs, ys); - for (i = 0; i < 256; i += 8) { - writePSFmt((i == 0) ? "[ " : " "); - for (j = 0; j < 8; ++j) { - if (font->getType() == fontTrueType && - !((Gfx8BitFont *)font)->getHasEncoding()) { - sprintf(buf, "c%02x", i+j); - charName = buf; - } else { - charName = ((Gfx8BitFont *)font)->getCharName(i+j); - // this is a kludge for broken PDF files that encode char 32 - // as .notdef - if (i+j == 32 && charName && !strcmp(charName, ".notdef")) { - charName = "space"; - } - } - writePS("/"); - writePSName(charName ? charName : (char *)".notdef"); - } - writePS((i == 256-8) ? (char *)"]\n" : (char *)"\n"); - } - writePS("pdfMakeFont\n"); - } - - if (psNameStr) { - delete psNameStr; - } -} - -void PSOutputDev::setupEmbeddedType1Font(Ref *id, char *psName) { - static char hexChar[17] = "0123456789abcdef"; - Object refObj, strObj, obj1, obj2; - Dict *dict; - int length1, length2; - int c; - int start[4]; - GBool binMode; - int i; - - // check if font is already embedded - for (i = 0; i < fontFileIDLen; ++i) { - if (fontFileIDs[i].num == id->num && - fontFileIDs[i].gen == id->gen) - return; - } - - // add entry to fontFileIDs list - if (fontFileIDLen >= fontFileIDSize) { - fontFileIDSize += 64; - fontFileIDs = (Ref *)grealloc(fontFileIDs, fontFileIDSize * sizeof(Ref)); - } - fontFileIDs[fontFileIDLen++] = *id; - - // get the font stream and info - refObj.initRef(id->num, id->gen); - refObj.fetch(xref, &strObj); - refObj.free(); - if (!strObj.isStream()) { - error(-1, "Embedded font file object is not a stream"); - goto err1; - } - if (!(dict = strObj.streamGetDict())) { - error(-1, "Embedded font stream is missing its dictionary"); - goto err1; - } - dict->lookup("Length1", &obj1); - dict->lookup("Length2", &obj2); - if (!obj1.isInt() || !obj2.isInt()) { - error(-1, "Missing length fields in embedded font stream dictionary"); - obj1.free(); - obj2.free(); - goto err1; - } - length1 = obj1.getInt(); - length2 = obj2.getInt(); - obj1.free(); - obj2.free(); - - // beginning comment - writePSFmt("%%%%BeginResource: font %s\n", psName); - embFontList->append("%%+ font "); - embFontList->append(psName); - embFontList->append("\n"); - - // copy ASCII portion of font - strObj.streamReset(); - for (i = 0; i < length1 && (c = strObj.streamGetChar()) != EOF; ++i) { - writePSChar(c); - } - - // figure out if encrypted portion is binary or ASCII - binMode = gFalse; - for (i = 0; i < 4; ++i) { - start[i] = strObj.streamGetChar(); - if (start[i] == EOF) { - error(-1, "Unexpected end of file in embedded font stream"); - goto err1; - } - if (!((start[i] >= '0' && start[i] <= '9') || - (start[i] >= 'A' && start[i] <= 'F') || - (start[i] >= 'a' && start[i] <= 'f'))) - binMode = gTrue; - } - - // convert binary data to ASCII - if (binMode) { - for (i = 0; i < 4; ++i) { - writePSChar(hexChar[(start[i] >> 4) & 0x0f]); - writePSChar(hexChar[start[i] & 0x0f]); - } - while (i < length2) { - if ((c = strObj.streamGetChar()) == EOF) { - break; - } - writePSChar(hexChar[(c >> 4) & 0x0f]); - writePSChar(hexChar[c & 0x0f]); - if (++i % 32 == 0) { - writePSChar('\n'); - } - } - if (i % 32 > 0) { - writePSChar('\n'); - } - - // already in ASCII format -- just copy it - } else { - for (i = 0; i < 4; ++i) { - writePSChar(start[i]); - } - for (i = 4; i < length2; ++i) { - if ((c = strObj.streamGetChar()) == EOF) { - break; - } - writePSChar(c); - } - } - - // write padding and "cleartomark" - for (i = 0; i < 8; ++i) { - writePS("00000000000000000000000000000000" - "00000000000000000000000000000000\n"); - } - writePS("cleartomark\n"); - - // ending comment - writePS("%%EndResource\n"); - - err1: - strObj.streamClose(); - strObj.free(); -} - -//~ This doesn't handle .pfb files or binary eexec data (which only -//~ happens in pfb files?). -void PSOutputDev::setupExternalType1Font(GString *fileName, char *psName) { - FILE *fontFile; - int c; - int i; - - // check if font is already embedded - for (i = 0; i < fontFileNameLen; ++i) { - if (!fontFileNames[i]->cmp(fileName)) { - return; - } - } - - // add entry to fontFileNames list - if (fontFileNameLen >= fontFileNameSize) { - fontFileNameSize += 64; - fontFileNames = (GString **)grealloc(fontFileNames, - fontFileNameSize * sizeof(GString *)); - } - fontFileNames[fontFileNameLen++] = fileName->copy(); - - // beginning comment - writePSFmt("%%%%BeginResource: font %s\n", psName); - embFontList->append("%%+ font "); - embFontList->append(psName); - embFontList->append("\n"); - - // copy the font file - if (!(fontFile = fopen(fileName->getCString(), "rb"))) { - error(-1, "Couldn't open external font file"); - return; - } - while ((c = fgetc(fontFile)) != EOF) { - writePSChar(c); - } - fclose(fontFile); - - // ending comment - writePS("%%EndResource\n"); -} - -void PSOutputDev::setupEmbeddedType1CFont(GfxFont *font, Ref *id, - char *psName) { - char *fontBuf; - int fontLen; - Type1CFontFile *t1cFile; - int i; - - // check if font is already embedded - for (i = 0; i < fontFileIDLen; ++i) { - if (fontFileIDs[i].num == id->num && - fontFileIDs[i].gen == id->gen) - return; - } - - // add entry to fontFileIDs list - if (fontFileIDLen >= fontFileIDSize) { - fontFileIDSize += 64; - fontFileIDs = (Ref *)grealloc(fontFileIDs, fontFileIDSize * sizeof(Ref)); - } - fontFileIDs[fontFileIDLen++] = *id; - - // beginning comment - writePSFmt("%%%%BeginResource: font %s\n", psName); - embFontList->append("%%+ font "); - embFontList->append(psName); - embFontList->append("\n"); - - // convert it to a Type 1 font - fontBuf = font->readEmbFontFile(xref, &fontLen); - t1cFile = new Type1CFontFile(fontBuf, fontLen); - t1cFile->convertToType1(outputFunc, outputStream); - delete t1cFile; - gfree(fontBuf); - - // ending comment - writePS("%%EndResource\n"); -} - -void PSOutputDev::setupEmbeddedTrueTypeFont(GfxFont *font, Ref *id, - char *psName) { - char *fontBuf; - int fontLen; - TrueTypeFontFile *ttFile; - CharCodeToUnicode *ctu; - int i; - - // check if font is already embedded - for (i = 0; i < fontFileIDLen; ++i) { - if (fontFileIDs[i].num == id->num && - fontFileIDs[i].gen == id->gen) - return; - } - - // add entry to fontFileIDs list - if (fontFileIDLen >= fontFileIDSize) { - fontFileIDSize += 64; - fontFileIDs = (Ref *)grealloc(fontFileIDs, fontFileIDSize * sizeof(Ref)); - } - fontFileIDs[fontFileIDLen++] = *id; - - // beginning comment - writePSFmt("%%%%BeginResource: font %s\n", psName); - embFontList->append("%%+ font "); - embFontList->append(psName); - embFontList->append("\n"); - - // convert it to a Type 42 font - fontBuf = font->readEmbFontFile(xref, &fontLen); - ttFile = new TrueTypeFontFile(fontBuf, fontLen); - ctu = ((Gfx8BitFont *)font)->getToUnicode(); - ttFile->convertToType42(psName, ((Gfx8BitFont *)font)->getEncoding(), - ctu, ((Gfx8BitFont *)font)->getHasEncoding(), - outputFunc, outputStream); - ctu->decRefCnt(); - delete ttFile; - gfree(fontBuf); - - // ending comment - writePS("%%EndResource\n"); -} - -void PSOutputDev::setupExternalTrueTypeFont(GfxFont *font, char *psName) { - GString *fileName; - char *fontBuf; - int fontLen; - TrueTypeFontFile *ttFile; - CharCodeToUnicode *ctu; - int i; - - // check if font is already embedded - fileName = font->getExtFontFile(); - for (i = 0; i < fontFileNameLen; ++i) { - if (!fontFileNames[i]->cmp(fileName)) { - return; - } - } - - // add entry to fontFileNames list - if (fontFileNameLen >= fontFileNameSize) { - fontFileNameSize += 64; - fontFileNames = (GString **)grealloc(fontFileNames, - fontFileNameSize * sizeof(GString *)); - } - fontFileNames[fontFileNameLen++] = fileName->copy(); - - // beginning comment - writePSFmt("%%%%BeginResource: font %s\n", psName); - embFontList->append("%%+ font "); - embFontList->append(psName); - embFontList->append("\n"); - - // convert it to a Type 42 font - fontBuf = font->readExtFontFile(&fontLen); - ttFile = new TrueTypeFontFile(fontBuf, fontLen); - ctu = ((Gfx8BitFont *)font)->getToUnicode(); - ttFile->convertToType42(psName, ((Gfx8BitFont *)font)->getEncoding(), - ctu, ((Gfx8BitFont *)font)->getHasEncoding(), - outputFunc, outputStream); - ctu->decRefCnt(); - delete ttFile; - gfree(fontBuf); - - // ending comment - writePS("%%EndResource\n"); -} - -void PSOutputDev::setupEmbeddedCIDType0Font(GfxFont *font, Ref *id, - char *psName) { - char *fontBuf; - int fontLen; - Type1CFontFile *t1cFile; - int i; - - // check if font is already embedded - for (i = 0; i < fontFileIDLen; ++i) { - if (fontFileIDs[i].num == id->num && - fontFileIDs[i].gen == id->gen) - return; - } - - // add entry to fontFileIDs list - if (fontFileIDLen >= fontFileIDSize) { - fontFileIDSize += 64; - fontFileIDs = (Ref *)grealloc(fontFileIDs, fontFileIDSize * sizeof(Ref)); - } - fontFileIDs[fontFileIDLen++] = *id; - - // beginning comment - writePSFmt("%%%%BeginResource: font %s\n", psName); - embFontList->append("%%+ font "); - embFontList->append(psName); - embFontList->append("\n"); - - // 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); - } - delete t1cFile; - gfree(fontBuf); - - // ending comment - writePS("%%EndResource\n"); -} - -void PSOutputDev::setupEmbeddedCIDTrueTypeFont(GfxFont *font, Ref *id, - char *psName) { - char *fontBuf; - int fontLen; - TrueTypeFontFile *ttFile; - int i; - - // check if font is already embedded - for (i = 0; i < fontFileIDLen; ++i) { - if (fontFileIDs[i].num == id->num && - fontFileIDs[i].gen == id->gen) - return; - } - - // add entry to fontFileIDs list - if (fontFileIDLen >= fontFileIDSize) { - fontFileIDSize += 64; - fontFileIDs = (Ref *)grealloc(fontFileIDs, fontFileIDSize * sizeof(Ref)); - } - fontFileIDs[fontFileIDLen++] = *id; - - // beginning comment - writePSFmt("%%%%BeginResource: font %s\n", psName); - embFontList->append("%%+ font "); - embFontList->append(psName); - embFontList->append("\n"); - - // convert it to a Type 0 font - fontBuf = font->readEmbFontFile(xref, &fontLen); - ttFile = new TrueTypeFontFile(fontBuf, fontLen); - if (globalParams->getPSLevel() >= psLevel3) { - ttFile->convertToCIDType2(psName, - ((GfxCIDFont *)font)->getCIDToGID(), - ((GfxCIDFont *)font)->getCIDToGIDLen(), - outputFunc, outputStream); - } else { - // otherwise: use a non-CID composite font - ttFile->convertToType0(psName, ((GfxCIDFont *)font)->getCIDToGID(), - ((GfxCIDFont *)font)->getCIDToGIDLen(), - outputFunc, outputStream); - } - delete ttFile; - gfree(fontBuf); - - // ending comment - writePS("%%EndResource\n"); -} - -void PSOutputDev::setupType3Font(GfxFont *font, char *psName, - Dict *parentResDict) { - Dict *resDict; - Dict *charProcs; - Object charProc; - Gfx *gfx; - PDFRectangle box; - double *m; - char buf[256]; - int i; - - // set up resources used by font - if ((resDict = ((Gfx8BitFont *)font)->getResources())) { - setupResources(resDict); - } else { - resDict = parentResDict; - } - - // beginning comment - writePSFmt("%%%%BeginResource: font %s\n", psName); - embFontList->append("%%+ font "); - embFontList->append(psName); - embFontList->append("\n"); - - // font dictionary - writePS("7 dict begin\n"); - writePS("/FontType 3 def\n"); - m = font->getFontMatrix(); - writePSFmt("/FontMatrix [%g %g %g %g %g %g] def\n", - m[0], m[1], m[2], m[3], m[4], m[5]); - m = font->getFontBBox(); - writePSFmt("/FontBBox [%g %g %g %g] def\n", - m[0], m[1], m[2], m[3]); - writePS("/Encoding 256 array def\n"); - writePS(" 0 1 255 { Encoding exch /.notdef put } for\n"); - writePS("/BuildGlyph {\n"); - writePS(" exch /CharProcs get exch\n"); - writePS(" 2 copy known not { pop /.notdef } if\n"); - writePS(" get exec\n"); - writePS("} bind def\n"); - writePS("/BuildChar {\n"); - writePS(" 1 index /Encoding get exch get\n"); - writePS(" 1 index /BuildGlyph get exec\n"); - writePS("} bind def\n"); - if ((charProcs = ((Gfx8BitFont *)font)->getCharProcs())) { - writePSFmt("/CharProcs %d dict def\n", charProcs->getLength()); - writePS("CharProcs begin\n"); - box.x1 = m[0]; - box.y1 = m[1]; - box.x2 = m[2]; - box.y2 = m[3]; - gfx = new Gfx(xref, this, resDict, &box, gFalse, NULL); - inType3Char = gTrue; - t3Cacheable = gFalse; - for (i = 0; i < charProcs->getLength(); ++i) { - writePS("/"); - writePSName(charProcs->getKey(i)); - writePS(" {\n"); - gfx->display(charProcs->getVal(i, &charProc)); - charProc.free(); - if (t3String) { - if (t3Cacheable) { - sprintf(buf, "%g %g %g %g %g %g setcachedevice\n", - t3WX, t3WY, t3LLX, t3LLY, t3URX, t3URY); - } else { - sprintf(buf, "%g %g setcharwidth\n", t3WX, t3WY); - } - (*outputFunc)(outputStream, buf, strlen(buf)); - (*outputFunc)(outputStream, t3String->getCString(), - t3String->getLength()); - delete t3String; - t3String = NULL; - } - (*outputFunc)(outputStream, "Q\n", 2); - writePS("} def\n"); - } - inType3Char = gFalse; - delete gfx; - writePS("end\n"); - } - writePS("currentdict end\n"); - writePSFmt("/%s exch definefont pop\n", psName); - - // ending comment - writePS("%%EndResource\n"); -} - -void PSOutputDev::setupImages(Dict *resDict) { - Object xObjDict, xObj, xObjRef, subtypeObj; - int i; - - if (mode != psModeForm) { - return; - } - - resDict->lookup("XObject", &xObjDict); - if (xObjDict.isDict()) { - for (i = 0; i < xObjDict.dictGetLength(); ++i) { - xObjDict.dictGetValNF(i, &xObjRef); - xObjDict.dictGetVal(i, &xObj); - if (xObj.isStream()) { - xObj.streamGetDict()->lookup("Subtype", &subtypeObj); - if (subtypeObj.isName("Image")) { - if (xObjRef.isRef()) { - setupImage(xObjRef.getRef(), xObj.getStream()); - } else { - error(-1, "Image in resource dict is not an indirect reference"); - } - } - subtypeObj.free(); - } - xObj.free(); - xObjRef.free(); - } - } - xObjDict.free(); -} - -void PSOutputDev::setupImage(Ref id, Stream *str) { - int c; - int size, line, col, i; - - // construct an encoder stream - if (globalParams->getPSASCIIHex()) { - str = new ASCIIHexEncoder(str); - } else { - str = new ASCII85Encoder(str); - } - - // compute image data size - str->reset(); - col = size = 0; - do { - do { - c = str->getChar(); - } while (c == '\n' || c == '\r'); - if (c == '~' || c == EOF) { - break; - } - if (c == 'z') { - ++col; - } else { - ++col; - for (i = 1; i <= 4; ++i) { - do { - c = str->getChar(); - } while (c == '\n' || c == '\r'); - if (c == '~' || c == EOF) { - break; - } - ++col; - } - } - if (col > 225) { - ++size; - col = 0; - } - } while (c != '~' && c != EOF); - ++size; - writePSFmt("%d array dup /ImData_%d_%d exch def\n", size, id.num, id.gen); - - // write the data into the array - str->reset(); - line = col = 0; - writePS("dup 0 <~"); - do { - do { - c = str->getChar(); - } while (c == '\n' || c == '\r'); - if (c == '~' || c == EOF) { - break; - } - if (c == 'z') { - writePSChar(c); - ++col; - } else { - writePSChar(c); - ++col; - for (i = 1; i <= 4; ++i) { - do { - c = str->getChar(); - } while (c == '\n' || c == '\r'); - if (c == '~' || c == EOF) { - break; - } - writePSChar(c); - ++col; - } - } - // each line is: "dup nnnnn <~...data...~> put<eol>" - // so max data length = 255 - 20 = 235 - // chunks are 1 or 4 bytes each, so we have to stop at 232 - // but make it 225 just to be safe - if (col > 225) { - writePS("~> put\n"); - ++line; - writePSFmt("dup %d <~", line); - col = 0; - } - } while (c != '~' && c != EOF); - writePS("~> put\n"); - writePS("pop\n"); - - delete str; -} - -void PSOutputDev::startPage(int pageNum, GfxState *state) { - int x1, y1, x2, y2, width, height, t; - - - switch (mode) { - - case psModePS: - writePSFmt("%%%%Page: %d %d\n", pageNum, seqPage); - writePS("%%BeginPageSetup\n"); - - // rotate, translate, and scale page - x1 = (int)(state->getX1() + 0.5); - y1 = (int)(state->getY1() + 0.5); - x2 = (int)(state->getX2() + 0.5); - y2 = (int)(state->getY2() + 0.5); - width = x2 - x1; - height = y2 - y1; - if (width > height && width > paperWidth) { - landscape = gTrue; - writePSFmt("%%%%PageQt::Orientation: %s\n", - state->getCTM()[0] ? "Landscape" : "Portrait"); - writePS("pdfStartPage\n"); - writePS("90 rotate\n"); - tx = -x1; - ty = -(y1 + paperWidth); - t = width; - width = height; - height = t; - } else { - landscape = gFalse; - writePSFmt("%%%%PageQt::Orientation: %s\n", - state->getCTM()[0] ? "Portrait" : "Landscape"); - writePS("pdfStartPage\n"); - tx = -x1; - ty = -y1; - } - if (width < paperWidth) { - tx += (paperWidth - width) / 2; - } - if (height < paperHeight) { - ty += (paperHeight - height) / 2; - } - if (tx != 0 || ty != 0) { - writePSFmt("%g %g translate\n", tx, ty); - } - if (width > paperWidth || height > paperHeight) { - xScale = (double)paperWidth / (double)width; - yScale = (double)paperHeight / (double)height; - if (yScale < xScale) { - xScale = yScale; - } else { - yScale = xScale; - } - writePSFmt("%0.4f %0.4f scale\n", xScale, xScale); - } else { - xScale = yScale = 1; - } - - writePS("%%EndPageSetup\n"); - ++seqPage; - break; - - case psModeEPS: - writePS("pdfStartPage\n"); - tx = ty = 0; - xScale = yScale = 1; - landscape = gFalse; - break; - - case psModeForm: - writePS("/PaintProc {\n"); - writePS("begin xpdf begin\n"); - writePS("pdfStartPage\n"); - tx = ty = 0; - xScale = yScale = 1; - landscape = gFalse; - break; - } -} - -void PSOutputDev::endPage() { - - if (mode == psModeForm) { - writePS("pdfEndPage\n"); - writePS("end end\n"); - writePS("} def\n"); - writePS("end end\n"); - } else { - writePS("showpage\n"); - writePS("%%PageTrailer\n"); - writePS("pdfEndPage\n"); - } -} - -void PSOutputDev::saveState(GfxState *state) { - writePS("q\n"); -} - -void PSOutputDev::restoreState(GfxState *state) { - writePS("Q\n"); -} - -void PSOutputDev::updateCTM(GfxState *state, double m11, double m12, - double m21, double m22, double m31, double m32) { - writePSFmt("[%g %g %g %g %g %g] cm\n", m11, m12, m21, m22, m31, m32); -} - -void PSOutputDev::updateLineDash(GfxState *state) { - double *dash; - double start; - int length, i; - - state->getLineDash(&dash, &length, &start); - writePS("["); - for (i = 0; i < length; ++i) - writePSFmt("%g%s", dash[i], (i == length-1) ? "" : " "); - writePSFmt("] %g d\n", start); -} - -void PSOutputDev::updateFlatness(GfxState *state) { - writePSFmt("%d i\n", state->getFlatness()); -} - -void PSOutputDev::updateLineJoin(GfxState *state) { - writePSFmt("%d j\n", state->getLineJoin()); -} - -void PSOutputDev::updateLineCap(GfxState *state) { - writePSFmt("%d J\n", state->getLineCap()); -} - -void PSOutputDev::updateMiterLimit(GfxState *state) { - writePSFmt("%g M\n", state->getMiterLimit()); -} - -void PSOutputDev::updateLineWidth(GfxState *state) { - writePSFmt("%g w\n", state->getLineWidth()); -} - -void PSOutputDev::updateFillColor(GfxState *state) { - GfxColor color; - double gray; - GfxRGB rgb; - GfxCMYK cmyk; - GfxSeparationColorSpace *sepCS; - - switch (level) { - case psLevel1: - state->getFillGray(&gray); - writePSFmt("%g g\n", gray); - break; - case psLevel1Sep: - state->getFillCMYK(&cmyk); - writePSFmt("%g %g %g %g k\n", cmyk.c, cmyk.m, cmyk.y, cmyk.k); - addProcessColor(cmyk.c, cmyk.m, cmyk.y, cmyk.k); - break; - case psLevel2: - case psLevel3: - if (state->getFillColorSpace()->getMode() == csDeviceCMYK) { - state->getFillCMYK(&cmyk); - writePSFmt("%g %g %g %g k\n", cmyk.c, cmyk.m, cmyk.y, cmyk.k); - } else { - state->getFillRGB(&rgb); - if (rgb.r == rgb.g && rgb.g == rgb.b) { - writePSFmt("%g g\n", rgb.r); - } else { - writePSFmt("%g %g %g rg\n", rgb.r, rgb.g, rgb.b); - } - } - break; - case psLevel2Sep: - case psLevel3Sep: - if (state->getFillColorSpace()->getMode() == csSeparation) { - sepCS = (GfxSeparationColorSpace *)state->getFillColorSpace(); - color.c[0] = 1; - sepCS->getCMYK(&color, &cmyk); - writePSFmt("%g %g %g %g %g (%s) ck\n", - state->getFillColor()->c[0], - cmyk.c, cmyk.m, cmyk.y, cmyk.k, - sepCS->getName()->getCString()); - addCustomColor(sepCS); - } else { - state->getFillCMYK(&cmyk); - writePSFmt("%g %g %g %g k\n", cmyk.c, cmyk.m, cmyk.y, cmyk.k); - addProcessColor(cmyk.c, cmyk.m, cmyk.y, cmyk.k); - } - break; - } - t3Cacheable = gFalse; -} - -void PSOutputDev::updateStrokeColor(GfxState *state) { - GfxColor color; - double gray; - GfxRGB rgb; - GfxCMYK cmyk; - GfxSeparationColorSpace *sepCS; - - switch (level) { - case psLevel1: - state->getStrokeGray(&gray); - writePSFmt("%g G\n", gray); - break; - case psLevel1Sep: - state->getStrokeCMYK(&cmyk); - writePSFmt("%g %g %g %g K\n", cmyk.c, cmyk.m, cmyk.y, cmyk.k); - addProcessColor(cmyk.c, cmyk.m, cmyk.y, cmyk.k); - break; - case psLevel2: - case psLevel3: - if (state->getStrokeColorSpace()->getMode() == csDeviceCMYK) { - state->getStrokeCMYK(&cmyk); - writePSFmt("%g %g %g %g K\n", cmyk.c, cmyk.m, cmyk.y, cmyk.k); - } else { - state->getStrokeRGB(&rgb); - if (rgb.r == rgb.g && rgb.g == rgb.b) { - writePSFmt("%g G\n", rgb.r); - } else { - writePSFmt("%g %g %g RG\n", rgb.r, rgb.g, rgb.b); - } - } - break; - case psLevel2Sep: - case psLevel3Sep: - if (state->getStrokeColorSpace()->getMode() == csSeparation) { - sepCS = (GfxSeparationColorSpace *)state->getStrokeColorSpace(); - color.c[0] = 1; - sepCS->getCMYK(&color, &cmyk); - writePSFmt("%g %g %g %g %g (%s) CK\n", - state->getStrokeColor()->c[0], - cmyk.c, cmyk.m, cmyk.y, cmyk.k, - sepCS->getName()->getCString()); - addCustomColor(sepCS); - } else { - state->getStrokeCMYK(&cmyk); - writePSFmt("%g %g %g %g K\n", cmyk.c, cmyk.m, cmyk.y, cmyk.k); - addProcessColor(cmyk.c, cmyk.m, cmyk.y, cmyk.k); - } - break; - } - t3Cacheable = gFalse; -} - -void PSOutputDev::addProcessColor(double c, double m, double y, double k) { - if (c > 0) { - processColors |= psProcessCyan; - } - if (m > 0) { - processColors |= psProcessMagenta; - } - if (y > 0) { - processColors |= psProcessYellow; - } - if (k > 0) { - processColors |= psProcessBlack; - } -} - -void PSOutputDev::addCustomColor(GfxSeparationColorSpace *sepCS) { - PSOutCustomColor *cc; - GfxColor color; - GfxCMYK cmyk; - - for (cc = customColors; cc; cc = cc->next) { - if (!cc->name->cmp(sepCS->getName())) { - return; - } - } - color.c[0] = 1; - sepCS->getCMYK(&color, &cmyk); - cc = new PSOutCustomColor(cmyk.c, cmyk.m, cmyk.y, cmyk.k, - sepCS->getName()->copy()); - cc->next = customColors; - customColors = cc; -} - -void PSOutputDev::updateFont(GfxState *state) { - if (state->getFont()) { - writePSFmt("/F%d_%d %g Tf\n", - state->getFont()->getID()->num, state->getFont()->getID()->gen, - state->getFontSize()); - } -} - -void PSOutputDev::updateTextMat(GfxState *state) { - double *mat; - - mat = state->getTextMat(); - writePSFmt("[%g %g %g %g %g %g] Tm\n", - mat[0], mat[1], mat[2], mat[3], mat[4], mat[5]); -} - -void PSOutputDev::updateCharSpace(GfxState *state) { - writePSFmt("%g Tc\n", state->getCharSpace()); -} - -void PSOutputDev::updateRender(GfxState *state) { - int rm; - - rm = state->getRender(); - writePSFmt("%d Tr\n", rm); - rm &= 3; - if (rm != 0 && rm != 3) { - t3Cacheable = gFalse; - } -} - -void PSOutputDev::updateRise(GfxState *state) { - writePSFmt("%g Ts\n", state->getRise()); -} - -void PSOutputDev::updateWordSpace(GfxState *state) { - writePSFmt("%g Tw\n", state->getWordSpace()); -} - -void PSOutputDev::updateHorizScaling(GfxState *state) { - writePSFmt("%g Tz\n", state->getHorizScaling()); -} - -void PSOutputDev::updateTextPos(GfxState *state) { - writePSFmt("%g %g Td\n", state->getLineX(), state->getLineY()); -} - -void PSOutputDev::updateTextShift(GfxState *state, double shift) { - if (state->getFont()->getWMode()) { - writePSFmt("%g TJmV\n", shift); - } else { - writePSFmt("%g TJm\n", shift); - } -} - -void PSOutputDev::stroke(GfxState *state) { - doPath(state->getPath()); - if (t3String) { - // if we're construct a cacheable Type 3 glyph, we need to do - // everything in the fill color - writePS("Sf\n"); - } else { - writePS("S\n"); - } -} - -void PSOutputDev::fill(GfxState *state) { - doPath(state->getPath()); - writePS("f\n"); -} - -void PSOutputDev::eoFill(GfxState *state) { - doPath(state->getPath()); - writePS("f*\n"); -} - -void PSOutputDev::clip(GfxState *state) { - doPath(state->getPath()); - writePS("W\n"); -} - -void PSOutputDev::eoClip(GfxState *state) { - doPath(state->getPath()); - writePS("W*\n"); -} - -void PSOutputDev::doPath(GfxPath *path) { - GfxSubpath *subpath; - double x0, y0, x1, y1, x2, y2, x3, y3, x4, y4; - int n, m, i, j; - - n = path->getNumSubpaths(); - - if (n == 1 && path->getSubpath(0)->getNumPoints() == 5) { - subpath = path->getSubpath(0); - x0 = subpath->getX(0); - y0 = subpath->getY(0); - x4 = subpath->getX(4); - y4 = subpath->getY(4); - if (x4 == x0 && y4 == y0) { - x1 = subpath->getX(1); - y1 = subpath->getY(1); - x2 = subpath->getX(2); - y2 = subpath->getY(2); - x3 = subpath->getX(3); - y3 = subpath->getY(3); - if (x0 == x1 && x2 == x3 && y0 == y3 && y1 == y2) { - writePSFmt("%g %g %g %g re\n", - x0 < x2 ? x0 : x2, y0 < y1 ? y0 : y1, - fabs(x2 - x0), fabs(y1 - y0)); - return; - } else if (x0 == x3 && x1 == x2 && y0 == y1 && y2 == y3) { - writePSFmt("%g %g %g %g re\n", - x0 < x1 ? x0 : x1, y0 < y2 ? y0 : y2, - fabs(x1 - x0), fabs(y2 - y0)); - return; - } - } - } - - for (i = 0; i < n; ++i) { - subpath = path->getSubpath(i); - m = subpath->getNumPoints(); - writePSFmt("%g %g m\n", subpath->getX(0), subpath->getY(0)); - j = 1; - while (j < m) { - if (subpath->getCurve(j)) { - writePSFmt("%g %g %g %g %g %g c\n", subpath->getX(j), subpath->getY(j), - subpath->getX(j+1), subpath->getY(j+1), - subpath->getX(j+2), subpath->getY(j+2)); - j += 3; - } else { - writePSFmt("%g %g l\n", subpath->getX(j), subpath->getY(j)); - ++j; - } - } - if (subpath->isClosed()) { - writePS("h\n"); - } - } -} - -void PSOutputDev::drawString(GfxState *state, GString *s) { - GfxFont *font; - int wMode; - GString *s2; - double dx, dy, dx2, dy2, originX, originY; - char *p; - UnicodeMap *uMap; - CharCode code; - Unicode u[8]; - char buf[8]; - int len, nChars, uLen, n, m, i, j; - - // check for invisible text -- this is used by Acrobat Capture - if ((state->getRender() & 3) == 3) { - return; - } - - // ignore empty strings - if (s->getLength() == 0) { - return; - } - - // get the font - if (!(font = state->getFont())) { - return; - } - wMode = font->getWMode(); - - // check for a subtitute 16-bit font - uMap = NULL; - if (font->isCIDFont()) { - for (i = 0; i < font16EncLen; ++i) { - if (font->getID()->num == font16Enc[i].fontID.num && - font->getID()->gen == font16Enc[i].fontID.gen) { - uMap = globalParams->getUnicodeMap(font16Enc[i].enc); - break; - } - } - } - - // compute width of chars in string, ignoring char spacing and word - // spacing -- the Tj operator will adjust for the metrics of the - // font that's actually used - dx = dy = 0; - nChars = 0; - p = s->getCString(); - len = s->getLength(); - if (font->isCIDFont()) { - s2 = new GString(); - } else { - s2 = s; - } - while (len > 0) { - n = font->getNextChar(p, len, &code, - u, (int)(sizeof(u) / sizeof(Unicode)), &uLen, - &dx2, &dy2, &originX, &originY); - if (font->isCIDFont()) { - if (uMap) { - for (i = 0; i < uLen; ++i) { - m = uMap->mapUnicode(u[i], buf, (int)sizeof(buf)); - for (j = 0; j < m; ++j) { - s2->append(buf[j]); - } - } - //~ this really needs to get the number of chars in the target - //~ encoding - which may be more than the number of Unicode - //~ chars - nChars += uLen; - } else { - s2->append((char)((code >> 8) & 0xff)); - s2->append((char)(code & 0xff)); - ++nChars; - } - } - dx += dx2; - dy += dy2; - p += n; - len -= n; - } - dx *= state->getFontSize() * state->getHorizScaling(); - dy *= state->getFontSize(); - if (uMap) { - uMap->decRefCnt(); - } - - if (s2->getLength() > 0) { - writePSString(s2); - if (font->isCIDFont()) { - if (wMode) { - writePSFmt(" %d %g Tj16V\n", nChars, dy); - } else { - writePSFmt(" %d %g Tj16\n", nChars, dx); - } - } else { - writePSFmt(" %g Tj\n", dx); - } - } - if (font->isCIDFont()) { - delete s2; - } -} - -void PSOutputDev::drawImageMask(GfxState *state, Object *ref, Stream *str, - int width, int height, GBool invert, - GBool inlineImg) { - int len; - - len = height * ((width + 7) / 8); - if (level == psLevel1 || level == psLevel1Sep) { - doImageL1(NULL, invert, inlineImg, str, width, height, len); - } else { - doImageL2(ref, NULL, invert, inlineImg, str, width, height, len); - } -} - -void PSOutputDev::drawImage(GfxState *state, Object *ref, Stream *str, - int width, int height, GfxImageColorMap *colorMap, - int *maskColors, GBool inlineImg) { - int len; - - len = height * ((width * colorMap->getNumPixelComps() * - colorMap->getBits() + 7) / 8); - switch (level) { - case psLevel1: - doImageL1(colorMap, gFalse, inlineImg, str, width, height, len); - break; - case psLevel1Sep: - //~ handle indexed, separation, ... color spaces - doImageL1Sep(colorMap, gFalse, inlineImg, str, width, height, len); - break; - case psLevel2: - case psLevel2Sep: - case psLevel3: - case psLevel3Sep: - doImageL2(ref, colorMap, gFalse, inlineImg, str, width, height, len); - break; - } - t3Cacheable = gFalse; -} - -void PSOutputDev::doImageL1(GfxImageColorMap *colorMap, - GBool invert, GBool inlineImg, - Stream *str, int width, int height, int len) { - ImageStream *imgStr; - Guchar pixBuf[gfxColorMaxComps]; - double gray; - int x, y, i; - - // width, height, matrix, bits per component - if (colorMap) { - writePSFmt("%d %d 8 [%d 0 0 %d 0 %d] pdfIm1\n", - width, height, - width, -height, height); - } else { - writePSFmt("%d %d %s [%d 0 0 %d 0 %d] pdfImM1\n", - width, height, invert ? "true" : "false", - width, -height, height); - } - - // image - if (colorMap) { - - // set up to process the data stream - imgStr = new ImageStream(str, width, colorMap->getNumPixelComps(), - colorMap->getBits()); - imgStr->reset(); - - // process the data stream - i = 0; - for (y = 0; y < height; ++y) { - - // write the line - for (x = 0; x < width; ++x) { - imgStr->getPixel(pixBuf); - colorMap->getGray(pixBuf, &gray); - writePSFmt("%02x", (int)(gray * 255 + 0.5)); - if (++i == 32) { - writePSChar('\n'); - i = 0; - } - } - } - if (i != 0) { - writePSChar('\n'); - } - delete imgStr; - - // imagemask - } else { - str->reset(); - i = 0; - for (y = 0; y < height; ++y) { - for (x = 0; x < width; x += 8) { - writePSFmt("%02x", str->getChar() & 0xff); - if (++i == 32) { - writePSChar('\n'); - i = 0; - } - } - } - if (i != 0) { - writePSChar('\n'); - } - str->close(); - } -} - -void PSOutputDev::doImageL1Sep(GfxImageColorMap *colorMap, - GBool invert, GBool inlineImg, - Stream *str, int width, int height, int len) { - ImageStream *imgStr; - Guchar *lineBuf; - Guchar pixBuf[gfxColorMaxComps]; - GfxCMYK cmyk; - int x, y, i, comp; - - // width, height, matrix, bits per component - writePSFmt("%d %d 8 [%d 0 0 %d 0 %d] pdfIm1Sep\n", - width, height, - width, -height, height); - - // allocate a line buffer - lineBuf = (Guchar *)gmalloc(4 * width); - - // set up to process the data stream - imgStr = new ImageStream(str, width, colorMap->getNumPixelComps(), - colorMap->getBits()); - imgStr->reset(); - - // process the data stream - i = 0; - for (y = 0; y < height; ++y) { - - // read the line - for (x = 0; x < width; ++x) { - imgStr->getPixel(pixBuf); - colorMap->getCMYK(pixBuf, &cmyk); - lineBuf[4*x+0] = (int)(255 * cmyk.c + 0.5); - lineBuf[4*x+1] = (int)(255 * cmyk.m + 0.5); - lineBuf[4*x+2] = (int)(255 * cmyk.y + 0.5); - lineBuf[4*x+3] = (int)(255 * cmyk.k + 0.5); - addProcessColor(cmyk.c, cmyk.m, cmyk.y, cmyk.k); - } - - // write one line of each color component - for (comp = 0; comp < 4; ++comp) { - for (x = 0; x < width; ++x) { - writePSFmt("%02x", lineBuf[4*x + comp]); - if (++i == 32) { - writePSChar('\n'); - i = 0; - } - } - } - } - - if (i != 0) { - writePSChar('\n'); - } - - delete imgStr; - gfree(lineBuf); -} - -void PSOutputDev::doImageL2(Object *ref, GfxImageColorMap *colorMap, - GBool invert, GBool inlineImg, - Stream *str, int width, int height, int len) { - GString *s; - int n, numComps; - GBool useRLE, useASCII, useCompressed; - GfxSeparationColorSpace *sepCS; - GfxColor color; - GfxCMYK cmyk; - int c; - int line, col, i; - - // color space - if (colorMap) { - dumpColorSpaceL2(colorMap->getColorSpace()); - writePS(" setcolorspace\n"); - } - - // set up the image data - if (mode == psModeForm || inType3Char) { - if (inlineImg) { - // create an array - str = new FixedLengthEncoder(str, len); - if (globalParams->getPSASCIIHex()) { - str = new ASCIIHexEncoder(str); - } else { - str = new ASCII85Encoder(str); - } - str->reset(); - line = col = 0; - writePS("[<~"); - do { - do { - c = str->getChar(); - } while (c == '\n' || c == '\r'); - if (c == '~' || c == EOF) { - break; - } - if (c == 'z') { - writePSChar(c); - ++col; - } else { - writePSChar(c); - ++col; - for (i = 1; i <= 4; ++i) { - do { - c = str->getChar(); - } while (c == '\n' || c == '\r'); - if (c == '~' || c == EOF) { - break; - } - writePSChar(c); - ++col; - } - } - // each line is: "dup nnnnn <~...data...~> put<eol>" - // so max data length = 255 - 20 = 235 - // chunks are 1 or 4 bytes each, so we have to stop at 232 - // but make it 225 just to be safe - if (col > 225) { - writePS("~>\n"); - ++line; - writePSFmt("<~", line); - col = 0; - } - } while (c != '~' && c != EOF); - writePS("~>]\n"); - writePS("0\n"); - delete str; - } else { - // set up to use the array already created by setupImages() - writePSFmt("ImData_%d_%d 0\n", ref->getRefNum(), ref->getRefGen()); - } - } - - // image dictionary - writePS("<<\n /ImageType 1\n"); - - // width, height, matrix, bits per component - writePSFmt(" /Width %d\n", width); - writePSFmt(" /Height %d\n", height); - writePSFmt(" /ImageMatrix [%d 0 0 %d 0 %d]\n", width, -height, height); - writePSFmt(" /BitsPerComponent %d\n", - colorMap ? colorMap->getBits() : 1); - - // decode - if (colorMap) { - writePS(" /Decode ["); - if (colorMap->getColorSpace()->getMode() == csSeparation) { - //~ this is a kludge -- see comment in dumpColorSpaceL2 - n = (1 << colorMap->getBits()) - 1; - writePSFmt("%g %g", colorMap->getDecodeLow(0) * n, - colorMap->getDecodeHigh(0) * n); - } else { - numComps = colorMap->getNumPixelComps(); - for (i = 0; i < numComps; ++i) { - if (i > 0) { - writePS(" "); - } - writePSFmt("%g %g", colorMap->getDecodeLow(i), - colorMap->getDecodeHigh(i)); - } - } - writePS("]\n"); - } else { - writePSFmt(" /Decode [%d %d]\n", invert ? 1 : 0, invert ? 0 : 1); - } - - if (mode == psModeForm || inType3Char) { - - // data source - writePS(" /DataSource { 2 copy get exch 1 add exch }\n"); - - // end of image dictionary - writePSFmt(">>\n%s\n", colorMap ? "image" : "imagemask"); - - // get rid of the array and index - writePS("pop pop\n"); - - } else { - - // data source - writePS(" /DataSource currentfile\n"); - s = str->getPSFilter(" "); - if (inlineImg || !s) { - useRLE = gTrue; - useASCII = gTrue; - useCompressed = gFalse; - } else { - useRLE = gFalse; - useASCII = str->isBinary(); - useCompressed = gTrue; - } - if (useASCII) { - writePSFmt(" /ASCII%sDecode filter\n", - globalParams->getPSASCIIHex() ? "Hex" : "85"); - } - if (useRLE) { - writePS(" /RunLengthDecode filter\n"); - } - if (useCompressed) { - writePS(s->getCString()); - } - if (s) { - delete s; - } - - // cut off inline image streams at appropriate length - if (inlineImg) { - str = new FixedLengthEncoder(str, len); - } else if (useCompressed) { - str = str->getBaseStream(); - } - - // add RunLengthEncode and ASCIIHex/85 encode filters - if (useRLE) { - str = new RunLengthEncoder(str); - } - if (useASCII) { - if (globalParams->getPSASCIIHex()) { - str = new ASCIIHexEncoder(str); - } else { - str = new ASCII85Encoder(str); - } - } - - // end of image dictionary - writePS(">>\n"); -#if OPI_SUPPORT - if (opi13Nest) { - if (inlineImg) { - // this can't happen -- OPI dictionaries are in XObjects - error(-1, "Internal: OPI in inline image"); - n = 0; - } else { - // need to read the stream to count characters -- the length - // is data-dependent (because of ASCII and RLE filters) - str->reset(); - n = 0; - while ((c = str->getChar()) != EOF) { - ++n; - } - str->close(); - } - // +6/7 for "pdfIm\n" / "pdfImM\n" - // +8 for newline + trailer - n += colorMap ? 14 : 15; - writePSFmt("%%%%BeginData: %d Hex Bytes\n", n); - } -#endif - if ((level == psLevel2Sep || level == psLevel3Sep) && colorMap && - colorMap->getColorSpace()->getMode() == csSeparation) { - color.c[0] = 1; - sepCS = (GfxSeparationColorSpace *)colorMap->getColorSpace(); - sepCS->getCMYK(&color, &cmyk); - writePSFmt("%g %g %g %g (%s) pdfImSep\n", - cmyk.c, cmyk.m, cmyk.y, cmyk.k, - sepCS->getName()->getCString()); - } else { - writePSFmt("%s\n", colorMap ? "pdfIm" : "pdfImM"); - } - - // copy the stream data - str->reset(); - while ((c = str->getChar()) != EOF) { - writePSChar(c); - } - str->close(); - - // add newline and trailer to the end - writePSChar('\n'); - writePS("%-EOD-\n"); -#if OPI_SUPPORT - if (opi13Nest) { - writePS("%%EndData\n"); - } -#endif - - // delete encoders - if (useRLE || useASCII || inlineImg) { - delete str; - } - } -} - -void PSOutputDev::dumpColorSpaceL2(GfxColorSpace *colorSpace) { - GfxCalGrayColorSpace *calGrayCS; - GfxCalRGBColorSpace *calRGBCS; - GfxLabColorSpace *labCS; - GfxIndexedColorSpace *indexedCS; - GfxSeparationColorSpace *separationCS; - GfxColorSpace *baseCS; - Guchar *lookup, *p; - double x[gfxColorMaxComps], y[gfxColorMaxComps]; - GfxColor color; - GfxCMYK cmyk; - Function *func; - int n, numComps, numAltComps; - int byte; - int i, j, k; - - switch (colorSpace->getMode()) { - - case csDeviceGray: - writePS("/DeviceGray"); - processColors |= psProcessBlack; - break; - - case csCalGray: - calGrayCS = (GfxCalGrayColorSpace *)colorSpace; - writePS("[/CIEBasedA <<\n"); - writePSFmt(" /DecodeA {%g exp} bind\n", calGrayCS->getGamma()); - writePSFmt(" /MatrixA [%g %g %g]\n", - calGrayCS->getWhiteX(), calGrayCS->getWhiteY(), - calGrayCS->getWhiteZ()); - writePSFmt(" /WhitePoint [%g %g %g]\n", - calGrayCS->getWhiteX(), calGrayCS->getWhiteY(), - calGrayCS->getWhiteZ()); - writePSFmt(" /BlackPoint [%g %g %g]\n", - calGrayCS->getBlackX(), calGrayCS->getBlackY(), - calGrayCS->getBlackZ()); - writePS(">>]"); - processColors |= psProcessBlack; - break; - - case csDeviceRGB: - writePS("/DeviceRGB"); - processColors |= psProcessCMYK; - break; - - case csCalRGB: - calRGBCS = (GfxCalRGBColorSpace *)colorSpace; - writePS("[/CIEBasedABC <<\n"); - writePSFmt(" /DecodeABC [{%g exp} bind {%g exp} bind {%g exp} bind]\n", - calRGBCS->getGammaR(), calRGBCS->getGammaG(), - calRGBCS->getGammaB()); - writePSFmt(" /MatrixABC [%g %g %g %g %g %g %g %g %g]\n", - calRGBCS->getMatrix()[0], calRGBCS->getMatrix()[1], - calRGBCS->getMatrix()[2], calRGBCS->getMatrix()[3], - calRGBCS->getMatrix()[4], calRGBCS->getMatrix()[5], - calRGBCS->getMatrix()[6], calRGBCS->getMatrix()[7], - calRGBCS->getMatrix()[8]); - writePSFmt(" /WhitePoint [%g %g %g]\n", - calRGBCS->getWhiteX(), calRGBCS->getWhiteY(), - calRGBCS->getWhiteZ()); - writePSFmt(" /BlackPoint [%g %g %g]\n", - calRGBCS->getBlackX(), calRGBCS->getBlackY(), - calRGBCS->getBlackZ()); - writePS(">>]"); - processColors |= psProcessCMYK; - break; - - case csDeviceCMYK: - writePS("/DeviceCMYK"); - processColors |= psProcessCMYK; - break; - - case csLab: - labCS = (GfxLabColorSpace *)colorSpace; - writePS("[/CIEBasedABC <<\n"); - writePSFmt(" /RangeABC [0 100 %g %g %g %g]\n", - labCS->getAMin(), labCS->getAMax(), - labCS->getBMin(), labCS->getBMax()); - writePS(" /DecodeABC [{16 add 116 div} bind {500 div} bind {200 div} bind]\n"); - writePS(" /MatrixABC [1 1 1 1 0 0 0 0 -1]\n"); - writePS(" /DecodeLMN\n"); - writePS(" [{dup 6 29 div ge {dup dup mul mul}\n"); - writePSFmt(" {4 29 div sub 108 841 div mul } ifelse %g mul} bind\n", - labCS->getWhiteX()); - writePS(" {dup 6 29 div ge {dup dup mul mul}\n"); - writePSFmt(" {4 29 div sub 108 841 div mul } ifelse %g mul} bind\n", - labCS->getWhiteY()); - writePS(" {dup 6 29 div ge {dup dup mul mul}\n"); - writePSFmt(" {4 29 div sub 108 841 div mul } ifelse %g mul} bind]\n", - labCS->getWhiteZ()); - writePSFmt(" /WhitePoint [%g %g %g]\n", - labCS->getWhiteX(), labCS->getWhiteY(), labCS->getWhiteZ()); - writePSFmt(" /BlackPoint [%g %g %g]\n", - labCS->getBlackX(), labCS->getBlackY(), labCS->getBlackZ()); - writePS(">>]"); - processColors |= psProcessCMYK; - break; - - case csICCBased: - dumpColorSpaceL2(((GfxICCBasedColorSpace *)colorSpace)->getAlt()); - break; - - case csIndexed: - indexedCS = (GfxIndexedColorSpace *)colorSpace; - baseCS = indexedCS->getBase(); - writePS("[/Indexed "); - dumpColorSpaceL2(baseCS); - n = indexedCS->getIndexHigh(); - numComps = baseCS->getNComps(); - lookup = indexedCS->getLookup(); - writePSFmt(" %d <\n", n); - if (baseCS->getMode() == csDeviceN) { - func = ((GfxDeviceNColorSpace *)baseCS)->getTintTransformFunc(); - numAltComps = ((GfxDeviceNColorSpace *)baseCS)->getAlt()->getNComps(); - p = lookup; - for (i = 0; i <= n; i += 8) { - writePS(" "); - for (j = i; j < i+8 && j <= n; ++j) { - for (k = 0; k < numComps; ++k) { - x[k] = *p++ / 255.0; - } - func->transform(x, y); - for (k = 0; k < numAltComps; ++k) { - byte = (int)(y[k] * 255 + 0.5); - if (byte < 0) { - byte = 0; - } else if (byte > 255) { - byte = 255; - } - writePSFmt("%02x", byte); - } - color.c[0] = j; - indexedCS->getCMYK(&color, &cmyk); - addProcessColor(cmyk.c, cmyk.m, cmyk.y, cmyk.k); - } - writePS("\n"); - } - } else { - for (i = 0; i <= n; i += 8) { - writePS(" "); - for (j = i; j < i+8 && j <= n; ++j) { - for (k = 0; k < numComps; ++k) { - writePSFmt("%02x", lookup[j * numComps + k]); - } - color.c[0] = j; - indexedCS->getCMYK(&color, &cmyk); - addProcessColor(cmyk.c, cmyk.m, cmyk.y, cmyk.k); - } - writePS("\n"); - } - } - writePS(">]"); - break; - - case csSeparation: - //~ this is a kludge -- the correct thing would to output a - //~ separation color space, with the specified alternate color - //~ space and tint transform - separationCS = (GfxSeparationColorSpace *)colorSpace; - writePS("[/Indexed "); - dumpColorSpaceL2(separationCS->getAlt()); - writePS(" 255 <\n"); - numComps = separationCS->getAlt()->getNComps(); - for (i = 0; i <= 255; i += 8) { - writePS(" "); - for (j = i; j < i+8 && j <= 255; ++j) { - x[0] = (double)j / 255.0; - separationCS->getFunc()->transform(x, y); - for (k = 0; k < numComps; ++k) { - writePSFmt("%02x", (int)(255 * y[k] + 0.5)); - } - } - writePS("\n"); - } - writePS(">]"); - addCustomColor(separationCS); - break; - - case csDeviceN: - // DeviceN color spaces are a Level 3 PostScript feature. - dumpColorSpaceL2(((GfxDeviceNColorSpace *)colorSpace)->getAlt()); - break; - - case csPattern: - //~ unimplemented - break; - - } -} - -#if OPI_SUPPORT -void PSOutputDev::opiBegin(GfxState *state, Dict *opiDict) { - Object dict; - - if (globalParams->getPSOPI()) { - opiDict->lookup("2.0", &dict); - if (dict.isDict()) { - opiBegin20(state, dict.getDict()); - dict.free(); - } else { - dict.free(); - opiDict->lookup("1.3", &dict); - if (dict.isDict()) { - opiBegin13(state, dict.getDict()); - } - dict.free(); - } - } -} - -void PSOutputDev::opiBegin20(GfxState *state, Dict *dict) { - Object obj1, obj2, obj3, obj4; - double width, height, left, right, top, bottom; - int w, h; - int i; - - writePS("%%BeginOPI: 2.0\n"); - writePS("%%Distilled\n"); - - dict->lookup("F", &obj1); - if (getFileSpec(&obj1, &obj2)) { - writePSFmt("%%%%ImageFileName: %s\n", - obj2.getString()->getCString()); - obj2.free(); - } - obj1.free(); - - dict->lookup("MainImage", &obj1); - if (obj1.isString()) { - writePSFmt("%%%%MainImage: %s\n", obj1.getString()->getCString()); - } - obj1.free(); - - //~ ignoring 'Tags' entry - //~ need to use writePSString() and deal with >255-char lines - - dict->lookup("Size", &obj1); - if (obj1.isArray() && obj1.arrayGetLength() == 2) { - obj1.arrayGet(0, &obj2); - width = obj2.getNum(); - obj2.free(); - obj1.arrayGet(1, &obj2); - height = obj2.getNum(); - obj2.free(); - writePSFmt("%%%%ImageDimensions: %g %g\n", width, height); - } - obj1.free(); - - dict->lookup("CropRect", &obj1); - if (obj1.isArray() && obj1.arrayGetLength() == 4) { - obj1.arrayGet(0, &obj2); - left = obj2.getNum(); - obj2.free(); - obj1.arrayGet(1, &obj2); - top = obj2.getNum(); - obj2.free(); - obj1.arrayGet(2, &obj2); - right = obj2.getNum(); - obj2.free(); - obj1.arrayGet(3, &obj2); - bottom = obj2.getNum(); - obj2.free(); - writePSFmt("%%%%ImageCropRect: %g %g %g %g\n", left, top, right, bottom); - } - obj1.free(); - - dict->lookup("Overprint", &obj1); - if (obj1.isBool()) { - writePSFmt("%%%%ImageOverprint: %s\n", obj1.getBool() ? "true" : "false"); - } - obj1.free(); - - dict->lookup("Inks", &obj1); - if (obj1.isName()) { - writePSFmt("%%%%ImageInks: %s\n", obj1.getName()); - } else if (obj1.isArray() && obj1.arrayGetLength() >= 1) { - obj1.arrayGet(0, &obj2); - if (obj2.isName()) { - writePSFmt("%%%%ImageInks: %s %d", - obj2.getName(), (obj1.arrayGetLength() - 1) / 2); - for (i = 1; i+1 < obj1.arrayGetLength(); i += 2) { - obj1.arrayGet(i, &obj3); - obj1.arrayGet(i+1, &obj4); - if (obj3.isString() && obj4.isNum()) { - writePS(" "); - writePSString(obj3.getString()); - writePSFmt(" %g", obj4.getNum()); - } - obj3.free(); - obj4.free(); - } - writePS("\n"); - } - obj2.free(); - } - obj1.free(); - - writePS("gsave\n"); - - writePS("%%BeginIncludedImage\n"); - - dict->lookup("IncludedImageDimensions", &obj1); - if (obj1.isArray() && obj1.arrayGetLength() == 2) { - obj1.arrayGet(0, &obj2); - w = obj2.getInt(); - obj2.free(); - obj1.arrayGet(1, &obj2); - h = obj2.getInt(); - obj2.free(); - writePSFmt("%%%%IncludedImageDimensions: %d %d\n", w, h); - } - obj1.free(); - - dict->lookup("IncludedImageQuality", &obj1); - if (obj1.isNum()) { - writePSFmt("%%%%IncludedImageQuality: %g\n", obj1.getNum()); - } - obj1.free(); - - ++opi20Nest; -} - -void PSOutputDev::opiBegin13(GfxState *state, Dict *dict) { - Object obj1, obj2; - int left, right, top, bottom, samples, bits, width, height; - double c, m, y, k; - double llx, lly, ulx, uly, urx, ury, lrx, lry; - double tllx, tlly, tulx, tuly, turx, tury, tlrx, tlry; - double horiz, vert; - int i, j; - - writePS("save\n"); - writePS("/opiMatrix2 matrix currentmatrix def\n"); - writePS("opiMatrix setmatrix\n"); - - dict->lookup("F", &obj1); - if (getFileSpec(&obj1, &obj2)) { - writePSFmt("%%ALDImageFileName: %s\n", - obj2.getString()->getCString()); - obj2.free(); - } - obj1.free(); - - dict->lookup("CropRect", &obj1); - if (obj1.isArray() && obj1.arrayGetLength() == 4) { - obj1.arrayGet(0, &obj2); - left = obj2.getInt(); - obj2.free(); - obj1.arrayGet(1, &obj2); - top = obj2.getInt(); - obj2.free(); - obj1.arrayGet(2, &obj2); - right = obj2.getInt(); - obj2.free(); - obj1.arrayGet(3, &obj2); - bottom = obj2.getInt(); - obj2.free(); - writePSFmt("%%ALDImageCropRect: %d %d %d %d\n", left, top, right, bottom); - } - obj1.free(); - - dict->lookup("Color", &obj1); - if (obj1.isArray() && obj1.arrayGetLength() == 5) { - obj1.arrayGet(0, &obj2); - c = obj2.getNum(); - obj2.free(); - obj1.arrayGet(1, &obj2); - m = obj2.getNum(); - obj2.free(); - obj1.arrayGet(2, &obj2); - y = obj2.getNum(); - obj2.free(); - obj1.arrayGet(3, &obj2); - k = obj2.getNum(); - obj2.free(); - obj1.arrayGet(4, &obj2); - if (obj2.isString()) { - writePSFmt("%%ALDImageColor: %g %g %g %g ", c, m, y, k); - writePSString(obj2.getString()); - writePS("\n"); - } - obj2.free(); - } - obj1.free(); - - dict->lookup("ColorType", &obj1); - if (obj1.isName()) { - writePSFmt("%%ALDImageColorType: %s\n", obj1.getName()); - } - obj1.free(); - - //~ ignores 'Comments' entry - //~ need to handle multiple lines - - dict->lookup("CropFixed", &obj1); - if (obj1.isArray()) { - obj1.arrayGet(0, &obj2); - ulx = obj2.getNum(); - obj2.free(); - obj1.arrayGet(1, &obj2); - uly = obj2.getNum(); - obj2.free(); - obj1.arrayGet(2, &obj2); - lrx = obj2.getNum(); - obj2.free(); - obj1.arrayGet(3, &obj2); - lry = obj2.getNum(); - obj2.free(); - writePSFmt("%%ALDImageCropFixed: %g %g %g %g\n", ulx, uly, lrx, lry); - } - obj1.free(); - - dict->lookup("GrayMap", &obj1); - if (obj1.isArray()) { - writePS("%ALDImageGrayMap:"); - for (i = 0; i < obj1.arrayGetLength(); i += 16) { - if (i > 0) { - writePS("\n%%+"); - } - for (j = 0; j < 16 && i+j < obj1.arrayGetLength(); ++j) { - obj1.arrayGet(i+j, &obj2); - writePSFmt(" %d", obj2.getInt()); - obj2.free(); - } - } - writePS("\n"); - } - obj1.free(); - - dict->lookup("ID", &obj1); - if (obj1.isString()) { - writePSFmt("%%ALDImageID: %s\n", obj1.getString()->getCString()); - } - obj1.free(); - - dict->lookup("ImageType", &obj1); - if (obj1.isArray() && obj1.arrayGetLength() == 2) { - obj1.arrayGet(0, &obj2); - samples = obj2.getInt(); - obj2.free(); - obj1.arrayGet(1, &obj2); - bits = obj2.getInt(); - obj2.free(); - writePSFmt("%%ALDImageType: %d %d\n", samples, bits); - } - obj1.free(); - - dict->lookup("Overprint", &obj1); - if (obj1.isBool()) { - writePSFmt("%%ALDImageOverprint: %s\n", obj1.getBool() ? "true" : "false"); - } - obj1.free(); - - dict->lookup("Position", &obj1); - if (obj1.isArray() && obj1.arrayGetLength() == 8) { - obj1.arrayGet(0, &obj2); - llx = obj2.getNum(); - obj2.free(); - obj1.arrayGet(1, &obj2); - lly = obj2.getNum(); - obj2.free(); - obj1.arrayGet(2, &obj2); - ulx = obj2.getNum(); - obj2.free(); - obj1.arrayGet(3, &obj2); - uly = obj2.getNum(); - obj2.free(); - obj1.arrayGet(4, &obj2); - urx = obj2.getNum(); - obj2.free(); - obj1.arrayGet(5, &obj2); - ury = obj2.getNum(); - obj2.free(); - obj1.arrayGet(6, &obj2); - lrx = obj2.getNum(); - obj2.free(); - obj1.arrayGet(7, &obj2); - lry = obj2.getNum(); - obj2.free(); - opiTransform(state, llx, lly, &tllx, &tlly); - opiTransform(state, ulx, uly, &tulx, &tuly); - opiTransform(state, urx, ury, &turx, &tury); - opiTransform(state, lrx, lry, &tlrx, &tlry); - writePSFmt("%%ALDImagePosition: %g %g %g %g %g %g %g %g\n", - tllx, tlly, tulx, tuly, turx, tury, tlrx, tlry); - obj2.free(); - } - obj1.free(); - - dict->lookup("Resolution", &obj1); - if (obj1.isArray() && obj1.arrayGetLength() == 2) { - obj1.arrayGet(0, &obj2); - horiz = obj2.getNum(); - obj2.free(); - obj1.arrayGet(1, &obj2); - vert = obj2.getNum(); - obj2.free(); - writePSFmt("%%ALDImageResoution: %g %g\n", horiz, vert); - obj2.free(); - } - obj1.free(); - - dict->lookup("Size", &obj1); - if (obj1.isArray() && obj1.arrayGetLength() == 2) { - obj1.arrayGet(0, &obj2); - width = obj2.getInt(); - obj2.free(); - obj1.arrayGet(1, &obj2); - height = obj2.getInt(); - obj2.free(); - writePSFmt("%%ALDImageDimensions: %d %d\n", width, height); - } - obj1.free(); - - //~ ignoring 'Tags' entry - //~ need to use writePSString() and deal with >255-char lines - - dict->lookup("Tint", &obj1); - if (obj1.isNum()) { - writePSFmt("%%ALDImageTint: %g\n", obj1.getNum()); - } - obj1.free(); - - dict->lookup("Transparency", &obj1); - if (obj1.isBool()) { - writePSFmt("%%ALDImageTransparency: %s\n", obj1.getBool() ? "true" : "false"); - } - obj1.free(); - - writePS("%%BeginObject: image\n"); - writePS("opiMatrix2 setmatrix\n"); - ++opi13Nest; -} - -// Convert PDF user space coordinates to PostScript default user space -// coordinates. This has to account for both the PDF CTM and the -// PSOutputDev page-fitting transform. -void PSOutputDev::opiTransform(GfxState *state, double x0, double y0, - double *x1, double *y1) { - double t; - - state->transform(x0, y0, x1, y1); - *x1 += tx; - *y1 += ty; - if (landscape) { - t = *x1; - *x1 = -*y1; - *y1 = t; - } - *x1 *= xScale; - *y1 *= yScale; -} - -void PSOutputDev::opiEnd(GfxState *state, Dict *opiDict) { - Object dict; - - if (globalParams->getPSOPI()) { - opiDict->lookup("2.0", &dict); - if (dict.isDict()) { - writePS("%%EndIncludedImage\n"); - writePS("%%EndOPI\n"); - writePS("grestore\n"); - --opi20Nest; - dict.free(); - } else { - dict.free(); - opiDict->lookup("1.3", &dict); - if (dict.isDict()) { - writePS("%%EndObject\n"); - writePS("restore\n"); - --opi13Nest; - } - dict.free(); - } - } -} - -GBool PSOutputDev::getFileSpec(Object *fileSpec, Object *fileName) { - if (fileSpec->isString()) { - fileSpec->copy(fileName); - return gTrue; - } - if (fileSpec->isDict()) { - fileSpec->dictLookup("DOS", fileName); - if (fileName->isString()) { - return gTrue; - } - fileName->free(); - fileSpec->dictLookup("Mac", fileName); - if (fileName->isString()) { - return gTrue; - } - fileName->free(); - fileSpec->dictLookup("Unix", fileName); - if (fileName->isString()) { - return gTrue; - } - fileName->free(); - fileSpec->dictLookup("F", fileName); - if (fileName->isString()) { - return gTrue; - } - fileName->free(); - } - return gFalse; -} -#endif // OPI_SUPPORT - -void PSOutputDev::type3D0(GfxState *state, double wx, double wy) { - writePSFmt("%g %g setcharwidth\n", wx, wy); - writePS("q\n"); -} - -void PSOutputDev::type3D1(GfxState *state, double wx, double wy, - double llx, double lly, double urx, double ury) { - t3WX = wx; - t3WY = wy; - t3LLX = llx; - t3LLY = lly; - t3URX = urx; - t3URY = ury; - t3String = new GString(); - writePS("q\n"); - t3Cacheable = gTrue; -} - -void PSOutputDev::psXObject(Stream *psStream, Stream *level1Stream) { - Stream *str; - int c; - - if ((level == psLevel1 || level == psLevel1Sep) && level1Stream) { - str = level1Stream; - } else { - str = psStream; - } - str->reset(); - while ((c = str->getChar()) != EOF) { - writePSChar(c); - } - str->close(); -} - -void PSOutputDev::writePSChar(char c) { - if (t3String) { - t3String->append(c); - } else { - (*outputFunc)(outputStream, &c, 1); - } -} - -void PSOutputDev::writePS(char *s) { - if (t3String) { - t3String->append(s); - } else { - (*outputFunc)(outputStream, s, strlen(s)); - } -} - -void PSOutputDev::writePSFmt(const char *fmt, ...) { - va_list args; - char buf[512]; - - va_start(args, fmt); - vsprintf(buf, fmt, args); - va_end(args); - if (t3String) { - t3String->append(buf); - } else { - (*outputFunc)(outputStream, buf, strlen(buf)); - } -} - -void PSOutputDev::writePSString(GString *s) { - Guchar *p; - int n; - char buf[8]; - - writePSChar('('); - for (p = (Guchar *)s->getCString(), n = s->getLength(); n; ++p, --n) { - if (*p == '(' || *p == ')' || *p == '\\') { - writePSChar('\\'); - writePSChar((char)*p); - } else if (*p < 0x20 || *p >= 0x80) { - sprintf(buf, "\\%03o", *p); - if (t3String) { - t3String->append(buf); - } else { - (*outputFunc)(outputStream, buf, strlen(buf)); - } - } else { - writePSChar((char)*p); - } - } - writePSChar(')'); -} - -void PSOutputDev::writePSName(char *s) { - char *p; - char c; - - p = s; - while ((c = *p++)) { - if (c <= (char)0x20 || c >= (char)0x7f || - c == '(' || c == ')' || c == '<' || c == '>' || - c == '[' || c == ']' || c == '{' || c == '}' || - c == '/' || c == '%') { - writePSFmt("#%02x", c & 0xff); - } else { - writePSChar(c); - } - } -} - -GString *PSOutputDev::filterPSName(GString *name) { - GString *name2; - char buf[8]; - int i; - char c; - - name2 = new GString(); - for (i = 0; i < name->getLength(); ++i) { - c = name->getChar(i); - if (c <= (char)0x20 || c >= (char)0x7f || - c == '(' || c == ')' || c == '<' || c == '>' || - c == '[' || c == ']' || c == '{' || c == '}' || - c == '/' || c == '%') { - sprintf(buf, "#%02x", c & 0xff); - name2->append(buf); - } else { - name2->append(c); - } - } - return name2; -} |