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

📄 splashoutputdev.cc

📁 将pdf文档转换为高质量的html文档
💻 CC
📖 第 1 页 / 共 5 页
字号:
      }      strObj.streamClose();      strObj.free();      fclose(tmpFile);      fileName = tmpFileName;    // if there is an external font file, use it    } else if (!(fileName = gfxFont->getExtFontFile())) {      // look for a display font mapping or a substitute font      if (gfxFont->isCIDFont()) {	if (((GfxCIDFont *)gfxFont)->getCollection()) {	  dfp = globalParams->	          getDisplayCIDFont(gfxFont->getName(),				    ((GfxCIDFont *)gfxFont)->getCollection());	}      } else {	if (gfxFont->getName()) {	  dfp = globalParams->getDisplayFont(gfxFont->getName());	}	if (!dfp) {	  // 8-bit font substitution	  if (gfxFont->isFixedWidth()) {	    substIdx = 8;	  } else if (gfxFont->isSerif()) {	    substIdx = 4;	  } else {	    substIdx = 0;	  }	  if (gfxFont->isBold()) {	    substIdx += 2;	  }	  if (gfxFont->isItalic()) {	    substIdx += 1;	  }	  substName = new GString(splashOutSubstFonts[substIdx].name);	  dfp = globalParams->getDisplayFont(substName);	  delete substName;	  id->setSubstIdx(substIdx);	}      }      if (!dfp) {	error(-1, "Couldn't find a font for '%s'",	      gfxFont->getName() ? gfxFont->getName()->getCString()	                         : "(unnamed)");	goto err2;      }      switch (dfp->kind) {      case displayFontT1:	fileName = dfp->t1.fileName;	fontType = gfxFont->isCIDFont() ? fontCIDType0 : fontType1;	break;      case displayFontTT:	fileName = dfp->tt.fileName;	fontType = gfxFont->isCIDFont() ? fontCIDType2 : fontTrueType;	break;      }    }    // load the font file    switch (fontType) {    case fontType1:      if (!(fontFile = fontEngine->loadType1Font(			   id,			   fileName->getCString(),			   fileName == tmpFileName,			   ((Gfx8BitFont *)gfxFont)->getEncoding()))) {	error(-1, "Couldn't create a font for '%s'",	      gfxFont->getName() ? gfxFont->getName()->getCString()	                         : "(unnamed)");	goto err2;      }      break;    case fontType1C:      if (!(fontFile = fontEngine->loadType1CFont(			   id,			   fileName->getCString(),			   fileName == tmpFileName,			   ((Gfx8BitFont *)gfxFont)->getEncoding()))) {	error(-1, "Couldn't create a font for '%s'",	      gfxFont->getName() ? gfxFont->getName()->getCString()	                         : "(unnamed)");	goto err2;      }      break;    case fontTrueType:      if ((ff = FoFiTrueType::load(fileName->getCString()))) {	codeToGID = ((Gfx8BitFont *)gfxFont)->getCodeToGIDMap(ff);	n = 256;	delete ff;      } else {	codeToGID = NULL;	n = 0;      }      if (!(fontFile = fontEngine->loadTrueTypeFont(			   id,			   fileName->getCString(),			   fileName == tmpFileName,			   codeToGID, n))) {	error(-1, "Couldn't create a font for '%s'",	      gfxFont->getName() ? gfxFont->getName()->getCString()	                         : "(unnamed)");	goto err2;      }      break;    case fontCIDType0:    case fontCIDType0C:      if (!(fontFile = fontEngine->loadCIDFont(			   id,			   fileName->getCString(),			   fileName == tmpFileName))) {	error(-1, "Couldn't create a font for '%s'",	      gfxFont->getName() ? gfxFont->getName()->getCString()	                         : "(unnamed)");	goto err2;      }      break;    case fontCIDType2:      codeToGID = NULL;      n = 0;      if (dfp) {	// create a CID-to-GID mapping, via Unicode	if ((ctu = ((GfxCIDFont *)gfxFont)->getToUnicode())) {	  if ((ff = FoFiTrueType::load(fileName->getCString()))) {	    // look for a Unicode cmap	    for (cmap = 0; cmap < ff->getNumCmaps(); ++cmap) {	      if ((ff->getCmapPlatform(cmap) == 3 &&		   ff->getCmapEncoding(cmap) == 1) ||		  ff->getCmapPlatform(cmap) == 0) {		break;	      }	    }	    if (cmap < ff->getNumCmaps()) {	      // map CID -> Unicode -> GID	      n = ctu->getLength();	      codeToGID = (Gushort *)gmallocn(n, sizeof(Gushort));	      for (code = 0; code < n; ++code) {		if (ctu->mapToUnicode(code, uBuf, 8) > 0) {		  codeToGID[code] = ff->mapCodeToGID(cmap, uBuf[0]);		} else {		  codeToGID[code] = 0;		}	      }	    }	    delete ff;	  }	  ctu->decRefCnt();	} else {	  error(-1, "Couldn't find a mapping to Unicode for font '%s'",		gfxFont->getName() ? gfxFont->getName()->getCString()		                   : "(unnamed)");	}      } else {	if (((GfxCIDFont *)gfxFont)->getCIDToGID()) {	  n = ((GfxCIDFont *)gfxFont)->getCIDToGIDLen();	  codeToGID = (Gushort *)gmallocn(n, sizeof(Gushort));	  memcpy(codeToGID, ((GfxCIDFont *)gfxFont)->getCIDToGID(),		 n * sizeof(Gushort));	}      }      if (!(fontFile = fontEngine->loadTrueTypeFont(			   id,			   fileName->getCString(),			   fileName == tmpFileName,			   codeToGID, n))) {	error(-1, "Couldn't create a font for '%s'",	      gfxFont->getName() ? gfxFont->getName()->getCString()	                         : "(unnamed)");	goto err2;      }      break;    default:      // this shouldn't happen      goto err2;    }  }  // get the font matrix  state->getFontTransMat(&m11, &m12, &m21, &m22);  m11 *= state->getHorizScaling();  m12 *= state->getHorizScaling();  // for substituted fonts: adjust the font matrix -- compare the  // width of 'm' in the original font and the substituted font  substIdx = ((SplashOutFontFileID *)fontFile->getID())->getSubstIdx();  if (substIdx >= 0) {    for (code = 0; code < 256; ++code) {      if ((name = ((Gfx8BitFont *)gfxFont)->getCharName(code)) &&	  name[0] == 'm' && name[1] == '\0') {	break;      }    }    if (code < 256) {      w1 = ((Gfx8BitFont *)gfxFont)->getWidth(code);      w2 = splashOutSubstFonts[substIdx].mWidth;      if (!gfxFont->isSymbolic()) {	// if real font is substantially narrower than substituted	// font, reduce the font size accordingly	if (w1 > 0.01 && w1 < 0.9 * w2) {	  w1 /= w2;	  m11 *= w1;	  m21 *= w1;	}      }    }  }  // create the scaled font  mat[0] = m11;  mat[1] = -m12;  mat[2] = m21;  mat[3] = -m22;  if (fabs(mat[0] * mat[3] - mat[1] * mat[2]) < 0.01) {    // avoid a singular (or close-to-singular) matrix    mat[0] = 0.01;  mat[1] = 0;    mat[2] = 0;     mat[3] = 0.01;  }  font = fontEngine->getFont(fontFile, mat);  if (tmpFileName) {    delete tmpFileName;  }  return; err2:  delete id; err1:  if (tmpFileName) {    delete tmpFileName;  }  return;}void SplashOutputDev::stroke(GfxState *state) {  SplashPath *path;  path = convertPath(state, state->getPath());  splash->stroke(path);  delete path;}void SplashOutputDev::fill(GfxState *state) {  SplashPath *path;  path = convertPath(state, state->getPath());  splash->fill(path, gFalse);  delete path;}void SplashOutputDev::eoFill(GfxState *state) {  SplashPath *path;  path = convertPath(state, state->getPath());  splash->fill(path, gTrue);  delete path;}void SplashOutputDev::clip(GfxState *state) {  SplashPath *path;  path = convertPath(state, state->getPath());  splash->clipToPath(path, gFalse);  delete path;}void SplashOutputDev::eoClip(GfxState *state) {  SplashPath *path;  path = convertPath(state, state->getPath());  splash->clipToPath(path, gTrue);  delete path;}SplashPath *SplashOutputDev::convertPath(GfxState *state, GfxPath *path) {  SplashPath *sPath;  GfxSubpath *subpath;  double x1, y1, x2, y2, x3, y3;  int i, j;  sPath = new SplashPath();  for (i = 0; i < path->getNumSubpaths(); ++i) {    subpath = path->getSubpath(i);    if (subpath->getNumPoints() > 0) {      state->transform(subpath->getX(0), subpath->getY(0), &x1, &y1);      sPath->moveTo((SplashCoord)x1, (SplashCoord)y1);      j = 1;      while (j < subpath->getNumPoints()) {	if (subpath->getCurve(j)) {	  state->transform(subpath->getX(j), subpath->getY(j), &x1, &y1);	  state->transform(subpath->getX(j+1), subpath->getY(j+1), &x2, &y2);	  state->transform(subpath->getX(j+2), subpath->getY(j+2), &x3, &y3);	  sPath->curveTo((SplashCoord)x1, (SplashCoord)y1,			 (SplashCoord)x2, (SplashCoord)y2,			 (SplashCoord)x3, (SplashCoord)y3);	  j += 3;	} else {	  state->transform(subpath->getX(j), subpath->getY(j), &x1, &y1);	  sPath->lineTo((SplashCoord)x1, (SplashCoord)y1);	  ++j;	}      }      if (subpath->isClosed()) {	sPath->close();      }    }  }  return sPath;}void SplashOutputDev::drawChar(GfxState *state, double x, double y,			       double dx, double dy,			       double originX, double originY,			       CharCode code, int nBytes,			       Unicode *u, int uLen) {  double x1, y1;  SplashPath *path;  int render;  if (needFontUpdate) {    updateFont(state);  }  if (!font) {    return;  }  // check for invisible text -- this is used by Acrobat Capture  render = state->getRender();  if (render == 3) {    return;  }  x -= originX;  y -= originY;  state->transform(x, y, &x1, &y1);  // fill  if (!(render & 1)) {    splash->fillChar((SplashCoord)x1, (SplashCoord)y1, code, font);  }  // stroke  if ((render & 3) == 1 || (render & 3) == 2) {    if ((path = font->getGlyphPath(code))) {      path->offset((SplashCoord)x1, (SplashCoord)y1);      splash->stroke(path);      delete path;    }  }  // clip  if (render & 4) {    path = font->getGlyphPath(code);    path->offset((SplashCoord)x1, (SplashCoord)y1);    if (textClipPath) {      textClipPath->append(path);      delete path;    } else {      textClipPath = path;    }  }}GBool SplashOutputDev::beginType3Char(GfxState *state, double x, double y,				      double dx, double dy,				      CharCode code, Unicode *u, int uLen) {  GfxFont *gfxFont;  Ref *fontID;  double *ctm, *bbox;  T3FontCache *t3Font;  T3GlyphStack *t3gs;  double x1, y1, xMin, yMin, xMax, yMax, xt, yt;  int i, j;  if (!(gfxFont = state->getFont())) {    return gFalse;  }  fontID = gfxFont->getID();  ctm = state->getCTM();  state->transform(0, 0, &xt, &yt);  // is it the first (MRU) font in the cache?  if (!(nT3Fonts > 0 &&	t3FontCache[0]->matches(fontID, ctm[0], ctm[1], ctm[2], ctm[3]))) {    // is the font elsewhere in the cache?    for (i = 1; i < nT3Fonts; ++i) {      if (t3FontCache[i]->matches(fontID, ctm[0], ctm[1], ctm[2], ctm[3])) {	t3Font = t3FontCache[i];	for (j = i; j > 0; --j) {	  t3FontCache[j] = t3FontCache[j - 1];	}	t3FontCache[0] = t3Font;	break;      }    }    if (i >= nT3Fonts) {      // create new entry in the font cache      if (nT3Fonts == splashOutT3FontCacheSize) {	delete t3FontCache[nT3Fonts - 1];	--nT3Fonts;      }      for (j = nT3Fonts; j > 0; --j) {	t3FontCache[j] = t3FontCache[j - 1];      }      ++nT3Fonts;      bbox = gfxFont->getFontBBox();      if (bbox[0] == 0 && bbox[1] == 0 && bbox[2] == 0 && bbox[3] == 0) {	// broken bounding box -- just take a guess	xMin = xt - 5;	xMax = xMin + 30;	yMax = yt + 15;	yMin = yMax - 45;      } else {	state->transform(bbox[0], bbox[1], &x1, &y1);	xMin = xMax = x1;	yMin = yMax = y1;	state->transform(bbox[0], bbox[3], &x1, &y1);	if (x1 < xMin) {	  xMin = x1;	} else if (x1 > xMax) {	  xMax = x1;	}	if (y1 < yMin) {	  yMin = y1;	} else if (y1 > yMax) {	  yMax = y1;	}	state->transform(bbox[2], bbox[1], &x1, &y1);	if (x1 < xMin) {	  xMin = x1;	} else if (x1 > xMax) {	  xMax = x1;	}	if (y1 < yMin) {	  yMin = y1;	} else if (y1 > yMax) {	  yMax = y1;	}	state->transform(bbox[2], bbox[3], &x1, &y1);	if (x1 < xMin) {	  xMin = x1;	} else if (x1 > xMax) {	  xMax = x1;	}	if (y1 < yMin) {	  yMin = y1;	} else if (y1 > yMax) {	  yMax = y1;	}      }      t3FontCache[0] = new T3FontCache(fontID, ctm[0], ctm[1], ctm[2], ctm[3],	                               (int)floor(xMin - xt),				       (int)floor(yMin - yt),				       (int)ceil(xMax) - (int)floor(xMin) + 3,				       (int)ceil(yMax) - (int)floor(yMin) + 3,				       colorMode != splashModeMono1);    }  }  t3Font = t3FontCache[0];  // is the glyph in the cache?  i = (code & (t3Font->cacheSets - 1)) * t3Font->cacheAssoc;  for (j = 0; j < t3Font->cacheAssoc; ++j) {    if ((t3Font->cacheTags[i+j].mru & 0x8000) &&	t3Font->cacheTags[i+j].code == code) {      drawType3Glyph(t3Font, &t3Font->cacheTags[i+j],		     t3Font->cacheData + (i+j) * t3Font->glyphSize,		     xt, yt);      return gTrue;    }  }  // push a new Type 3 glyph record  t3gs = new T3GlyphStack();  t3gs->next = t3GlyphStack;  t3GlyphStack = t3gs;  t3GlyphStack->code = code;  t3GlyphStack->x = xt;  t3GlyphStack->y = yt;  t3GlyphStack->cache = t3Font;  t3GlyphStack->cacheTag = NULL;  t3GlyphStack->cacheData = NULL;  return gFalse;}void SplashOutputDev::endType3Char(GfxState *state) {  T3GlyphStack *t3gs;  double *ctm;  if (t3GlyphStack->cacheTag) {    memcpy(t3GlyphStack->cacheData, bitmap->getDataPtr(),	   t3GlyphStack->cache->glyphSize);    delete bitmap;    delete splash;    bitmap = t3GlyphStack->origBitmap;    splash = t3GlyphStack->origSplash;    ctm = state->getCTM();    state->setCTM(ctm[0], ctm[1], ctm[2], ctm[3],		  t3GlyphStack->origCTM4, t3GlyphStack->origCTM5);    drawType3Glyph(t3GlyphStack->cache,		   t3GlyphStack->cacheTag, t3GlyphStack->cacheData,		   t3GlyphStack->x, t3GlyphStack->y);  }  t3gs = t3GlyphStack;  t3GlyphStack = t3gs->next;  delete t3gs;}void SplashOutputDev::type3D0(GfxState *state, double wx, double wy) {}

⌨️ 快捷键说明

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