📄 splashoutputdev.cc
字号:
m11 = m11A; m12 = m12A; m21 = m21A; m22 = m22A; glyphX = glyphXA; glyphY = glyphYA; glyphW = glyphWA; glyphH = glyphHA; 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 double x, y; // position to draw the glyph //----- 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};//------------------------------------------------------------------------// SplashOutputDev//------------------------------------------------------------------------SplashOutputDev::SplashOutputDev(SplashColorMode colorModeA, int bitmapRowPadA, GBool reverseVideoA, SplashColorPtr paperColorA, GBool bitmapTopDownA, GBool allowAntialiasA) { colorMode = colorModeA; bitmapRowPad = bitmapRowPadA; bitmapTopDown = bitmapTopDownA; allowAntialias = allowAntialiasA; reverseVideo = reverseVideoA; splashColorCopy(paperColor, paperColorA); xref = NULL; bitmap = new SplashBitmap(1, 1, bitmapRowPad, colorMode, bitmapTopDown); splash = new Splash(bitmap); splash->clear(paperColor); fontEngine = NULL; nT3Fonts = 0; t3GlyphStack = NULL; font = NULL; needFontUpdate = gFalse; textClipPath = NULL;}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) { int w, h; SplashColor color; w = state ? (int)(state->getPageWidth() + 0.5) : 1; h = state ? (int)(state->getPageHeight() + 0.5) : 1; if (splash) { delete splash; } if (!bitmap || w != bitmap->getWidth() || h != bitmap->getHeight()) { if (bitmap) { delete bitmap; } bitmap = new SplashBitmap(w, h, bitmapRowPad, colorMode, bitmapTopDown); } splash = new Splash(bitmap); switch (colorMode) { case splashModeMono1: case splashModeMono8: color[0] = 0; break; case splashModeRGB8: case splashModeBGR8: color[0] = color[1] = color[2] = 0; break; case splashModeAMono8: color[0] = 0xff; color[1] = 0; break; case splashModeARGB8: color[0] = 255; color[1] = color[2] = color[3] = 0; break; case splashModeBGRA8: color[0] = color[1] = color[2] = 0; color[3] = 255; break;#if SPLASH_CMYK case splashModeCMYK8: color[0] = color[1] = color[2] = color[3] = 0; break; case splashModeACMYK8: color[0] = 255; color[1] = color[2] = color[3] = color[4] = 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); splash->clear(paperColor);}void SplashOutputDev::endPage() {}void SplashOutputDev::drawLink(Link *link, Catalog *catalog) { double x1, y1, x2, y2; LinkBorderStyle *borderStyle; double r, g, b; GfxRGB rgb; GfxGray gray;#if SPLASH_CMYK GfxCMYK cmyk;#endif double *dash; int dashLength; SplashCoord dashList[20]; SplashPath *path; int x, y, i; link->getRect(&x1, &y1, &x2, &y2); borderStyle = link->getBorderStyle(); if (borderStyle->getWidth() > 0) { borderStyle->getColor(&r, &g, &b); rgb.r = dblToCol(r); rgb.g = dblToCol(g); rgb.b = dblToCol(b); gray = dblToCol(0.299 * r + 0.587 * g + 0.114 * b); if (gray > gfxColorComp1) { gray = gfxColorComp1; }#if SPLASH_CMYK cmyk.c = gfxColorComp1 - rgb.r; cmyk.m = gfxColorComp1 - rgb.g; cmyk.y = gfxColorComp1 - rgb.b; cmyk.k = 0; splash->setStrokePattern(getColor(gray, &rgb, &cmyk));#else splash->setStrokePattern(getColor(gray, &rgb));#endif splash->setLineWidth((SplashCoord)borderStyle->getWidth()); borderStyle->getDash(&dash, &dashLength); if (borderStyle->getType() == linkBorderDashed && dashLength > 0) { if (dashLength > 20) { dashLength = 20; } for (i = 0; i < dashLength; ++i) { dashList[i] = (SplashCoord)dash[i]; } splash->setLineDash(dashList, dashLength, 0); } path = new SplashPath(); if (borderStyle->getType() == linkBorderUnderlined) { cvtUserToDev(x1, y1, &x, &y); path->moveTo((SplashCoord)x, (SplashCoord)y); cvtUserToDev(x2, y1, &x, &y); path->lineTo((SplashCoord)x, (SplashCoord)y); } else { cvtUserToDev(x1, y1, &x, &y); path->moveTo((SplashCoord)x, (SplashCoord)y); cvtUserToDev(x2, y1, &x, &y); path->lineTo((SplashCoord)x, (SplashCoord)y); cvtUserToDev(x2, y2, &x, &y); path->lineTo((SplashCoord)x, (SplashCoord)y); cvtUserToDev(x1, y2, &x, &y); path->lineTo((SplashCoord)x, (SplashCoord)y); path->close(); } splash->stroke(path); delete path; }}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); updateFillColor(state); updateStrokeColor(state); needFontUpdate = gTrue;}void SplashOutputDev::updateCTM(GfxState *state, double m11, double m12, double m21, double m22, double m31, double m32) { updateLineDash(state); updateLineJoin(state); updateLineCap(state); updateLineWidth(state);}void SplashOutputDev::updateLineDash(GfxState *state) { double *dashPattern; int dashLength; double dashStart; SplashCoord dash[20]; SplashCoord phase; int i; state->getLineDash(&dashPattern, &dashLength, &dashStart); if (dashLength > 20) { dashLength = 20; } for (i = 0; i < dashLength; ++i) { dash[i] = (SplashCoord)state->transformWidth(dashPattern[i]); if (dash[i] < 1) { dash[i] = 1; } } phase = (SplashCoord)state->transformWidth(dashStart); splash->setLineDash(dash, dashLength, phase);}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->getTransformedLineWidth());}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 color0, color1; 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: color0[0] = 0; color1[0] = 1; pattern = new SplashHalftone(color0, color1, splash->getScreen()->copy(), (SplashCoord)colToDbl(gray)); break; case splashModeMono8: color1[0] = colToByte(gray); pattern = new SplashSolidColor(color1); break; case splashModeAMono8: color1[0] = 255; color1[1] = colToByte(gray); pattern = new SplashSolidColor(color1); break; case splashModeRGB8: color1[0] = colToByte(r); color1[1] = colToByte(g); color1[2] = colToByte(b); pattern = new SplashSolidColor(color1); break; case splashModeBGR8: color1[2] = colToByte(r); color1[1] = colToByte(g); color1[0] = colToByte(b); pattern = new SplashSolidColor(color1); break; case splashModeARGB8: color1[0] = 255; color1[1] = colToByte(r); color1[2] = colToByte(g); color1[3] = colToByte(b); pattern = new SplashSolidColor(color1); break; case splashModeBGRA8: color1[3] = 255; color1[2] = colToByte(r); color1[1] = colToByte(g); color1[0] = colToByte(b); pattern = new SplashSolidColor(color1); break;#if SPLASH_CMYK case splashModeCMYK8: color1[0] = colToByte(cmyk->c); color1[1] = colToByte(cmyk->m); color1[2] = colToByte(cmyk->y); color1[3] = colToByte(cmyk->k); pattern = new SplashSolidColor(color1); break; case splashModeACMYK8: color1[0] = 255; color1[1] = colToByte(cmyk->c); color1[2] = colToByte(cmyk->m); color1[3] = colToByte(cmyk->y); color1[4] = colToByte(cmyk->k); pattern = new SplashSolidColor(color1); 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) { 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 m11, m12, m21, m22, w1, w2; 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(); strObj.streamReset(); while ((c = strObj.streamGetChar()) != EOF) { fputc(c, tmpFile);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -