?? splash.cc
字號:
//========================================================================//// Splash.cc////========================================================================#include <aconf.h>#ifdef USE_GCC_PRAGMAS#pragma implementation#endif#include <stdlib.h>#include <string.h>#include "gmem.h"#include "SplashErrorCodes.h"#include "SplashMath.h"#include "SplashBitmap.h"#include "SplashState.h"#include "SplashPath.h"#include "SplashXPath.h"#include "SplashXPathScanner.h"#include "SplashPattern.h"#include "SplashScreen.h"#include "SplashFont.h"#include "SplashGlyphBitmap.h"#include "Splash.h"//------------------------------------------------------------------------// distance of Bezier control point from center for circle approximation// = (4 * (sqrt(2) - 1) / 3) * r#define bezierCircle ((SplashCoord)0.55228475)#define bezierCircle2 ((SplashCoord)(0.5 * 0.55228475))// Divide a 16-bit value (in [0, 255*255]) by 255, returning an 8-bit result.static inline Guchar div255(int x) { return (Guchar)((x + (x >> 8) + 0x80) >> 8);}//------------------------------------------------------------------------// SplashPipe//------------------------------------------------------------------------#define splashPipeMaxStages 9struct SplashPipe { // pixel coordinates int x, y; // source pattern SplashPattern *pattern; // source alpha and color SplashCoord aInput; GBool usesShape; Guchar aSrc; SplashColorPtr cSrc; SplashColor cSrcVal; // non-isolated group alpha0 Guchar *alpha0Ptr; // soft mask SplashColorPtr softMaskPtr; // destination alpha and color SplashColorPtr destColorPtr; int destColorMask; Guchar *destAlphaPtr; // shape SplashCoord shape; // result alpha and color GBool noTransparency; SplashPipeResultColorCtrl resultColorCtrl; // non-isolated group correction int nonIsolatedGroup;};SplashPipeResultColorCtrl Splash::pipeResultColorNoAlphaBlend[] = { splashPipeResultColorNoAlphaBlendMono, splashPipeResultColorNoAlphaBlendMono, splashPipeResultColorNoAlphaBlendRGB, splashPipeResultColorNoAlphaBlendRGB#if SPLASH_CMYK , splashPipeResultColorNoAlphaBlendCMYK#endif};SplashPipeResultColorCtrl Splash::pipeResultColorAlphaNoBlend[] = { splashPipeResultColorAlphaNoBlendMono, splashPipeResultColorAlphaNoBlendMono, splashPipeResultColorAlphaNoBlendRGB, splashPipeResultColorAlphaNoBlendRGB#if SPLASH_CMYK , splashPipeResultColorAlphaNoBlendCMYK#endif};SplashPipeResultColorCtrl Splash::pipeResultColorAlphaBlend[] = { splashPipeResultColorAlphaBlendMono, splashPipeResultColorAlphaBlendMono, splashPipeResultColorAlphaBlendRGB, splashPipeResultColorAlphaBlendRGB#if SPLASH_CMYK , splashPipeResultColorAlphaBlendCMYK#endif};//------------------------------------------------------------------------static void blendXor(SplashColorPtr src, SplashColorPtr dest, SplashColorPtr blend, SplashColorMode cm) { int i; for (i = 0; i < splashColorModeNComps[cm]; ++i) { blend[i] = src[i] ^ dest[i]; }}//------------------------------------------------------------------------// modified region//------------------------------------------------------------------------void Splash::clearModRegion() { modXMin = bitmap->getWidth(); modYMin = bitmap->getHeight(); modXMax = -1; modYMax = -1;}inline void Splash::updateModX(int x) { if (x < modXMin) { modXMin = x; } if (x > modXMax) { modXMax = x; }}inline void Splash::updateModY(int y) { if (y < modYMin) { modYMin = y; } if (y > modYMax) { modYMax = y; }}//------------------------------------------------------------------------// pipeline//------------------------------------------------------------------------inline void Splash::pipeInit(SplashPipe *pipe, int x, int y, SplashPattern *pattern, SplashColorPtr cSrc, SplashCoord aInput, GBool usesShape, GBool nonIsolatedGroup) { pipeSetXY(pipe, x, y); pipe->pattern = NULL; // source color if (pattern) { if (pattern->isStatic()) { pattern->getColor(x, y, pipe->cSrcVal); } else { pipe->pattern = pattern; } pipe->cSrc = pipe->cSrcVal; } else { pipe->cSrc = cSrc; } // source alpha pipe->aInput = aInput; if (!state->softMask) { if (usesShape) { pipe->aInput *= 255; } else { pipe->aSrc = (Guchar)splashRound(pipe->aInput * 255); } } pipe->usesShape = usesShape; // result alpha if (aInput == 1 && !state->softMask && !usesShape && !state->inNonIsolatedGroup) { pipe->noTransparency = gTrue; } else { pipe->noTransparency = gFalse; } // result color if (pipe->noTransparency) { // the !state->blendFunc case is handled separately in pipeRun pipe->resultColorCtrl = pipeResultColorNoAlphaBlend[bitmap->mode]; } else if (!state->blendFunc) { pipe->resultColorCtrl = pipeResultColorAlphaNoBlend[bitmap->mode]; } else { pipe->resultColorCtrl = pipeResultColorAlphaBlend[bitmap->mode]; } // non-isolated group correction if (nonIsolatedGroup) { pipe->nonIsolatedGroup = splashColorModeNComps[bitmap->mode]; } else { pipe->nonIsolatedGroup = 0; }}inline void Splash::pipeRun(SplashPipe *pipe) { Guchar aSrc, aDest, alpha2, alpha0, aResult; SplashColor cDest, cBlend; Guchar cResult0, cResult1, cResult2, cResult3; //----- source color // static pattern: handled in pipeInit // fixed color: handled in pipeInit // dynamic pattern if (pipe->pattern) { pipe->pattern->getColor(pipe->x, pipe->y, pipe->cSrcVal); } if (pipe->noTransparency && !state->blendFunc) { //----- write destination pixel switch (bitmap->mode) { case splashModeMono1: cResult0 = pipe->cSrc[0]; if (state->screen->test(pipe->x, pipe->y, cResult0)) { *pipe->destColorPtr |= pipe->destColorMask; } else { *pipe->destColorPtr &= ~pipe->destColorMask; } if (!(pipe->destColorMask >>= 1)) { pipe->destColorMask = 0x80; ++pipe->destColorPtr; } break; case splashModeMono8: *pipe->destColorPtr++ = pipe->cSrc[0]; break; case splashModeRGB8: *pipe->destColorPtr++ = pipe->cSrc[0]; *pipe->destColorPtr++ = pipe->cSrc[1]; *pipe->destColorPtr++ = pipe->cSrc[2]; break; case splashModeBGR8: *pipe->destColorPtr++ = pipe->cSrc[2]; *pipe->destColorPtr++ = pipe->cSrc[1]; *pipe->destColorPtr++ = pipe->cSrc[0]; break;#if SPLASH_CMYK case splashModeCMYK8: *pipe->destColorPtr++ = pipe->cSrc[0]; *pipe->destColorPtr++ = pipe->cSrc[1]; *pipe->destColorPtr++ = pipe->cSrc[2]; *pipe->destColorPtr++ = pipe->cSrc[3]; break;#endif } if (pipe->destAlphaPtr) { *pipe->destAlphaPtr++ = 255; } } else { //----- read destination pixel switch (bitmap->mode) { case splashModeMono1: cDest[0] = (*pipe->destColorPtr & pipe->destColorMask) ? 0xff : 0x00; break; case splashModeMono8: cDest[0] = *pipe->destColorPtr; break; case splashModeRGB8: cDest[0] = pipe->destColorPtr[0]; cDest[1] = pipe->destColorPtr[1]; cDest[2] = pipe->destColorPtr[2]; break; case splashModeBGR8: cDest[0] = pipe->destColorPtr[2]; cDest[1] = pipe->destColorPtr[1]; cDest[2] = pipe->destColorPtr[0]; break;#if SPLASH_CMYK case splashModeCMYK8: cDest[0] = pipe->destColorPtr[0]; cDest[1] = pipe->destColorPtr[1]; cDest[2] = pipe->destColorPtr[2]; cDest[3] = pipe->destColorPtr[3]; break;#endif } if (pipe->destAlphaPtr) { aDest = *pipe->destAlphaPtr; } else { aDest = 0xff; } //----- blend function if (state->blendFunc) { (*state->blendFunc)(pipe->cSrc, cDest, cBlend, bitmap->mode); } //----- source alpha if (state->softMask) { if (pipe->usesShape) { aSrc = (Guchar)splashRound(pipe->aInput * *pipe->softMaskPtr++ * pipe->shape); } else { aSrc = (Guchar)splashRound(pipe->aInput * *pipe->softMaskPtr++); } } else if (pipe->usesShape) { // pipe->aInput is premultiplied by 255 in pipeInit aSrc = (Guchar)splashRound(pipe->aInput * pipe->shape); } else { // precomputed in pipeInit aSrc = pipe->aSrc; } //----- result alpha and non-isolated group element correction if (pipe->noTransparency) { alpha2 = aResult = 255; } else { aResult = aSrc + aDest - div255(aSrc * aDest); if (pipe->alpha0Ptr) { alpha0 = *pipe->alpha0Ptr++; alpha2 = aResult + alpha0 - div255(aResult * alpha0); } else { alpha2 = aResult; } } //----- result color cResult0 = cResult1 = cResult2 = cResult3 = 0; // make gcc happy switch (pipe->resultColorCtrl) {#if SPLASH_CMYK case splashPipeResultColorNoAlphaBlendCMYK: cResult3 = div255((255 - aDest) * pipe->cSrc[3] + aDest * cBlend[3]);#endif case splashPipeResultColorNoAlphaBlendRGB: cResult2 = div255((255 - aDest) * pipe->cSrc[2] + aDest * cBlend[2]); cResult1 = div255((255 - aDest) * pipe->cSrc[1] + aDest * cBlend[1]); case splashPipeResultColorNoAlphaBlendMono: cResult0 = div255((255 - aDest) * pipe->cSrc[0] + aDest * cBlend[0]); break; case splashPipeResultColorAlphaNoBlendMono: if (alpha2 == 0) { cResult0 = 0; } else { cResult0 = (Guchar)(((alpha2 - aSrc) * cDest[0] + aSrc * pipe->cSrc[0]) / alpha2); } break; case splashPipeResultColorAlphaNoBlendRGB: if (alpha2 == 0) { cResult0 = 0; cResult1 = 0; cResult2 = 0; } else { cResult0 = (Guchar)(((alpha2 - aSrc) * cDest[0] + aSrc * pipe->cSrc[0]) / alpha2); cResult1 = (Guchar)(((alpha2 - aSrc) * cDest[1] + aSrc * pipe->cSrc[1]) / alpha2); cResult2 = (Guchar)(((alpha2 - aSrc) * cDest[2] + aSrc * pipe->cSrc[2]) / alpha2); } break;#if SPLASH_CMYK case splashPipeResultColorAlphaNoBlendCMYK: if (alpha2 == 0) { cResult0 = 0; cResult1 = 0; cResult2 = 0; cResult3 = 0; } else { cResult0 = (Guchar)(((alpha2 - aSrc) * cDest[0] + aSrc * pipe->cSrc[0]) / alpha2); cResult1 = (Guchar)(((alpha2 - aSrc) * cDest[1] + aSrc * pipe->cSrc[1]) / alpha2); cResult2 = (Guchar)(((alpha2 - aSrc) * cDest[2] + aSrc * pipe->cSrc[2]) / alpha2); cResult3 = (Guchar)(((alpha2 - aSrc) * cDest[3] + aSrc * pipe->cSrc[3]) / alpha2); } break;#endif case splashPipeResultColorAlphaBlendMono: if (alpha2 == 0) { cResult0 = 0; } else { cResult0 = (Guchar)(((alpha2 - aSrc) * cDest[0] + aSrc * ((255 - aDest) * pipe->cSrc[0] + aDest * cBlend[0]) / 255) / alpha2); } break; case splashPipeResultColorAlphaBlendRGB: if (alpha2 == 0) { cResult0 = 0; cResult1 = 0; cResult2 = 0; } else { cResult0 = (Guchar)(((alpha2 - aSrc) * cDest[0] + aSrc * ((255 - aDest) * pipe->cSrc[0] + aDest * cBlend[0]) / 255) / alpha2); cResult1 = (Guchar)(((alpha2 - aSrc) * cDest[1] + aSrc * ((255 - aDest) * pipe->cSrc[1] + aDest * cBlend[1]) / 255) / alpha2); cResult2 = (Guchar)(((alpha2 - aSrc) * cDest[2] + aSrc * ((255 - aDest) * pipe->cSrc[2] + aDest * cBlend[2]) / 255) / alpha2); } break;#if SPLASH_CMYK case splashPipeResultColorAlphaBlendCMYK: if (alpha2 == 0) { cResult0 = 0; cResult1 = 0; cResult2 = 0; cResult3 = 0; } else { cResult0 = (Guchar)(((alpha2 - aSrc) * cDest[0] + aSrc * ((255 - aDest) * pipe->cSrc[0] + aDest * cBlend[0]) / 255) / alpha2); cResult1 = (Guchar)(((alpha2 - aSrc) * cDest[1] + aSrc * ((255 - aDest) * pipe->cSrc[1] + aDest * cBlend[1]) / 255) / alpha2); cResult2 = (Guchar)(((alpha2 - aSrc) * cDest[2] + aSrc * ((255 - aDest) * pipe->cSrc[2] + aDest * cBlend[2]) / 255) / alpha2); cResult3 = (Guchar)(((alpha2 - aSrc) * cDest[3] + aSrc * ((255 - aDest) * pipe->cSrc[3] + aDest * cBlend[3]) / 255) / alpha2); } break;#endif } //----- non-isolated group correction if (aResult != 0) { switch (pipe->nonIsolatedGroup) {#if SPLASH_CMYK case 4: cResult3 += (cResult3 - cDest[3]) * aDest * (255 - aResult) / (255 * aResult);#endif case 3: cResult2 += (cResult2 - cDest[2]) * aDest * (255 - aResult) / (255 * aResult); cResult1 += (cResult1 - cDest[1]) * aDest * (255 - aResult) / (255 * aResult); case 1: cResult0 += (cResult0 - cDest[0]) * aDest * (255 - aResult) / (255 * aResult); case 0: break; } } //----- write destination pixel switch (bitmap->mode) { case splashModeMono1: if (state->screen->test(pipe->x, pipe->y, cResult0)) { *pipe->destColorPtr |= pipe->destColorMask; } else { *pipe->destColorPtr &= ~pipe->destColorMask; } if (!(pipe->destColorMask >>= 1)) { pipe->destColorMask = 0x80; ++pipe->destColorPtr; } break; case splashModeMono8: *pipe->destColorPtr++ = cResult0; break; case splashModeRGB8:
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -