📄 psoutputdev.cc
字号:
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; } } }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -