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