⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 psoutputdev.cc

📁 这是一个做pdf阅读器的源代码文件,是大家学习阅读器资料的很好参考
💻 CC
📖 第 1 页 / 共 5 页
字号:
    }  }}void PSOutputDev::setupResources(Dict *resDict) {  Object xObjDict, xObjRef, xObj, patDict, patRef, pat, resObj;  Ref ref0, ref1;  GBool skip;  int i, j;  setupFonts(resDict);  setupImages(resDict);  setupForms(resDict);  //----- recursively scan XObjects  resDict->lookup("XObject", &xObjDict);  if (xObjDict.isDict()) {    for (i = 0; i < xObjDict.dictGetLength(); ++i) {      // avoid infinite recursion on XObjects      skip = gFalse;      if ((xObjDict.dictGetValNF(i, &xObjRef)->isRef())) {	ref0 = xObjRef.getRef();	for (j = 0; j < xobjStack->getLength(); ++j) {	  ref1 = *(Ref *)xobjStack->get(j);	  if (ref1.num == ref0.num && ref1.gen == ref0.gen) {	    skip = gTrue;	    break;	  }	}	if (!skip) {	  xobjStack->append(&ref0);	}      }      if (!skip) {	// process the XObject's resource dictionary	xObjDict.dictGetVal(i, &xObj);	if (xObj.isStream()) {	  xObj.streamGetDict()->lookup("Resources", &resObj);	  if (resObj.isDict()) {	    setupResources(resObj.getDict());	  }	  resObj.free();	}	xObj.free();      }      if (xObjRef.isRef() && !skip) {	xobjStack->del(xobjStack->getLength() - 1);      }      xObjRef.free();    }  }  xObjDict.free();  //----- recursively scan Patterns  resDict->lookup("Pattern", &patDict);  if (patDict.isDict()) {    inType3Char = gTrue;    for (i = 0; i < patDict.dictGetLength(); ++i) {      // avoid infinite recursion on Patterns      skip = gFalse;      if ((patDict.dictGetValNF(i, &patRef)->isRef())) {	ref0 = patRef.getRef();	for (j = 0; j < xobjStack->getLength(); ++j) {	  ref1 = *(Ref *)xobjStack->get(j);	  if (ref1.num == ref0.num && ref1.gen == ref0.gen) {	    skip = gTrue;	    break;	  }	}	if (!skip) {	  xobjStack->append(&ref0);	}      }      if (!skip) {	// process the Pattern's resource dictionary	patDict.dictGetVal(i, &pat);	if (pat.isStream()) {	  pat.streamGetDict()->lookup("Resources", &resObj);	  if (resObj.isDict()) {	    setupResources(resObj.getDict());	  }	  resObj.free();	}	pat.free();      }      if (patRef.isRef() && !skip) {	xobjStack->del(xobjStack->getLength() - 1);      }      patRef.free();    }    inType3Char = gFalse;  }  patDict.free();}void PSOutputDev::setupFonts(Dict *resDict) {  Object obj1, obj2;  Ref r;  GfxFontDict *gfxFontDict;  GfxFont *font;  int i;  gfxFontDict = NULL;  resDict->lookupNF("Font", &obj1);  if (obj1.isRef()) {    obj1.fetch(xref, &obj2);    if (obj2.isDict()) {      r = obj1.getRef();      gfxFontDict = new GfxFontDict(xref, &r, obj2.getDict());    }    obj2.free();  } else if (obj1.isDict()) {    gfxFontDict = new GfxFontDict(xref, NULL, obj1.getDict());  }  if (gfxFontDict) {    for (i = 0; i < gfxFontDict->getNumFonts(); ++i) {      if ((font = gfxFontDict->getFont(i))) {	setupFont(font, resDict);      }    }    delete gfxFontDict;  }  obj1.free();}void PSOutputDev::setupFont(GfxFont *font, Dict *parentResDict) {  Ref fontFileID;  GString *name;  PSFontParam *fontParam;  GString *psName;  char buf[16];  GBool subst;  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 *)greallocn(fontIDs, fontIDSize, sizeof(Ref));  }  fontIDs[fontIDLen++] = *font->getID();  xs = ys = 1;  subst = gFalse;  // check for resident 8-bit font  if (font->getName() &&      (fontParam = globalParams->getPSFont(font->getName()))) {    psName = new GString(fontParam->psFontName->getCString());  // check for embedded Type 1 font  } else if (globalParams->getPSEmbedType1() &&	     font->getType() == fontType1 &&	     font->getEmbeddedFontID(&fontFileID)) {    psName = filterPSName(font->getEmbeddedFontName());    setupEmbeddedType1Font(&fontFileID, psName);  // check for embedded Type 1C font  } else if (globalParams->getPSEmbedType1() &&	     font->getType() == fontType1C &&	     font->getEmbeddedFontID(&fontFileID)) {    // use the PDF font name because the embedded font name might    // not include the subset prefix    psName = filterPSName(font->getOrigName());    setupEmbeddedType1CFont(font, &fontFileID, psName);  // check for embedded OpenType - Type 1C font  } else if (globalParams->getPSEmbedType1() &&	     font->getType() == fontType1COT &&	     font->getEmbeddedFontID(&fontFileID)) {    // use the PDF font name because the embedded font name might    // not include the subset prefix    psName = filterPSName(font->getOrigName());    setupEmbeddedOpenTypeT1CFont(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()->copy();    setupExternalType1Font(font->getExtFontFile(), psName);  // check for embedded TrueType font  } else if (globalParams->getPSEmbedTrueType() &&	     (font->getType() == fontTrueType ||	      font->getType() == fontTrueTypeOT) &&	     font->getEmbeddedFontID(&fontFileID)) {    psName = filterPSName(font->getEmbeddedFontName());    setupEmbeddedTrueTypeFont(font, &fontFileID, psName);  // check for external TrueType font file  } else if (globalParams->getPSEmbedTrueType() &&	     font->getType() == fontTrueType &&	     font->getExtFontFile()) {    psName = filterPSName(font->getName());    setupExternalTrueTypeFont(font, psName);  // check for embedded CID PostScript font  } else if (globalParams->getPSEmbedCIDPostScript() &&	     font->getType() == fontCIDType0C &&	     font->getEmbeddedFontID(&fontFileID)) {    psName = filterPSName(font->getEmbeddedFontName());    setupEmbeddedCIDType0Font(font, &fontFileID, psName);  // check for embedded CID TrueType font  } else if (globalParams->getPSEmbedCIDTrueType() &&	     (font->getType() == fontCIDType2 ||	      font->getType() == fontCIDType2OT) &&	     font->getEmbeddedFontID(&fontFileID)) {    psName = filterPSName(font->getEmbeddedFontName());    //~ should check to see if font actually uses vertical mode    setupEmbeddedCIDTrueTypeFont(font, &fontFileID, psName, gTrue);  // check for embedded OpenType - CID CFF font  } else if (globalParams->getPSEmbedCIDPostScript() &&	     font->getType() == fontCIDType0COT &&	     font->getEmbeddedFontID(&fontFileID)) {    psName = filterPSName(font->getEmbeddedFontName());    setupEmbeddedOpenTypeCFFFont(font, &fontFileID, psName);  // check for Type 3 font  } else if (font->getType() == fontType3) {    psName = GString::format("T3_{0:d}_{1:d}",			     font->getID()->num, font->getID()->gen);    setupType3Font(font, psName, parentResDict);  // do 8-bit font substitution  } else if (!font->isCIDFont()) {    subst = gTrue;    name = font->getName();    psName = NULL;    if (name) {      for (i = 0; psFonts[i]; ++i) {	if (name->cmp(psFonts[i]) == 0) {	  psName = new GString(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 = new GString(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()))) {    subst = gTrue;    psName = fontParam->psFontName->copy();    if (font16EncLen >= font16EncSize) {      font16EncSize += 16;      font16Enc = (PSFont16Enc *)greallocn(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{0:d}_{1:d} /{2:t} {3:d} pdfMakeFont16L3\n",		 font->getID()->num, font->getID()->gen, psName,		 font->getWMode());    } else {      writePSFmt("/F{0:d}_{1:d} /{2:t} {3:d} pdfMakeFont16\n",		 font->getID()->num, font->getID()->gen, psName,		 font->getWMode());    }  } else {    writePSFmt("/F{0:d}_{1:d} /{2:t} {3:.4g} {4:.4g}\n",	       font->getID()->num, font->getID()->gen, psName, xs, ys);    for (i = 0; i < 256; i += 8) {      writePS((char *)((i == 0) ? "[ " : "  "));      for (j = 0; j < 8; ++j) {	if (font->getType() == fontTrueType &&	    !subst &&	    !((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");	// the empty name is legal in PDF and PostScript, but PostScript	// uses a double-slash (//...) for "immediately evaluated names",	// so we need to add a space character here	if (charName && !charName[0]) {	  writePS(" ");	}      }      writePS((i == 256-8) ? (char *)"]\n" : (char *)"\n");    }    writePS("pdfMakeFont\n");  }  delete psName;}void PSOutputDev::setupEmbeddedType1Font(Ref *id, GString *psName) {  static char hexChar[17] = "0123456789abcdef";  Object refObj, strObj, obj1, obj2, obj3;  Dict *dict;  int length1, length2, length3;  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 *)greallocn(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);  dict->lookup("Length3", &obj3);  if (!obj1.isInt() || !obj2.isInt() || !obj3.isInt()) {    error(-1, "Missing length fields in embedded font stream dictionary");    obj1.free();    obj2.free();    obj3.free();    goto err1;  }  length1 = obj1.getInt();  length2 = obj2.getInt();  length3 = obj3.getInt();  obj1.free();  obj2.free();  obj3.free();  // beginning comment  writePSFmt("%%BeginResource: font {0:t}\n", psName);  embFontList->append("%%+ font ");  embFontList->append(psName->getCString());  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]);    }#if 0 // this causes trouble for various PostScript printers    // if Length2 is incorrect (too small), font data gets chopped, so    // we take a few extra characters from the trailer just in case    length2 += length3 >= 8 ? 8 : length3;#endif    while (i < length2) {      if ((c = strObj.streamGetChar()) == EOF) {

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -