📄 splashoutputdev.cc
字号:
m22 = m22A; glyphX = glyphXA; glyphY = glyphYA; glyphW = glyphWA; glyphH = glyphHA; validBBox = validBBoxA; if (aa) { glyphSize = glyphW * glyphH; } else { glyphSize = ((glyphW + 7) >> 3) * glyphH; } cacheAssoc = 8; if (glyphSize <= 256) { cacheSets = 8; } else if (glyphSize <= 512) { cacheSets = 4; } else if (glyphSize <= 1024) { cacheSets = 2; } else { cacheSets = 1; } cacheData = (Guchar *)gmallocn(cacheSets * cacheAssoc, glyphSize); cacheTags = (T3FontCacheTag *)gmallocn(cacheSets * cacheAssoc, sizeof(T3FontCacheTag)); for (i = 0; i < cacheSets * cacheAssoc; ++i) { cacheTags[i].mru = i & (cacheAssoc - 1); }}T3FontCache::~T3FontCache() { gfree(cacheData); gfree(cacheTags);}struct T3GlyphStack { Gushort code; // character code //----- cache info T3FontCache *cache; // font cache for the current font T3FontCacheTag *cacheTag; // pointer to cache tag for the glyph Guchar *cacheData; // pointer to cache data for the glyph //----- saved state SplashBitmap *origBitmap; Splash *origSplash; double origCTM4, origCTM5; T3GlyphStack *next; // next object on stack};//------------------------------------------------------------------------// SplashTransparencyGroup//------------------------------------------------------------------------struct SplashTransparencyGroup { int tx, ty; // translation coordinates SplashBitmap *tBitmap; // bitmap for transparency group GfxColorSpace *blendingColorSpace; GBool isolated; //----- saved state SplashBitmap *origBitmap; Splash *origSplash; SplashTransparencyGroup *next;};//------------------------------------------------------------------------// SplashOutputDev//------------------------------------------------------------------------SplashOutputDev::SplashOutputDev(SplashColorMode colorModeA, int bitmapRowPadA, GBool reverseVideoA, SplashColorPtr paperColorA, GBool bitmapTopDownA, GBool allowAntialiasA) { colorMode = colorModeA; bitmapRowPad = bitmapRowPadA; bitmapTopDown = bitmapTopDownA; allowAntialias = allowAntialiasA; vectorAntialias = allowAntialias && globalParams->getVectorAntialias() && colorMode != splashModeMono1; setupScreenParams(72.0, 72.0); reverseVideo = reverseVideoA; splashColorCopy(paperColor, paperColorA); xref = NULL; bitmap = new SplashBitmap(1, 1, bitmapRowPad, colorMode, colorMode != splashModeMono1, bitmapTopDown); splash = new Splash(bitmap, vectorAntialias, &screenParams); splash->clear(paperColor, 0); fontEngine = NULL; nT3Fonts = 0; t3GlyphStack = NULL; font = NULL; needFontUpdate = gFalse; textClipPath = NULL; transpGroupStack = NULL;}void SplashOutputDev::setupScreenParams(double hDPI, double vDPI) { screenParams.size = globalParams->getScreenSize(); screenParams.dotRadius = globalParams->getScreenDotRadius(); screenParams.gamma = (SplashCoord)globalParams->getScreenGamma(); screenParams.blackThreshold = (SplashCoord)globalParams->getScreenBlackThreshold(); screenParams.whiteThreshold = (SplashCoord)globalParams->getScreenWhiteThreshold(); switch (globalParams->getScreenType()) { case screenDispersed: screenParams.type = splashScreenDispersed; if (screenParams.size < 0) { screenParams.size = 4; } break; case screenClustered: screenParams.type = splashScreenClustered; if (screenParams.size < 0) { screenParams.size = 10; } break; case screenStochasticClustered: screenParams.type = splashScreenStochasticClustered; if (screenParams.size < 0) { screenParams.size = 100; } if (screenParams.dotRadius < 0) { screenParams.dotRadius = 2; } break; case screenUnset: default: // use clustered dithering for resolution >= 300 dpi // (compare to 299.9 to avoid floating point issues) if (hDPI > 299.9 && vDPI > 299.9) { screenParams.type = splashScreenStochasticClustered; if (screenParams.size < 0) { screenParams.size = 100; } if (screenParams.dotRadius < 0) { screenParams.dotRadius = 2; } } else { screenParams.type = splashScreenDispersed; if (screenParams.size < 0) { screenParams.size = 4; } } }}SplashOutputDev::~SplashOutputDev() { int i; for (i = 0; i < nT3Fonts; ++i) { delete t3FontCache[i]; } if (fontEngine) { delete fontEngine; } if (splash) { delete splash; } if (bitmap) { delete bitmap; }}void SplashOutputDev::startDoc(XRef *xrefA) { int i; xref = xrefA; if (fontEngine) { delete fontEngine; } fontEngine = new SplashFontEngine(#if HAVE_T1LIB_H globalParams->getEnableT1lib(),#endif#if HAVE_FREETYPE_FREETYPE_H || HAVE_FREETYPE_H globalParams->getEnableFreeType(),#endif allowAntialias && globalParams->getAntialias() && colorMode != splashModeMono1); for (i = 0; i < nT3Fonts; ++i) { delete t3FontCache[i]; } nT3Fonts = 0;}void SplashOutputDev::startPage(int pageNum, GfxState *state, double x1,double y1,double x2,double y2) { int w, h; double *ctm; SplashCoord mat[6]; SplashColor color; if (state) { setupScreenParams(state->getHDPI(), state->getVDPI()); w = (int)(state->getPageWidth() + 0.5); if (w <= 0) { w = 1; } h = (int)(state->getPageHeight() + 0.5); if (h <= 0) { h = 1; } } else { w = h = 1; } if (splash) { delete splash; } if (!bitmap || w != bitmap->getWidth() || h != bitmap->getHeight()) { if (bitmap) { delete bitmap; } bitmap = new SplashBitmap(w, h, bitmapRowPad, colorMode, colorMode != splashModeMono1, bitmapTopDown); } splash = new Splash(bitmap, vectorAntialias, &screenParams); if (state) { ctm = state->getCTM(); mat[0] = (SplashCoord)ctm[0]; mat[1] = (SplashCoord)ctm[1]; mat[2] = (SplashCoord)ctm[2]; mat[3] = (SplashCoord)ctm[3]; mat[4] = (SplashCoord)ctm[4]; mat[5] = (SplashCoord)ctm[5]; splash->setMatrix(mat); } switch (colorMode) { case splashModeMono1: case splashModeMono8: color[0] = 0; break; case splashModeRGB8: case splashModeBGR8: color[0] = color[1] = color[2] = 0; break;#if SPLASH_CMYK case splashModeCMYK8: color[0] = color[1] = color[2] = color[3] = 0; break;#endif } splash->setStrokePattern(new SplashSolidColor(color)); splash->setFillPattern(new SplashSolidColor(color)); splash->setLineCap(splashLineCapButt); splash->setLineJoin(splashLineJoinMiter); splash->setLineDash(NULL, 0, 0); splash->setMiterLimit(10); splash->setFlatness(1); // the SA parameter supposedly defaults to false, but Acrobat // apparently hardwires it to true splash->setStrokeAdjust(globalParams->getStrokeAdjust()); splash->clear(paperColor, 0);}void SplashOutputDev::endPage() { if (colorMode != splashModeMono1) { splash->compositeBackground(paperColor); }}void SplashOutputDev::saveState(GfxState *state) { splash->saveState();}void SplashOutputDev::restoreState(GfxState *state) { splash->restoreState(); needFontUpdate = gTrue;}void SplashOutputDev::updateAll(GfxState *state) { updateLineDash(state); updateLineJoin(state); updateLineCap(state); updateLineWidth(state); updateFlatness(state); updateMiterLimit(state); updateStrokeAdjust(state); updateFillColor(state); updateStrokeColor(state); needFontUpdate = gTrue;}void SplashOutputDev::updateCTM(GfxState *state, double m11, double m12, double m21, double m22, double m31, double m32) { double *ctm; SplashCoord mat[6]; ctm = state->getCTM(); mat[0] = (SplashCoord)ctm[0]; mat[1] = (SplashCoord)ctm[1]; mat[2] = (SplashCoord)ctm[2]; mat[3] = (SplashCoord)ctm[3]; mat[4] = (SplashCoord)ctm[4]; mat[5] = (SplashCoord)ctm[5]; splash->setMatrix(mat);}void SplashOutputDev::updateLineDash(GfxState *state) { double *dashPattern; int dashLength; double dashStart; SplashCoord dash[20]; int i; state->getLineDash(&dashPattern, &dashLength, &dashStart); if (dashLength > 20) { dashLength = 20; } for (i = 0; i < dashLength; ++i) { dash[i] = (SplashCoord)dashPattern[i]; if (dash[i] < 0) { dash[i] = 0; } } splash->setLineDash(dash, dashLength, (SplashCoord)dashStart);}void SplashOutputDev::updateFlatness(GfxState *state) { splash->setFlatness(state->getFlatness());}void SplashOutputDev::updateLineJoin(GfxState *state) { splash->setLineJoin(state->getLineJoin());}void SplashOutputDev::updateLineCap(GfxState *state) { splash->setLineCap(state->getLineCap());}void SplashOutputDev::updateMiterLimit(GfxState *state) { splash->setMiterLimit(state->getMiterLimit());}void SplashOutputDev::updateLineWidth(GfxState *state) { splash->setLineWidth(state->getLineWidth());}void SplashOutputDev::updateStrokeAdjust(GfxState *state) {#if 0 // the SA parameter supposedly defaults to false, but Acrobat // apparently hardwires it to true splash->setStrokeAdjust(state->getStrokeAdjust());#endif}void SplashOutputDev::updateFillColor(GfxState *state) { GfxGray gray; GfxRGB rgb;#if SPLASH_CMYK GfxCMYK cmyk;#endif state->getFillGray(&gray); state->getFillRGB(&rgb);#if SPLASH_CMYK state->getFillCMYK(&cmyk); splash->setFillPattern(getColor(gray, &rgb, &cmyk));#else splash->setFillPattern(getColor(gray, &rgb));#endif}void SplashOutputDev::updateStrokeColor(GfxState *state) { GfxGray gray; GfxRGB rgb;#if SPLASH_CMYK GfxCMYK cmyk;#endif state->getStrokeGray(&gray); state->getStrokeRGB(&rgb);#if SPLASH_CMYK state->getStrokeCMYK(&cmyk); splash->setStrokePattern(getColor(gray, &rgb, &cmyk));#else splash->setStrokePattern(getColor(gray, &rgb));#endif}#if SPLASH_CMYKSplashPattern *SplashOutputDev::getColor(GfxGray gray, GfxRGB *rgb, GfxCMYK *cmyk) {#elseSplashPattern *SplashOutputDev::getColor(GfxGray gray, GfxRGB *rgb) {#endif SplashPattern *pattern; SplashColor color; GfxColorComp r, g, b; if (reverseVideo) { gray = gfxColorComp1 - gray; r = gfxColorComp1 - rgb->r; g = gfxColorComp1 - rgb->g; b = gfxColorComp1 - rgb->b; } else { r = rgb->r; g = rgb->g; b = rgb->b; } pattern = NULL; // make gcc happy switch (colorMode) { case splashModeMono1: case splashModeMono8: color[0] = colToByte(gray); pattern = new SplashSolidColor(color); break; case splashModeRGB8: case splashModeBGR8: color[0] = colToByte(r); color[1] = colToByte(g); color[2] = colToByte(b); pattern = new SplashSolidColor(color); break;#if SPLASH_CMYK case splashModeCMYK8: color[0] = colToByte(cmyk->c); color[1] = colToByte(cmyk->m); color[2] = colToByte(cmyk->y); color[3] = colToByte(cmyk->k); pattern = new SplashSolidColor(color); break;#endif } return pattern;}void SplashOutputDev::updateBlendMode(GfxState *state) { splash->setBlendFunc(splashOutBlendFuncs[state->getBlendMode()]);}void SplashOutputDev::updateFillOpacity(GfxState *state) { splash->setFillAlpha((SplashCoord)state->getFillOpacity());}void SplashOutputDev::updateStrokeOpacity(GfxState *state) { splash->setStrokeAlpha((SplashCoord)state->getStrokeOpacity());}void SplashOutputDev::updateFont(GfxState *state) { needFontUpdate = gTrue;}void SplashOutputDev::doUpdateFont(GfxState *state) { GfxFont *gfxFont; GfxFontType fontType; SplashOutFontFileID *id; SplashFontFile *fontFile; FoFiTrueType *ff; Ref embRef; Object refObj, strObj; GString *tmpFileName, *fileName, *substName; FILE *tmpFile; Gushort *codeToGID; DisplayFontParam *dfp; CharCodeToUnicode *ctu; double *textMat; double m11, m12, m21, m22, w1, w2, fontSize; SplashCoord mat[4]; char *name; Unicode uBuf[8]; int c, substIdx, n, code, cmap; needFontUpdate = gFalse; font = NULL; tmpFileName = NULL; substIdx = -1; dfp = NULL; if (!(gfxFont = state->getFont())) { goto err1; } fontType = gfxFont->getType(); if (fontType == fontType3) { goto err1; } // check the font file cache id = new SplashOutFontFileID(gfxFont->getID()); if ((fontFile = fontEngine->getFontFile(id))) { delete id; } else { // if there is an embedded font, write it to disk if (gfxFont->getEmbeddedFontID(&embRef)) { if (!openTempFile(&tmpFileName, &tmpFile, "wb", NULL)) { error(-1, "Couldn't create temporary font file"); goto err2; } refObj.initRef(embRef.num, embRef.gen); refObj.fetch(xref, &strObj); refObj.free(); if (!strObj.isStream()) {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -