diff options
author | Denis Bitouzé <dbitouze@wanadoo.fr> | 2021-02-25 18:23:07 +0000 |
---|---|---|
committer | Denis Bitouzé <dbitouze@wanadoo.fr> | 2021-02-25 18:23:07 +0000 |
commit | c6101f91d071883b48b1b4b51e5eba0f36d9a78d (patch) | |
tree | 1bf7f5a881d7a4f5c5bf59d0b2821943dd822372 /Build/source/libs/xpdf/xpdf-src/splash | |
parent | 07ee7222e389b0777456b427a55c22d0e6ffd267 (diff) |
French translation for tlmgr updated
git-svn-id: svn://tug.org/texlive/trunk@57912 c570f23f-e606-0410-a88d-b1316a301751
Diffstat (limited to 'Build/source/libs/xpdf/xpdf-src/splash')
37 files changed, 0 insertions, 15614 deletions
diff --git a/Build/source/libs/xpdf/xpdf-src/splash/CMakeLists.txt b/Build/source/libs/xpdf/xpdf-src/splash/CMakeLists.txt deleted file mode 100644 index f84968cfb2a..00000000000 --- a/Build/source/libs/xpdf/xpdf-src/splash/CMakeLists.txt +++ /dev/null @@ -1,47 +0,0 @@ -#======================================================================== -# -# splash/CMakeLists.txt -# -# CMake script for the splash library. -# -# Copyright 2015 Glyph & Cog, LLC -# -#======================================================================== - -if (HAVE_SPLASH) - include_directories("${PROJECT_SOURCE_DIR}") - include_directories("${PROJECT_BINARY_DIR}") - include_directories("${PROJECT_SOURCE_DIR}/goo") - include_directories("${PROJECT_SOURCE_DIR}/fofi") - include_directories("${FREETYPE_INCLUDE_DIRS}") - - if (HAVE_DTYPE4_H) - include_directories("${DTYPE_INCLUDE_DIR}") - set(DTYPE_SRCS - SplashDT4Font.cc SplashDT4FontEngine.cc SplashDT4FontFile.cc) - endif () - - add_library(splash_objs OBJECT - Splash.cc - SplashBitmap.cc - SplashClip.cc - SplashFTFont.cc - SplashFTFontEngine.cc - SplashFTFontFile.cc - SplashFont.cc - SplashFontEngine.cc - SplashFontFile.cc - SplashFontFileID.cc - SplashPath.cc - SplashPattern.cc - SplashScreen.cc - SplashState.cc - SplashXPath.cc - SplashXPathScanner.cc - ${DTYPE_SRCS} - ) - - add_library(splash - $<TARGET_OBJECTS:splash_objs> - ) -endif () diff --git a/Build/source/libs/xpdf/xpdf-src/splash/Splash.cc b/Build/source/libs/xpdf/xpdf-src/splash/Splash.cc deleted file mode 100644 index 343db796fb2..00000000000 --- a/Build/source/libs/xpdf/xpdf-src/splash/Splash.cc +++ /dev/null @@ -1,8210 +0,0 @@ -//======================================================================== -// -// Splash.cc -// -// Copyright 2003-2020 Glyph & Cog, LLC -// -//======================================================================== - -#include <aconf.h> - -#ifdef USE_GCC_PRAGMAS -#pragma implementation -#endif - -#include <stdlib.h> -#include <string.h> -#include <limits.h> -#include <math.h> -#include "gmem.h" -#include "gmempp.h" -#include "GString.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" - -// the MSVC math.h doesn't define this -#ifndef M_PI -#define M_PI 3.14159265358979323846 -#endif - -//------------------------------------------------------------------------ - -// 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); -} - -// Clip x to lie in [0, 255]. -static inline Guchar clip255(int x) { - return x < 0 ? 0 : x > 255 ? 255 : (Guchar)x; -} - -// Used by drawImage and fillImageMask to divide the target -// quadrilateral into sections. -struct ImageSection { - int y0, y1; // actual y range - int ia0, ia1; // vertex indices for edge A - int ib0, ib1; // vertex indices for edge B - SplashCoord xa0, ya0, xa1, ya1; // edge A - SplashCoord dxdya; // slope of edge A - SplashCoord xb0, yb0, xb1, yb1; // edge B - SplashCoord dxdyb; // slope of edge B -}; - -//------------------------------------------------------------------------ -// SplashPipe -//------------------------------------------------------------------------ - -#define splashPipeMaxStages 9 - -struct SplashPipe { - // source pattern - SplashPattern *pattern; - - // source alpha and color - Guchar aInput; - SplashColor cSrcVal; - - // source overprint mask - //~ this is a kludge - this pointer should be passed as an arg to the - //~ pipeRun function, but that would require passing in a lot of - //~ null pointers, since it's rarely used - Guint *srcOverprintMaskPtr; - - // special cases and result color - GBool noTransparency; - GBool shapeOnly; - SplashPipeResultColorCtrl resultColorCtrl; - - // non-isolated group correction - // (this is only used when Splash::composite() is called to composite - // a non-isolated group onto the backdrop) - GBool nonIsolatedGroup; - - // the "run" function - void (Splash::*run)(SplashPipe *pipe, int x0, int x1, int y, - Guchar *shapePtr, SplashColorPtr cSrcPtr); -}; - -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 -}; - -//------------------------------------------------------------------------ -// modified region -//------------------------------------------------------------------------ - -void Splash::clearModRegion() { - modXMin = bitmap->width; - modYMin = bitmap->height; - 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, SplashPattern *pattern, - Guchar aInput, GBool usesShape, - GBool nonIsolatedGroup, GBool usesSrcOverprint) { - SplashColorMode mode; - - mode = bitmap->mode; - - pipe->pattern = NULL; - - // source color - if (pattern && pattern->isStatic()) { - pattern->getColor(0, 0, pipe->cSrcVal); - pipe->pattern = NULL; - } else { - pipe->pattern = pattern; - } - - // source alpha - pipe->aInput = aInput; - - // source overprint mask - pipe->srcOverprintMaskPtr = NULL; - - // special cases - pipe->noTransparency = aInput == 255 && - !state->softMask && - !usesShape && - !state->inNonIsolatedGroup && - !state->inKnockoutGroup && - !nonIsolatedGroup && - state->overprintMask == 0xffffffff; - pipe->shapeOnly = aInput == 255 && - !state->softMask && - usesShape && - !state->inNonIsolatedGroup && - !state->inKnockoutGroup && - !nonIsolatedGroup && - state->overprintMask == 0xffffffff; - - // result color - if (pipe->noTransparency) { - // the !state->blendFunc case is handled separately in pipeRun - pipe->resultColorCtrl = pipeResultColorNoAlphaBlend[mode]; - } else if (!state->blendFunc) { - pipe->resultColorCtrl = pipeResultColorAlphaNoBlend[mode]; - } else { - pipe->resultColorCtrl = pipeResultColorAlphaBlend[mode]; - } - - // non-isolated group correction - pipe->nonIsolatedGroup = nonIsolatedGroup; - - // select the 'run' function - pipe->run = &Splash::pipeRun; - if (overprintMaskBitmap || usesSrcOverprint) { - // use Splash::pipeRun - } else if (!pipe->pattern && pipe->noTransparency && !state->blendFunc) { - if (mode == splashModeMono1 && !bitmap->alpha) { - pipe->run = &Splash::pipeRunSimpleMono1; - } else if (mode == splashModeMono8 && bitmap->alpha) { - pipe->run = &Splash::pipeRunSimpleMono8; - } else if (mode == splashModeRGB8 && bitmap->alpha) { - pipe->run = &Splash::pipeRunSimpleRGB8; - } else if (mode == splashModeBGR8 && bitmap->alpha) { - pipe->run = &Splash::pipeRunSimpleBGR8; -#if SPLASH_CMYK - } else if (mode == splashModeCMYK8 && bitmap->alpha) { - pipe->run = &Splash::pipeRunSimpleCMYK8; -#endif - } - } else if (!pipe->pattern && pipe->shapeOnly && !state->blendFunc) { - if (mode == splashModeMono1 && !bitmap->alpha) { - pipe->run = &Splash::pipeRunShapeMono1; - } else if (mode == splashModeMono8 && bitmap->alpha) { - pipe->run = &Splash::pipeRunShapeMono8; - } else if (mode == splashModeRGB8 && bitmap->alpha) { - pipe->run = &Splash::pipeRunShapeRGB8; - } else if (mode == splashModeBGR8 && bitmap->alpha) { - pipe->run = &Splash::pipeRunShapeBGR8; -#if SPLASH_CMYK - } else if (mode == splashModeCMYK8 && bitmap->alpha) { - pipe->run = &Splash::pipeRunShapeCMYK8; -#endif - } else if (mode == splashModeMono8 && !bitmap->alpha) { - // this is used when drawing soft-masked images - pipe->run = &Splash::pipeRunShapeNoAlphaMono8; - } - } else if (!pipe->pattern && !pipe->noTransparency && !state->softMask && - usesShape && - !(state->inNonIsolatedGroup && groupBackBitmap->alpha) && - !state->inKnockoutGroup && - !state->blendFunc && !pipe->nonIsolatedGroup) { - if (mode == splashModeMono1 && !bitmap->alpha) { - pipe->run = &Splash::pipeRunAAMono1; - } else if (mode == splashModeMono8 && bitmap->alpha) { - pipe->run = &Splash::pipeRunAAMono8; - } else if (mode == splashModeRGB8 && bitmap->alpha) { - pipe->run = &Splash::pipeRunAARGB8; - } else if (mode == splashModeBGR8 && bitmap->alpha) { - pipe->run = &Splash::pipeRunAABGR8; -#if SPLASH_CMYK - } else if (mode == splashModeCMYK8 && bitmap->alpha) { - pipe->run = &Splash::pipeRunAACMYK8; -#endif - } - } else if (!pipe->pattern && - aInput == 255 && - state->softMask && - usesShape && - !state->inNonIsolatedGroup && - !state->inKnockoutGroup && - !nonIsolatedGroup && - state->overprintMask == 0xffffffff && - !state->blendFunc) { - if (mode == splashModeMono8 && bitmap->alpha) { - pipe->run = &Splash::pipeRunSoftMaskMono8; - } else if (mode == splashModeRGB8 && bitmap->alpha) { - pipe->run = &Splash::pipeRunSoftMaskRGB8; - } else if (mode == splashModeBGR8 && bitmap->alpha) { - pipe->run = &Splash::pipeRunSoftMaskBGR8; -#if SPLASH_CMYK - } else if (mode == splashModeCMYK8 && bitmap->alpha) { - pipe->run = &Splash::pipeRunSoftMaskCMYK8; -#endif - } - } else if (!pipe->pattern && !pipe->noTransparency && !state->softMask && - usesShape && - state->inNonIsolatedGroup && groupBackBitmap->alpha && - !state->inKnockoutGroup && - !state->blendFunc && !pipe->nonIsolatedGroup) { - if (mode == splashModeMono8 && bitmap->alpha) { - pipe->run = &Splash::pipeRunNonIsoMono8; - } else if (mode == splashModeRGB8 && bitmap->alpha) { - pipe->run = &Splash::pipeRunNonIsoRGB8; - } else if (mode == splashModeBGR8 && bitmap->alpha) { - pipe->run = &Splash::pipeRunNonIsoBGR8; -#if SPLASH_CMYK - } else if (mode == splashModeCMYK8 && bitmap->alpha) { - pipe->run = &Splash::pipeRunNonIsoCMYK8; -#endif - } - } -} - -// general case -void Splash::pipeRun(SplashPipe *pipe, int x0, int x1, int y, - Guchar *shapePtr, SplashColorPtr cSrcPtr) { - Guchar *shapePtr2; - Guchar shape, aSrc, aDest, alphaI, alphaIm1, alpha0, aResult; - SplashColor cSrc, cDest, cBlend; - Guchar shapeVal, cResult0, cResult1, cResult2, cResult3; - int cSrcStride, shapeStride, x, lastX, t; - SplashColorPtr destColorPtr; - Guchar destColorMask; - Guchar *destAlphaPtr; - SplashColorPtr color0Ptr; - Guchar color0Mask; - Guchar *alpha0Ptr; - SplashColorPtr softMaskPtr; - Guint overprintMask; - Guint *overprintMaskPtr; -#if SPLASH_CMYK - Guchar aPrev; - SplashColor cSrc2, cDest2; -#endif - - if (cSrcPtr && !pipe->pattern) { - cSrcStride = bitmapComps; - } else { - cSrcPtr = pipe->cSrcVal; - cSrcStride = 0; - } - - if (shapePtr) { - shapePtr2 = shapePtr; - shapeStride = 1; - for (; x0 <= x1; ++x0) { - if (*shapePtr2) { - break; - } - cSrcPtr += cSrcStride; - ++shapePtr2; - if (pipe->srcOverprintMaskPtr) { - ++pipe->srcOverprintMaskPtr; - } - } - } else { - shapeVal = 0xff; - shapePtr2 = &shapeVal; - shapeStride = 0; - } - if (x0 > x1) { - return; - } - updateModX(x0); - updateModY(y); - lastX = x0; - - useDestRow(y); - - if (bitmap->mode == splashModeMono1) { - destColorPtr = &bitmap->data[y * bitmap->rowSize + (x0 >> 3)]; - destColorMask = (Guchar)(0x80 >> (x0 & 7)); - } else { - destColorPtr = &bitmap->data[y * bitmap->rowSize + x0 * bitmapComps]; - destColorMask = 0; // make gcc happy - } - if (bitmap->alpha) { - destAlphaPtr = &bitmap->alpha[y * bitmap->alphaRowSize + x0]; - } else { - destAlphaPtr = NULL; - } - if (state->softMask) { - softMaskPtr = &state->softMask->data[y * state->softMask->rowSize + x0]; - } else { - softMaskPtr = NULL; - } - if (state->inKnockoutGroup) { - if (bitmap->mode == splashModeMono1) { - color0Ptr = - &groupBackBitmap->data[(groupBackY + y) * groupBackBitmap->rowSize + - ((groupBackX + x0) >> 3)]; - color0Mask = (Guchar)(0x80 >> ((groupBackX + x0) & 7)); - } else { - color0Ptr = - &groupBackBitmap->data[(groupBackY + y) * groupBackBitmap->rowSize + - (groupBackX + x0) * bitmapComps]; - color0Mask = 0; // make gcc happy - } - } else { - color0Ptr = NULL; - color0Mask = 0; // make gcc happy - } - if (state->inNonIsolatedGroup && groupBackBitmap->alpha) { - alpha0Ptr = - &groupBackBitmap->alpha[(groupBackY + y) - * groupBackBitmap->alphaRowSize + - (groupBackX + x0)]; - } else { - alpha0Ptr = NULL; - } - if (overprintMaskBitmap) { - overprintMaskPtr = overprintMaskBitmap + y * bitmap->width + x0; - } else { - overprintMaskPtr = NULL; - } - - for (x = x0; x <= x1; ++x) { - - //----- shape - - shape = *shapePtr2; - if (!shape) { - if (bitmap->mode == splashModeMono1) { - destColorPtr += destColorMask & 1; - destColorMask = (Guchar)((destColorMask << 7) | (destColorMask >> 1)); - } else { - destColorPtr += bitmapComps; - } - if (destAlphaPtr) { - ++destAlphaPtr; - } - if (softMaskPtr) { - ++softMaskPtr; - } - if (color0Ptr) { - if (bitmap->mode == splashModeMono1) { - color0Ptr += color0Mask & 1; - color0Mask = (Guchar)((color0Mask << 7) | (color0Mask >> 1)); - } else { - color0Ptr += bitmapComps; - } - } - if (alpha0Ptr) { - ++alpha0Ptr; - } - cSrcPtr += cSrcStride; - shapePtr2 += shapeStride; - if (pipe->srcOverprintMaskPtr) { - ++pipe->srcOverprintMaskPtr; - } - if (overprintMaskPtr) { - ++overprintMaskPtr; - } - continue; - } - lastX = x; - - //----- source color - - // static pattern: handled in pipeInit - // fixed color: handled in pipeInit - - // dynamic pattern - if (pipe->pattern) { - pipe->pattern->getColor(x, y, pipe->cSrcVal); - } - - cResult0 = cResult1 = cResult2 = cResult3 = 0; // make gcc happy - - if (pipe->noTransparency && !state->blendFunc) { - - //----- result color - - switch (bitmap->mode) { - case splashModeMono1: - case splashModeMono8: - cResult0 = state->grayTransfer[cSrcPtr[0]]; - break; - case splashModeRGB8: - case splashModeBGR8: - cResult0 = state->rgbTransferR[cSrcPtr[0]]; - cResult1 = state->rgbTransferG[cSrcPtr[1]]; - cResult2 = state->rgbTransferB[cSrcPtr[2]]; - break; -#if SPLASH_CMYK - case splashModeCMYK8: - cResult0 = state->cmykTransferC[cSrcPtr[0]]; - cResult1 = state->cmykTransferM[cSrcPtr[1]]; - cResult2 = state->cmykTransferY[cSrcPtr[2]]; - cResult3 = state->cmykTransferK[cSrcPtr[3]]; - break; -#endif - } - aResult = 255; - - } else { // if (noTransparency && !blendFunc) - - //----- read destination pixel - // (or backdrop color, for knockout groups) - - if (color0Ptr) { - - switch (bitmap->mode) { - case splashModeMono1: - cDest[0] = (*color0Ptr & color0Mask) ? 0xff : 0x00; - color0Ptr += color0Mask & 1; - color0Mask = (Guchar)((color0Mask << 7) | (color0Mask >> 1)); - break; - case splashModeMono8: - cDest[0] = *color0Ptr++; - break; - case splashModeRGB8: - cDest[0] = color0Ptr[0]; - cDest[1] = color0Ptr[1]; - cDest[2] = color0Ptr[2]; - color0Ptr += 3; - break; - case splashModeBGR8: - cDest[2] = color0Ptr[0]; - cDest[1] = color0Ptr[1]; - cDest[0] = color0Ptr[2]; - color0Ptr += 3; - break; -#if SPLASH_CMYK - case splashModeCMYK8: - cDest[0] = color0Ptr[0]; - cDest[1] = color0Ptr[1]; - cDest[2] = color0Ptr[2]; - cDest[3] = color0Ptr[3]; - color0Ptr += 4; - break; -#endif - } - - } else { - - switch (bitmap->mode) { - case splashModeMono1: - cDest[0] = (*destColorPtr & destColorMask) ? 0xff : 0x00; - break; - case splashModeMono8: - cDest[0] = *destColorPtr; - break; - case splashModeRGB8: - cDest[0] = destColorPtr[0]; - cDest[1] = destColorPtr[1]; - cDest[2] = destColorPtr[2]; - break; - case splashModeBGR8: - cDest[0] = destColorPtr[2]; - cDest[1] = destColorPtr[1]; - cDest[2] = destColorPtr[0]; - break; -#if SPLASH_CMYK - case splashModeCMYK8: - cDest[0] = destColorPtr[0]; - cDest[1] = destColorPtr[1]; - cDest[2] = destColorPtr[2]; - cDest[3] = destColorPtr[3]; - break; -#endif - } - - } - - if (destAlphaPtr) { - aDest = *destAlphaPtr; - } else { - aDest = 0xff; - } - - //----- read source color; handle overprint - - if (pipe->srcOverprintMaskPtr) { - overprintMask = *pipe->srcOverprintMaskPtr++; - } else { - overprintMask = state->overprintMask; - } - if (overprintMaskPtr) { - *overprintMaskPtr++ |= overprintMask; - } - - switch (bitmap->mode) { - case splashModeMono1: - case splashModeMono8: - cSrc[0] = state->grayTransfer[cSrcPtr[0]]; - break; - case splashModeRGB8: - case splashModeBGR8: - cSrc[0] = state->rgbTransferR[cSrcPtr[0]]; - cSrc[1] = state->rgbTransferG[cSrcPtr[1]]; - cSrc[2] = state->rgbTransferB[cSrcPtr[2]]; - break; -#if SPLASH_CMYK - case splashModeCMYK8: - if (alpha0Ptr) { // non-isolated group - if (color0Ptr) { // non-isolated, knockout group - aPrev = *alpha0Ptr; - } else { // non-isolated, non-knockout group - aPrev = (Guchar)(*alpha0Ptr + aDest - div255(*alpha0Ptr * aDest)); - } - } else { // isolated group - if (color0Ptr) { // isolated, knockout group - aPrev = 0; - } else { // isolated, non-knockout group - aPrev = aDest; - } - } - if (overprintMask & 0x01) { - cSrc[0] = state->cmykTransferC[cSrcPtr[0]]; - } else { - cSrc[0] = div255(aPrev * cDest[0]); - } - if (overprintMask & 0x02) { - cSrc[1] = state->cmykTransferM[cSrcPtr[1]]; - } else { - cSrc[1] = div255(aPrev * cDest[1]); - } - if (overprintMask & 0x04) { - cSrc[2] = state->cmykTransferY[cSrcPtr[2]]; - } else { - cSrc[2] = div255(aPrev * cDest[2]); - } - if (overprintMask & 0x08) { - cSrc[3] = state->cmykTransferK[cSrcPtr[3]]; - } else { - cSrc[3] = div255(aPrev * cDest[3]); - } - break; -#endif - } - - //----- source alpha - - if (softMaskPtr) { - if (shapePtr) { - aSrc = div255(div255(pipe->aInput * *softMaskPtr++) * shape); - } else { - aSrc = div255(pipe->aInput * *softMaskPtr++); - } - } else if (shapePtr) { - aSrc = div255(pipe->aInput * shape); - } else { - aSrc = pipe->aInput; - } - - //----- non-isolated group correction - - if (pipe->nonIsolatedGroup) { - // This path is only used when Splash::composite() is called to - // composite a non-isolated group onto the backdrop. In this - // case, shape is the source (group) alpha. - t = (aDest * 255) / shape - aDest; - switch (bitmap->mode) { -#if SPLASH_CMYK - case splashModeCMYK8: - cSrc[3] = clip255(cSrc[3] + ((cSrc[3] - cDest[3]) * t) / 255); -#endif - case splashModeRGB8: - case splashModeBGR8: - cSrc[2] = clip255(cSrc[2] + ((cSrc[2] - cDest[2]) * t) / 255); - cSrc[1] = clip255(cSrc[1] + ((cSrc[1] - cDest[1]) * t) / 255); - case splashModeMono1: - case splashModeMono8: - cSrc[0] = clip255(cSrc[0] + ((cSrc[0] - cDest[0]) * t) / 255); - break; - } - } - - //----- blend function - - if (state->blendFunc) { -#if SPLASH_CMYK - if (bitmap->mode == splashModeCMYK8) { - // convert colors to additive - cSrc2[0] = (Guchar)(0xff - cSrc[0]); - cSrc2[1] = (Guchar)(0xff - cSrc[1]); - cSrc2[2] = (Guchar)(0xff - cSrc[2]); - cSrc2[3] = (Guchar)(0xff - cSrc[3]); - cDest2[0] = (Guchar)(0xff - cDest[0]); - cDest2[1] = (Guchar)(0xff - cDest[1]); - cDest2[2] = (Guchar)(0xff - cDest[2]); - cDest2[3] = (Guchar)(0xff - cDest[3]); - (*state->blendFunc)(cSrc2, cDest2, cBlend, bitmap->mode); - // convert result back to subtractive - cBlend[0] = (Guchar)(0xff - cBlend[0]); - cBlend[1] = (Guchar)(0xff - cBlend[1]); - cBlend[2] = (Guchar)(0xff - cBlend[2]); - cBlend[3] = (Guchar)(0xff - cBlend[3]); - } else -#endif - (*state->blendFunc)(cSrc, cDest, cBlend, bitmap->mode); - } - - //----- result alpha and non-isolated group element correction - - // alphaI = alpha_i - // alphaIm1 = alpha_(i-1) - - if (pipe->noTransparency) { - alphaI = alphaIm1 = aResult = 255; - } else if (alpha0Ptr) { - if (color0Ptr) { - // non-isolated, knockout - aResult = aSrc; - alpha0 = *alpha0Ptr++; - alphaI = (Guchar)(aSrc + alpha0 - div255(aSrc * alpha0)); - alphaIm1 = alpha0; - } else { - // non-isolated, non-knockout - aResult = (Guchar)(aSrc + aDest - div255(aSrc * aDest)); - alpha0 = *alpha0Ptr++; - alphaI = (Guchar)(aResult + alpha0 - div255(aResult * alpha0)); - alphaIm1 = (Guchar)(alpha0 + aDest - div255(alpha0 * aDest)); - } - } else { - if (color0Ptr) { - // isolated, knockout - aResult = aSrc; - alphaI = aSrc; - alphaIm1 = 0; - } else { - // isolated, non-knockout - aResult = (Guchar)(aSrc + aDest - div255(aSrc * aDest)); - alphaI = aResult; - alphaIm1 = aDest; - } - } - - //----- result color - - switch (pipe->resultColorCtrl) { - - case splashPipeResultColorNoAlphaBlendMono: - cResult0 = div255((255 - aDest) * cSrc[0] + aDest * cBlend[0]); - break; - case splashPipeResultColorNoAlphaBlendRGB: - cResult0 = div255((255 - aDest) * cSrc[0] + aDest * cBlend[0]); - cResult1 = div255((255 - aDest) * cSrc[1] + aDest * cBlend[1]); - cResult2 = div255((255 - aDest) * cSrc[2] + aDest * cBlend[2]); - break; -#if SPLASH_CMYK - case splashPipeResultColorNoAlphaBlendCMYK: - cResult0 = div255((255 - aDest) * cSrc[0] + aDest * cBlend[0]); - cResult1 = div255((255 - aDest) * cSrc[1] + aDest * cBlend[1]); - cResult2 = div255((255 - aDest) * cSrc[2] + aDest * cBlend[2]); - cResult3 = div255((255 - aDest) * cSrc[3] + aDest * cBlend[3]); - break; -#endif - - case splashPipeResultColorAlphaNoBlendMono: - if (alphaI == 0) { - cResult0 = 0; - } else { - cResult0 = (Guchar)(((alphaI - aSrc) * cDest[0] + aSrc * cSrc[0]) - / alphaI); - } - break; - case splashPipeResultColorAlphaNoBlendRGB: - if (alphaI == 0) { - cResult0 = 0; - cResult1 = 0; - cResult2 = 0; - } else { - cResult0 = (Guchar)(((alphaI - aSrc) * cDest[0] + aSrc * cSrc[0]) - / alphaI); - cResult1 = (Guchar)(((alphaI - aSrc) * cDest[1] + aSrc * cSrc[1]) - / alphaI); - cResult2 = (Guchar)(((alphaI - aSrc) * cDest[2] + aSrc * cSrc[2]) - / alphaI); - } - break; -#if SPLASH_CMYK - case splashPipeResultColorAlphaNoBlendCMYK: - if (alphaI == 0) { - cResult0 = 0; - cResult1 = 0; - cResult2 = 0; - cResult3 = 0; - } else { - cResult0 = (Guchar)(((alphaI - aSrc) * cDest[0] + aSrc * cSrc[0]) - / alphaI); - cResult1 = (Guchar)(((alphaI - aSrc) * cDest[1] + aSrc * cSrc[1]) - / alphaI); - cResult2 = (Guchar)(((alphaI - aSrc) * cDest[2] + aSrc * cSrc[2]) - / alphaI); - cResult3 = (Guchar)(((alphaI - aSrc) * cDest[3] + aSrc * cSrc[3]) - / alphaI); - } - break; -#endif - - case splashPipeResultColorAlphaBlendMono: - if (alphaI == 0) { - cResult0 = 0; - } else { - cResult0 = (Guchar)(((alphaI - aSrc) * cDest[0] + - aSrc * ((255 - alphaIm1) * cSrc[0] + - alphaIm1 * cBlend[0]) / 255) - / alphaI); - } - break; - case splashPipeResultColorAlphaBlendRGB: - if (alphaI == 0) { - cResult0 = 0; - cResult1 = 0; - cResult2 = 0; - } else { - cResult0 = (Guchar)(((alphaI - aSrc) * cDest[0] + - aSrc * ((255 - alphaIm1) * cSrc[0] + - alphaIm1 * cBlend[0]) / 255) - / alphaI); - cResult1 = (Guchar)(((alphaI - aSrc) * cDest[1] + - aSrc * ((255 - alphaIm1) * cSrc[1] + - alphaIm1 * cBlend[1]) / 255) - / alphaI); - cResult2 = (Guchar)(((alphaI - aSrc) * cDest[2] + - aSrc * ((255 - alphaIm1) * cSrc[2] + - alphaIm1 * cBlend[2]) / 255) - / alphaI); - } - break; -#if SPLASH_CMYK - case splashPipeResultColorAlphaBlendCMYK: - if (alphaI == 0) { - cResult0 = 0; - cResult1 = 0; - cResult2 = 0; - cResult3 = 0; - } else { - cResult0 = (Guchar)(((alphaI - aSrc) * cDest[0] + - aSrc * ((255 - alphaIm1) * cSrc[0] + - alphaIm1 * cBlend[0]) / 255) - / alphaI); - cResult1 = (Guchar)(((alphaI - aSrc) * cDest[1] + - aSrc * ((255 - alphaIm1) * cSrc[1] + - alphaIm1 * cBlend[1]) / 255) - / alphaI); - cResult2 = (Guchar)(((alphaI - aSrc) * cDest[2] + - aSrc * ((255 - alphaIm1) * cSrc[2] + - alphaIm1 * cBlend[2]) / 255) - / alphaI); - cResult3 = (Guchar)(((alphaI - aSrc) * cDest[3] + - aSrc * ((255 - alphaIm1) * cSrc[3] + - alphaIm1 * cBlend[3]) / 255) - / alphaI); - } - break; -#endif - } - - } // if (noTransparency && !blendFunc) - - //----- write destination pixel - - switch (bitmap->mode) { - case splashModeMono1: - if (state->screen->test(x, y, cResult0)) { - *destColorPtr |= destColorMask; - } else { - *destColorPtr &= (Guchar)~destColorMask; - } - destColorPtr += destColorMask & 1; - destColorMask = (Guchar)((destColorMask << 7) | (destColorMask >> 1)); - break; - case splashModeMono8: - *destColorPtr++ = cResult0; - break; - case splashModeRGB8: - destColorPtr[0] = cResult0; - destColorPtr[1] = cResult1; - destColorPtr[2] = cResult2; - destColorPtr += 3; - break; - case splashModeBGR8: - destColorPtr[0] = cResult2; - destColorPtr[1] = cResult1; - destColorPtr[2] = cResult0; - destColorPtr += 3; - break; -#if SPLASH_CMYK - case splashModeCMYK8: - destColorPtr[0] = cResult0; - destColorPtr[1] = cResult1; - destColorPtr[2] = cResult2; - destColorPtr[3] = cResult3; - destColorPtr += 4; - break; -#endif - } - if (destAlphaPtr) { - *destAlphaPtr++ = aResult; - } - - cSrcPtr += cSrcStride; - shapePtr2 += shapeStride; - } // for (x ...) - - updateModX(lastX); -} - -// special case: -// !pipe->pattern && pipe->noTransparency && !state->blendFunc && -// bitmap->mode == splashModeMono1 && !bitmap->alpha) { -void Splash::pipeRunSimpleMono1(SplashPipe *pipe, int x0, int x1, int y, - Guchar *shapePtr, SplashColorPtr cSrcPtr) { - Guchar cResult0; - SplashColorPtr destColorPtr; - Guchar destColorMask; - SplashScreenCursor screenCursor; - int cSrcStride, x; - - if (cSrcPtr) { - cSrcStride = 1; - } else { - cSrcPtr = pipe->cSrcVal; - cSrcStride = 0; - } - if (x0 > x1) { - return; - } - updateModX(x0); - updateModX(x1); - updateModY(y); - - useDestRow(y); - - destColorPtr = &bitmap->data[y * bitmap->rowSize + (x0 >> 3)]; - destColorMask = (Guchar)(0x80 >> (x0 & 7)); - - screenCursor = state->screen->getTestCursor(y); - - for (x = x0; x <= x1; ++x) { - - //----- write destination pixel - cResult0 = state->grayTransfer[cSrcPtr[0]]; - if (state->screen->testWithCursor(screenCursor, x, cResult0)) { - *destColorPtr |= destColorMask; - } else { - *destColorPtr &= (Guchar)~destColorMask; - } - destColorPtr += destColorMask & 1; - destColorMask = (Guchar)((destColorMask << 7) | (destColorMask >> 1)); - - cSrcPtr += cSrcStride; - } -} - -// special case: -// !pipe->pattern && pipe->noTransparency && !state->blendFunc && -// bitmap->mode == splashModeMono8 && bitmap->alpha) { -void Splash::pipeRunSimpleMono8(SplashPipe *pipe, int x0, int x1, int y, - Guchar *shapePtr, SplashColorPtr cSrcPtr) { - SplashColorPtr destColorPtr; - Guchar *destAlphaPtr; - int cSrcStride, x; - - if (cSrcPtr) { - cSrcStride = 1; - } else { - cSrcPtr = pipe->cSrcVal; - cSrcStride = 0; - } - if (x0 > x1) { - return; - } - updateModX(x0); - updateModX(x1); - updateModY(y); - - useDestRow(y); - - destColorPtr = &bitmap->data[y * bitmap->rowSize + x0]; - destAlphaPtr = &bitmap->alpha[y * bitmap->alphaRowSize + x0]; - - for (x = x0; x <= x1; ++x) { - - //----- write destination pixel - *destColorPtr++ = state->grayTransfer[cSrcPtr[0]]; - *destAlphaPtr++ = 255; - - cSrcPtr += cSrcStride; - } -} - -// special case: -// !pipe->pattern && pipe->noTransparency && !state->blendFunc && -// bitmap->mode == splashModeRGB8 && bitmap->alpha) { -void Splash::pipeRunSimpleRGB8(SplashPipe *pipe, int x0, int x1, int y, - Guchar *shapePtr, SplashColorPtr cSrcPtr) { - SplashColorPtr destColorPtr; - Guchar *destAlphaPtr; - int cSrcStride, x; - - if (cSrcPtr) { - cSrcStride = 3; - } else { - cSrcPtr = pipe->cSrcVal; - cSrcStride = 0; - } - if (x0 > x1) { - return; - } - updateModX(x0); - updateModX(x1); - updateModY(y); - - useDestRow(y); - - destColorPtr = &bitmap->data[y * bitmap->rowSize + 3 * x0]; - destAlphaPtr = &bitmap->alpha[y * bitmap->alphaRowSize + x0]; - - for (x = x0; x <= x1; ++x) { - - //----- write destination pixel - destColorPtr[0] = state->rgbTransferR[cSrcPtr[0]]; - destColorPtr[1] = state->rgbTransferG[cSrcPtr[1]]; - destColorPtr[2] = state->rgbTransferB[cSrcPtr[2]]; - destColorPtr += 3; - *destAlphaPtr++ = 255; - - cSrcPtr += cSrcStride; - } -} - -// special case: -// !pipe->pattern && pipe->noTransparency && !state->blendFunc && -// bitmap->mode == splashModeBGR8 && bitmap->alpha) { -void Splash::pipeRunSimpleBGR8(SplashPipe *pipe, int x0, int x1, int y, - Guchar *shapePtr, SplashColorPtr cSrcPtr) { - SplashColorPtr destColorPtr; - Guchar *destAlphaPtr; - int cSrcStride, x; - - if (cSrcPtr) { - cSrcStride = 3; - } else { - cSrcPtr = pipe->cSrcVal; - cSrcStride = 0; - } - if (x0 > x1) { - return; - } - updateModX(x0); - updateModX(x1); - updateModY(y); - - useDestRow(y); - - destColorPtr = &bitmap->data[y * bitmap->rowSize + 3 * x0]; - destAlphaPtr = &bitmap->alpha[y * bitmap->alphaRowSize + x0]; - - for (x = x0; x <= x1; ++x) { - - //----- write destination pixel - destColorPtr[0] = state->rgbTransferB[cSrcPtr[2]]; - destColorPtr[1] = state->rgbTransferG[cSrcPtr[1]]; - destColorPtr[2] = state->rgbTransferR[cSrcPtr[0]]; - destColorPtr += 3; - *destAlphaPtr++ = 255; - - cSrcPtr += cSrcStride; - } -} - -#if SPLASH_CMYK -// special case: -// !pipe->pattern && pipe->noTransparency && !state->blendFunc && -// bitmap->mode == splashModeCMYK8 && bitmap->alpha) { -void Splash::pipeRunSimpleCMYK8(SplashPipe *pipe, int x0, int x1, int y, - Guchar *shapePtr, SplashColorPtr cSrcPtr) { - SplashColorPtr destColorPtr; - Guchar *destAlphaPtr; - int cSrcStride, x; - - if (cSrcPtr) { - cSrcStride = 4; - } else { - cSrcPtr = pipe->cSrcVal; - cSrcStride = 0; - } - if (x0 > x1) { - return; - } - updateModX(x0); - updateModX(x1); - updateModY(y); - - useDestRow(y); - - destColorPtr = &bitmap->data[y * bitmap->rowSize + 4 * x0]; - destAlphaPtr = &bitmap->alpha[y * bitmap->alphaRowSize + x0]; - - for (x = x0; x <= x1; ++x) { - - //----- write destination pixel - destColorPtr[0] = state->cmykTransferC[cSrcPtr[0]]; - destColorPtr[1] = state->cmykTransferM[cSrcPtr[1]]; - destColorPtr[2] = state->cmykTransferY[cSrcPtr[2]]; - destColorPtr[3] = state->cmykTransferK[cSrcPtr[3]]; - destColorPtr += 4; - *destAlphaPtr++ = 255; - - cSrcPtr += cSrcStride; - } -} -#endif - - -// special case: -// !pipe->pattern && pipe->shapeOnly && !state->blendFunc && -// bitmap->mode == splashModeMono1 && !bitmap->alpha -void Splash::pipeRunShapeMono1(SplashPipe *pipe, int x0, int x1, int y, - Guchar *shapePtr, SplashColorPtr cSrcPtr) { - Guchar shape, aSrc, cSrc0, cDest0, cResult0; - SplashColorPtr destColorPtr; - Guchar destColorMask; - SplashScreenCursor screenCursor; - int cSrcStride, x, lastX; - - if (cSrcPtr) { - cSrcStride = 1; - } else { - cSrcPtr = pipe->cSrcVal; - cSrcStride = 0; - } - for (; x0 <= x1; ++x0) { - if (*shapePtr) { - break; - } - cSrcPtr += cSrcStride; - ++shapePtr; - } - if (x0 > x1) { - return; - } - updateModX(x0); - updateModY(y); - lastX = x0; - - useDestRow(y); - - destColorPtr = &bitmap->data[y * bitmap->rowSize + (x0 >> 3)]; - destColorMask = (Guchar)(0x80 >> (x0 & 7)); - - screenCursor = state->screen->getTestCursor(y); - - for (x = x0; x <= x1; ++x) { - - //----- shape - shape = *shapePtr; - if (!shape) { - destColorPtr += destColorMask & 1; - destColorMask = (Guchar)((destColorMask << 7) | (destColorMask >> 1)); - cSrcPtr += cSrcStride; - ++shapePtr; - continue; - } - lastX = x; - - //----- source color - cSrc0 = state->grayTransfer[cSrcPtr[0]]; - - //----- source alpha - aSrc = shape; - - //----- special case for aSrc = 255 - if (aSrc == 255) { - cResult0 = cSrc0; - } else { - - //----- read destination pixel - cDest0 = (*destColorPtr & destColorMask) ? 0xff : 0x00; - - //----- result color - // note: aDest = alphaI = aResult = 0xff - cResult0 = (Guchar)div255((0xff - aSrc) * cDest0 + aSrc * cSrc0); - } - - //----- write destination pixel - if (state->screen->testWithCursor(screenCursor, x, cResult0)) { - *destColorPtr |= destColorMask; - } else { - *destColorPtr &= (Guchar)~destColorMask; - } - destColorPtr += destColorMask & 1; - destColorMask = (Guchar)((destColorMask << 7) | (destColorMask >> 1)); - - cSrcPtr += cSrcStride; - ++shapePtr; - } - - updateModX(lastX); -} - -// special case: -// !pipe->pattern && pipe->shapeOnly && !state->blendFunc && -// bitmap->mode == splashModeMono8 && bitmap->alpha -void Splash::pipeRunShapeMono8(SplashPipe *pipe, int x0, int x1, int y, - Guchar *shapePtr, SplashColorPtr cSrcPtr) { - Guchar shape, aSrc, aDest, alphaI, aResult, cSrc0, cDest0, cResult0; - SplashColorPtr destColorPtr; - Guchar *destAlphaPtr; - int cSrcStride, x, lastX; - - if (cSrcPtr) { - cSrcStride = 1; - } else { - cSrcPtr = pipe->cSrcVal; - cSrcStride = 0; - } - for (; x0 <= x1; ++x0) { - if (*shapePtr) { - break; - } - cSrcPtr += cSrcStride; - ++shapePtr; - } - if (x0 > x1) { - return; - } - updateModX(x0); - updateModY(y); - lastX = x0; - - useDestRow(y); - - destColorPtr = &bitmap->data[y * bitmap->rowSize + x0]; - destAlphaPtr = &bitmap->alpha[y * bitmap->alphaRowSize + x0]; - - for (x = x0; x <= x1; ++x) { - - //----- shape - shape = *shapePtr; - if (!shape) { - ++destColorPtr; - ++destAlphaPtr; - cSrcPtr += cSrcStride; - ++shapePtr; - continue; - } - lastX = x; - - //----- source color - cSrc0 = state->grayTransfer[cSrcPtr[0]]; - - //----- source alpha - aSrc = shape; - - //----- special case for aSrc = 255 - if (aSrc == 255) { - aResult = 255; - cResult0 = cSrc0; - } else { - - //----- read destination alpha - aDest = *destAlphaPtr; - - //----- special case for aDest = 0 - if (aDest == 0) { - aResult = aSrc; - cResult0 = cSrc0; - } else { - - //----- read destination pixel - cDest0 = *destColorPtr; - - //----- result alpha and non-isolated group element correction - aResult = (Guchar)(aSrc + aDest - div255(aSrc * aDest)); - alphaI = aResult; - - //----- result color - cResult0 = (Guchar)(((alphaI - aSrc) * cDest0 + aSrc * cSrc0) / alphaI); - } - } - - //----- write destination pixel - *destColorPtr++ = cResult0; - *destAlphaPtr++ = aResult; - - cSrcPtr += cSrcStride; - ++shapePtr; - } - - updateModX(lastX); -} - -// special case: -// !pipe->pattern && pipe->shapeOnly && !state->blendFunc && -// bitmap->mode == splashModeRGB8 && bitmap->alpha -void Splash::pipeRunShapeRGB8(SplashPipe *pipe, int x0, int x1, int y, - Guchar *shapePtr, SplashColorPtr cSrcPtr) { - Guchar shape, aSrc, aDest, alphaI, aResult; - Guchar cSrc0, cSrc1, cSrc2; - Guchar cDest0, cDest1, cDest2; - Guchar cResult0, cResult1, cResult2; - SplashColorPtr destColorPtr; - Guchar *destAlphaPtr; - int cSrcStride, x, lastX; - - if (cSrcPtr) { - cSrcStride = 3; - } else { - cSrcPtr = pipe->cSrcVal; - cSrcStride = 0; - } - for (; x0 <= x1; ++x0) { - if (*shapePtr) { - break; - } - cSrcPtr += cSrcStride; - ++shapePtr; - } - if (x0 > x1) { - return; - } - updateModX(x0); - updateModY(y); - lastX = x0; - - useDestRow(y); - - destColorPtr = &bitmap->data[y * bitmap->rowSize + 3 * x0]; - destAlphaPtr = &bitmap->alpha[y * bitmap->alphaRowSize + x0]; - - for (x = x0; x <= x1; ++x) { - - //----- shape - shape = *shapePtr; - if (!shape) { - destColorPtr += 3; - ++destAlphaPtr; - cSrcPtr += cSrcStride; - ++shapePtr; - continue; - } - lastX = x; - - //----- source color - cSrc0 = state->rgbTransferR[cSrcPtr[0]]; - cSrc1 = state->rgbTransferG[cSrcPtr[1]]; - cSrc2 = state->rgbTransferB[cSrcPtr[2]]; - - //----- source alpha - aSrc = shape; - - //----- special case for aSrc = 255 - if (aSrc == 255) { - aResult = 255; - cResult0 = cSrc0; - cResult1 = cSrc1; - cResult2 = cSrc2; - } else { - - //----- read destination alpha - aDest = *destAlphaPtr; - - //----- special case for aDest = 0 - if (aDest == 0) { - aResult = aSrc; - cResult0 = cSrc0; - cResult1 = cSrc1; - cResult2 = cSrc2; - } else { - - //----- read destination pixel - cDest0 = destColorPtr[0]; - cDest1 = destColorPtr[1]; - cDest2 = destColorPtr[2]; - - //----- result alpha and non-isolated group element correction - aResult = (Guchar)(aSrc + aDest - div255(aSrc * aDest)); - alphaI = aResult; - - //----- result color - cResult0 = (Guchar)(((alphaI - aSrc) * cDest0 + aSrc * cSrc0) / alphaI); - cResult1 = (Guchar)(((alphaI - aSrc) * cDest1 + aSrc * cSrc1) / alphaI); - cResult2 = (Guchar)(((alphaI - aSrc) * cDest2 + aSrc * cSrc2) / alphaI); - } - } - - //----- write destination pixel - destColorPtr[0] = cResult0; - destColorPtr[1] = cResult1; - destColorPtr[2] = cResult2; - destColorPtr += 3; - *destAlphaPtr++ = aResult; - - cSrcPtr += cSrcStride; - ++shapePtr; - } - - updateModX(lastX); -} - -// special case: -// !pipe->pattern && pipe->shapeOnly && !state->blendFunc && -// bitmap->mode == splashModeBGR8 && bitmap->alpha -void Splash::pipeRunShapeBGR8(SplashPipe *pipe, int x0, int x1, int y, - Guchar *shapePtr, SplashColorPtr cSrcPtr) { - Guchar shape, aSrc, aDest, alphaI, aResult; - Guchar cSrc0, cSrc1, cSrc2; - Guchar cDest0, cDest1, cDest2; - Guchar cResult0, cResult1, cResult2; - SplashColorPtr destColorPtr; - Guchar *destAlphaPtr; - int cSrcStride, x, lastX; - - if (cSrcPtr) { - cSrcStride = 3; - } else { - cSrcPtr = pipe->cSrcVal; - cSrcStride = 0; - } - for (; x0 <= x1; ++x0) { - if (*shapePtr) { - break; - } - cSrcPtr += cSrcStride; - ++shapePtr; - } - if (x0 > x1) { - return; - } - updateModX(x0); - updateModY(y); - lastX = x0; - - useDestRow(y); - - destColorPtr = &bitmap->data[y * bitmap->rowSize + 3 * x0]; - destAlphaPtr = &bitmap->alpha[y * bitmap->alphaRowSize + x0]; - - for (x = x0; x <= x1; ++x) { - - //----- shape - shape = *shapePtr; - if (!shape) { - destColorPtr += 3; - ++destAlphaPtr; - cSrcPtr += cSrcStride; - ++shapePtr; - continue; - } - lastX = x; - - //----- source color - cSrc0 = state->rgbTransferR[cSrcPtr[0]]; - cSrc1 = state->rgbTransferG[cSrcPtr[1]]; - cSrc2 = state->rgbTransferB[cSrcPtr[2]]; - - //----- source alpha - aSrc = shape; - - //----- special case for aSrc = 255 - if (aSrc == 255) { - aResult = 255; - cResult0 = cSrc0; - cResult1 = cSrc1; - cResult2 = cSrc2; - } else { - - //----- read destination alpha - aDest = *destAlphaPtr; - - //----- special case for aDest = 0 - if (aDest == 0) { - aResult = aSrc; - cResult0 = cSrc0; - cResult1 = cSrc1; - cResult2 = cSrc2; - } else { - - //----- read destination pixel - cDest0 = destColorPtr[2]; - cDest1 = destColorPtr[1]; - cDest2 = destColorPtr[0]; - - //----- result alpha and non-isolated group element correction - aResult = (Guchar)(aSrc + aDest - div255(aSrc * aDest)); - alphaI = aResult; - - //----- result color - cResult0 = (Guchar)(((alphaI - aSrc) * cDest0 + aSrc * cSrc0) / alphaI); - cResult1 = (Guchar)(((alphaI - aSrc) * cDest1 + aSrc * cSrc1) / alphaI); - cResult2 = (Guchar)(((alphaI - aSrc) * cDest2 + aSrc * cSrc2) / alphaI); - } - } - - //----- write destination pixel - destColorPtr[0] = cResult2; - destColorPtr[1] = cResult1; - destColorPtr[2] = cResult0; - destColorPtr += 3; - *destAlphaPtr++ = aResult; - - cSrcPtr += cSrcStride; - ++shapePtr; - } - - updateModX(lastX); -} - -#if SPLASH_CMYK -// special case: -// !pipe->pattern && pipe->shapeOnly && !state->blendFunc && -// bitmap->mode == splashModeCMYK8 && bitmap->alpha -void Splash::pipeRunShapeCMYK8(SplashPipe *pipe, int x0, int x1, int y, - Guchar *shapePtr, SplashColorPtr cSrcPtr) { - Guchar shape, aSrc, aDest, alphaI, aResult; - Guchar cSrc0, cSrc1, cSrc2, cSrc3; - Guchar cDest0, cDest1, cDest2, cDest3; - Guchar cResult0, cResult1, cResult2, cResult3; - SplashColorPtr destColorPtr; - Guchar *destAlphaPtr; - int cSrcStride, x, lastX; - - if (cSrcPtr) { - cSrcStride = 4; - } else { - cSrcPtr = pipe->cSrcVal; - cSrcStride = 0; - } - for (; x0 <= x1; ++x0) { - if (*shapePtr) { - break; - } - cSrcPtr += cSrcStride; - ++shapePtr; - } - if (x0 > x1) { - return; - } - updateModX(x0); - updateModY(y); - lastX = x0; - - useDestRow(y); - - destColorPtr = &bitmap->data[y * bitmap->rowSize + 4 * x0]; - destAlphaPtr = &bitmap->alpha[y * bitmap->alphaRowSize + x0]; - - for (x = x0; x <= x1; ++x) { - - //----- shape - shape = *shapePtr; - if (!shape) { - destColorPtr += 4; - ++destAlphaPtr; - cSrcPtr += cSrcStride; - ++shapePtr; - continue; - } - lastX = x; - - //----- read destination pixel - cDest0 = destColorPtr[0]; - cDest1 = destColorPtr[1]; - cDest2 = destColorPtr[2]; - cDest3 = destColorPtr[3]; - aDest = *destAlphaPtr; - - //----- overprint - cSrc0 = state->cmykTransferC[cSrcPtr[0]]; - cSrc1 = state->cmykTransferM[cSrcPtr[1]]; - cSrc2 = state->cmykTransferY[cSrcPtr[2]]; - cSrc3 = state->cmykTransferK[cSrcPtr[3]]; - - //----- source alpha - aSrc = shape; - - //----- special case for aSrc = 255 - if (aSrc == 255) { - aResult = 255; - cResult0 = cSrc0; - cResult1 = cSrc1; - cResult2 = cSrc2; - cResult3 = cSrc3; - } else { - - //----- special case for aDest = 0 - if (aDest == 0) { - aResult = aSrc; - cResult0 = cSrc0; - cResult1 = cSrc1; - cResult2 = cSrc2; - cResult3 = cSrc3; - } else { - - //----- result alpha and non-isolated group element correction - aResult = (Guchar)(aSrc + aDest - div255(aSrc * aDest)); - alphaI = aResult; - - //----- result color - cResult0 = (Guchar)(((alphaI - aSrc) * cDest0 + aSrc * cSrc0) / alphaI); - cResult1 = (Guchar)(((alphaI - aSrc) * cDest1 + aSrc * cSrc1) / alphaI); - cResult2 = (Guchar)(((alphaI - aSrc) * cDest2 + aSrc * cSrc2) / alphaI); - cResult3 = (Guchar)(((alphaI - aSrc) * cDest3 + aSrc * cSrc3) / alphaI); - } - } - - //----- write destination pixel - destColorPtr[0] = cResult0; - destColorPtr[1] = cResult1; - destColorPtr[2] = cResult2; - destColorPtr[3] = cResult3; - destColorPtr += 4; - *destAlphaPtr++ = aResult; - - cSrcPtr += cSrcStride; - ++shapePtr; - } - - updateModX(lastX); -} -#endif - - -// special case: -// !pipe->pattern && pipe->shapeOnly && !state->blendFunc && -// bitmap->mode == splashModeMono8 && !bitmap->alpha -void Splash::pipeRunShapeNoAlphaMono8(SplashPipe *pipe, int x0, int x1, int y, - Guchar *shapePtr, - SplashColorPtr cSrcPtr) { - Guchar shape, aSrc, cSrc0, cDest0, cResult0; - SplashColorPtr destColorPtr; - int cSrcStride, x, lastX; - - if (cSrcPtr) { - cSrcStride = 1; - } else { - cSrcPtr = pipe->cSrcVal; - cSrcStride = 0; - } - for (; x0 <= x1; ++x0) { - if (*shapePtr) { - break; - } - cSrcPtr += cSrcStride; - ++shapePtr; - } - if (x0 > x1) { - return; - } - updateModX(x0); - updateModY(y); - lastX = x0; - - useDestRow(y); - - destColorPtr = &bitmap->data[y * bitmap->rowSize + x0]; - - for (x = x0; x <= x1; ++x) { - - //----- shape - shape = *shapePtr; - if (!shape) { - ++destColorPtr; - cSrcPtr += cSrcStride; - ++shapePtr; - continue; - } - lastX = x; - - //----- source color - cSrc0 = state->grayTransfer[cSrcPtr[0]]; - - //----- source alpha - aSrc = shape; - - //----- special case for aSrc = 255 - if (aSrc == 255) { - cResult0 = cSrc0; - } else { - - //----- read destination pixel - cDest0 = *destColorPtr; - - //----- result color - cResult0 = div255((255 - aSrc) * cDest0 + aSrc * cSrc0); - } - - //----- write destination pixel - *destColorPtr++ = cResult0; - - cSrcPtr += cSrcStride; - ++shapePtr; - } - - updateModX(lastX); -} - -// special case: -// !pipe->pattern && !pipe->noTransparency && !state->softMask && -// pipe->usesShape && !pipe->alpha0Ptr && !state->blendFunc && -// !pipe->nonIsolatedGroup && -// bitmap->mode == splashModeMono1 && !bitmap->alpha -void Splash::pipeRunAAMono1(SplashPipe *pipe, int x0, int x1, int y, - Guchar *shapePtr, SplashColorPtr cSrcPtr) { - Guchar shape, aSrc, cSrc0, cDest0, cResult0; - SplashColorPtr destColorPtr; - Guchar destColorMask; - SplashScreenCursor screenCursor; - int cSrcStride, x, lastX; - - if (cSrcPtr) { - cSrcStride = 1; - } else { - cSrcPtr = pipe->cSrcVal; - cSrcStride = 0; - } - for (; x0 <= x1; ++x0) { - if (*shapePtr) { - break; - } - cSrcPtr += cSrcStride; - ++shapePtr; - } - if (x0 > x1) { - return; - } - updateModX(x0); - updateModY(y); - lastX = x0; - - useDestRow(y); - - destColorPtr = &bitmap->data[y * bitmap->rowSize + (x0 >> 3)]; - destColorMask = (Guchar)(0x80 >> (x0 & 7)); - - screenCursor = state->screen->getTestCursor(y); - - for (x = x0; x <= x1; ++x) { - - //----- shape - shape = *shapePtr; - if (!shape) { - destColorPtr += destColorMask & 1; - destColorMask = (Guchar)((destColorMask << 7) | (destColorMask >> 1)); - cSrcPtr += cSrcStride; - ++shapePtr; - continue; - } - lastX = x; - - //----- read destination pixel - cDest0 = (*destColorPtr & destColorMask) ? 0xff : 0x00; - - //----- source color - cSrc0 = state->grayTransfer[cSrcPtr[0]]; - - //----- source alpha - aSrc = div255(pipe->aInput * shape); - - //----- result color - // note: aDest = alphaI = aResult = 0xff - cResult0 = (Guchar)div255((0xff - aSrc) * cDest0 + aSrc * cSrc0); - - //----- write destination pixel - if (state->screen->testWithCursor(screenCursor, x, cResult0)) { - *destColorPtr |= destColorMask; - } else { - *destColorPtr &= (Guchar)~destColorMask; - } - destColorPtr += destColorMask & 1; - destColorMask = (Guchar)((destColorMask << 7) | (destColorMask >> 1)); - - cSrcPtr += cSrcStride; - ++shapePtr; - } - - updateModX(lastX); -} - -// special case: -// !pipe->pattern && !pipe->noTransparency && !state->softMask && -// pipe->usesShape && !pipe->alpha0Ptr && !state->blendFunc && -// !pipe->nonIsolatedGroup && -// bitmap->mode == splashModeMono8 && bitmap->alpha -void Splash::pipeRunAAMono8(SplashPipe *pipe, int x0, int x1, int y, - Guchar *shapePtr, SplashColorPtr cSrcPtr) { - Guchar shape, aSrc, aDest, alphaI, aResult, cSrc0, cDest0, cResult0; - SplashColorPtr destColorPtr; - Guchar *destAlphaPtr; - int cSrcStride, x, lastX; - - if (cSrcPtr) { - cSrcStride = 1; - } else { - cSrcPtr = pipe->cSrcVal; - cSrcStride = 0; - } - for (; x0 <= x1; ++x0) { - if (*shapePtr) { - break; - } - cSrcPtr += cSrcStride; - ++shapePtr; - } - if (x0 > x1) { - return; - } - updateModX(x0); - updateModY(y); - lastX = x0; - - useDestRow(y); - - destColorPtr = &bitmap->data[y * bitmap->rowSize + x0]; - destAlphaPtr = &bitmap->alpha[y * bitmap->alphaRowSize + x0]; - - for (x = x0; x <= x1; ++x) { - - //----- shape - shape = *shapePtr; - if (!shape) { - ++destColorPtr; - ++destAlphaPtr; - cSrcPtr += cSrcStride; - ++shapePtr; - continue; - } - lastX = x; - - //----- read destination pixel - cDest0 = *destColorPtr; - aDest = *destAlphaPtr; - - //----- source color - cSrc0 = state->grayTransfer[cSrcPtr[0]]; - - //----- source alpha - aSrc = div255(pipe->aInput * shape); - - //----- result alpha and non-isolated group element correction - aResult = (Guchar)(aSrc + aDest - div255(aSrc * aDest)); - alphaI = aResult; - - //----- result color - if (alphaI == 0) { - cResult0 = 0; - } else { - cResult0 = (Guchar)(((alphaI - aSrc) * cDest0 + aSrc * cSrc0) / alphaI); - } - - //----- write destination pixel - *destColorPtr++ = cResult0; - *destAlphaPtr++ = aResult; - - cSrcPtr += cSrcStride; - ++shapePtr; - } - - updateModX(lastX); -} - -// special case: -// !pipe->pattern && !pipe->noTransparency && !state->softMask && -// pipe->usesShape && !pipe->alpha0Ptr && !state->blendFunc && -// !pipe->nonIsolatedGroup && -// bitmap->mode == splashModeRGB8 && bitmap->alpha -void Splash::pipeRunAARGB8(SplashPipe *pipe, int x0, int x1, int y, - Guchar *shapePtr, SplashColorPtr cSrcPtr) { - Guchar shape, aSrc, aDest, alphaI, aResult; - Guchar cSrc0, cSrc1, cSrc2; - Guchar cDest0, cDest1, cDest2; - Guchar cResult0, cResult1, cResult2; - SplashColorPtr destColorPtr; - Guchar *destAlphaPtr; - int cSrcStride, x, lastX; - - if (cSrcPtr) { - cSrcStride = 3; - } else { - cSrcPtr = pipe->cSrcVal; - cSrcStride = 0; - } - for (; x0 <= x1; ++x0) { - if (*shapePtr) { - break; - } - cSrcPtr += cSrcStride; - ++shapePtr; - } - if (x0 > x1) { - return; - } - updateModX(x0); - updateModY(y); - lastX = x0; - - useDestRow(y); - - destColorPtr = &bitmap->data[y * bitmap->rowSize + 3 * x0]; - destAlphaPtr = &bitmap->alpha[y * bitmap->alphaRowSize + x0]; - - for (x = x0; x <= x1; ++x) { - - //----- shape - shape = *shapePtr; - if (!shape) { - destColorPtr += 3; - ++destAlphaPtr; - cSrcPtr += cSrcStride; - ++shapePtr; - continue; - } - lastX = x; - - //----- read destination pixel - cDest0 = destColorPtr[0]; - cDest1 = destColorPtr[1]; - cDest2 = destColorPtr[2]; - aDest = *destAlphaPtr; - - //----- source color - cSrc0 = state->rgbTransferR[cSrcPtr[0]]; - cSrc1 = state->rgbTransferG[cSrcPtr[1]]; - cSrc2 = state->rgbTransferB[cSrcPtr[2]]; - - //----- source alpha - aSrc = div255(pipe->aInput * shape); - - //----- result alpha and non-isolated group element correction - aResult = (Guchar)(aSrc + aDest - div255(aSrc * aDest)); - alphaI = aResult; - - //----- result color - if (alphaI == 0) { - cResult0 = 0; - cResult1 = 0; - cResult2 = 0; - } else { - cResult0 = (Guchar)(((alphaI - aSrc) * cDest0 + aSrc * cSrc0) / alphaI); - cResult1 = (Guchar)(((alphaI - aSrc) * cDest1 + aSrc * cSrc1) / alphaI); - cResult2 = (Guchar)(((alphaI - aSrc) * cDest2 + aSrc * cSrc2) / alphaI); - } - - //----- write destination pixel - destColorPtr[0] = cResult0; - destColorPtr[1] = cResult1; - destColorPtr[2] = cResult2; - destColorPtr += 3; - *destAlphaPtr++ = aResult; - - cSrcPtr += cSrcStride; - ++shapePtr; - } - - updateModX(lastX); -} - -// special case: -// !pipe->pattern && !pipe->noTransparency && !state->softMask && -// pipe->usesShape && !pipe->alpha0Ptr && !state->blendFunc && -// !pipe->nonIsolatedGroup && -// bitmap->mode == splashModeBGR8 && bitmap->alpha -void Splash::pipeRunAABGR8(SplashPipe *pipe, int x0, int x1, int y, - Guchar *shapePtr, SplashColorPtr cSrcPtr) { - Guchar shape, aSrc, aDest, alphaI, aResult; - Guchar cSrc0, cSrc1, cSrc2; - Guchar cDest0, cDest1, cDest2; - Guchar cResult0, cResult1, cResult2; - SplashColorPtr destColorPtr; - Guchar *destAlphaPtr; - int cSrcStride, x, lastX; - - if (cSrcPtr) { - cSrcStride = 3; - } else { - cSrcPtr = pipe->cSrcVal; - cSrcStride = 0; - } - for (; x0 <= x1; ++x0) { - if (*shapePtr) { - break; - } - cSrcPtr += cSrcStride; - ++shapePtr; - } - if (x0 > x1) { - return; - } - updateModX(x0); - updateModY(y); - lastX = x0; - - useDestRow(y); - - destColorPtr = &bitmap->data[y * bitmap->rowSize + 3 * x0]; - destAlphaPtr = &bitmap->alpha[y * bitmap->alphaRowSize + x0]; - - for (x = x0; x <= x1; ++x) { - - //----- shape - shape = *shapePtr; - if (!shape) { - destColorPtr += 3; - ++destAlphaPtr; - cSrcPtr += cSrcStride; - ++shapePtr; - continue; - } - lastX = x; - - //----- read destination pixel - cDest0 = destColorPtr[2]; - cDest1 = destColorPtr[1]; - cDest2 = destColorPtr[0]; - aDest = *destAlphaPtr; - - //----- source color - cSrc0 = state->rgbTransferR[cSrcPtr[0]]; - cSrc1 = state->rgbTransferG[cSrcPtr[1]]; - cSrc2 = state->rgbTransferB[cSrcPtr[2]]; - - //----- source alpha - aSrc = div255(pipe->aInput * shape); - - //----- result alpha and non-isolated group element correction - aResult = (Guchar)(aSrc + aDest - div255(aSrc * aDest)); - alphaI = aResult; - - //----- result color - if (alphaI == 0) { - cResult0 = 0; - cResult1 = 0; - cResult2 = 0; - } else { - cResult0 = (Guchar)(((alphaI - aSrc) * cDest0 + aSrc * cSrc0) / alphaI); - cResult1 = (Guchar)(((alphaI - aSrc) * cDest1 + aSrc * cSrc1) / alphaI); - cResult2 = (Guchar)(((alphaI - aSrc) * cDest2 + aSrc * cSrc2) / alphaI); - } - - //----- write destination pixel - destColorPtr[0] = cResult2; - destColorPtr[1] = cResult1; - destColorPtr[2] = cResult0; - destColorPtr += 3; - *destAlphaPtr++ = aResult; - - cSrcPtr += cSrcStride; - ++shapePtr; - } - - updateModX(lastX); -} - -#if SPLASH_CMYK -// special case: -// !pipe->pattern && !pipe->noTransparency && !state->softMask && -// pipe->usesShape && !pipe->alpha0Ptr && !state->blendFunc && -// !pipe->nonIsolatedGroup && -// bitmap->mode == splashModeCMYK8 && bitmap->alpha -void Splash::pipeRunAACMYK8(SplashPipe *pipe, int x0, int x1, int y, - Guchar *shapePtr, SplashColorPtr cSrcPtr) { - Guchar shape, aSrc, aDest, alphaI, aResult; - Guchar cSrc0, cSrc1, cSrc2, cSrc3; - Guchar cDest0, cDest1, cDest2, cDest3; - Guchar cResult0, cResult1, cResult2, cResult3; - SplashColorPtr destColorPtr; - Guchar *destAlphaPtr; - int cSrcStride, x, lastX; - - if (cSrcPtr) { - cSrcStride = 4; - } else { - cSrcPtr = pipe->cSrcVal; - cSrcStride = 0; - } - for (; x0 <= x1; ++x0) { - if (*shapePtr) { - break; - } - cSrcPtr += cSrcStride; - ++shapePtr; - } - if (x0 > x1) { - return; - } - updateModX(x0); - updateModY(y); - lastX = x0; - - useDestRow(y); - - destColorPtr = &bitmap->data[y * bitmap->rowSize + 4 * x0]; - destAlphaPtr = &bitmap->alpha[y * bitmap->alphaRowSize + x0]; - - for (x = x0; x <= x1; ++x) { - - //----- shape - shape = *shapePtr; - if (!shape) { - destColorPtr += 4; - ++destAlphaPtr; - cSrcPtr += cSrcStride; - ++shapePtr; - continue; - } - lastX = x; - - //----- read destination pixel - cDest0 = destColorPtr[0]; - cDest1 = destColorPtr[1]; - cDest2 = destColorPtr[2]; - cDest3 = destColorPtr[3]; - aDest = *destAlphaPtr; - - //----- overprint - if (state->overprintMask & 1) { - cSrc0 = state->cmykTransferC[cSrcPtr[0]]; - } else { - cSrc0 = div255(aDest * cDest0); - } - if (state->overprintMask & 2) { - cSrc1 = state->cmykTransferM[cSrcPtr[1]]; - } else { - cSrc1 = div255(aDest * cDest1); - } - if (state->overprintMask & 4) { - cSrc2 = state->cmykTransferY[cSrcPtr[2]]; - } else { - cSrc2 = div255(aDest * cDest2); - } - if (state->overprintMask & 8) { - cSrc3 = state->cmykTransferK[cSrcPtr[3]]; - } else { - cSrc3 = div255(aDest * cDest3); - } - - //----- source alpha - aSrc = div255(pipe->aInput * shape); - - //----- result alpha and non-isolated group element correction - aResult = (Guchar)(aSrc + aDest - div255(aSrc * aDest)); - alphaI = aResult; - - //----- result color - if (alphaI == 0) { - cResult0 = 0; - cResult1 = 0; - cResult2 = 0; - cResult3 = 0; - } else { - cResult0 = (Guchar)(((alphaI - aSrc) * cDest0 + aSrc * cSrc0) / alphaI); - cResult1 = (Guchar)(((alphaI - aSrc) * cDest1 + aSrc * cSrc1) / alphaI); - cResult2 = (Guchar)(((alphaI - aSrc) * cDest2 + aSrc * cSrc2) / alphaI); - cResult3 = (Guchar)(((alphaI - aSrc) * cDest3 + aSrc * cSrc3) / alphaI); - } - - //----- write destination pixel - destColorPtr[0] = cResult0; - destColorPtr[1] = cResult1; - destColorPtr[2] = cResult2; - destColorPtr[3] = cResult3; - destColorPtr += 4; - *destAlphaPtr++ = aResult; - - cSrcPtr += cSrcStride; - ++shapePtr; - } - - updateModX(lastX); -} -#endif - - -// special case: -// !pipe->pattern && aInput == 255 && state->softMask && usesShape && -// !state->inNonIsolatedGroup && !state->inKnockoutGroup && -// !nonIsolatedGroup && state->overprintMask == 0xffffffff && -// !state->blendFunc && -// bitmap->mode == splashModeMono8 && bitmap->alpha -void Splash::pipeRunSoftMaskMono8(SplashPipe *pipe, int x0, int x1, int y, - Guchar *shapePtr, SplashColorPtr cSrcPtr) { - Guchar shape, aSrc, aDest, alphaI, aResult; - Guchar cSrc0, cDest0, cResult0; - SplashColorPtr destColorPtr; - Guchar *destAlphaPtr; - SplashColorPtr softMaskPtr; - int cSrcStride, x, lastX; - - if (cSrcPtr) { - cSrcStride = 1; - } else { - cSrcPtr = pipe->cSrcVal; - cSrcStride = 0; - } - for (; x0 <= x1; ++x0) { - if (*shapePtr) { - break; - } - cSrcPtr += cSrcStride; - ++shapePtr; - } - if (x0 > x1) { - return; - } - updateModX(x0); - updateModY(y); - lastX = x0; - - useDestRow(y); - - destColorPtr = &bitmap->data[y * bitmap->rowSize + x0]; - destAlphaPtr = &bitmap->alpha[y * bitmap->alphaRowSize + x0]; - softMaskPtr = &state->softMask->data[y * state->softMask->rowSize + x0]; - - for (x = x0; x <= x1; ++x) { - - //----- shape - shape = *shapePtr; - if (!shape) { - ++destColorPtr; - ++destAlphaPtr; - ++softMaskPtr; - cSrcPtr += cSrcStride; - ++shapePtr; - continue; - } - lastX = x; - - //----- read source color - cSrc0 = state->grayTransfer[cSrcPtr[0]]; - - //----- source alpha - aSrc = div255(*softMaskPtr++ * shape); - - //----- special case for aSrc = 255 - if (aSrc == 255) { - aResult = 255; - cResult0 = cSrc0; - } else { - - //----- read destination alpha - aDest = *destAlphaPtr; - - //----- special case for aDest = 0 - if (aDest == 0) { - aResult = aSrc; - cResult0 = cSrc0; - } else { - - //----- read destination pixel - cDest0 = destColorPtr[0]; - - //----- result alpha and non-isolated group element correction - aResult = (Guchar)(aSrc + aDest - div255(aSrc * aDest)); - alphaI = aResult; - - //----- result color - cResult0 = (Guchar)(((alphaI - aSrc) * cDest0 + aSrc * cSrc0) / alphaI); - } - } - - //----- write destination pixel - destColorPtr[0] = cResult0; - ++destColorPtr; - *destAlphaPtr++ = aResult; - - cSrcPtr += cSrcStride; - ++shapePtr; - } - - updateModX(lastX); -} - -// special case: -// !pipe->pattern && aInput == 255 && state->softMask && usesShape && -// !state->inNonIsolatedGroup && !state->inKnockoutGroup && -// !nonIsolatedGroup && state->overprintMask == 0xffffffff && -// !state->blendFunc && -// bitmap->mode == splashModeRGB8 && bitmap->alpha -void Splash::pipeRunSoftMaskRGB8(SplashPipe *pipe, int x0, int x1, int y, - Guchar *shapePtr, SplashColorPtr cSrcPtr) { - Guchar shape, aSrc, aDest, alphaI, aResult; - Guchar cSrc0, cSrc1, cSrc2; - Guchar cDest0, cDest1, cDest2; - Guchar cResult0, cResult1, cResult2; - SplashColorPtr destColorPtr; - Guchar *destAlphaPtr; - SplashColorPtr softMaskPtr; - int cSrcStride, x, lastX; - - if (cSrcPtr) { - cSrcStride = 3; - } else { - cSrcPtr = pipe->cSrcVal; - cSrcStride = 0; - } - for (; x0 <= x1; ++x0) { - if (*shapePtr) { - break; - } - cSrcPtr += cSrcStride; - ++shapePtr; - } - if (x0 > x1) { - return; - } - updateModX(x0); - updateModY(y); - lastX = x0; - - useDestRow(y); - - destColorPtr = &bitmap->data[y * bitmap->rowSize + x0 * 3]; - destAlphaPtr = &bitmap->alpha[y * bitmap->alphaRowSize + x0]; - softMaskPtr = &state->softMask->data[y * state->softMask->rowSize + x0]; - - for (x = x0; x <= x1; ++x) { - - //----- shape - shape = *shapePtr; - if (!shape) { - destColorPtr += 3; - ++destAlphaPtr; - ++softMaskPtr; - cSrcPtr += cSrcStride; - ++shapePtr; - continue; - } - lastX = x; - - //----- read source color - cSrc0 = state->rgbTransferR[cSrcPtr[0]]; - cSrc1 = state->rgbTransferG[cSrcPtr[1]]; - cSrc2 = state->rgbTransferB[cSrcPtr[2]]; - - //----- source alpha - aSrc = div255(*softMaskPtr++ * shape); - - //----- special case for aSrc = 255 - if (aSrc == 255) { - aResult = 255; - cResult0 = cSrc0; - cResult1 = cSrc1; - cResult2 = cSrc2; - } else { - - //----- read destination alpha - aDest = *destAlphaPtr; - - //----- special case for aDest = 0 - if (aDest == 0) { - aResult = aSrc; - cResult0 = cSrc0; - cResult1 = cSrc1; - cResult2 = cSrc2; - } else { - - //----- read destination pixel - cDest0 = destColorPtr[0]; - cDest1 = destColorPtr[1]; - cDest2 = destColorPtr[2]; - - //----- result alpha and non-isolated group element correction - aResult = (Guchar)(aSrc + aDest - div255(aSrc * aDest)); - alphaI = aResult; - - //----- result color - cResult0 = (Guchar)(((alphaI - aSrc) * cDest0 + aSrc * cSrc0) / alphaI); - cResult1 = (Guchar)(((alphaI - aSrc) * cDest1 + aSrc * cSrc1) / alphaI); - cResult2 = (Guchar)(((alphaI - aSrc) * cDest2 + aSrc * cSrc2) / alphaI); - } - } - - //----- write destination pixel - destColorPtr[0] = cResult0; - destColorPtr[1] = cResult1; - destColorPtr[2] = cResult2; - destColorPtr += 3; - *destAlphaPtr++ = aResult; - - cSrcPtr += cSrcStride; - ++shapePtr; - } - - updateModX(lastX); -} - -// special case: -// !pipe->pattern && aInput == 255 && state->softMask && usesShape && -// !state->inNonIsolatedGroup && !state->inKnockoutGroup && -// !nonIsolatedGroup && state->overprintMask == 0xffffffff && -// !state->blendFunc && -// bitmap->mode == splashModeBGR8 && bitmap->alpha -void Splash::pipeRunSoftMaskBGR8(SplashPipe *pipe, int x0, int x1, int y, - Guchar *shapePtr, SplashColorPtr cSrcPtr) { - Guchar shape, aSrc, aDest, alphaI, aResult; - Guchar cSrc0, cSrc1, cSrc2; - Guchar cDest0, cDest1, cDest2; - Guchar cResult0, cResult1, cResult2; - SplashColorPtr destColorPtr; - Guchar *destAlphaPtr; - SplashColorPtr softMaskPtr; - int cSrcStride, x, lastX; - - if (cSrcPtr) { - cSrcStride = 3; - } else { - cSrcPtr = pipe->cSrcVal; - cSrcStride = 0; - } - for (; x0 <= x1; ++x0) { - if (*shapePtr) { - break; - } - cSrcPtr += cSrcStride; - ++shapePtr; - } - if (x0 > x1) { - return; - } - updateModX(x0); - updateModY(y); - lastX = x0; - - useDestRow(y); - - destColorPtr = &bitmap->data[y * bitmap->rowSize + x0 * 3]; - destAlphaPtr = &bitmap->alpha[y * bitmap->alphaRowSize + x0]; - softMaskPtr = &state->softMask->data[y * state->softMask->rowSize + x0]; - - for (x = x0; x <= x1; ++x) { - - //----- shape - shape = *shapePtr; - if (!shape) { - destColorPtr += 3; - ++destAlphaPtr; - ++softMaskPtr; - cSrcPtr += cSrcStride; - ++shapePtr; - continue; - } - lastX = x; - - //----- read source color - cSrc0 = state->rgbTransferR[cSrcPtr[0]]; - cSrc1 = state->rgbTransferG[cSrcPtr[1]]; - cSrc2 = state->rgbTransferB[cSrcPtr[2]]; - - //----- source alpha - aSrc = div255(*softMaskPtr++ * shape); - - //----- special case for aSrc = 255 - if (aSrc == 255) { - aResult = 255; - cResult0 = cSrc0; - cResult1 = cSrc1; - cResult2 = cSrc2; - } else { - - //----- read destination alpha - aDest = *destAlphaPtr; - - //----- special case for aDest = 0 - if (aDest == 0) { - aResult = aSrc; - cResult0 = cSrc0; - cResult1 = cSrc1; - cResult2 = cSrc2; - } else { - - //----- read destination pixel - cDest0 = destColorPtr[2]; - cDest1 = destColorPtr[1]; - cDest2 = destColorPtr[0]; - - //----- result alpha and non-isolated group element correction - aResult = (Guchar)(aSrc + aDest - div255(aSrc * aDest)); - alphaI = aResult; - - //----- result color - cResult0 = (Guchar)(((alphaI - aSrc) * cDest0 + aSrc * cSrc0) / alphaI); - cResult1 = (Guchar)(((alphaI - aSrc) * cDest1 + aSrc * cSrc1) / alphaI); - cResult2 = (Guchar)(((alphaI - aSrc) * cDest2 + aSrc * cSrc2) / alphaI); - } - } - - //----- write destination pixel - destColorPtr[2] = cResult0; - destColorPtr[1] = cResult1; - destColorPtr[0] = cResult2; - destColorPtr += 3; - *destAlphaPtr++ = aResult; - - cSrcPtr += cSrcStride; - ++shapePtr; - } - - updateModX(lastX); -} - -#if SPLASH_CMYK -// special case: -// !pipe->pattern && aInput == 255 && state->softMask && usesShape && -// !state->inNonIsolatedGroup && !state->inKnockoutGroup && -// !nonIsolatedGroup && state->overprintMask == 0xffffffff && -// !state->blendFunc && -// bitmap->mode == splashModeCMYK8 && bitmap->alpha -void Splash::pipeRunSoftMaskCMYK8(SplashPipe *pipe, int x0, int x1, int y, - Guchar *shapePtr, SplashColorPtr cSrcPtr) { - Guchar shape, aSrc, aDest, alphaI, aResult; - Guchar cSrc0, cSrc1, cSrc2, cSrc3; - Guchar cDest0, cDest1, cDest2, cDest3; - Guchar cResult0, cResult1, cResult2, cResult3; - SplashColorPtr destColorPtr; - Guchar *destAlphaPtr; - SplashColorPtr softMaskPtr; - int cSrcStride, x, lastX; - - if (cSrcPtr) { - cSrcStride = 4; - } else { - cSrcPtr = pipe->cSrcVal; - cSrcStride = 0; - } - for (; x0 <= x1; ++x0) { - if (*shapePtr) { - break; - } - cSrcPtr += cSrcStride; - ++shapePtr; - } - if (x0 > x1) { - return; - } - updateModX(x0); - updateModY(y); - lastX = x0; - - useDestRow(y); - - destColorPtr = &bitmap->data[y * bitmap->rowSize + x0 * 4]; - destAlphaPtr = &bitmap->alpha[y * bitmap->alphaRowSize + x0]; - softMaskPtr = &state->softMask->data[y * state->softMask->rowSize + x0]; - - for (x = x0; x <= x1; ++x) { - - //----- shape - shape = *shapePtr; - if (!shape) { - destColorPtr += 4; - ++destAlphaPtr; - ++softMaskPtr; - cSrcPtr += cSrcStride; - ++shapePtr; - continue; - } - lastX = x; - - //----- read destination pixel - cDest0 = destColorPtr[0]; - cDest1 = destColorPtr[1]; - cDest2 = destColorPtr[2]; - cDest3 = destColorPtr[3]; - - //----- read destination alpha - aDest = *destAlphaPtr; - - //----- overprint - cSrc0 = state->cmykTransferC[cSrcPtr[0]]; - cSrc1 = state->cmykTransferM[cSrcPtr[1]]; - cSrc2 = state->cmykTransferY[cSrcPtr[2]]; - cSrc3 = state->cmykTransferK[cSrcPtr[3]]; - - //----- source alpha - aSrc = div255(*softMaskPtr++ * shape); - - //----- special case for aSrc = 255 - if (aSrc == 255) { - aResult = 255; - cResult0 = cSrc0; - cResult1 = cSrc1; - cResult2 = cSrc2; - cResult3 = cSrc3; - } else { - - //----- special case for aDest = 0 - if (aDest == 0) { - aResult = aSrc; - cResult0 = cSrc0; - cResult1 = cSrc1; - cResult2 = cSrc2; - cResult3 = cSrc3; - } else { - - //----- result alpha and non-isolated group element correction - aResult = (Guchar)(aSrc + aDest - div255(aSrc * aDest)); - alphaI = aResult; - - //----- result color - cResult0 = (Guchar)(((alphaI - aSrc) * cDest0 + aSrc * cSrc0) / alphaI); - cResult1 = (Guchar)(((alphaI - aSrc) * cDest1 + aSrc * cSrc1) / alphaI); - cResult2 = (Guchar)(((alphaI - aSrc) * cDest2 + aSrc * cSrc2) / alphaI); - cResult3 = (Guchar)(((alphaI - aSrc) * cDest3 + aSrc * cSrc3) / alphaI); - } - } - - //----- write destination pixel - destColorPtr[0] = cResult0; - destColorPtr[1] = cResult1; - destColorPtr[2] = cResult2; - destColorPtr[3] = cResult3; - destColorPtr += 4; - *destAlphaPtr++ = aResult; - - cSrcPtr += cSrcStride; - ++shapePtr; - } - - updateModX(lastX); -} -#endif - - -void Splash::pipeRunNonIsoMono8(SplashPipe *pipe, int x0, int x1, int y, - Guchar *shapePtr, SplashColorPtr cSrcPtr) { - Guchar shape, aSrc, aDest, alphaI, alpha0, aResult; - Guchar cSrc0, cDest0, cResult0; - SplashColorPtr destColorPtr; - Guchar *destAlphaPtr; - Guchar *alpha0Ptr; - int cSrcStride, x, lastX; - - if (cSrcPtr) { - cSrcStride = 1; - } else { - cSrcPtr = pipe->cSrcVal; - cSrcStride = 0; - } - for (; x0 <= x1; ++x0) { - if (*shapePtr) { - break; - } - cSrcPtr += cSrcStride; - ++shapePtr; - } - if (x0 > x1) { - return; - } - updateModX(x0); - updateModY(y); - lastX = x0; - - useDestRow(y); - - destColorPtr = &bitmap->data[y * bitmap->rowSize + x0]; - destAlphaPtr = &bitmap->alpha[y * bitmap->alphaRowSize + x0]; - alpha0Ptr = &groupBackBitmap->alpha[(groupBackY + y) - * groupBackBitmap->alphaRowSize + - (groupBackX + x0)]; - - for (x = x0; x <= x1; ++x) { - - //----- shape - shape = *shapePtr; - if (!shape) { - destColorPtr += 1; - ++destAlphaPtr; - ++alpha0Ptr; - cSrcPtr += cSrcStride; - ++shapePtr; - continue; - } - lastX = x; - - //----- read destination pixel - cDest0 = destColorPtr[0]; - aDest = *destAlphaPtr; - - //----- source color - cSrc0 = state->grayTransfer[cSrcPtr[0]]; - - //----- source alpha - aSrc = div255(pipe->aInput * shape); - - //----- result alpha and non-isolated group element correction - aResult = (Guchar)(aSrc + aDest - div255(aSrc * aDest)); - alpha0 = *alpha0Ptr++; - alphaI = (Guchar)(aResult + alpha0 - div255(aResult * alpha0)); - - //----- result color - if (alphaI == 0) { - cResult0 = 0; - } else { - cResult0 = (Guchar)(((alphaI - aSrc) * cDest0 + aSrc * cSrc0) / alphaI); - } - - //----- write destination pixel - *destColorPtr++ = cResult0; - *destAlphaPtr++ = aResult; - - cSrcPtr += cSrcStride; - ++shapePtr; - } // for (x ...) - - updateModX(lastX); -} - -void Splash::pipeRunNonIsoRGB8(SplashPipe *pipe, int x0, int x1, int y, - Guchar *shapePtr, SplashColorPtr cSrcPtr) { - Guchar shape, aSrc, aDest, alphaI, alpha0, aResult; - Guchar cSrc0, cSrc1, cSrc2; - Guchar cDest0, cDest1, cDest2; - Guchar cResult0, cResult1, cResult2; - SplashColorPtr destColorPtr; - Guchar *destAlphaPtr; - Guchar *alpha0Ptr; - int cSrcStride, x, lastX; - - if (cSrcPtr) { - cSrcStride = 3; - } else { - cSrcPtr = pipe->cSrcVal; - cSrcStride = 0; - } - for (; x0 <= x1; ++x0) { - if (*shapePtr) { - break; - } - cSrcPtr += cSrcStride; - ++shapePtr; - } - if (x0 > x1) { - return; - } - updateModX(x0); - updateModY(y); - lastX = x0; - - useDestRow(y); - - destColorPtr = &bitmap->data[y * bitmap->rowSize + x0 * 3]; - destAlphaPtr = &bitmap->alpha[y * bitmap->alphaRowSize + x0]; - alpha0Ptr = &groupBackBitmap->alpha[(groupBackY + y) - * groupBackBitmap->alphaRowSize + - (groupBackX + x0)]; - - for (x = x0; x <= x1; ++x) { - - //----- shape - shape = *shapePtr; - if (!shape) { - destColorPtr += 3; - ++destAlphaPtr; - ++alpha0Ptr; - cSrcPtr += cSrcStride; - ++shapePtr; - continue; - } - lastX = x; - - //----- read destination pixel - cDest0 = destColorPtr[0]; - cDest1 = destColorPtr[1]; - cDest2 = destColorPtr[2]; - aDest = *destAlphaPtr; - - //----- source color - cSrc0 = state->rgbTransferR[cSrcPtr[0]]; - cSrc1 = state->rgbTransferG[cSrcPtr[1]]; - cSrc2 = state->rgbTransferB[cSrcPtr[2]]; - - //----- source alpha - aSrc = div255(pipe->aInput * shape); - - //----- result alpha and non-isolated group element correction - aResult = (Guchar)(aSrc + aDest - div255(aSrc * aDest)); - alpha0 = *alpha0Ptr++; - alphaI = (Guchar)(aResult + alpha0 - div255(aResult * alpha0)); - - //----- result color - if (alphaI == 0) { - cResult0 = 0; - cResult1 = 0; - cResult2 = 0; - } else { - cResult0 = (Guchar)(((alphaI - aSrc) * cDest0 + aSrc * cSrc0) / alphaI); - cResult1 = (Guchar)(((alphaI - aSrc) * cDest1 + aSrc * cSrc1) / alphaI); - cResult2 = (Guchar)(((alphaI - aSrc) * cDest2 + aSrc * cSrc2) / alphaI); - } - - //----- write destination pixel - destColorPtr[0] = cResult0; - destColorPtr[1] = cResult1; - destColorPtr[2] = cResult2; - destColorPtr += 3; - *destAlphaPtr++ = aResult; - - cSrcPtr += cSrcStride; - ++shapePtr; - } // for (x ...) - - updateModX(lastX); -} - -void Splash::pipeRunNonIsoBGR8(SplashPipe *pipe, int x0, int x1, int y, - Guchar *shapePtr, SplashColorPtr cSrcPtr) { - Guchar shape, aSrc, aDest, alphaI, alpha0, aResult; - Guchar cSrc0, cSrc1, cSrc2; - Guchar cDest0, cDest1, cDest2; - Guchar cResult0, cResult1, cResult2; - SplashColorPtr destColorPtr; - Guchar *destAlphaPtr; - Guchar *alpha0Ptr; - int cSrcStride, x, lastX; - - if (cSrcPtr) { - cSrcStride = 3; - } else { - cSrcPtr = pipe->cSrcVal; - cSrcStride = 0; - } - for (; x0 <= x1; ++x0) { - if (*shapePtr) { - break; - } - cSrcPtr += cSrcStride; - ++shapePtr; - } - if (x0 > x1) { - return; - } - updateModX(x0); - updateModY(y); - lastX = x0; - - useDestRow(y); - - destColorPtr = &bitmap->data[y * bitmap->rowSize + x0 * 3]; - destAlphaPtr = &bitmap->alpha[y * bitmap->alphaRowSize + x0]; - alpha0Ptr = &groupBackBitmap->alpha[(groupBackY + y) - * groupBackBitmap->alphaRowSize + - (groupBackX + x0)]; - - for (x = x0; x <= x1; ++x) { - - //----- shape - shape = *shapePtr; - if (!shape) { - destColorPtr += 3; - ++destAlphaPtr; - ++alpha0Ptr; - cSrcPtr += cSrcStride; - ++shapePtr; - continue; - } - lastX = x; - - //----- read destination pixel - cDest0 = destColorPtr[2]; - cDest1 = destColorPtr[1]; - cDest2 = destColorPtr[0]; - aDest = *destAlphaPtr; - - //----- source color - cSrc0 = state->rgbTransferR[cSrcPtr[0]]; - cSrc1 = state->rgbTransferG[cSrcPtr[1]]; - cSrc2 = state->rgbTransferB[cSrcPtr[2]]; - - //----- source alpha - aSrc = div255(pipe->aInput * shape); - - //----- result alpha and non-isolated group element correction - aResult = (Guchar)(aSrc + aDest - div255(aSrc * aDest)); - alpha0 = *alpha0Ptr++; - alphaI = (Guchar)(aResult + alpha0 - div255(aResult * alpha0)); - - //----- result color - if (alphaI == 0) { - cResult0 = 0; - cResult1 = 0; - cResult2 = 0; - } else { - cResult0 = (Guchar)(((alphaI - aSrc) * cDest0 + aSrc * cSrc0) / alphaI); - cResult1 = (Guchar)(((alphaI - aSrc) * cDest1 + aSrc * cSrc1) / alphaI); - cResult2 = (Guchar)(((alphaI - aSrc) * cDest2 + aSrc * cSrc2) / alphaI); - } - - //----- write destination pixel - destColorPtr[0] = cResult2; - destColorPtr[1] = cResult1; - destColorPtr[2] = cResult0; - destColorPtr += 3; - *destAlphaPtr++ = aResult; - - cSrcPtr += cSrcStride; - ++shapePtr; - } // for (x ...) - - updateModX(lastX); -} - -#if SPLASH_CMYK -void Splash::pipeRunNonIsoCMYK8(SplashPipe *pipe, int x0, int x1, int y, - Guchar *shapePtr, SplashColorPtr cSrcPtr) { - Guchar shape, aSrc, aDest, alphaI, alpha0, aResult, aPrev; - Guchar cSrc0, cSrc1, cSrc2, cSrc3; - Guchar cDest0, cDest1, cDest2, cDest3; - Guchar cResult0, cResult1, cResult2, cResult3; - SplashColorPtr destColorPtr; - Guchar *destAlphaPtr; - Guchar *alpha0Ptr; - int cSrcStride, x, lastX; - - if (cSrcPtr) { - cSrcStride = 4; - } else { - cSrcPtr = pipe->cSrcVal; - cSrcStride = 0; - } - for (; x0 <= x1; ++x0) { - if (*shapePtr) { - break; - } - cSrcPtr += cSrcStride; - ++shapePtr; - } - if (x0 > x1) { - return; - } - updateModX(x0); - updateModY(y); - lastX = x0; - - useDestRow(y); - - destColorPtr = &bitmap->data[y * bitmap->rowSize + x0 * 4]; - destAlphaPtr = &bitmap->alpha[y * bitmap->alphaRowSize + x0]; - alpha0Ptr = &groupBackBitmap->alpha[(groupBackY + y) - * groupBackBitmap->alphaRowSize + - (groupBackX + x0)]; - - for (x = x0; x <= x1; ++x) { - - //----- shape - shape = *shapePtr; - if (!shape) { - destColorPtr += 4; - ++destAlphaPtr; - ++alpha0Ptr; - cSrcPtr += cSrcStride; - ++shapePtr; - continue; - } - lastX = x; - - //----- read destination pixel - cDest0 = destColorPtr[0]; - cDest1 = destColorPtr[1]; - cDest2 = destColorPtr[2]; - cDest3 = destColorPtr[3]; - aDest = *destAlphaPtr; - - //----- overprint - aPrev = (Guchar)(*alpha0Ptr + aDest - div255(*alpha0Ptr * aDest)); - if (state->overprintMask & 0x01) { - cSrc0 = state->cmykTransferC[cSrcPtr[0]]; - } else { - cSrc0 = div255(aPrev * cDest0); - } - if (state->overprintMask & 0x02) { - cSrc1 = state->cmykTransferM[cSrcPtr[1]]; - } else { - cSrc1 = div255(aPrev * cDest1); - } - if (state->overprintMask & 0x04) { - cSrc2 = state->cmykTransferY[cSrcPtr[2]]; - } else { - cSrc2 = div255(aPrev * cDest2); - } - if (state->overprintMask & 0x08) { - cSrc3 = state->cmykTransferK[cSrcPtr[3]]; - } else { - cSrc3 = div255(aPrev * cDest3); - } - - //----- source alpha - aSrc = div255(pipe->aInput * shape); - - //----- result alpha and non-isolated group element correction - aResult = (Guchar)(aSrc + aDest - div255(aSrc * aDest)); - alpha0 = *alpha0Ptr++; - alphaI = (Guchar)(aResult + alpha0 - div255(aResult * alpha0)); - - //----- result color - if (alphaI == 0) { - cResult0 = 0; - cResult1 = 0; - cResult2 = 0; - cResult3 = 0; - } else { - cResult0 = (Guchar)(((alphaI - aSrc) * cDest0 + aSrc * cSrc0) / alphaI); - cResult1 = (Guchar)(((alphaI - aSrc) * cDest1 + aSrc * cSrc1) / alphaI); - cResult2 = (Guchar)(((alphaI - aSrc) * cDest2 + aSrc * cSrc2) / alphaI); - cResult3 = (Guchar)(((alphaI - aSrc) * cDest3 + aSrc * cSrc3) / alphaI); - } - - //----- write destination pixel - destColorPtr[0] = cResult0; - destColorPtr[1] = cResult1; - destColorPtr[2] = cResult2; - destColorPtr[3] = cResult3; - destColorPtr += 4; - *destAlphaPtr++ = aResult; - - cSrcPtr += cSrcStride; - ++shapePtr; - } // for (x ...) - - updateModX(lastX); -} -#endif - - -void Splash::useDestRow(int y) { - int y0, y1, yy; - - if (groupDestInitMode == splashGroupDestPreInit) { - return; - } - if (groupDestInitYMin > groupDestInitYMax) { - y0 = y1 = y; - groupDestInitYMin = groupDestInitYMax = y; - } else if (y < groupDestInitYMin) { - y0 = y; - y1 = groupDestInitYMin - 1; - groupDestInitYMin = y; - } else if (y > groupDestInitYMax) { - y0 = groupDestInitYMax + 1; - y1 = y; - groupDestInitYMax = y; - } else { - return; - } - for (yy = y0; yy <= y1; ++yy) { - if (groupDestInitMode == splashGroupDestInitZero) { - // same as clear(color=0, alpha=0) - memset(bitmap->data + bitmap->rowSize * yy, 0, - bitmap->rowSize < 0 ? -bitmap->rowSize : bitmap->rowSize); - if (bitmap->alpha) { - memset(bitmap->alpha + bitmap->alphaRowSize * yy, 0, - bitmap->alphaRowSize); - } - } else { // (groupDestInitMode == splashGroupDestInitCopy) - // same as blitTransparent - copyGroupBackdropRow(yy); - } - } -} - -void Splash::copyGroupBackdropRow(int y) { - SplashColorPtr p, q; - Guchar mask, srcMask; - int x; - - if (groupBackBitmap->mode != bitmap->mode) { - return; - } - - if (bitmap->mode == splashModeMono1) { - p = &bitmap->data[y * bitmap->rowSize]; - mask = (Guchar)0x80; - q = &groupBackBitmap->data[(groupBackY + y) * groupBackBitmap->rowSize - + (groupBackX >> 3)]; - srcMask = (Guchar)(0x80 >> (groupBackX & 7)); - for (x = 0; x < bitmap->width; ++x) { - if (*q & srcMask) { - *p |= mask; - } else { - *p &= (Guchar)~mask; - } - if (!(mask = (Guchar)(mask >> 1))) { - mask = 0x80; - ++p; - } - if (!(srcMask = (Guchar)(srcMask >> 1))) { - srcMask = 0x80; - ++q; - } - } - } else { - p = &bitmap->data[y * bitmap->rowSize]; - q = &groupBackBitmap->data[(groupBackY + y) * groupBackBitmap->rowSize - + bitmapComps * groupBackX]; - memcpy(p, q, bitmapComps * bitmap->width); - } - - if (bitmap->alpha) { - memset(&bitmap->alpha[y * bitmap->alphaRowSize], 0, bitmap->width); - } -} - -//------------------------------------------------------------------------ - -// Transform a point from user space to device space. -inline void Splash::transform(SplashCoord *matrix, - SplashCoord xi, SplashCoord yi, - SplashCoord *xo, SplashCoord *yo) { - // [ m[0] m[1] 0 ] - // [xo yo 1] = [xi yi 1] * [ m[2] m[3] 0 ] - // [ m[4] m[5] 1 ] - *xo = xi * matrix[0] + yi * matrix[2] + matrix[4]; - *yo = xi * matrix[1] + yi * matrix[3] + matrix[5]; -} - -//------------------------------------------------------------------------ -// SplashImageCache -//------------------------------------------------------------------------ - -SplashImageCache::SplashImageCache() { - tag = NULL; - width = 0; - height = 0; - mode = splashModeRGB8; - alpha = gFalse; - interpolate = gFalse; - colorData = NULL; - alphaData = NULL; - refCount = 1; -} - -SplashImageCache::~SplashImageCache() { - if (tag) { - delete tag; - } - gfree(colorData); - gfree(alphaData); -} - -GBool SplashImageCache::match(GString *aTag, int aWidth, int aHeight, - SplashColorMode aMode, GBool aAlpha, - GBool aInterpolate) { - return aTag && tag && !aTag->cmp(tag) && - aWidth == width && aHeight == height && - aMode == mode && aAlpha == alpha && - aInterpolate == interpolate; -} - -void SplashImageCache::reset(GString *aTag, int aWidth, int aHeight, - SplashColorMode aMode, GBool aAlpha, - GBool aInterpolate) { - if (tag) { - delete tag; - } - if (aTag) { - tag = aTag->copy(); - } else { - tag = NULL; - } - width = aWidth; - height = aHeight; - mode = aMode; - alpha = aAlpha; - interpolate = aInterpolate; - gfree(colorData); - colorData = NULL; - gfree(alphaData); - alphaData = NULL; -} - -void SplashImageCache::incRefCount() { - ++refCount; -} - -void SplashImageCache::decRefCount() { - --refCount; - if (refCount == 0) { - delete this; - } -} - -//------------------------------------------------------------------------ -// ImageScaler -//------------------------------------------------------------------------ - -// Abstract base class. -class ImageScaler { -public: - - ImageScaler() {} - virtual ~ImageScaler() {} - - // Compute the next line of the scaled image. This can be called up - // to [scaledHeight] times. - virtual void nextLine() = 0; - - // Retrieve the color and alpha data generated by the most recent - // call to nextLine(). - virtual Guchar *colorData() = 0; - virtual Guchar *alphaData() = 0; -}; - -//------------------------------------------------------------------------ -// BasicImageScaler -//------------------------------------------------------------------------ - -// The actual image scaler. -class BasicImageScaler: public ImageScaler { -public: - - BasicImageScaler(SplashImageSource aSrc, void *aSrcData, - int aSrcWidth, int aSrcHeight, int aNComps, GBool aHasAlpha, - int aScaledWidth, int aScaledHeight, GBool aInterpolate); - virtual ~BasicImageScaler(); - virtual void nextLine(); - virtual Guchar *colorData() { return colorLine; } - virtual Guchar *alphaData() { return alphaLine; } - -protected: - - void vertDownscaleHorizDownscale(); - void vertDownscaleHorizUpscaleNoInterp(); - void vertDownscaleHorizUpscaleInterp(); - void vertUpscaleHorizDownscaleNoInterp(); - void vertUpscaleHorizDownscaleInterp(); - void vertUpscaleHorizUpscaleNoInterp(); - void vertUpscaleHorizUpscaleInterp(); - - // source image data function - SplashImageSource src; - void *srcData; - - // source image size - int srcWidth; - int srcHeight; - - // scaled image size - int scaledWidth; - int scaledHeight; - - // number of color and alpha components - int nComps; - GBool hasAlpha; - - // params/state for vertical scaling - int yp, yq; - int yt, yn; - int ySrcCur, yScaledCur; - SplashCoord yInvScale; - - // params for horizontal scaling - int xp, xq; - SplashCoord xInvScale; - - // scaling function - void (BasicImageScaler::*scalingFunc)(); - - // temporary buffers for vertical scaling - Guchar *colorTmpBuf0; - Guchar *colorTmpBuf1; - Guchar *colorTmpBuf2; - Guchar *alphaTmpBuf0; - Guchar *alphaTmpBuf1; - Guchar *alphaTmpBuf2; - Guint *colorAccBuf; - Guint *alphaAccBuf; - - // output of horizontal scaling - Guchar *colorLine; - Guchar *alphaLine; -}; - -BasicImageScaler::BasicImageScaler(SplashImageSource aSrc, void *aSrcData, - int aSrcWidth, int aSrcHeight, - int aNComps, GBool aHasAlpha, - int aScaledWidth, int aScaledHeight, - GBool aInterpolate) { - colorTmpBuf0 = NULL; - colorTmpBuf1 = NULL; - colorTmpBuf2 = NULL; - alphaTmpBuf0 = NULL; - alphaTmpBuf1 = NULL; - alphaTmpBuf2 = NULL; - colorAccBuf = NULL; - alphaAccBuf = NULL; - colorLine = NULL; - alphaLine = NULL; - - src = aSrc; - srcData = aSrcData; - srcWidth = aSrcWidth; - srcHeight = aSrcHeight; - scaledWidth = aScaledWidth; - scaledHeight = aScaledHeight; - nComps = aNComps; - hasAlpha = aHasAlpha; - - // select scaling function; allocate buffers - if (scaledHeight <= srcHeight) { - // vertical downscaling - yp = srcHeight / scaledHeight; - yq = srcHeight % scaledHeight; - yt = 0; - colorTmpBuf0 = (Guchar *)gmallocn(srcWidth, nComps); - colorAccBuf = (Guint *)gmallocn(srcWidth, nComps * (int)sizeof(Guint)); - if (hasAlpha) { - alphaTmpBuf0 = (Guchar *)gmalloc(srcWidth); - alphaAccBuf = (Guint *)gmallocn(srcWidth, sizeof(Guint)); - } - if (scaledWidth <= srcWidth) { - scalingFunc = &BasicImageScaler::vertDownscaleHorizDownscale; - } else { - if (aInterpolate) { - scalingFunc = &BasicImageScaler::vertDownscaleHorizUpscaleInterp; - } else { - scalingFunc = &BasicImageScaler::vertDownscaleHorizUpscaleNoInterp; - } - } - } else { - // vertical upscaling - yp = scaledHeight / srcHeight; - yq = scaledHeight % srcHeight; - yt = 0; - yn = 0; - if (aInterpolate) { - yInvScale = (SplashCoord)srcHeight / (SplashCoord)scaledHeight; - colorTmpBuf0 = (Guchar *)gmallocn(srcWidth, nComps); - colorTmpBuf1 = (Guchar *)gmallocn(srcWidth, nComps); - if (hasAlpha) { - alphaTmpBuf0 = (Guchar *)gmalloc(srcWidth); - alphaTmpBuf1 = (Guchar *)gmalloc(srcWidth); - } - ySrcCur = 0; - yScaledCur = 0; - if (scaledWidth <= srcWidth) { - scalingFunc = &BasicImageScaler::vertUpscaleHorizDownscaleInterp; - } else { - colorTmpBuf2 = (Guchar *)gmallocn(srcWidth, nComps); - if (hasAlpha) { - alphaTmpBuf2 = (Guchar *)gmalloc(srcWidth); - } - scalingFunc = &BasicImageScaler::vertUpscaleHorizUpscaleInterp; - } - } else { - colorTmpBuf0 = (Guchar *)gmallocn(srcWidth, nComps); - if (hasAlpha) { - alphaTmpBuf0 = (Guchar *)gmalloc(srcWidth); - } - if (scaledWidth <= srcWidth) { - scalingFunc = &BasicImageScaler::vertUpscaleHorizDownscaleNoInterp; - } else { - scalingFunc = &BasicImageScaler::vertUpscaleHorizUpscaleNoInterp; - } - } - } - if (scaledWidth <= srcWidth) { - xp = srcWidth / scaledWidth; - xq = srcWidth % scaledWidth; - } else { - xp = scaledWidth / srcWidth; - xq = scaledWidth % srcWidth; - if (aInterpolate) { - xInvScale = (SplashCoord)srcWidth / (SplashCoord)scaledWidth; - } - } - colorLine = (Guchar *)gmallocn(scaledWidth, nComps); - if (hasAlpha) { - alphaLine = (Guchar *)gmalloc(scaledWidth); - } -} - -BasicImageScaler::~BasicImageScaler() { - gfree(colorTmpBuf0); - gfree(colorTmpBuf1); - gfree(colorTmpBuf2); - gfree(alphaTmpBuf0); - gfree(alphaTmpBuf1); - gfree(alphaTmpBuf2); - gfree(colorAccBuf); - gfree(alphaAccBuf); - gfree(colorLine); - gfree(alphaLine); -} - -void BasicImageScaler::nextLine() { - (this->*scalingFunc)(); -} - -void BasicImageScaler::vertDownscaleHorizDownscale() { - //--- vert downscale - int yStep = yp; - yt += yq; - if (yt >= scaledHeight) { - yt -= scaledHeight; - ++yStep; - } - memset(colorAccBuf, 0, (srcWidth * nComps) * sizeof(Guint)); - if (hasAlpha) { - memset(alphaAccBuf, 0, srcWidth * sizeof(Guint)); - } - int nRowComps = srcWidth * nComps; - for (int i = 0; i < yStep; ++i) { - (*src)(srcData, colorTmpBuf0, alphaTmpBuf0); - for (int j = 0; j < nRowComps; ++j) { - colorAccBuf[j] += colorTmpBuf0[j]; - } - if (hasAlpha) { - for (int j = 0; j < srcWidth; ++j) { - alphaAccBuf[j] += alphaTmpBuf0[j]; - } - } - } - - //--- horiz downscale - int colorAcc[splashMaxColorComps]; - int xt = 0; - int unscaledColorIdx = 0; - int unscaledAlphaIdx = 0; - int scaledColorIdx = 0; - - for (int scaledIdx = 0; scaledIdx < scaledWidth; ++scaledIdx) { - int xStep = xp; - xt += xq; - if (xt >= scaledWidth) { - xt -= scaledWidth; - ++xStep; - } - - for (int j = 0; j < nComps; ++j) { - colorAcc[j] = 0; - } - for (int i = 0; i < xStep; ++i) { - for (int j = 0; j < nComps; ++j) { - colorAcc[j] += colorAccBuf[unscaledColorIdx + j]; - } - unscaledColorIdx += nComps; - } - int nPixels = yStep * xStep; - for (int j = 0; j < nComps; ++j) { - colorLine[scaledColorIdx + j] = (Guchar)(colorAcc[j] / nPixels); - } - scaledColorIdx += nComps; - - if (hasAlpha) { - int alphaAcc = 0; - for (int i = 0; i < xStep; ++i) { - alphaAcc += alphaAccBuf[unscaledAlphaIdx]; - ++unscaledAlphaIdx; - } - alphaLine[scaledIdx] = (Guchar)(alphaAcc / nPixels); - } - } -} - -void BasicImageScaler::vertDownscaleHorizUpscaleNoInterp() { - //--- vert downscale - int yStep = yp; - yt += yq; - if (yt >= scaledHeight) { - yt -= scaledHeight; - ++yStep; - } - memset(colorAccBuf, 0, (srcWidth * nComps) * sizeof(Guint)); - if (hasAlpha) { - memset(alphaAccBuf, 0, srcWidth * sizeof(Guint)); - } - int nRowComps = srcWidth * nComps; - for (int i = 0; i < yStep; ++i) { - (*src)(srcData, colorTmpBuf0, alphaTmpBuf0); - for (int j = 0; j < nRowComps; ++j) { - colorAccBuf[j] += colorTmpBuf0[j]; - } - if (hasAlpha) { - for (int j = 0; j < srcWidth; ++j) { - alphaAccBuf[j] += alphaTmpBuf0[j]; - } - } - } - - //--- horiz upscale - Guchar colorBuf[splashMaxColorComps]; - int xt = 0; - int scaledColorIdx = 0; - int srcColorIdx = 0; - int scaledAlphaIdx = 0; - for (int srcIdx = 0; srcIdx < srcWidth; ++srcIdx) { - int xStep = xp; - xt += xq; - if (xt >= srcWidth) { - xt -= srcWidth; - ++xStep; - } - for (int j = 0; j < nComps; ++j) { - colorBuf[j] = (Guchar)(colorAccBuf[srcColorIdx + j] / yStep); - } - srcColorIdx += nComps; - for (int i = 0; i < xStep; ++i) { - for (int j = 0; j < nComps; ++j) { - colorLine[scaledColorIdx + j] = colorBuf[j]; - } - scaledColorIdx += nComps; - } - if (hasAlpha) { - Guchar alphaBuf = (Guchar)(alphaAccBuf[srcIdx] / yStep); - for (int i = 0; i < xStep; ++i) { - alphaLine[scaledAlphaIdx] = alphaBuf; - ++scaledAlphaIdx; - } - } - } -} - -void BasicImageScaler::vertDownscaleHorizUpscaleInterp() { - //--- vert downscale - int yStep = yp; - yt += yq; - if (yt >= scaledHeight) { - yt -= scaledHeight; - ++yStep; - } - memset(colorAccBuf, 0, (srcWidth * nComps) * sizeof(Guint)); - if (hasAlpha) { - memset(alphaAccBuf, 0, srcWidth * sizeof(Guint)); - } - int nRowComps = srcWidth * nComps; - for (int i = 0; i < yStep; ++i) { - (*src)(srcData, colorTmpBuf0, alphaTmpBuf0); - for (int j = 0; j < nRowComps; ++j) { - colorAccBuf[j] += colorTmpBuf0[j]; - } - if (hasAlpha) { - for (int j = 0; j < srcWidth; ++j) { - alphaAccBuf[j] += alphaTmpBuf0[j]; - } - } - } - for (int j = 0; j < srcWidth * nComps; ++j) { - colorAccBuf[j] /= yStep; - } - if (hasAlpha) { - for (int j = 0; j < srcWidth; ++j) { - alphaAccBuf[j] /= yStep; - } - } - - //--- horiz upscale - int scaledColorIdx = 0; - for (int scaledIdx = 0; scaledIdx < scaledWidth; ++scaledIdx) { - SplashCoord xs = ((SplashCoord)scaledIdx + 0.5) * xInvScale; - int x0 = splashFloor(xs - 0.5); - int x1 = x0 + 1; - SplashCoord s0 = (SplashCoord)x1 + 0.5 - xs; - SplashCoord s1 = (SplashCoord)1 - s0; - if (x0 < 0) { - x0 = 0; - } - if (x1 >= srcWidth) { - x1 = srcWidth - 1; - } - for (int j = 0; j < nComps; ++j) { - colorLine[scaledColorIdx + j] = - (Guchar)(int)(s0 * colorAccBuf[x0 * nComps + j] + - s1 * colorAccBuf[x1 * nComps + j]); - } - scaledColorIdx += nComps; - if (hasAlpha) { - alphaLine[scaledIdx] = (Guchar)(int)(s0 * alphaAccBuf[x0] + - s1 * alphaAccBuf[x1]); - } - } -} - -void BasicImageScaler::vertUpscaleHorizDownscaleNoInterp() { - //--- vert upscale - if (yn == 0) { - yn = yp; - yt += yq; - if (yt >= srcHeight) { - yt -= srcHeight; - ++yn; - } - (*src)(srcData, colorTmpBuf0, alphaTmpBuf0); - } - --yn; - - //--- horiz downscale - int colorAcc[splashMaxColorComps]; - int xt = 0; - int unscaledColorIdx = 0; - int unscaledAlphaIdx = 0; - int scaledColorIdx = 0; - for (int scaledIdx = 0; scaledIdx < scaledWidth; ++scaledIdx) { - int xStep = xp; - xt += xq; - if (xt >= scaledWidth) { - xt -= scaledWidth; - ++xStep; - } - - for (int j = 0; j < nComps; ++j) { - colorAcc[j] = 0; - } - for (int i = 0; i < xStep; ++i) { - for (int j = 0; j < nComps; ++j) { - colorAcc[j] += colorTmpBuf0[unscaledColorIdx + j]; - } - unscaledColorIdx += nComps; - } - for (int j = 0; j < nComps; ++j) { - colorLine[scaledColorIdx + j] = (Guchar)(colorAcc[j] / xStep); - } - scaledColorIdx += nComps; - - if (hasAlpha) { - int alphaAcc = 0; - for (int i = 0; i < xStep; ++i) { - alphaAcc += alphaTmpBuf0[unscaledAlphaIdx]; - ++unscaledAlphaIdx; - } - alphaLine[scaledIdx] = (Guchar)(alphaAcc / xStep); - } - } -} - -void BasicImageScaler::vertUpscaleHorizDownscaleInterp() { - //--- vert upscale - if (ySrcCur == 0) { - (*src)(srcData, colorTmpBuf0, alphaTmpBuf0); - (*src)(srcData, colorTmpBuf1, alphaTmpBuf1); - ySrcCur = 1; - } - SplashCoord ys = ((SplashCoord)yScaledCur + 0.5) * yInvScale; - int y0 = splashFloor(ys - 0.5); - int y1 = y0 + 1; - SplashCoord vs0 = (SplashCoord)y1 + 0.5 - ys; - SplashCoord vs1 = (SplashCoord)1 - vs0; - if (y1 > ySrcCur && ySrcCur < srcHeight - 1) { - Guchar *t = colorTmpBuf0; - colorTmpBuf0 = colorTmpBuf1; - colorTmpBuf1 = t; - if (hasAlpha) { - t = alphaTmpBuf0; - alphaTmpBuf0 = alphaTmpBuf1; - alphaTmpBuf1 = t; - } - (*src)(srcData, colorTmpBuf1, alphaTmpBuf1); - ++ySrcCur; - } - Guchar *color0 = colorTmpBuf0; - Guchar *color1 = colorTmpBuf1; - Guchar *alpha0 = alphaTmpBuf0; - Guchar *alpha1 = alphaTmpBuf1; - if (y0 < 0) { - y0 = 0; - color1 = color0; - alpha1 = alpha0; - } - if (y1 >= srcHeight) { - y1 = srcHeight - 1; - color0 = color1; - alpha0 = alpha1; - } - ++yScaledCur; - - //--- horiz downscale - int colorAcc[splashMaxColorComps]; - int xt = 0; - int unscaledColorIdx = 0; - int unscaledAlphaIdx = 0; - int scaledColorIdx = 0; - for (int scaledIdx = 0; scaledIdx < scaledWidth; ++scaledIdx) { - int xStep = xp; - xt += xq; - if (xt >= scaledWidth) { - xt -= scaledWidth; - ++xStep; - } - - for (int j = 0; j < nComps; ++j) { - colorAcc[j] = 0; - } - for (int i = 0; i < xStep; ++i) { - for (int j = 0; j < nComps; ++j) { - colorAcc[j] += (int)(vs0 * (int)color0[unscaledColorIdx + j] + - vs1 * (int)color1[unscaledColorIdx + j]); - } - unscaledColorIdx += nComps; - } - for (int j = 0; j < nComps; ++j) { - colorLine[scaledColorIdx + j] = (Guchar)(colorAcc[j] / xStep); - } - scaledColorIdx += nComps; - - if (hasAlpha) { - int alphaAcc = 0; - for (int i = 0; i < xStep; ++i) { - alphaAcc += (int)(vs0 * (int)alpha0[unscaledAlphaIdx] + - vs1 * (int)alpha1[unscaledAlphaIdx]); - ++unscaledAlphaIdx; - } - alphaLine[scaledIdx] = (Guchar)(alphaAcc / xStep); - } - } -} - -void BasicImageScaler::vertUpscaleHorizUpscaleNoInterp() { - //--- vert upscale - if (yn == 0) { - yn = yp; - yt += yq; - if (yt >= srcHeight) { - yt -= srcHeight; - ++yn; - } - (*src)(srcData, colorTmpBuf0, alphaTmpBuf0); - } - --yn; - - //--- horiz upscale - int xt = 0; - int scaledColorIdx = 0; - int srcColorIdx = 0; - int scaledAlphaIdx = 0; - for (int srcIdx = 0; srcIdx < srcWidth; ++srcIdx) { - int xStep = xp; - xt += xq; - if (xt >= srcWidth) { - xt -= srcWidth; - ++xStep; - } - for (int i = 0; i < xStep; ++i) { - for (int j = 0; j < nComps; ++j) { - colorLine[scaledColorIdx + j] = colorTmpBuf0[srcColorIdx + j]; - } - scaledColorIdx += nComps; - } - srcColorIdx += nComps; - if (hasAlpha) { - Guchar alphaBuf = alphaTmpBuf0[srcIdx]; - for (int i = 0; i < xStep; ++i) { - alphaLine[scaledAlphaIdx] = alphaBuf; - ++scaledAlphaIdx; - } - } - } -} - -void BasicImageScaler::vertUpscaleHorizUpscaleInterp() { - //--- vert upscale - if (ySrcCur == 0) { - (*src)(srcData, colorTmpBuf0, alphaTmpBuf0); - (*src)(srcData, colorTmpBuf1, alphaTmpBuf1); - ySrcCur = 1; - } - SplashCoord ys = ((SplashCoord)yScaledCur + 0.5) * yInvScale; - int y0 = splashFloor(ys - 0.5); - int y1 = y0 + 1; - SplashCoord vs0 = (SplashCoord)y1 + 0.5 - ys; - SplashCoord vs1 = (SplashCoord)1 - vs0; - if (y1 > ySrcCur && ySrcCur < srcHeight - 1) { - Guchar *t = colorTmpBuf0; - colorTmpBuf0 = colorTmpBuf1; - colorTmpBuf1 = t; - if (hasAlpha) { - t = alphaTmpBuf0; - alphaTmpBuf0 = alphaTmpBuf1; - alphaTmpBuf1 = t; - } - (*src)(srcData, colorTmpBuf1, alphaTmpBuf1); - ++ySrcCur; - } - Guchar *color0 = colorTmpBuf0; - Guchar *color1 = colorTmpBuf1; - Guchar *alpha0 = alphaTmpBuf0; - Guchar *alpha1 = alphaTmpBuf1; - if (y0 < 0) { - y0 = 0; - color1 = color0; - alpha1 = alpha0; - } - if (y1 >= srcHeight) { - y1 = srcHeight - 1; - color0 = color1; - alpha0 = alpha1; - } - ++yScaledCur; - for (int srcIdx = 0; srcIdx < srcWidth * nComps; ++srcIdx) { - colorTmpBuf2[srcIdx] = (Guchar)(int)(vs0 * (int)color0[srcIdx] + - vs1 * (int)color1[srcIdx]); - } - if (hasAlpha) { - for (int srcIdx = 0; srcIdx < srcWidth; ++srcIdx) { - alphaTmpBuf2[srcIdx] = (Guchar)(int)(vs0 * (int)alpha0[srcIdx] + - vs1 * (int)alpha1[srcIdx]); - } - } - - //--- horiz upscale - int scaledColorIdx = 0; - for (int scaledIdx = 0; scaledIdx < scaledWidth; ++scaledIdx) { - SplashCoord xs = ((SplashCoord)scaledIdx + 0.5) * xInvScale; - int x0 = splashFloor(xs - 0.5); - int x1 = x0 + 1; - SplashCoord hs0 = (SplashCoord)x1 + 0.5 - xs; - SplashCoord hs1 = (SplashCoord)1 - hs0; - if (x0 < 0) { - x0 = 0; - } - if (x1 >= srcWidth) { - x1 = srcWidth - 1; - } - for (int j = 0; j < nComps; ++j) { - colorLine[scaledColorIdx + j] = - (Guchar)(int)(hs0 * (int)colorTmpBuf2[x0 * nComps + j] + - hs1 * (int)colorTmpBuf2[x1 * nComps + j]); - } - scaledColorIdx += nComps; - if (hasAlpha) { - alphaLine[scaledIdx] = (Guchar)(int)(hs0 * (int)alphaTmpBuf2[x0] + - hs1 * (int)alphaTmpBuf2[x1]); - } - } -} - -//------------------------------------------------------------------------ -// SavingImageScaler -//------------------------------------------------------------------------ - -// Wrapper around BasicImageScaler that saves the scaled image for use -// by ReplayImageScaler. -class SavingImageScaler: public BasicImageScaler { -public: - - SavingImageScaler(SplashImageSource aSrc, void *aSrcData, - int aSrcWidth, int aSrcHeight, int aNComps, GBool aHasAlpha, - int aScaledWidth, int aScaledHeight, GBool aInterpolate, - Guchar *aColorCache, Guchar *aAlphaCache); - virtual void nextLine(); - -private: - - Guchar *colorPtr; - Guchar *alphaPtr; -}; - -SavingImageScaler::SavingImageScaler(SplashImageSource aSrc, void *aSrcData, - int aSrcWidth, int aSrcHeight, - int aNComps, GBool aHasAlpha, - int aScaledWidth, int aScaledHeight, - GBool aInterpolate, - Guchar *aColorCache, Guchar *aAlphaCache): - BasicImageScaler(aSrc, aSrcData, aSrcWidth, aSrcHeight, aNComps, aHasAlpha, - aScaledWidth, aScaledHeight, aInterpolate) -{ - colorPtr = aColorCache; - alphaPtr = aAlphaCache; -} - -void SavingImageScaler::nextLine() { - BasicImageScaler::nextLine(); - memcpy(colorPtr, colorData(), scaledWidth * nComps); - colorPtr += scaledWidth * nComps; - if (hasAlpha) { - memcpy(alphaPtr, alphaData(), scaledWidth); - alphaPtr += scaledWidth; - } -} - -//------------------------------------------------------------------------ -// ReplayImageScaler -//------------------------------------------------------------------------ - -// "Replay" a scaled image saved by SavingImageScaler. -class ReplayImageScaler: public ImageScaler { -public: - - ReplayImageScaler(int aNComps, GBool aHasAlpha, - int aScaledWidth, - Guchar *aColorCache, Guchar *aAlphaCache); - virtual void nextLine(); - virtual Guchar *colorData() { return colorLine; } - virtual Guchar *alphaData() { return alphaLine; } - -private: - - int nComps; - GBool hasAlpha; - int scaledWidth; - Guchar *colorPtr; - Guchar *alphaPtr; - Guchar *colorLine; - Guchar *alphaLine; -}; - -ReplayImageScaler::ReplayImageScaler(int aNComps, GBool aHasAlpha, - int aScaledWidth, - Guchar *aColorCache, Guchar *aAlphaCache) { - nComps = aNComps; - hasAlpha = aHasAlpha; - scaledWidth = aScaledWidth; - colorPtr = aColorCache; - alphaPtr = aAlphaCache; - colorLine = NULL; - alphaLine = NULL; -} - -void ReplayImageScaler::nextLine() { - colorLine = colorPtr; - alphaLine = alphaPtr; - colorPtr += scaledWidth * nComps; - if (hasAlpha) { - alphaPtr += scaledWidth; - } -} - -//------------------------------------------------------------------------ -// ImageMaskScaler -//------------------------------------------------------------------------ - -class ImageMaskScaler { -public: - - // Set up a MaskScaler to scale from [srcWidth]x[srcHeight] to - // [scaledWidth]x[scaledHeight]. - ImageMaskScaler(SplashImageMaskSource aSrc, void *aSrcData, - int aSrcWidth, int aSrcHeight, - int aScaledWidth, int aScaledHeight, GBool aInterpolate); - - ~ImageMaskScaler(); - - // Compute the next line of the scaled image mask. This can be - // called up to [scaledHeight] times. - void nextLine(); - - // Retrieve the data generated by the most recent call to - // nextLine(). - Guchar *data() { return line; } - -private: - - void vertDownscaleHorizDownscale(); - void vertDownscaleHorizUpscaleNoInterp(); - void vertDownscaleHorizUpscaleInterp(); - void vertUpscaleHorizDownscaleNoInterp(); - void vertUpscaleHorizDownscaleInterp(); - void vertUpscaleHorizUpscaleNoInterp(); - void vertUpscaleHorizUpscaleInterp(); - - // source image data function - SplashImageMaskSource src; - void *srcData; - - // source image size - int srcWidth; - int srcHeight; - - // scaled image size - int scaledWidth; - int scaledHeight; - - // params/state for vertical scaling - int yp, yq; - int yt, yn; - int ySrcCur, yScaledCur; - SplashCoord yInvScale; - - // params for horizontal scaling - int xp, xq; - SplashCoord xInvScale; - - // vertical and horizontal scaling functions - void (ImageMaskScaler::*scalingFunc)(); - - // temporary buffers for vertical scaling - Guchar *tmpBuf0; - Guchar *tmpBuf1; - Guchar *tmpBuf2; - Guint *accBuf; - - // output of horizontal scaling - Guchar *line; -}; - -ImageMaskScaler::ImageMaskScaler(SplashImageMaskSource aSrc, void *aSrcData, - int aSrcWidth, int aSrcHeight, - int aScaledWidth, int aScaledHeight, - GBool aInterpolate) { - tmpBuf0 = NULL; - tmpBuf1 = NULL; - tmpBuf2 = NULL; - accBuf = NULL; - line = NULL; - - src = aSrc; - srcData = aSrcData; - srcWidth = aSrcWidth; - srcHeight = aSrcHeight; - scaledWidth = aScaledWidth; - scaledHeight = aScaledHeight; - - // select scaling function; allocate buffers - if (scaledHeight <= srcHeight) { - // vertical downscaling - yp = srcHeight / scaledHeight; - yq = srcHeight % scaledHeight; - yt = 0; - tmpBuf0 = (Guchar *)gmalloc(srcWidth); - accBuf = (Guint *)gmallocn(srcWidth, sizeof(Guint)); - if (scaledWidth <= srcWidth) { - scalingFunc = &ImageMaskScaler::vertDownscaleHorizDownscale; - } else { - if (aInterpolate) { - scalingFunc = &ImageMaskScaler::vertDownscaleHorizUpscaleInterp; - } else { - scalingFunc = &ImageMaskScaler::vertDownscaleHorizUpscaleNoInterp; - } - } - } else { - // vertical upscaling - yp = scaledHeight / srcHeight; - yq = scaledHeight % srcHeight; - yt = 0; - yn = 0; - if (aInterpolate) { - yInvScale = (SplashCoord)srcHeight / (SplashCoord)scaledHeight; - tmpBuf0 = (Guchar *)gmalloc(srcWidth); - tmpBuf1 = (Guchar *)gmalloc(srcWidth); - ySrcCur = 0; - yScaledCur = 0; - if (scaledWidth <= srcWidth) { - scalingFunc = &ImageMaskScaler::vertUpscaleHorizDownscaleInterp; - } else { - tmpBuf2 = (Guchar *)gmalloc(srcWidth); - scalingFunc = &ImageMaskScaler::vertUpscaleHorizUpscaleInterp; - } - } else { - tmpBuf0 = (Guchar *)gmalloc(srcWidth); - if (scaledWidth <= srcWidth) { - scalingFunc = &ImageMaskScaler::vertUpscaleHorizDownscaleNoInterp; - } else { - scalingFunc = &ImageMaskScaler::vertUpscaleHorizUpscaleNoInterp; - } - } - } - if (scaledWidth <= srcWidth) { - xp = srcWidth / scaledWidth; - xq = srcWidth % scaledWidth; - } else { - xp = scaledWidth / srcWidth; - xq = scaledWidth % srcWidth; - if (aInterpolate) { - xInvScale = (SplashCoord)srcWidth / (SplashCoord)scaledWidth; - } - } - line = (Guchar *)gmalloc(scaledWidth); -} - -ImageMaskScaler::~ImageMaskScaler() { - gfree(tmpBuf0); - gfree(tmpBuf1); - gfree(tmpBuf2); - gfree(accBuf); - gfree(line); -} - -void ImageMaskScaler::nextLine() { - (this->*scalingFunc)(); -} - -void ImageMaskScaler::vertDownscaleHorizDownscale() { - //--- vert downscale - int yStep = yp; - yt += yq; - if (yt >= scaledHeight) { - yt -= scaledHeight; - ++yStep; - } - memset(accBuf, 0, srcWidth * sizeof(Guint)); - for (int i = 0; i < yStep; ++i) { - (*src)(srcData, tmpBuf0); - for (int j = 0; j < srcWidth; ++j) { - accBuf[j] += tmpBuf0[j]; - } - } - - //--- horiz downscale - int acc; - int xt = 0; - int unscaledIdx = 0; - for (int scaledIdx = 0; scaledIdx < scaledWidth; ++scaledIdx) { - int xStep = xp; - xt += xq; - if (xt >= scaledWidth) { - xt -= scaledWidth; - ++xStep; - } - - acc = 0; - for (int i = 0; i < xStep; ++i) { - acc += accBuf[unscaledIdx]; - ++unscaledIdx; - } - line[scaledIdx] = (Guchar)((255 * acc) / (xStep * yStep)); - } -} - -void ImageMaskScaler::vertDownscaleHorizUpscaleNoInterp() { - //--- vert downscale - int yStep = yp; - yt += yq; - if (yt >= scaledHeight) { - yt -= scaledHeight; - ++yStep; - } - memset(accBuf, 0, srcWidth * sizeof(Guint)); - for (int i = 0; i < yStep; ++i) { - (*src)(srcData, tmpBuf0); - for (int j = 0; j < srcWidth; ++j) { - accBuf[j] += tmpBuf0[j]; - } - } - - //--- horiz upscale - int xt = 0; - int scaledIdx = 0; - for (int srcIdx = 0; srcIdx < srcWidth; ++srcIdx) { - int xStep = xp; - xt += xq; - if (xt >= srcWidth) { - xt -= srcWidth; - ++xStep; - } - Guchar buf = (Guchar)((255 * accBuf[srcIdx]) / yStep); - for (int i = 0; i < xStep; ++i) { - line[scaledIdx] = buf; - ++scaledIdx; - } - } -} - -void ImageMaskScaler::vertDownscaleHorizUpscaleInterp() { - //--- vert downscale - int yStep = yp; - yt += yq; - if (yt >= scaledHeight) { - yt -= scaledHeight; - ++yStep; - } - memset(accBuf, 0, srcWidth * sizeof(Guint)); - for (int i = 0; i < yStep; ++i) { - (*src)(srcData, tmpBuf0); - for (int j = 0; j < srcWidth; ++j) { - accBuf[j] += tmpBuf0[j]; - } - } - for (int j = 0; j < srcWidth; ++j) { - accBuf[j] = (255 * accBuf[j]) / yStep; - } - - //--- horiz upscale - for (int scaledIdx = 0; scaledIdx < scaledWidth; ++scaledIdx) { - SplashCoord xs = ((SplashCoord)scaledIdx + 0.5) * xInvScale; - int x0 = splashFloor(xs - 0.5); - int x1 = x0 + 1; - SplashCoord s0 = (SplashCoord)x1 + 0.5 - xs; - SplashCoord s1 = (SplashCoord)1 - s0; - if (x0 < 0) { - x0 = 0; - } - if (x1 >= srcWidth) { - x1 = srcWidth - 1; - } - line[scaledIdx] = (Guchar)(int)(s0 * accBuf[x0] + s1 * accBuf[x1]); - } -} - -void ImageMaskScaler::vertUpscaleHorizDownscaleNoInterp() { - //--- vert upscale - if (yn == 0) { - yn = yp; - yt += yq; - if (yt >= srcHeight) { - yt -= srcHeight; - ++yn; - } - (*src)(srcData, tmpBuf0); - } - --yn; - - //--- horiz downscale - int acc; - int xt = 0; - int unscaledIdx = 0; - for (int scaledIdx = 0; scaledIdx < scaledWidth; ++scaledIdx) { - int xStep = xp; - xt += xq; - if (xt >= scaledWidth) { - xt -= scaledWidth; - ++xStep; - } - - acc = 0; - for (int i = 0; i < xStep; ++i) { - acc += tmpBuf0[unscaledIdx]; - ++unscaledIdx; - } - line[scaledIdx] = (Guchar)((255 * acc) / xStep); - } -} - -void ImageMaskScaler::vertUpscaleHorizDownscaleInterp() { - //--- vert upscale - if (ySrcCur == 0) { - (*src)(srcData, tmpBuf0); - (*src)(srcData, tmpBuf1); - ySrcCur = 1; - } - SplashCoord ys = ((SplashCoord)yScaledCur + 0.5) * yInvScale; - int y0 = splashFloor(ys - 0.5); - int y1 = y0 + 1; - SplashCoord vs0 = (SplashCoord)y1 + 0.5 - ys; - SplashCoord vs1 = (SplashCoord)1 - vs0; - if (y1 > ySrcCur && ySrcCur < srcHeight - 1) { - Guchar *t = tmpBuf0; - tmpBuf0 = tmpBuf1; - tmpBuf1 = t; - (*src)(srcData, tmpBuf1); - ++ySrcCur; - } - Guchar *mask0 = tmpBuf0; - Guchar *mask1 = tmpBuf1; - if (y0 < 0) { - y0 = 0; - mask1 = mask0; - } - if (y1 >= srcHeight) { - y1 = srcHeight - 1; - mask0 = mask1; - } - ++yScaledCur; - - //--- horiz downscale - int acc; - int xt = 0; - int unscaledIdx = 0; - for (int scaledIdx = 0; scaledIdx < scaledWidth; ++scaledIdx) { - int xStep = xp; - xt += xq; - if (xt >= scaledWidth) { - xt -= scaledWidth; - ++xStep; - } - - acc = 0; - for (int i = 0; i < xStep; ++i) { - acc += (int)(vs0 * (int)mask0[unscaledIdx] + - vs1 * (int)mask1[unscaledIdx]); - ++unscaledIdx; - } - line[scaledIdx] = (Guchar)((255 * acc) / xStep); - } -} - -void ImageMaskScaler::vertUpscaleHorizUpscaleNoInterp() { - //--- vert upscale - if (yn == 0) { - yn = yp; - yt += yq; - if (yt >= srcHeight) { - yt -= srcHeight; - ++yn; - } - (*src)(srcData, tmpBuf0); - } - --yn; - - //--- horiz upscale - int xt = 0; - int scaledIdx = 0; - for (int srcIdx = 0; srcIdx < srcWidth; ++srcIdx) { - int xStep = xp; - xt += xq; - if (xt >= srcWidth) { - xt -= srcWidth; - ++xStep; - } - Guchar buf = (Guchar)(255 * tmpBuf0[srcIdx]); - for (int i = 0; i < xStep; ++i) { - line[scaledIdx] = buf; - ++scaledIdx; - } - } -} - -void ImageMaskScaler::vertUpscaleHorizUpscaleInterp() { - //--- vert upscale - if (ySrcCur == 0) { - (*src)(srcData, tmpBuf0); - (*src)(srcData, tmpBuf1); - ySrcCur = 1; - } - SplashCoord ys = ((SplashCoord)yScaledCur + 0.5) * yInvScale; - int y0 = splashFloor(ys - 0.5); - int y1 = y0 + 1; - SplashCoord vs0 = (SplashCoord)255 * ((SplashCoord)y1 + 0.5 - ys); - SplashCoord vs1 = (SplashCoord)255 - vs0; - if (y1 > ySrcCur && ySrcCur < srcHeight - 1) { - Guchar *t = tmpBuf0; - tmpBuf0 = tmpBuf1; - tmpBuf1 = t; - (*src)(srcData, tmpBuf1); - ++ySrcCur; - } - Guchar *mask0 = tmpBuf0; - Guchar *mask1 = tmpBuf1; - if (y0 < 0) { - y0 = 0; - mask1 = mask0; - } - if (y1 >= srcHeight) { - y1 = srcHeight - 1; - mask0 = mask1; - } - ++yScaledCur; - for (int srcIdx = 0; srcIdx < srcWidth; ++srcIdx) { - tmpBuf2[srcIdx] = (Guchar)(int)(vs0 * (int)mask0[srcIdx] + - vs1 * (int)mask1[srcIdx]); - } - - //--- horiz upscale - for (int scaledIdx = 0; scaledIdx < scaledWidth; ++scaledIdx) { - SplashCoord xs = ((SplashCoord)scaledIdx + 0.5) * xInvScale; - int x0 = splashFloor(xs - 0.5); - int x1 = x0 + 1; - SplashCoord hs0 = (SplashCoord)x1 + 0.5 - xs; - SplashCoord hs1 = (SplashCoord)1 - hs0; - if (x0 < 0) { - x0 = 0; - } - if (x1 >= srcWidth) { - x1 = srcWidth - 1; - } - line[scaledIdx] = (Guchar)(int)(hs0 * (int)tmpBuf2[x0] + - hs1 * (int)tmpBuf2[x1]); - } -} - -//------------------------------------------------------------------------ -// Splash -//------------------------------------------------------------------------ - -Splash::Splash(SplashBitmap *bitmapA, GBool vectorAntialiasA, - SplashImageCache *imageCacheA, - SplashScreenParams *screenParams) { - bitmap = bitmapA; - bitmapComps = splashColorModeNComps[bitmap->mode]; - vectorAntialias = vectorAntialiasA; - inShading = gFalse; - state = new SplashState(bitmap->width, bitmap->height, vectorAntialias, - screenParams); - scanBuf = (Guchar *)gmalloc(bitmap->width); - if (bitmap->mode == splashModeMono1) { - scanBuf2 = (Guchar *)gmalloc(bitmap->width); - } else { - scanBuf2 = NULL; - } - groupBackBitmap = NULL; - groupDestInitMode = splashGroupDestPreInit; - overprintMaskBitmap = NULL; - minLineWidth = 0; - clearModRegion(); - debugMode = gFalse; - - if (imageCacheA) { - imageCache = imageCacheA; - imageCache->incRefCount(); - } else { - imageCache = new SplashImageCache(); - } -} - -Splash::Splash(SplashBitmap *bitmapA, GBool vectorAntialiasA, - SplashImageCache *imageCacheA, SplashScreen *screenA) { - bitmap = bitmapA; - bitmapComps = splashColorModeNComps[bitmap->mode]; - vectorAntialias = vectorAntialiasA; - inShading = gFalse; - state = new SplashState(bitmap->width, bitmap->height, vectorAntialias, - screenA); - scanBuf = (Guchar *)gmalloc(bitmap->width); - if (bitmap->mode == splashModeMono1) { - scanBuf2 = (Guchar *)gmalloc(bitmap->width); - } else { - scanBuf2 = NULL; - } - groupBackBitmap = NULL; - groupDestInitMode = splashGroupDestPreInit; - overprintMaskBitmap = NULL; - minLineWidth = 0; - clearModRegion(); - debugMode = gFalse; - - if (imageCacheA) { - imageCache = imageCacheA; - imageCache->incRefCount(); - } else { - imageCache = new SplashImageCache(); - } -} - -Splash::~Splash() { - imageCache->decRefCount(); - - while (state->next) { - restoreState(); - } - delete state; - gfree(scanBuf); - gfree(scanBuf2); -} - -//------------------------------------------------------------------------ -// state read -//------------------------------------------------------------------------ - -SplashCoord *Splash::getMatrix() { - return state->matrix; -} - -SplashPattern *Splash::getStrokePattern() { - return state->strokePattern; -} - -SplashPattern *Splash::getFillPattern() { - return state->fillPattern; -} - -SplashScreen *Splash::getScreen() { - return state->screen; -} - -SplashBlendFunc Splash::getBlendFunc() { - return state->blendFunc; -} - -SplashCoord Splash::getStrokeAlpha() { - return state->strokeAlpha; -} - -SplashCoord Splash::getFillAlpha() { - return state->fillAlpha; -} - -SplashCoord Splash::getLineWidth() { - return state->lineWidth; -} - -int Splash::getLineCap() { - return state->lineCap; -} - -int Splash::getLineJoin() { - return state->lineJoin; -} - -SplashCoord Splash::getMiterLimit() { - return state->miterLimit; -} - -SplashCoord Splash::getFlatness() { - return state->flatness; -} - -SplashCoord *Splash::getLineDash() { - return state->lineDash; -} - -int Splash::getLineDashLength() { - return state->lineDashLength; -} - -SplashCoord Splash::getLineDashPhase() { - return state->lineDashPhase; -} - -SplashStrokeAdjustMode Splash::getStrokeAdjust() { - return state->strokeAdjust; -} - -SplashClip *Splash::getClip() { - return state->clip; -} - -SplashBitmap *Splash::getSoftMask() { - return state->softMask; -} - -GBool Splash::getInNonIsolatedGroup() { - return state->inNonIsolatedGroup; -} - -GBool Splash::getInKnockoutGroup() { - return state->inKnockoutGroup; -} - -//------------------------------------------------------------------------ -// state write -//------------------------------------------------------------------------ - -void Splash::setMatrix(SplashCoord *matrix) { - memcpy(state->matrix, matrix, 6 * sizeof(SplashCoord)); -} - -void Splash::setStrokePattern(SplashPattern *strokePattern) { - state->setStrokePattern(strokePattern); -} - -void Splash::setFillPattern(SplashPattern *fillPattern) { - state->setFillPattern(fillPattern); -} - -void Splash::setScreen(SplashScreen *screen) { - state->setScreen(screen); -} - -void Splash::setBlendFunc(SplashBlendFunc func) { - state->blendFunc = func; -} - -void Splash::setStrokeAlpha(SplashCoord alpha) { - state->strokeAlpha = alpha; -} - -void Splash::setFillAlpha(SplashCoord alpha) { - state->fillAlpha = alpha; -} - -void Splash::setLineWidth(SplashCoord lineWidth) { - state->lineWidth = lineWidth; -} - -void Splash::setLineCap(int lineCap) { - if (lineCap >= 0 && lineCap <= 2) { - state->lineCap = lineCap; - } else { - state->lineCap = 0; - } -} - -void Splash::setLineJoin(int lineJoin) { - if (lineJoin >= 0 && lineJoin <= 2) { - state->lineJoin = lineJoin; - } else { - state->lineJoin = 0; - } -} - -void Splash::setMiterLimit(SplashCoord miterLimit) { - state->miterLimit = miterLimit; -} - -void Splash::setFlatness(SplashCoord flatness) { - if (flatness < 1) { - state->flatness = 1; - } else { - state->flatness = flatness; - } -} - -void Splash::setLineDash(SplashCoord *lineDash, int lineDashLength, - SplashCoord lineDashPhase) { - state->setLineDash(lineDash, lineDashLength, lineDashPhase); -} - -void Splash::setStrokeAdjust(SplashStrokeAdjustMode strokeAdjust) { - state->strokeAdjust = strokeAdjust; -} - -void Splash::clipResetToRect(SplashCoord x0, SplashCoord y0, - SplashCoord x1, SplashCoord y1) { - state->clipResetToRect(x0, y0, x1, y1); -} - -SplashError Splash::clipToRect(SplashCoord x0, SplashCoord y0, - SplashCoord x1, SplashCoord y1) { - return state->clipToRect(x0, y0, x1, y1); -} - -SplashError Splash::clipToPath(SplashPath *path, GBool eo) { - return state->clipToPath(path, eo); -} - -void Splash::setSoftMask(SplashBitmap *softMask) { - state->setSoftMask(softMask); -} - -void Splash::setInTransparencyGroup(SplashBitmap *groupBackBitmapA, - int groupBackXA, int groupBackYA, - SplashGroupDestInitMode groupDestInitModeA, - GBool nonIsolated, GBool knockout) { - groupBackBitmap = groupBackBitmapA; - groupBackX = groupBackXA; - groupBackY = groupBackYA; - groupDestInitMode = groupDestInitModeA; - groupDestInitYMin = 1; - groupDestInitYMax = 0; - state->inNonIsolatedGroup = nonIsolated; - state->inKnockoutGroup = knockout; -} - -void Splash::forceDeferredInit(int y, int h) { - useDestRow(y); - useDestRow(y + h - 1); -} - -void Splash::setTransfer(Guchar *red, Guchar *green, Guchar *blue, - Guchar *gray) { - state->setTransfer(red, green, blue, gray); -} - -void Splash::setOverprintMask(Guint overprintMask) { - state->overprintMask = overprintMask; -} - - -void Splash::setEnablePathSimplification(GBool en) { - state->enablePathSimplification = en; -} - -//------------------------------------------------------------------------ -// state save/restore -//------------------------------------------------------------------------ - -void Splash::saveState() { - SplashState *newState; - - newState = state->copy(); - newState->next = state; - state = newState; -} - -SplashError Splash::restoreState() { - SplashState *oldState; - - if (!state->next) { - return splashErrNoSave; - } - oldState = state; - state = state->next; - delete oldState; - return splashOk; -} - -//------------------------------------------------------------------------ -// drawing operations -//------------------------------------------------------------------------ - -void Splash::clear(SplashColorPtr color, Guchar alpha) { - SplashColorPtr row, p; - Guchar mono; - int x, y; - - switch (bitmap->mode) { - case splashModeMono1: - mono = (color[0] & 0x80) ? 0xff : 0x00; - if (bitmap->rowSize < 0) { - memset(bitmap->data + bitmap->rowSize * (bitmap->height - 1), - mono, -bitmap->rowSize * bitmap->height); - } else { - memset(bitmap->data, mono, bitmap->rowSize * bitmap->height); - } - break; - case splashModeMono8: - if (bitmap->rowSize < 0) { - memset(bitmap->data + bitmap->rowSize * (bitmap->height - 1), - color[0], -bitmap->rowSize * bitmap->height); - } else { - memset(bitmap->data, color[0], bitmap->rowSize * bitmap->height); - } - break; - case splashModeRGB8: - if (color[0] == color[1] && color[1] == color[2]) { - if (bitmap->rowSize < 0) { - memset(bitmap->data + bitmap->rowSize * (bitmap->height - 1), - color[0], -bitmap->rowSize * bitmap->height); - } else { - memset(bitmap->data, color[0], bitmap->rowSize * bitmap->height); - } - } else { - row = bitmap->data; - for (y = 0; y < bitmap->height; ++y) { - p = row; - for (x = 0; x < bitmap->width; ++x) { - *p++ = color[0]; - *p++ = color[1]; - *p++ = color[2]; - } - row += bitmap->rowSize; - } - } - break; - case splashModeBGR8: - if (color[0] == color[1] && color[1] == color[2]) { - if (bitmap->rowSize < 0) { - memset(bitmap->data + bitmap->rowSize * (bitmap->height - 1), - color[0], -bitmap->rowSize * bitmap->height); - } else { - memset(bitmap->data, color[0], bitmap->rowSize * bitmap->height); - } - } else { - row = bitmap->data; - for (y = 0; y < bitmap->height; ++y) { - p = row; - for (x = 0; x < bitmap->width; ++x) { - *p++ = color[2]; - *p++ = color[1]; - *p++ = color[0]; - } - row += bitmap->rowSize; - } - } - break; -#if SPLASH_CMYK - case splashModeCMYK8: - if (color[0] == color[1] && color[1] == color[2] && color[2] == color[3]) { - if (bitmap->rowSize < 0) { - memset(bitmap->data + bitmap->rowSize * (bitmap->height - 1), - color[0], -bitmap->rowSize * bitmap->height); - } else { - memset(bitmap->data, color[0], bitmap->rowSize * bitmap->height); - } - } else { - row = bitmap->data; - for (y = 0; y < bitmap->height; ++y) { - p = row; - for (x = 0; x < bitmap->width; ++x) { - *p++ = color[0]; - *p++ = color[1]; - *p++ = color[2]; - *p++ = color[3]; - } - row += bitmap->rowSize; - } - } - break; -#endif - } - - if (bitmap->alpha) { - memset(bitmap->alpha, alpha, bitmap->alphaRowSize * bitmap->height); - } - - updateModX(0); - updateModY(0); - updateModX(bitmap->width - 1); - updateModY(bitmap->height - 1); -} - -SplashError Splash::stroke(SplashPath *path) { - SplashPath *path2, *dPath; - SplashCoord t0, t1, t2, t3, w, w2, lineDashMax, lineDashTotal; - int lineCap, lineJoin, i; - - if (debugMode) { - printf("stroke [dash:%d] [width:%.2f]:\n", - state->lineDashLength, (double)state->lineWidth); - dumpPath(path); - } - opClipRes = splashClipAllOutside; - if (path->length == 0) { - return splashErrEmptyPath; - } - path2 = flattenPath(path, state->matrix, state->flatness); - - // Compute an approximation of the transformed line width. - // Given a CTM of [m0 m1], - // [m2 m3] - // if |m0|*|m3| >= |m1|*|m2| then use min{|m0|,|m3|}, else - // use min{|m1|,|m2|}. - // This handles the common cases -- [s 0 ] and [0 s] -- - // [0 +/-s] [+/-s 0] - // well, and still does something reasonable for the uncommon - // case transforms. - t0 = splashAbs(state->matrix[0]); - t1 = splashAbs(state->matrix[1]); - t2 = splashAbs(state->matrix[2]); - t3 = splashAbs(state->matrix[3]); - if (t0 * t3 >= t1 * t2) { - w = (t0 < t3) ? t0 : t3; - } else { - w = (t1 < t2) ? t1 : t2; - } - w2 = w * state->lineWidth; - - // construct the dashed path - if (state->lineDashLength > 0) { - - // check the maximum transformed dash element length (using the - // same approximation as for line width) -- if it's less than 0.1 - // pixel, don't apply the dash pattern; this avoids a huge - // performance/memory hit with PDF files that use absurd dash - // patterns like [0.0007 0.0003] - lineDashTotal = 0; - lineDashMax = 0; - for (i = 0; i < state->lineDashLength; ++i) { - lineDashTotal += state->lineDash[i]; - if (state->lineDash[i] > lineDashMax) { - lineDashMax = state->lineDash[i]; - } - } - // Acrobat simply draws nothing if the dash array is [0] - if (lineDashTotal == 0) { - delete path2; - return splashOk; - } - if (w * lineDashMax > 0.1) { - - dPath = makeDashedPath(path2); - delete path2; - path2 = dPath; - if (path2->length == 0) { - delete path2; - return splashErrEmptyPath; - } - } - } - - // round caps on narrow lines look bad, and can't be - // stroke-adjusted, so use projecting caps instead (but we can't do - // this if there are zero-length dashes or segments, because those - // turn into round dots) - lineCap = state->lineCap; - lineJoin = state->lineJoin; - if (state->strokeAdjust == splashStrokeAdjustCAD && - w2 < 3.5) { - if (lineCap == splashLineCapRound && - !state->lineDashContainsZeroLengthDashes() && - !path->containsZeroLengthSubpaths()) { - lineCap = splashLineCapProjecting; - } - if (lineJoin == splashLineJoinRound) { - lineJoin = splashLineJoinBevel; - } - } - - // if there is a min line width set, and the transformed line width - // is smaller, use the min line width - if (w > 0 && w2 < minLineWidth) { - strokeWide(path2, minLineWidth / w, splashLineCapButt, splashLineJoinBevel); - } else if (bitmap->mode == splashModeMono1 || !vectorAntialias) { - // in monochrome mode or if antialiasing is disabled, use 0-width - // lines for any transformed line width <= 1 -- lines less than 1 - // pixel wide look too fat without antialiasing - if (w2 < 1.001) { - strokeNarrow(path2); - } else { - strokeWide(path2, state->lineWidth, lineCap, lineJoin); - } - } else { - // in gray and color modes, only use 0-width lines if the line - // width is explicitly set to 0 - if (state->lineWidth == 0) { - strokeNarrow(path2); - } else { - strokeWide(path2, state->lineWidth, lineCap, lineJoin); - } - } - - delete path2; - return splashOk; -} - -void Splash::strokeNarrow(SplashPath *path) { - SplashPipe pipe; - SplashXPath *xPath; - SplashXPathSeg *seg; - int x0, x1, y0, y1, xa, xb, y; - SplashCoord dxdy; - SplashClipResult clipRes; - int nClipRes[3]; - int i; - - nClipRes[0] = nClipRes[1] = nClipRes[2] = 0; - - xPath = new SplashXPath(path, state->matrix, state->flatness, gFalse, - state->enablePathSimplification, - state->strokeAdjust); - - pipeInit(&pipe, state->strokePattern, - (Guchar)splashRound(state->strokeAlpha * 255), - gTrue, gFalse); - - for (i = 0, seg = xPath->segs; i < xPath->length; ++i, ++seg) { - if (seg->y0 <= seg->y1) { - y0 = splashFloor(seg->y0); - y1 = splashFloor(seg->y1); - x0 = splashFloor(seg->x0); - x1 = splashFloor(seg->x1); - } else { - y0 = splashFloor(seg->y1); - y1 = splashFloor(seg->y0); - x0 = splashFloor(seg->x1); - x1 = splashFloor(seg->x0); - } - if ((clipRes = state->clip->testRect(x0 <= x1 ? x0 : x1, y0, - x0 <= x1 ? x1 : x0, y1, - state->strokeAdjust)) - != splashClipAllOutside) { - if (y0 == y1) { - if (x0 <= x1) { - drawStrokeSpan(&pipe, x0, x1, y0, clipRes == splashClipAllInside); - } else { - drawStrokeSpan(&pipe, x1, x0, y0, clipRes == splashClipAllInside); - } - } else { - dxdy = seg->dxdy; - y = state->clip->getYMinI(state->strokeAdjust); - if (y0 < y) { - y0 = y; - x0 = splashFloor(seg->x0 + ((SplashCoord)y0 - seg->y0) * dxdy); - } - y = state->clip->getYMaxI(state->strokeAdjust); - if (y1 > y) { - y1 = y; - x1 = splashFloor(seg->x0 + ((SplashCoord)y1 - seg->y0) * dxdy); - } - if (x0 <= x1) { - xa = x0; - for (y = y0; y <= y1; ++y) { - if (y < y1) { - xb = splashFloor(seg->x0 + - ((SplashCoord)y + 1 - seg->y0) * dxdy); - } else { - xb = x1 + 1; - } - if (xa == xb) { - drawStrokeSpan(&pipe, xa, xa, y, clipRes == splashClipAllInside); - } else { - drawStrokeSpan(&pipe, xa, xb - 1, y, - clipRes == splashClipAllInside); - } - xa = xb; - } - } else { - xa = x0; - for (y = y0; y <= y1; ++y) { - if (y < y1) { - xb = splashFloor(seg->x0 + - ((SplashCoord)y + 1 - seg->y0) * dxdy); - } else { - xb = x1 - 1; - } - if (xa == xb) { - drawStrokeSpan(&pipe, xa, xa, y, clipRes == splashClipAllInside); - } else { - drawStrokeSpan(&pipe, xb + 1, xa, y, - clipRes == splashClipAllInside); - } - xa = xb; - } - } - } - } - ++nClipRes[clipRes]; - } - if (nClipRes[splashClipPartial] || - (nClipRes[splashClipAllInside] && nClipRes[splashClipAllOutside])) { - opClipRes = splashClipPartial; - } else if (nClipRes[splashClipAllInside]) { - opClipRes = splashClipAllInside; - } else { - opClipRes = splashClipAllOutside; - } - - delete xPath; -} - -void Splash::drawStrokeSpan(SplashPipe *pipe, int x0, int x1, int y, - GBool noClip) { - int x; - - x = state->clip->getXMinI(state->strokeAdjust); - if (x > x0) { - x0 = x; - } - x = state->clip->getXMaxI(state->strokeAdjust); - if (x < x1) { - x1 = x; - } - if (x0 > x1) { - return; - } - for (x = x0; x <= x1; ++x) { - scanBuf[x] = 0xff; - } - if (!noClip) { - if (!state->clip->clipSpanBinary(scanBuf, y, x0, x1, state->strokeAdjust)) { - return; - } - } - (this->*pipe->run)(pipe, x0, x1, y, scanBuf + x0, NULL); -} - -void Splash::strokeWide(SplashPath *path, SplashCoord w, - int lineCap, int lineJoin) { - SplashPath *path2; - - path2 = makeStrokePath(path, w, lineCap, lineJoin, gFalse); - fillWithPattern(path2, gFalse, state->strokePattern, state->strokeAlpha); - delete path2; -} - -SplashPath *Splash::flattenPath(SplashPath *path, SplashCoord *matrix, - SplashCoord flatness) { - SplashPath *fPath; - SplashCoord flatness2; - Guchar flag; - int i; - - fPath = new SplashPath(); -#if USE_FIXEDPOINT - flatness2 = flatness; -#else - flatness2 = flatness * flatness; -#endif - i = 0; - while (i < path->length) { - flag = path->flags[i]; - if (flag & splashPathFirst) { - fPath->moveTo(path->pts[i].x, path->pts[i].y); - ++i; - } else { - if (flag & splashPathCurve) { - flattenCurve(path->pts[i-1].x, path->pts[i-1].y, - path->pts[i ].x, path->pts[i ].y, - path->pts[i+1].x, path->pts[i+1].y, - path->pts[i+2].x, path->pts[i+2].y, - matrix, flatness2, fPath); - i += 3; - } else { - fPath->lineTo(path->pts[i].x, path->pts[i].y); - ++i; - } - if (path->flags[i-1] & splashPathClosed) { - fPath->close(); - } - } - } - return fPath; -} - -void Splash::flattenCurve(SplashCoord x0, SplashCoord y0, - SplashCoord x1, SplashCoord y1, - SplashCoord x2, SplashCoord y2, - SplashCoord x3, SplashCoord y3, - SplashCoord *matrix, SplashCoord flatness2, - SplashPath *fPath) { - SplashCoord cx[splashMaxCurveSplits + 1][3]; - SplashCoord cy[splashMaxCurveSplits + 1][3]; - int cNext[splashMaxCurveSplits + 1]; - SplashCoord xl0, xl1, xl2, xr0, xr1, xr2, xr3, xx1, xx2, xh; - SplashCoord yl0, yl1, yl2, yr0, yr1, yr2, yr3, yy1, yy2, yh; - SplashCoord dx, dy, mx, my, tx, ty, d1, d2; - int p1, p2, p3; - - // initial segment - p1 = 0; - p2 = splashMaxCurveSplits; - cx[p1][0] = x0; cy[p1][0] = y0; - cx[p1][1] = x1; cy[p1][1] = y1; - cx[p1][2] = x2; cy[p1][2] = y2; - cx[p2][0] = x3; cy[p2][0] = y3; - cNext[p1] = p2; - - while (p1 < splashMaxCurveSplits) { - - // get the next segment - xl0 = cx[p1][0]; yl0 = cy[p1][0]; - xx1 = cx[p1][1]; yy1 = cy[p1][1]; - xx2 = cx[p1][2]; yy2 = cy[p1][2]; - p2 = cNext[p1]; - xr3 = cx[p2][0]; yr3 = cy[p2][0]; - - // compute the distances (in device space) from the control points - // to the midpoint of the straight line (this is a bit of a hack, - // but it's much faster than computing the actual distances to the - // line) - transform(matrix, (xl0 + xr3) * 0.5, (yl0 + yr3) * 0.5, &mx, &my); - transform(matrix, xx1, yy1, &tx, &ty); -#if USE_FIXEDPOINT - d1 = splashDist(tx, ty, mx, my); -#else - dx = tx - mx; - dy = ty - my; - d1 = dx*dx + dy*dy; -#endif - transform(matrix, xx2, yy2, &tx, &ty); -#if USE_FIXEDPOINT - d2 = splashDist(tx, ty, mx, my); -#else - dx = tx - mx; - dy = ty - my; - d2 = dx*dx + dy*dy; -#endif - - // if the curve is flat enough, or no more subdivisions are - // allowed, add the straight line segment - if (p2 - p1 == 1 || (d1 <= flatness2 && d2 <= flatness2)) { - fPath->lineTo(xr3, yr3); - p1 = p2; - - // otherwise, subdivide the curve - } else { - xl1 = splashAvg(xl0, xx1); - yl1 = splashAvg(yl0, yy1); - xh = splashAvg(xx1, xx2); - yh = splashAvg(yy1, yy2); - xl2 = splashAvg(xl1, xh); - yl2 = splashAvg(yl1, yh); - xr2 = splashAvg(xx2, xr3); - yr2 = splashAvg(yy2, yr3); - xr1 = splashAvg(xh, xr2); - yr1 = splashAvg(yh, yr2); - xr0 = splashAvg(xl2, xr1); - yr0 = splashAvg(yl2, yr1); - // add the new subdivision points - p3 = (p1 + p2) / 2; - cx[p1][1] = xl1; cy[p1][1] = yl1; - cx[p1][2] = xl2; cy[p1][2] = yl2; - cNext[p1] = p3; - cx[p3][0] = xr0; cy[p3][0] = yr0; - cx[p3][1] = xr1; cy[p3][1] = yr1; - cx[p3][2] = xr2; cy[p3][2] = yr2; - cNext[p3] = p2; - } - } -} - -SplashPath *Splash::makeDashedPath(SplashPath *path) { - SplashPath *dPath; - SplashCoord lineDashTotal; - SplashCoord lineDashStartPhase, lineDashDist, segLen; - SplashCoord x0, y0, x1, y1, xa, ya; - GBool lineDashStartOn, lineDashEndOn, lineDashOn, newPath; - int lineDashStartIdx, lineDashIdx, subpathStart, nDashes; - int i, j, k; - - lineDashTotal = 0; - for (i = 0; i < state->lineDashLength; ++i) { - lineDashTotal += state->lineDash[i]; - } - // Acrobat simply draws nothing if the dash array is [0] - if (lineDashTotal == 0) { - return new SplashPath(); - } - lineDashStartPhase = state->lineDashPhase; - if (lineDashStartPhase > lineDashTotal * 2) { - i = splashFloor(lineDashStartPhase / (lineDashTotal * 2)); - lineDashStartPhase -= lineDashTotal * i * 2; - } else if (lineDashStartPhase < 0) { - i = splashCeil(-lineDashStartPhase / (lineDashTotal * 2)); - lineDashStartPhase += lineDashTotal * i * 2; - } - i = splashFloor(lineDashStartPhase / lineDashTotal); - lineDashStartPhase -= (SplashCoord)i * lineDashTotal; - lineDashStartOn = gTrue; - lineDashStartIdx = 0; - if (lineDashStartPhase > 0) { - while (lineDashStartPhase >= state->lineDash[lineDashStartIdx]) { - lineDashStartOn = !lineDashStartOn; - lineDashStartPhase -= state->lineDash[lineDashStartIdx]; - if (++lineDashStartIdx == state->lineDashLength) { - lineDashStartIdx = 0; - } - } - } - - dPath = new SplashPath(); - - // process each subpath - i = 0; - while (i < path->length) { - - // find the end of the subpath - for (j = i; - j < path->length - 1 && !(path->flags[j] & splashPathLast); - ++j) ; - - // initialize the dash parameters - lineDashOn = lineDashStartOn; - lineDashEndOn = lineDashStartOn; - lineDashIdx = lineDashStartIdx; - lineDashDist = state->lineDash[lineDashIdx] - lineDashStartPhase; - subpathStart = dPath->length; - nDashes = 0; - - // process each segment of the subpath - newPath = gTrue; - for (k = i; k < j; ++k) { - - // grab the segment - x0 = path->pts[k].x; - y0 = path->pts[k].y; - x1 = path->pts[k+1].x; - y1 = path->pts[k+1].y; - segLen = splashDist(x0, y0, x1, y1); - - // process the segment - while (segLen > 0) { - - // Special case for zero-length dash segments: draw a very - // short -- but not zero-length -- segment. This ensures that - // we get the correct behavior with butt and projecting line - // caps. The PS/PDF specs imply that zero-length segments are - // not drawn unless the line cap is round, but Acrobat and - // Ghostscript both draw very short segments (for butt caps) - // and squares (for projecting caps). - if (lineDashDist == 0) { - if (lineDashOn) { - if (newPath) { - dPath->moveTo(x0, y0); - newPath = gFalse; - ++nDashes; - } - xa = x0 + ((SplashCoord)0.001 / segLen) * (x1 - x0); - ya = y0 + ((SplashCoord)0.001 / segLen) * (y1 - y0); - dPath->lineTo(xa, ya); - } - - } else if (lineDashDist >= segLen) { - if (lineDashOn) { - if (newPath) { - dPath->moveTo(x0, y0); - newPath = gFalse; - ++nDashes; - } - dPath->lineTo(x1, y1); - } - lineDashDist -= segLen; - segLen = 0; - - } else { - xa = x0 + (lineDashDist / segLen) * (x1 - x0); - ya = y0 + (lineDashDist / segLen) * (y1 - y0); - if (lineDashOn) { - if (newPath) { - dPath->moveTo(x0, y0); - newPath = gFalse; - ++nDashes; - } - dPath->lineTo(xa, ya); - } - x0 = xa; - y0 = ya; - segLen -= lineDashDist; - lineDashDist = 0; - } - - lineDashEndOn = lineDashOn; - - // get the next entry in the dash array - if (lineDashDist <= 0) { - lineDashOn = !lineDashOn; - if (++lineDashIdx == state->lineDashLength) { - lineDashIdx = 0; - } - lineDashDist = state->lineDash[lineDashIdx]; - newPath = gTrue; - } - } - } - - // in a closed subpath, where the dash pattern is "on" at both the - // start and end of the subpath, we need to merge the start and - // end to get a proper line join - if ((path->flags[j] & splashPathClosed) && - lineDashStartOn && - lineDashEndOn) { - if (nDashes == 1) { - dPath->close(); - } else if (nDashes > 1) { - k = subpathStart; - do { - ++k; - dPath->lineTo(dPath->pts[k].x, dPath->pts[k].y); - } while (!(dPath->flags[k] & splashPathLast)); - ++k; - memmove(&dPath->pts[subpathStart], &dPath->pts[k], - (dPath->length - k) * sizeof(SplashPathPoint)); - memmove(&dPath->flags[subpathStart], &dPath->flags[k], - (dPath->length - k) * sizeof(Guchar)); - dPath->length -= k - subpathStart; - dPath->curSubpath -= k - subpathStart; - } - } - - i = j + 1; - } - - return dPath; -} - -SplashError Splash::fill(SplashPath *path, GBool eo) { - if (debugMode) { - printf("fill [eo:%d]:\n", eo); - dumpPath(path); - } - return fillWithPattern(path, eo, state->fillPattern, state->fillAlpha); -} - -SplashError Splash::fillWithPattern(SplashPath *path, GBool eo, - SplashPattern *pattern, - SplashCoord alpha) { - SplashPipe pipe; - SplashPath *path2; - SplashXPath *xPath; - SplashXPathScanner *scanner; - int xMin, yMin, xMax, xMin2, xMax2, yMax, y, t; - SplashClipResult clipRes; - - if (path->length == 0) { - return splashErrEmptyPath; - } - if (pathAllOutside(path)) { - opClipRes = splashClipAllOutside; - return splashOk; - } - - path2 = tweakFillPath(path); - - xPath = new SplashXPath(path2, state->matrix, state->flatness, gTrue, - state->enablePathSimplification, - state->strokeAdjust); - if (path2 != path) { - delete path2; - } - xMin = xPath->getXMin(); - yMin = xPath->getYMin(); - xMax = xPath->getXMax(); - yMax = xPath->getYMax(); - if (xMin > xMax || yMin > yMax) { - delete xPath; - return splashOk; - } - scanner = new SplashXPathScanner(xPath, eo, yMin, yMax); - - // check clipping - if ((clipRes = state->clip->testRect(xMin, yMin, xMax, yMax, - state->strokeAdjust)) - != splashClipAllOutside) { - - if ((t = state->clip->getXMinI(state->strokeAdjust)) > xMin) { - xMin = t; - } - if ((t = state->clip->getXMaxI(state->strokeAdjust)) < xMax) { - xMax = t; - } - if ((t = state->clip->getYMinI(state->strokeAdjust)) > yMin) { - yMin = t; - } - if ((t = state->clip->getYMaxI(state->strokeAdjust)) < yMax) { - yMax = t; - } - if (xMin > xMax || yMin > yMax) { - delete scanner; - delete xPath; - return splashOk; - } - - pipeInit(&pipe, pattern, (Guchar)splashRound(alpha * 255), - gTrue, gFalse); - - // draw the spans - if (vectorAntialias && !inShading) { - for (y = yMin; y <= yMax; ++y) { - scanner->getSpan(scanBuf, y, xMin, xMax, &xMin2, &xMax2); - if (xMin2 <= xMax2) { - if (clipRes != splashClipAllInside) { - state->clip->clipSpan(scanBuf, y, xMin2, xMax2, - state->strokeAdjust); - } - (this->*pipe.run)(&pipe, xMin2, xMax2, y, scanBuf + xMin2, NULL); - } - } - } else { - for (y = yMin; y <= yMax; ++y) { - scanner->getSpanBinary(scanBuf, y, xMin, xMax, &xMin2, &xMax2); - if (xMin2 <= xMax2) { - if (clipRes != splashClipAllInside) { - state->clip->clipSpanBinary(scanBuf, y, xMin2, xMax2, - state->strokeAdjust); - } - (this->*pipe.run)(&pipe, xMin2, xMax2, y, scanBuf + xMin2, NULL); - } - } - } - } - opClipRes = clipRes; - - delete scanner; - delete xPath; - return splashOk; -} - -// Applies various tweaks to a fill path: -// (1) add stroke adjust hints to a filled rectangle -// (2) applies a minimum width to a zero-width filled rectangle (so -// stroke adjustment works correctly -// (3) convert a degenerate fill ('moveto lineto fill' and 'moveto -// lineto closepath fill') to a minimum-width filled rectangle -// -// These tweaks only apply to paths with a single subpath. -// -// Returns either the unchanged input path or a new path (in which -// case the returned path must be deleted by the caller). -SplashPath *Splash::tweakFillPath(SplashPath *path) { - SplashPath *path2; - SplashCoord xx0, yy0, xx1, yy1, dx, dy, d, wx, wy, w; - int n; - - if (state->strokeAdjust == splashStrokeAdjustOff || path->hints) { - return path; - } - - n = path->getLength(); - if (!((n == 2) || - (n == 3 && - path->flags[1] == 0) || - (n == 4 && - path->flags[1] == 0 && - path->flags[2] == 0) || - (n == 5 && - path->flags[1] == 0 && - path->flags[2] == 0 && - path->flags[3] == 0))) { - return path; - } - - path2 = path; - - // degenerate fill (2 or 3 points) or rectangle of (nearly) zero - // width --> replace with a min-width rectangle and hint - if (n == 2 || - (n == 3 && (path->flags[0] & splashPathClosed)) || - (n == 3 && (splashAbs(path->pts[0].x - path->pts[2].x) < 0.001 && - splashAbs(path->pts[0].y - path->pts[2].y) < 0.001)) || - ((n == 4 || - (n == 5 && (path->flags[0] & splashPathClosed))) && - ((splashAbs(path->pts[0].x - path->pts[1].x) < 0.001 && - splashAbs(path->pts[0].y - path->pts[1].y) < 0.001 && - splashAbs(path->pts[2].x - path->pts[3].x) < 0.001 && - splashAbs(path->pts[2].y - path->pts[3].y) < 0.001) || - (splashAbs(path->pts[0].x - path->pts[3].x) < 0.001 && - splashAbs(path->pts[0].y - path->pts[3].y) < 0.001 && - splashAbs(path->pts[1].x - path->pts[2].x) < 0.001 && - splashAbs(path->pts[1].y - path->pts[2].y) < 0.001)))) { - wx = state->matrix[0] + state->matrix[2]; - wy = state->matrix[1] + state->matrix[3]; - w = splashSqrt(wx*wx + wy*wy); - if (w < 0.001) { - w = 0; - } else { - // min width is 0.1 -- this constant is minWidth * sqrt(2) - w = (SplashCoord)0.1414 / w; - } - xx0 = path->pts[0].x; - yy0 = path->pts[0].y; - if (n <= 3) { - xx1 = path->pts[1].x; - yy1 = path->pts[1].y; - } else { - xx1 = path->pts[2].x; - yy1 = path->pts[2].y; - } - dx = xx1 - xx0; - dy = yy1 - yy0; - d = splashSqrt(dx * dx + dy * dy); - if (d < 0.001) { - d = 0; - } else { - d = w / d; - } - dx *= d; - dy *= d; - path2 = new SplashPath(); - path2->moveTo(xx0 + dy, yy0 - dx); - path2->lineTo(xx1 + dy, yy1 - dx); - path2->lineTo(xx1 - dy, yy1 + dx); - path2->lineTo(xx0 - dy, yy0 + dx); - path2->close(gTrue); - path2->addStrokeAdjustHint(0, 2, 0, 4); - path2->addStrokeAdjustHint(1, 3, 0, 4); - - // unclosed rectangle --> close and hint - } else if (n == 4 && !(path->flags[0] & splashPathClosed)) { - path2->close(gTrue); - path2->addStrokeAdjustHint(0, 2, 0, 4); - path2->addStrokeAdjustHint(1, 3, 0, 4); - - // closed rectangle --> hint - } else if (n == 5 && (path->flags[0] & splashPathClosed)) { - path2->addStrokeAdjustHint(0, 2, 0, 4); - path2->addStrokeAdjustHint(1, 3, 0, 4); - } - - return path2; -} - -GBool Splash::pathAllOutside(SplashPath *path) { - SplashCoord xMin1, yMin1, xMax1, yMax1; - SplashCoord xMin2, yMin2, xMax2, yMax2; - SplashCoord x, y; - int xMinI, yMinI, xMaxI, yMaxI; - int i; - - xMin1 = xMax1 = path->pts[0].x; - yMin1 = yMax1 = path->pts[0].y; - for (i = 1; i < path->length; ++i) { - if (path->pts[i].x < xMin1) { - xMin1 = path->pts[i].x; - } else if (path->pts[i].x > xMax1) { - xMax1 = path->pts[i].x; - } - if (path->pts[i].y < yMin1) { - yMin1 = path->pts[i].y; - } else if (path->pts[i].y > yMax1) { - yMax1 = path->pts[i].y; - } - } - - transform(state->matrix, xMin1, yMin1, &x, &y); - xMin2 = xMax2 = x; - yMin2 = yMax2 = y; - transform(state->matrix, xMin1, yMax1, &x, &y); - if (x < xMin2) { - xMin2 = x; - } else if (x > xMax2) { - xMax2 = x; - } - if (y < yMin2) { - yMin2 = y; - } else if (y > yMax2) { - yMax2 = y; - } - transform(state->matrix, xMax1, yMin1, &x, &y); - if (x < xMin2) { - xMin2 = x; - } else if (x > xMax2) { - xMax2 = x; - } - if (y < yMin2) { - yMin2 = y; - } else if (y > yMax2) { - yMax2 = y; - } - transform(state->matrix, xMax1, yMax1, &x, &y); - if (x < xMin2) { - xMin2 = x; - } else if (x > xMax2) { - xMax2 = x; - } - if (y < yMin2) { - yMin2 = y; - } else if (y > yMax2) { - yMax2 = y; - } - // sanity-check the coordinates - xMinI/yMinI/xMaxI/yMaxI are - // 32-bit integers, so coords need to be < 2^31 - SplashXPath::clampCoords(&xMin2, &yMin2); - SplashXPath::clampCoords(&xMax2, &yMax2); - xMinI = splashFloor(xMin2); - yMinI = splashFloor(yMin2); - xMaxI = splashFloor(xMax2); - yMaxI = splashFloor(yMax2); - - return state->clip->testRect(xMinI, yMinI, xMaxI, yMaxI, - state->strokeAdjust) == - splashClipAllOutside; -} - -SplashError Splash::fillChar(SplashCoord x, SplashCoord y, - int c, SplashFont *font) { - SplashGlyphBitmap glyph; - SplashCoord xt, yt; - int x0, y0, xFrac, yFrac; - SplashError err; - - if (debugMode) { - printf("fillChar: x=%.2f y=%.2f c=%3d=0x%02x='%c'\n", - (double)x, (double)y, c, c, c); - } - transform(state->matrix, x, y, &xt, &yt); - x0 = splashFloor(xt); - xFrac = splashFloor((xt - x0) * splashFontFraction); - y0 = splashFloor(yt); - yFrac = splashFloor((yt - y0) * splashFontFraction); - if (!font->getGlyph(c, xFrac, yFrac, &glyph)) { - return splashErrNoGlyph; - } - err = fillGlyph2(x0, y0, &glyph); - if (glyph.freeData) { - gfree(glyph.data); - } - return err; -} - -SplashError Splash::fillGlyph(SplashCoord x, SplashCoord y, - SplashGlyphBitmap *glyph) { - SplashCoord xt, yt; - int x0, y0; - - transform(state->matrix, x, y, &xt, &yt); - x0 = splashFloor(xt); - y0 = splashFloor(yt); - return fillGlyph2(x0, y0, glyph); -} - -SplashError Splash::fillGlyph2(int x0, int y0, SplashGlyphBitmap *glyph) { - SplashPipe pipe; - SplashClipResult clipRes; - Guchar alpha; - Guchar *p; - int xMin, yMin, xMax, yMax; - int x, y, xg, yg, xx, t; - - xg = x0 - glyph->x; - yg = y0 - glyph->y; - xMin = xg; - xMax = xg + glyph->w - 1; - yMin = yg; - yMax = yg + glyph->h - 1; - if ((clipRes = state->clip->testRect(xMin, yMin, xMax, yMax, - state->strokeAdjust)) - != splashClipAllOutside) { - pipeInit(&pipe, state->fillPattern, - (Guchar)splashRound(state->fillAlpha * 255), - gTrue, gFalse); - if (clipRes == splashClipAllInside) { - if (glyph->aa) { - p = glyph->data; - for (y = yMin; y <= yMax; ++y) { - (this->*pipe.run)(&pipe, xMin, xMax, y, - glyph->data + (y - yMin) * glyph->w, NULL); - } - } else { - p = glyph->data; - for (y = yMin; y <= yMax; ++y) { - for (x = xMin; x <= xMax; x += 8) { - alpha = *p++; - for (xx = 0; xx < 8 && x + xx <= xMax; ++xx) { - scanBuf[x + xx] = (alpha & 0x80) ? 0xff : 0x00; - alpha = (Guchar)(alpha << 1); - } - } - (this->*pipe.run)(&pipe, xMin, xMax, y, scanBuf + xMin, NULL); - } - } - } else { - if ((t = state->clip->getXMinI(state->strokeAdjust)) > xMin) { - xMin = t; - } - if ((t = state->clip->getXMaxI(state->strokeAdjust)) < xMax) { - xMax = t; - } - if ((t = state->clip->getYMinI(state->strokeAdjust)) > yMin) { - yMin = t; - } - if ((t = state->clip->getYMaxI(state->strokeAdjust)) < yMax) { - yMax = t; - } - if (xMin <= xMax && yMin <= yMax) { - if (glyph->aa) { - for (y = yMin; y <= yMax; ++y) { - p = glyph->data + (y - yg) * glyph->w + (xMin - xg); - memcpy(scanBuf + xMin, p, xMax - xMin + 1); - state->clip->clipSpan(scanBuf, y, xMin, xMax, - state->strokeAdjust); - (this->*pipe.run)(&pipe, xMin, xMax, y, scanBuf + xMin, NULL); - } - } else { - for (y = yMin; y <= yMax; ++y) { - p = glyph->data + (y - yg) * ((glyph->w + 7) >> 3) - + ((xMin - xg) >> 3); - alpha = *p++; - xx = (xMin - xg) & 7; - alpha = (Guchar)(alpha << xx); - for (x = xMin; xx < 8 && x <= xMax; ++x, ++xx) { - scanBuf[x] = (alpha & 0x80) ? 255 : 0; - alpha = (Guchar)(alpha << 1); - } - for (; x <= xMax; x += 8) { - alpha = *p++; - for (xx = 0; xx < 8 && x + xx <= xMax; ++xx) { - scanBuf[x + xx] = (alpha & 0x80) ? 255 : 0; - alpha = (Guchar)(alpha << 1); - } - } - state->clip->clipSpanBinary(scanBuf, y, xMin, xMax, - state->strokeAdjust); - (this->*pipe.run)(&pipe, xMin, xMax, y, scanBuf + xMin, NULL); - } - } - } - } - } - opClipRes = clipRes; - - return splashOk; -} - -void Splash::getImageBounds(SplashCoord xyMin, SplashCoord xyMax, - int *xyMinI, int *xyMaxI) { - if (state->strokeAdjust == splashStrokeAdjustOff) { - // make sure the coords fit in 32-bit ints -#if USE_FIXEDPOINT - if (xyMin < -32767) { - xyMin = -32767; - } else if (xyMin > 32767) { - xyMin = 32767; - } - if (xyMax < -32767) { - xyMax = -32767; - } else if (xyMax > 32767) { - xyMax = 32767; - } -#else - if (xyMin < -1e9) { - xyMin = -1e9; - } else if (xyMin > 1e9) { - xyMin = 1e9; - } - if (xyMax < -1e9) { - xyMax = -1e9; - } else if (xyMax > 1e9) { - xyMax = 1e9; - } -#endif - *xyMinI = splashFloor(xyMin); - *xyMaxI = splashFloor(xyMax); - if (*xyMaxI <= *xyMinI) { - *xyMaxI = *xyMinI + 1; - } - } else { - splashStrokeAdjust(xyMin, xyMax, xyMinI, xyMaxI, state->strokeAdjust); - } -} - -struct SplashDrawImageMaskRowData { - SplashPipe pipe; -}; - -// The glyphMode flag is not currently used, but may be useful if the -// stroke adjustment behavior is changed. -SplashError Splash::fillImageMask(GString *imageTag, - SplashImageMaskSource src, void *srcData, - int w, int h, SplashCoord *mat, - GBool glyphMode, GBool interpolate) { - if (debugMode) { - printf("fillImageMask: w=%d h=%d mat=[%.2f %.2f %.2f %.2f %.2f %.2f]\n", - w, h, (double)mat[0], (double)mat[1], (double)mat[2], - (double)mat[3], (double)mat[4], (double)mat[5]); - } - - //--- check for singular matrix - if (!splashCheckDet(mat[0], mat[1], mat[2], mat[3], 0.000001)) { - return splashErrSingularMatrix; - } - - //--- compute image bbox, check clipping - GBool flipsOnly = splashAbs(mat[1]) <= 0.0001 && splashAbs(mat[2]) <= 0.0001; - GBool horizFlip = gFalse; - GBool vertFlip = gFalse; - int xMin, yMin, xMax, yMax; - if (flipsOnly) { - horizFlip = mat[0] < 0; - vertFlip = mat[3] < 0; - if (vertFlip) { - if (horizFlip) { // bottom-up, mirrored - getImageBounds(mat[0] + mat[4], mat[4], &xMin, &xMax); - getImageBounds(mat[3] + mat[5], mat[5], &yMin, &yMax); - } else { // bottom-up - getImageBounds(mat[4], mat[0] + mat[4], &xMin, &xMax); - getImageBounds(mat[3] + mat[5], mat[5], &yMin, &yMax); - } - } else { - if (horizFlip) { // top-down, mirrored - getImageBounds(mat[0] + mat[4], mat[4], &xMin, &xMax); - getImageBounds(mat[5], mat[3] + mat[5], &yMin, &yMax); - } else { // top-down - getImageBounds(mat[4], mat[0] + mat[4], &xMin, &xMax); - getImageBounds(mat[5], mat[3] + mat[5], &yMin, &yMax); - } - } - } else { - int xx = splashRound(mat[4]); // (0,0) - int yy = splashRound(mat[5]); - xMin = xMax = xx; - yMin = yMax = yy; - xx = splashRound(mat[0] + mat[4]); // (1,0) - yy = splashRound(mat[1] + mat[5]); - if (xx < xMin) { - xMin = xx; - } else if (xx > xMax) { - xMax = xx; - } - if (yy < yMin) { - yMin = yy; - } else if (yy > yMax) { - yMax = yy; - } - xx = splashRound(mat[2] + mat[4]); // (0,1) - yy = splashRound(mat[3] + mat[5]); - if (xx < xMin) { - xMin = xx; - } else if (xx > xMax) { - xMax = xx; - } - if (yy < yMin) { - yMin = yy; - } else if (yy > yMax) { - yMax = yy; - } - xx = splashRound(mat[0] + mat[2] + mat[4]); // (1,1) - yy = splashRound(mat[1] + mat[3] + mat[5]); - if (xx < xMin) { - xMin = xx; - } else if (xx > xMax) { - xMax = xx; - } - if (yy < yMin) { - yMin = yy; - } else if (yy > yMax) { - yMax = yy; - } - if (xMax <= xMin) { - xMax = xMin + 1; - } - if (yMax <= yMin) { - yMax = yMin + 1; - } - } - SplashClipResult clipRes = - state->clip->testRect(xMin, yMin, xMax - 1, yMax - 1, - state->strokeAdjust); - // If the scaled mask is much wider and/or taller than the clip - // region, we use the "arbitrary" scaling path, to avoid a - // potentially very slow loop in the flips-only path (which scans - // the full width and height of the scaled mask, regardless of the - // clip region). - int clipW = state->clip->getXMaxI(state->strokeAdjust) - - state->clip->getXMinI(state->strokeAdjust); - int clipH = state->clip->getYMaxI(state->strokeAdjust) - - state->clip->getYMinI(state->strokeAdjust); - GBool veryLarge = ((xMax - xMin) / 8 > clipW && xMax - xMin > 1000) || - ((yMax - yMin) / 8 > clipH && yMax - yMin > 1000); - - //--- set up the SplashDrawImageMaskRowData object and the pipes - SplashDrawImageMaskRowData dd; - pipeInit(&dd.pipe, state->fillPattern, - (Guchar)splashRound(state->fillAlpha * 255), - gTrue, gFalse); - - //--- choose the drawRow function - SplashDrawImageMaskRowFunc drawRowFunc; - if (clipRes == splashClipAllInside) { - drawRowFunc = &Splash::drawImageMaskRowNoClip; - } else { - if (vectorAntialias) { - drawRowFunc = &Splash::drawImageMaskRowClipAA; - } else { - drawRowFunc = &Splash::drawImageMaskRowClipNoAA; - } - } - - //--- horizontal/vertical flips only - if (flipsOnly && !veryLarge) { - if (clipRes != splashClipAllOutside) { - int scaledWidth = xMax - xMin; - int scaledHeight = yMax - yMin; - ImageMaskScaler scaler(src, srcData, w, h, - scaledWidth, scaledHeight, interpolate); - Guchar *tmpLine = NULL; - if (horizFlip) { - tmpLine = (Guchar *)gmalloc(scaledWidth); - } - if (vertFlip) { - if (horizFlip) { // bottom-up, mirrored - for (int y = 0; y < scaledHeight; ++y) { - scaler.nextLine(); - mirrorImageMaskRow(scaler.data(), tmpLine, scaledWidth); - (this->*drawRowFunc)(&dd, tmpLine, - xMin, yMax - 1 - y, scaledWidth); - } - } else { // bottom-up - for (int y = 0; y < scaledHeight; ++y) { - scaler.nextLine(); - (this->*drawRowFunc)(&dd, scaler.data(), - xMin, yMax - 1 - y, scaledWidth); - } - } - } else { - if (horizFlip) { // top-down, mirrored - for (int y = 0; y < scaledHeight; ++y) { - scaler.nextLine(); - mirrorImageMaskRow(scaler.data(), tmpLine, scaledWidth); - (this->*drawRowFunc)(&dd, tmpLine, - xMin, yMin + y, scaledWidth); - } - } else { // top-down - for (int y = 0; y < scaledHeight; ++y) { - scaler.nextLine(); - (this->*drawRowFunc)(&dd, scaler.data(), - xMin, yMin + y, scaledWidth); - } - } - } - gfree(tmpLine); - } - - //--- arbitrary transform - } else { - // estimate of size of scaled image - int scaledWidth = splashRound(splashSqrt(mat[0] * mat[0] - + mat[1] * mat[1])); - int scaledHeight = splashRound(splashSqrt(mat[2] * mat[2] - + mat[3] * mat[3])); - if (scaledWidth < 1) { - scaledWidth = 1; - } - if (scaledHeight < 1) { - scaledHeight = 1; - } - GBool downscaling = gTrue; - if (veryLarge || (scaledWidth >= w && scaledHeight >= h)) { - downscaling = gFalse; - scaledWidth = w; - scaledHeight = h; - } - - // compute mapping from device space to scaled image space - SplashCoord mat1[6]; - mat1[0] = mat[0] / scaledWidth; - mat1[1] = mat[1] / scaledWidth; - mat1[2] = mat[2] / scaledHeight; - mat1[3] = mat[3] / scaledHeight; - mat1[4] = mat[4]; - mat1[5] = mat[5]; - SplashCoord det = mat1[0] * mat1[3] - mat1[1] * mat1[2]; - if (splashAbs(det) < 1e-6) { - // this should be caught by the singular matrix check in drawImage - return splashErrSingularMatrix; - } - SplashCoord invMat[6]; - invMat[0] = mat1[3] / det; - invMat[1] = -mat1[1] / det; - invMat[2] = -mat1[2] / det; - invMat[3] = mat1[0] / det; - // the extra "+ 0.5 * (...)" terms are here because the - // drawImageArbitrary(No)Interp functions multiply by pixel - // centers, (x + 0.5, y + 0.5) - invMat[4] = (mat1[2] * mat1[5] - mat1[3] * mat1[4]) / det - + (invMat[0] + invMat[2]) * 0.5; - invMat[5] = (mat1[1] * mat1[4] - mat1[0] * mat1[5]) / det - + (invMat[1] + invMat[3]) * 0.5; - - // if downscaling: store the downscaled image mask - // if upscaling: store the unscaled image mask - Guchar *scaledMask = (Guchar *)gmallocn(scaledHeight, scaledWidth); - if (downscaling) { - ImageMaskScaler scaler(src, srcData, w, h, - scaledWidth, scaledHeight, interpolate); - Guchar *ptr = scaledMask; - for (int y = 0; y < scaledHeight; ++y) { - scaler.nextLine(); - memcpy(ptr, scaler.data(), scaledWidth); - ptr += scaledWidth; - } - } else { - Guchar *ptr = scaledMask; - for (int y = 0; y < scaledHeight; ++y) { - (*src)(srcData, ptr); - for (int x = 0; x < scaledWidth; ++x) { - *ptr = (Guchar)(*ptr * 255); - ++ptr; - } - } - } - - // draw it - if (interpolate) { - drawImageMaskArbitraryInterp(scaledMask, - &dd, drawRowFunc, invMat, - scaledWidth, scaledHeight, - xMin, yMin, xMax, yMax); - } else { - drawImageMaskArbitraryNoInterp(scaledMask, - &dd, drawRowFunc, invMat, - scaledWidth, scaledHeight, - xMin, yMin, xMax, yMax); - } - - // free the downscaled/unscaled image - gfree(scaledMask); - } - - return splashOk; -} - -void Splash::drawImageMaskArbitraryNoInterp( - Guchar *scaledMask, - SplashDrawImageMaskRowData *dd, - SplashDrawImageMaskRowFunc drawRowFunc, - SplashCoord *invMat, - int scaledWidth, int scaledHeight, - int xMin, int yMin, int xMax, int yMax) { - int tt = state->clip->getXMinI(state->strokeAdjust); - if (tt > xMin) { - xMin = tt; - } - tt = state->clip->getXMaxI(state->strokeAdjust) + 1; - if (tt < xMax) { - xMax = tt; - } - tt = state->clip->getYMinI(state->strokeAdjust); - if (tt > yMin) { - yMin = tt; - } - tt = state->clip->getYMaxI(state->strokeAdjust) + 1; - if (tt < yMax) { - yMax = tt; - } - if (xMax <= xMin || yMax <= yMin) { - return; - } - - Guchar *buf = (Guchar *)gmalloc(xMax - xMin); - - for (int y = yMin; y < yMax; ++y) { - int rowMin = xMax; - int rowMax = 0; - for (int x = xMin; x < xMax; ++x) { - // note: invMat includes a "+0.5" factor so that this is really - // a multiply by (x+0.5, y+0.5) - int xx = splashFloor((SplashCoord)x * invMat[0] - + (SplashCoord)y * invMat[2] + invMat[4]); - int yy = splashFloor((SplashCoord)x * invMat[1] - + (SplashCoord)y * invMat[3] + invMat[5]); - if (xx >= 0 && xx < scaledWidth && - yy >= 0 && yy < scaledHeight) { - Guchar *p = scaledMask + (yy * scaledWidth + xx); - Guchar *q = buf + (x - xMin); - *q = *p; - if (x < rowMin) { - rowMin = x; - } - rowMax = x + 1; - } - } - if (rowMin < rowMax) { - (this->*drawRowFunc)(dd, buf + (rowMin - xMin), - rowMin, y, rowMax - rowMin); - } - } - - gfree(buf); -} - -void Splash::drawImageMaskArbitraryInterp( - Guchar *scaledMask, - SplashDrawImageMaskRowData *dd, - SplashDrawImageMaskRowFunc drawRowFunc, - SplashCoord *invMat, - int scaledWidth, int scaledHeight, - int xMin, int yMin, int xMax, int yMax) { - int tt = state->clip->getXMinI(state->strokeAdjust); - if (tt > xMin) { - xMin = tt; - } - tt = state->clip->getXMaxI(state->strokeAdjust) + 1; - if (tt < xMax) { - xMax = tt; - } - tt = state->clip->getYMinI(state->strokeAdjust); - if (tt > yMin) { - yMin = tt; - } - tt = state->clip->getYMaxI(state->strokeAdjust) + 1; - if (tt < yMax) { - yMax = tt; - } - if (xMax <= xMin || yMax <= yMin) { - return; - } - - Guchar *buf = (Guchar *)gmalloc(xMax - xMin); - - for (int y = yMin; y < yMax; ++y) { - int rowMin = xMax; - int rowMax = 0; - for (int x = xMin; x < xMax; ++x) { - // note: invMat includes a "+0.5" factor so that this is really - // a multiply by (x+0.5, y+0.5) - SplashCoord xs = (SplashCoord)x * invMat[0] - + (SplashCoord)y * invMat[2] + invMat[4]; - SplashCoord ys = (SplashCoord)x * invMat[1] - + (SplashCoord)y * invMat[3] + invMat[5]; - int x0 = splashFloor(xs - 0.5); - int x1 = x0 + 1; - int y0 = splashFloor(ys - 0.5); - int y1 = y0 + 1; - if (x1 >= 0 && x0 < scaledWidth && y1 >= 0 && y0 < scaledHeight) { - SplashCoord sx0 = (SplashCoord)x1 + 0.5 - xs; - SplashCoord sx1 = (SplashCoord)1 - sx0; - SplashCoord sy0 = (SplashCoord)y1 + 0.5 - ys; - SplashCoord sy1 = (SplashCoord)1 - sy0; - if (x0 < 0) { - x0 = 0; - } - if (x1 >= scaledWidth) { - x1 = scaledWidth - 1; - } - if (y0 < 0) { - y0 = 0; - } - if (y1 >= scaledHeight) { - y1 = scaledHeight - 1; - } - Guchar *p00 = scaledMask + (y0 * scaledWidth + x0); - Guchar *p10 = scaledMask + (y0 * scaledWidth + x1); - Guchar *p01 = scaledMask + (y1 * scaledWidth + x0); - Guchar *p11 = scaledMask + (y1 * scaledWidth + x1); - Guchar *q = buf + (x - xMin); - *q = (Guchar)(int)(sx0 * (sy0 * (int)*p00 + sy1 * (int)*p01) + - sx1 * (sy0 * (int)*p10 + sy1 * (int)*p11)); - if (x < rowMin) { - rowMin = x; - } - rowMax = x + 1; - } - } - if (rowMin < rowMax) { - (this->*drawRowFunc)(dd, buf + (rowMin - xMin), - rowMin, y, rowMax - rowMin); - } - } - - gfree(buf); -} - -void Splash::mirrorImageMaskRow(Guchar *maskIn, Guchar *maskOut, int width) { - Guchar *p, *q; - - p = maskIn; - q = maskOut + (width - 1); - for (int i = 0; i < width; ++i) { - *q = *p; - ++p; - --q; - } -} - -void Splash::drawImageMaskRowNoClip(SplashDrawImageMaskRowData *data, - Guchar *maskData, - int x, int y, int width) { - (this->*data->pipe.run)(&data->pipe, x, x + width - 1, y, maskData, NULL); -} - -void Splash::drawImageMaskRowClipNoAA(SplashDrawImageMaskRowData *data, - Guchar *maskData, - int x, int y, int width) { - if (y < 0 || y >= bitmap->height) { - return; - } - if (x < 0) { - maskData -= x; - width += x; - x = 0; - } - if (x + width > bitmap->width) { - width = bitmap->width - x; - } - if (width <= 0) { - return; - } - memcpy(scanBuf + x, maskData, width); - state->clip->clipSpanBinary(scanBuf, y, x, x + width - 1, - state->strokeAdjust); - (this->*data->pipe.run)(&data->pipe, x, x + width - 1, y, - scanBuf + x, NULL); -} - -void Splash::drawImageMaskRowClipAA(SplashDrawImageMaskRowData *data, - Guchar *maskData, - int x, int y, int width) { - if (y < 0 || y >= bitmap->height) { - return; - } - if (x < 0) { - maskData -= x; - width += x; - x = 0; - } - if (x + width > bitmap->width) { - width = bitmap->width - x; - } - if (width <= 0) { - return; - } - memcpy(scanBuf + x, maskData, width); - state->clip->clipSpan(scanBuf, y, x, x + width - 1, state->strokeAdjust); - (this->*data->pipe.run)(&data->pipe, x, x + width - 1, y, - scanBuf + x, NULL); -} - -struct SplashDrawImageRowData { - int nComps; - GBool srcAlpha; - SplashPipe pipe; -}; - -SplashError Splash::drawImage(GString *imageTag, - SplashImageSource src, void *srcData, - SplashColorMode srcMode, GBool srcAlpha, - int w, int h, SplashCoord *mat, - GBool interpolate) { - if (debugMode) { - printf("drawImage: srcMode=%d srcAlpha=%d w=%d h=%d mat=[%.2f %.2f %.2f %.2f %.2f %.2f]\n", - srcMode, srcAlpha, w, h, (double)mat[0], (double)mat[1], (double)mat[2], - (double)mat[3], (double)mat[4], (double)mat[5]); - } - - //--- check color modes - GBool ok = gFalse; - int nComps = 0; - switch (bitmap->mode) { - case splashModeMono1: - case splashModeMono8: - ok = srcMode == splashModeMono8; - nComps = 1; - break; - case splashModeRGB8: - case splashModeBGR8: - ok = srcMode == splashModeRGB8; - nComps = 3; - break; -#if SPLASH_CMYK - case splashModeCMYK8: - ok = srcMode == splashModeCMYK8; - nComps = 4; - break; -#endif - default: - ok = gFalse; - break; - } - if (!ok) { - return splashErrModeMismatch; - } - - //--- check for singular matrix - if (!splashCheckDet(mat[0], mat[1], mat[2], mat[3], 0.000001)) { - return splashErrSingularMatrix; - } - - //--- compute image bbox, check clipping - GBool flipsOnly = splashAbs(mat[1]) <= 0.0001 && splashAbs(mat[2]) <= 0.0001; - GBool horizFlip = gFalse; - GBool vertFlip = gFalse; - int xMin, yMin, xMax, yMax; - if (flipsOnly) { - horizFlip = mat[0] < 0; - vertFlip = mat[3] < 0; - if (vertFlip) { - if (horizFlip) { // bottom-up, mirrored - getImageBounds(mat[0] + mat[4], mat[4], &xMin, &xMax); - getImageBounds(mat[3] + mat[5], mat[5], &yMin, &yMax); - } else { // bottom-up - getImageBounds(mat[4], mat[0] + mat[4], &xMin, &xMax); - getImageBounds(mat[3] + mat[5], mat[5], &yMin, &yMax); - } - } else { - if (horizFlip) { // top-down, mirrored - getImageBounds(mat[0] + mat[4], mat[4], &xMin, &xMax); - getImageBounds(mat[5], mat[3] + mat[5], &yMin, &yMax); - } else { // top-down - getImageBounds(mat[4], mat[0] + mat[4], &xMin, &xMax); - getImageBounds(mat[5], mat[3] + mat[5], &yMin, &yMax); - } - } - } else { - int xx = splashRound(mat[4]); // (0,0) - int yy = splashRound(mat[5]); - xMin = xMax = xx; - yMin = yMax = yy; - xx = splashRound(mat[0] + mat[4]); // (1,0) - yy = splashRound(mat[1] + mat[5]); - if (xx < xMin) { - xMin = xx; - } else if (xx > xMax) { - xMax = xx; - } - if (yy < yMin) { - yMin = yy; - } else if (yy > yMax) { - yMax = yy; - } - xx = splashRound(mat[2] + mat[4]); // (0,1) - yy = splashRound(mat[3] + mat[5]); - if (xx < xMin) { - xMin = xx; - } else if (xx > xMax) { - xMax = xx; - } - if (yy < yMin) { - yMin = yy; - } else if (yy > yMax) { - yMax = yy; - } - xx = splashRound(mat[0] + mat[2] + mat[4]); // (1,1) - yy = splashRound(mat[1] + mat[3] + mat[5]); - if (xx < xMin) { - xMin = xx; - } else if (xx > xMax) { - xMax = xx; - } - if (yy < yMin) { - yMin = yy; - } else if (yy > yMax) { - yMax = yy; - } - if (xMax <= xMin) { - xMax = xMin + 1; - } - if (yMax <= yMin) { - yMax = yMin + 1; - } - } - SplashClipResult clipRes = - state->clip->testRect(xMin, yMin, xMax - 1, yMax - 1, - state->strokeAdjust); - // If the scaled image is much wider and/or taller than the clip - // region, we use the arbitrary transform path, to avoid a - // potentially very slow loop in the flips-only path (which scans - // the full width and height of the scaled image, regardless of the - // clip region). - int clipW = state->clip->getXMaxI(state->strokeAdjust) - - state->clip->getXMinI(state->strokeAdjust); - int clipH = state->clip->getYMaxI(state->strokeAdjust) - - state->clip->getYMinI(state->strokeAdjust); - GBool veryLarge = ((xMax - xMin) / 8 > clipW && xMax - xMin > 1000) || - ((yMax - yMin) / 8 > clipH && yMax - yMin > 1000); - - //--- set up the SplashDrawImageRowData object and the pipes - SplashDrawImageRowData dd; - dd.nComps = nComps; - dd.srcAlpha = srcAlpha; - pipeInit(&dd.pipe, NULL, - (Guchar)splashRound(state->fillAlpha * 255), - clipRes != splashClipAllInside || srcAlpha, - gFalse); - - //--- choose the drawRow function - SplashDrawImageRowFunc drawRowFunc; - if (clipRes == splashClipAllInside) { - if (srcAlpha) { - drawRowFunc = &Splash::drawImageRowNoClipAlpha; - } else { - drawRowFunc = &Splash::drawImageRowNoClipNoAlpha; - } - } else { - if (srcAlpha) { - if (vectorAntialias) { - drawRowFunc = &Splash::drawImageRowClipAlphaAA; - } else { - drawRowFunc = &Splash::drawImageRowClipAlphaNoAA; - } - } else { - if (vectorAntialias) { - drawRowFunc = &Splash::drawImageRowClipNoAlphaAA; - } else { - drawRowFunc = &Splash::drawImageRowClipNoAlphaNoAA; - } - } - } - - //--- horizontal/vertical flips only - if (flipsOnly && !veryLarge) { - if (clipRes != splashClipAllOutside) { - int scaledWidth = xMax - xMin; - int scaledHeight = yMax - yMin; - ImageScaler *scaler = getImageScaler(imageTag, src, srcData, - w, h, nComps, - scaledWidth, scaledHeight, - srcMode, srcAlpha, interpolate); - Guchar *tmpLine = NULL; - Guchar *tmpAlphaLine = NULL; - if (horizFlip) { - tmpLine = (Guchar *)gmallocn(scaledWidth, nComps); - if (srcAlpha) { - tmpAlphaLine = (Guchar *)gmalloc(scaledWidth); - } - } - if (vertFlip) { - if (horizFlip) { // bottom-up, mirrored - for (int y = 0; y < scaledHeight; ++y) { - scaler->nextLine(); - mirrorImageRow(scaler->colorData(), scaler->alphaData(), - tmpLine, tmpAlphaLine, - scaledWidth, nComps, srcAlpha); - (this->*drawRowFunc)(&dd, tmpLine, tmpAlphaLine, - xMin, yMax - 1 - y, scaledWidth); - } - } else { // bottom-up - for (int y = 0; y < scaledHeight; ++y) { - scaler->nextLine(); - (this->*drawRowFunc)(&dd, scaler->colorData(), scaler->alphaData(), - xMin, yMax - 1 - y, scaledWidth); - } - } - } else { - if (horizFlip) { // top-down, mirrored - for (int y = 0; y < scaledHeight; ++y) { - scaler->nextLine(); - mirrorImageRow(scaler->colorData(), scaler->alphaData(), - tmpLine, tmpAlphaLine, - scaledWidth, nComps, srcAlpha); - (this->*drawRowFunc)(&dd, tmpLine, tmpAlphaLine, - xMin, yMin + y, scaledWidth); - } - } else { // top-down - for (int y = 0; y < scaledHeight; ++y) { - scaler->nextLine(); - (this->*drawRowFunc)(&dd, scaler->colorData(), scaler->alphaData(), - xMin, yMin + y, scaledWidth); - } - } - } - gfree(tmpLine); - gfree(tmpAlphaLine); - delete scaler; - } - - //--- arbitrary transform - } else { - // estimate of size of scaled image - int scaledWidth = splashRound(splashSqrt(mat[0] * mat[0] - + mat[1] * mat[1])); - int scaledHeight = splashRound(splashSqrt(mat[2] * mat[2] - + mat[3] * mat[3])); - if (scaledWidth < 1) { - scaledWidth = 1; - } - if (scaledHeight < 1) { - scaledHeight = 1; - } - if (veryLarge || (scaledWidth >= w && scaledHeight >= h)) { - scaledWidth = w; - scaledHeight = h; - } - - // compute mapping from device space to scaled image space - SplashCoord mat1[6]; - mat1[0] = mat[0] / scaledWidth; - mat1[1] = mat[1] / scaledWidth; - mat1[2] = mat[2] / scaledHeight; - mat1[3] = mat[3] / scaledHeight; - mat1[4] = mat[4]; - mat1[5] = mat[5]; - SplashCoord det = mat1[0] * mat1[3] - mat1[1] * mat1[2]; - if (splashAbs(det) < 1e-6) { - // this should be caught by the singular matrix check in drawImage - return splashErrSingularMatrix; - } - SplashCoord invMat[6]; - invMat[0] = mat1[3] / det; - invMat[1] = -mat1[1] / det; - invMat[2] = -mat1[2] / det; - invMat[3] = mat1[0] / det; - // the extra "+ 0.5 * (...)" terms are here because the - // drawImageArbitrary(No)Interp functions multiply by pixel - // centers, (x + 0.5, y + 0.5) - invMat[4] = (mat1[2] * mat1[5] - mat1[3] * mat1[4]) / det - + (invMat[0] + invMat[2]) * 0.5; - invMat[5] = (mat1[1] * mat1[4] - mat1[0] * mat1[5]) / det - + (invMat[1] + invMat[3]) * 0.5; - - Guchar *scaledColor, *scaledAlpha; - GBool freeScaledImage; - getScaledImage(imageTag, src, srcData, w, h, nComps, - scaledWidth, scaledHeight, srcMode, srcAlpha, interpolate, - &scaledColor, &scaledAlpha, &freeScaledImage); - - // draw it - if (interpolate) { - drawImageArbitraryInterp(scaledColor, scaledAlpha, - &dd, drawRowFunc, invMat, - scaledWidth, scaledHeight, - xMin, yMin, xMax, yMax, - nComps, srcAlpha); - } else { - drawImageArbitraryNoInterp(scaledColor, scaledAlpha, - &dd, drawRowFunc, invMat, - scaledWidth, scaledHeight, - xMin, yMin, xMax, yMax, - nComps, srcAlpha); - } - - // free the downscaled/unscaled image - if (freeScaledImage) { - gfree(scaledColor); - gfree(scaledAlpha); - } - } - - return splashOk; -} - -ImageScaler *Splash::getImageScaler(GString *imageTag, - SplashImageSource src, void *srcData, - int w, int h, int nComps, - int scaledWidth, int scaledHeight, - SplashColorMode srcMode, - GBool srcAlpha, GBool interpolate) { - // Notes: - // - // * If the scaled image width or height is greater than 2000, we - // don't cache it. - // - // * Caching is done on the third consecutive use (second - // consecutive reuse) of an image; this avoids overhead on the - // common case of single-use images. - - if (scaledWidth < 2000 && scaledHeight < 2000 && - imageCache->match(imageTag, scaledWidth, scaledHeight, - srcMode, srcAlpha, interpolate)) { - if (imageCache->colorData) { - return new ReplayImageScaler(nComps, srcAlpha, scaledWidth, - imageCache->colorData, - imageCache->alphaData); - } else { - int lineSize; - if (scaledWidth < INT_MAX / nComps) { - lineSize = scaledWidth * nComps; - } else { - lineSize = -1; - } - imageCache->colorData = (Guchar *)gmallocn(scaledHeight, lineSize); - if (srcAlpha) { - imageCache->alphaData = (Guchar *)gmallocn(scaledHeight, scaledWidth); - } - return new SavingImageScaler(src, srcData, - w, h, nComps, srcAlpha, - scaledWidth, scaledHeight, - interpolate, - imageCache->colorData, - imageCache->alphaData); - } - } else { - imageCache->reset(imageTag, scaledWidth, scaledHeight, - srcMode, srcAlpha, interpolate); - return new BasicImageScaler(src, srcData, - w, h, nComps, srcAlpha, - scaledWidth, scaledHeight, - interpolate); - } -} - -void Splash::getScaledImage(GString *imageTag, - SplashImageSource src, void *srcData, - int w, int h, int nComps, - int scaledWidth, int scaledHeight, - SplashColorMode srcMode, - GBool srcAlpha, GBool interpolate, - Guchar **scaledColor, Guchar **scaledAlpha, - GBool *freeScaledImage) { - // Notes: - // - // * If the scaled image width or height is greater than 2000, we - // don't cache it. - // - // * This buffers the whole image anyway, so there's no reason to - // skip caching on the first reuse. - - if (scaledWidth >= 2000 || scaledHeight >= 2000) { - int lineSize; - if (scaledWidth < INT_MAX / nComps) { - lineSize = scaledWidth * nComps; - } else { - lineSize = -1; - } - *scaledColor = (Guchar *)gmallocn(scaledHeight, lineSize); - if (srcAlpha) { - *scaledAlpha = (Guchar *)gmallocn(scaledHeight, scaledWidth); - } else { - *scaledAlpha = NULL; - } - *freeScaledImage = gTrue; - if (scaledWidth == w && scaledHeight == h) { - Guchar *colorPtr = *scaledColor; - Guchar *alphaPtr = *scaledAlpha; - for (int y = 0; y < scaledHeight; ++y) { - (*src)(srcData, colorPtr, alphaPtr); - colorPtr += scaledWidth * nComps; - if (srcAlpha) { - alphaPtr += scaledWidth; - } - } - } else { - BasicImageScaler scaler(src, srcData, w, h, nComps, srcAlpha, - scaledWidth, scaledHeight, interpolate); - Guchar *colorPtr = *scaledColor; - Guchar *alphaPtr = *scaledAlpha; - for (int y = 0; y < scaledHeight; ++y) { - scaler.nextLine(); - memcpy(colorPtr, scaler.colorData(), scaledWidth * nComps); - colorPtr += scaledWidth * nComps; - if (srcAlpha) { - memcpy(alphaPtr, scaler.alphaData(), scaledWidth); - alphaPtr += scaledWidth; - } - } - } - } else { - if (!imageCache->match(imageTag, scaledWidth, scaledHeight, - srcMode, srcAlpha, interpolate) || - !imageCache->colorData) { - imageCache->reset(imageTag, scaledWidth, scaledHeight, - srcMode, srcAlpha, interpolate); - int lineSize; - if (scaledWidth < INT_MAX / nComps) { - lineSize = scaledWidth * nComps; - } else { - lineSize = -1; - } - imageCache->colorData = (Guchar *)gmallocn(scaledHeight, lineSize); - if (srcAlpha) { - imageCache->alphaData = (Guchar *)gmallocn(scaledHeight, scaledWidth); - } - if (scaledWidth == w && scaledHeight == h) { - Guchar *colorPtr = imageCache->colorData; - Guchar *alphaPtr = imageCache->alphaData; - for (int y = 0; y < scaledHeight; ++y) { - (*src)(srcData, colorPtr, alphaPtr); - colorPtr += scaledWidth * nComps; - if (srcAlpha) { - alphaPtr += scaledWidth; - } - } - } else { - SavingImageScaler scaler(src, srcData, w, h, nComps, srcAlpha, - scaledWidth, scaledHeight, interpolate, - imageCache->colorData, imageCache->alphaData); - Guchar *colorPtr = imageCache->colorData; - Guchar *alphaPtr = imageCache->alphaData; - for (int y = 0; y < scaledHeight; ++y) { - scaler.nextLine(); - memcpy(colorPtr, scaler.colorData(), scaledWidth * nComps); - colorPtr += scaledWidth * nComps; - if (srcAlpha) { - memcpy(alphaPtr, scaler.alphaData(), scaledWidth); - alphaPtr += scaledWidth; - } - } - } - } - *scaledColor = imageCache->colorData; - *scaledAlpha = imageCache->alphaData; - *freeScaledImage = gFalse; - } -} - -void Splash::drawImageArbitraryNoInterp(Guchar *scaledColor, - Guchar *scaledAlpha, - SplashDrawImageRowData *dd, - SplashDrawImageRowFunc drawRowFunc, - SplashCoord *invMat, - int scaledWidth, int scaledHeight, - int xMin, int yMin, int xMax, int yMax, - int nComps, GBool srcAlpha) { - int tt = state->clip->getXMinI(state->strokeAdjust); - if (tt > xMin) { - xMin = tt; - } - tt = state->clip->getXMaxI(state->strokeAdjust) + 1; - if (tt < xMax) { - xMax = tt; - } - tt = state->clip->getYMinI(state->strokeAdjust); - if (tt > yMin) { - yMin = tt; - } - tt = state->clip->getYMaxI(state->strokeAdjust) + 1; - if (tt < yMax) { - yMax = tt; - } - if (xMax <= xMin || yMax <= yMin) { - return; - } - - Guchar *colorBuf = (Guchar *)gmallocn(xMax - xMin, nComps); - Guchar *alphaBuf = NULL; - if (srcAlpha) { - alphaBuf = (Guchar *)gmalloc(xMax - xMin); - } - - for (int y = yMin; y < yMax; ++y) { - int rowMin = xMax; - int rowMax = 0; - for (int x = xMin; x < xMax; ++x) { - // note: invMat includes a "+0.5" factor so that this is really - // a multiply by (x+0.5, y+0.5) - int xx = splashFloor((SplashCoord)x * invMat[0] - + (SplashCoord)y * invMat[2] + invMat[4]); - int yy = splashFloor((SplashCoord)x * invMat[1] - + (SplashCoord)y * invMat[3] + invMat[5]); - if (xx >= 0 && xx < scaledWidth && - yy >= 0 && yy < scaledHeight) { - Guchar *p = scaledColor + (yy * scaledWidth + xx) * nComps; - Guchar *q = colorBuf + (x - xMin) * nComps; - for (int i = 0; i < nComps; ++i) { - *q++ = *p++; - } - if (srcAlpha) { - alphaBuf[x - xMin] = scaledAlpha[yy * scaledWidth + xx]; - } - if (x < rowMin) { - rowMin = x; - } - rowMax = x + 1; - } - } - if (rowMin < rowMax) { - (this->*drawRowFunc)(dd, - colorBuf + (rowMin - xMin) * nComps, - alphaBuf + (rowMin - xMin), - rowMin, y, rowMax - rowMin); - } - } - - gfree(colorBuf); - gfree(alphaBuf); -} - -void Splash::drawImageArbitraryInterp(Guchar *scaledColor, Guchar *scaledAlpha, - SplashDrawImageRowData *dd, - SplashDrawImageRowFunc drawRowFunc, - SplashCoord *invMat, - int scaledWidth, int scaledHeight, - int xMin, int yMin, int xMax, int yMax, - int nComps, GBool srcAlpha) { - int tt = state->clip->getXMinI(state->strokeAdjust); - if (tt > xMin) { - xMin = tt; - } - tt = state->clip->getXMaxI(state->strokeAdjust) + 1; - if (tt < xMax) { - xMax = tt; - } - tt = state->clip->getYMinI(state->strokeAdjust); - if (tt > yMin) { - yMin = tt; - } - tt = state->clip->getYMaxI(state->strokeAdjust) + 1; - if (tt < yMax) { - yMax = tt; - } - if (xMax <= xMin || yMax <= yMin) { - return; - } - - Guchar *colorBuf = (Guchar *)gmallocn(xMax - xMin, nComps); - Guchar *alphaBuf = NULL; - if (srcAlpha) { - alphaBuf = (Guchar *)gmalloc(xMax - xMin); - } - - for (int y = yMin; y < yMax; ++y) { - int rowMin = xMax; - int rowMax = 0; - for (int x = xMin; x < xMax; ++x) { - // note: invMat includes a "+0.5" factor so that this is really - // a multiply by (x+0.5, y+0.5) - SplashCoord xs = (SplashCoord)x * invMat[0] - + (SplashCoord)y * invMat[2] + invMat[4]; - SplashCoord ys = (SplashCoord)x * invMat[1] - + (SplashCoord)y * invMat[3] + invMat[5]; - int x0 = splashFloor(xs - 0.5); - int x1 = x0 + 1; - int y0 = splashFloor(ys - 0.5); - int y1 = y0 + 1; - if (x1 >= 0 && x0 < scaledWidth && y1 >= 0 && y0 < scaledHeight) { - SplashCoord sx0 = (SplashCoord)x1 + 0.5 - xs; - SplashCoord sx1 = (SplashCoord)1 - sx0; - SplashCoord sy0 = (SplashCoord)y1 + 0.5 - ys; - SplashCoord sy1 = (SplashCoord)1 - sy0; - if (x0 < 0) { - x0 = 0; - } - if (x1 >= scaledWidth) { - x1 = scaledWidth - 1; - } - if (y0 < 0) { - y0 = 0; - } - if (y1 >= scaledHeight) { - y1 = scaledHeight - 1; - } - Guchar *p00 = scaledColor + (y0 * scaledWidth + x0) * nComps; - Guchar *p10 = scaledColor + (y0 * scaledWidth + x1) * nComps; - Guchar *p01 = scaledColor + (y1 * scaledWidth + x0) * nComps; - Guchar *p11 = scaledColor + (y1 * scaledWidth + x1) * nComps; - Guchar *q = colorBuf + (x - xMin) * nComps; - for (int i = 0; i < nComps; ++i) { - *q++ = (Guchar)(int)(sx0 * (sy0 * (int)*p00++ + sy1 * (int)*p01++) + - sx1 * (sy0 * (int)*p10++ + sy1 * (int)*p11++)); - } - if (srcAlpha) { - p00 = scaledAlpha + (y0 * scaledWidth + x0); - p10 = scaledAlpha + (y0 * scaledWidth + x1); - p01 = scaledAlpha + (y1 * scaledWidth + x0); - p11 = scaledAlpha + (y1 * scaledWidth + x1); - q = alphaBuf + (x - xMin); - *q = (Guchar)(int)(sx0 * (sy0 * (int)*p00 + sy1 * (int)*p01) + - sx1 * (sy0 * (int)*p10 + sy1 * (int)*p11)); - } - if (x < rowMin) { - rowMin = x; - } - rowMax = x + 1; - } - } - if (rowMin < rowMax) { - (this->*drawRowFunc)(dd, - colorBuf + (rowMin - xMin) * nComps, - alphaBuf + (rowMin - xMin), - rowMin, y, rowMax - rowMin); - } - } - - gfree(colorBuf); - gfree(alphaBuf); -} - -void Splash::mirrorImageRow(Guchar *colorIn, Guchar *alphaIn, - Guchar *colorOut, Guchar *alphaOut, - int width, int nComps, GBool srcAlpha) { - Guchar *p, *q; - - p = colorIn; - q = colorOut + (width - 1) * nComps; - for (int i = 0; i < width; ++i) { - for (int j = 0; j < nComps; ++j) { - q[j] = p[j]; - } - p += nComps; - q -= nComps; - } - - if (srcAlpha) { - p = alphaIn; - q = alphaOut + (width - 1); - for (int i = 0; i < width; ++i) { - *q = *p; - ++p; - --q; - } - } -} - -void Splash::drawImageRowNoClipNoAlpha(SplashDrawImageRowData *data, - Guchar *colorData, Guchar *alphaData, - int x, int y, int width) { - (this->*data->pipe.run)(&data->pipe, x, x + width - 1, y, NULL, colorData); -} - -void Splash::drawImageRowNoClipAlpha(SplashDrawImageRowData *data, - Guchar *colorData, Guchar *alphaData, - int x, int y, int width) { - (this->*data->pipe.run)(&data->pipe, x, x + width - 1, y, - alphaData, colorData); -} - -void Splash::drawImageRowClipNoAlphaNoAA(SplashDrawImageRowData *data, - Guchar *colorData, - Guchar *alphaData, - int x, int y, int width) { - if (y < 0 || y >= bitmap->height) { - return; - } - if (x < 0) { - colorData -= x * data->nComps; - width += x; - x = 0; - } - if (x + width > bitmap->width) { - width = bitmap->width - x; - } - if (width <= 0) { - return; - } - memset(scanBuf + x, 0xff, width); - state->clip->clipSpanBinary(scanBuf, y, x, x + width - 1, - state->strokeAdjust); - (this->*data->pipe.run)(&data->pipe, x, x + width - 1, y, - scanBuf + x, colorData); -} - -void Splash::drawImageRowClipNoAlphaAA(SplashDrawImageRowData *data, - Guchar *colorData, - Guchar *alphaData, - int x, int y, int width) { - if (y < 0 || y >= bitmap->height) { - return; - } - if (x < 0) { - colorData -= x * data->nComps; - width += x; - x = 0; - } - if (x + width > bitmap->width) { - width = bitmap->width - x; - } - if (width <= 0) { - return; - } - memset(scanBuf + x, 0xff, width); - state->clip->clipSpan(scanBuf, y, x, x + width - 1, state->strokeAdjust); - (this->*data->pipe.run)(&data->pipe, x, x + width - 1, y, - scanBuf + x, colorData); -} - -void Splash::drawImageRowClipAlphaNoAA(SplashDrawImageRowData *data, - Guchar *colorData, - Guchar *alphaData, - int x, int y, int width) { - if (y < 0 || y >= bitmap->height) { - return; - } - if (x < 0) { - colorData -= x * data->nComps; - alphaData -= x; - width += x; - x = 0; - } - if (x + width > bitmap->width) { - width = bitmap->width - x; - } - if (width <= 0) { - return; - } - memcpy(scanBuf + x, alphaData, width); - state->clip->clipSpanBinary(scanBuf, y, x, x + width - 1, - state->strokeAdjust); - (this->*data->pipe.run)(&data->pipe, x, x + width - 1, y, - scanBuf + x, colorData); -} - -void Splash::drawImageRowClipAlphaAA(SplashDrawImageRowData *data, - Guchar *colorData, - Guchar *alphaData, - int x, int y, int width) { - if (y < 0 || y >= bitmap->height) { - return; - } - if (x < 0) { - colorData -= x * data->nComps; - alphaData -= x; - width += x; - x = 0; - } - if (x + width > bitmap->width) { - width = bitmap->width - x; - } - if (width <= 0) { - return; - } - memcpy(scanBuf + x, alphaData, width); - state->clip->clipSpan(scanBuf, y, x, x + width - 1, state->strokeAdjust); - (this->*data->pipe.run)(&data->pipe, x, x + width - 1, y, - scanBuf + x, colorData); -} - -SplashError Splash::composite(SplashBitmap *src, int xSrc, int ySrc, - int xDest, int yDest, int w, int h, - GBool noClip, GBool nonIsolated) { - SplashPipe pipe; - Guchar *mono1Ptr, *lineBuf, *linePtr; - Guchar mono1Mask, b; - int x0, x1, x, y0, y1, y, t; - - if (!(src->mode == bitmap->mode || - (src->mode == splashModeMono8 && bitmap->mode == splashModeMono1) || - (src->mode == splashModeRGB8 && bitmap->mode == splashModeBGR8))) { - return splashErrModeMismatch; - } - - pipeInit(&pipe, NULL, - (Guchar)splashRound(state->fillAlpha * 255), - !noClip || src->alpha != NULL, nonIsolated); - if (src->mode == splashModeMono1) { - // in mono1 mode, pipeRun expects the source to be in mono8 - // format, so we need to extract the source color values into - // scanBuf, expanding them from mono1 to mono8 - if (noClip) { - if (src->alpha) { - for (y = 0; y < h; ++y) { - mono1Ptr = src->data + (ySrc + y) * src->rowSize + (xSrc >> 3); - mono1Mask = (Guchar)(0x80 >> (xSrc & 7)); - for (x = 0; x < w; ++x) { - scanBuf[x] = (*mono1Ptr & mono1Mask) ? 0xff : 0x00; - mono1Ptr += mono1Mask & 1; - mono1Mask = (Guchar)((mono1Mask << 7) | (mono1Mask >> 1)); - } - // this uses shape instead of alpha, which isn't technically - // correct, but works out the same - (this->*pipe.run)(&pipe, xDest, xDest + w - 1, yDest + y, - src->alpha + - (ySrc + y) * src->alphaRowSize + xSrc, - scanBuf); - } - } else { - for (y = 0; y < h; ++y) { - mono1Ptr = src->data + (ySrc + y) * src->rowSize + (xSrc >> 3); - mono1Mask = (Guchar)(0x80 >> (xSrc & 7)); - for (x = 0; x < w; ++x) { - scanBuf[x] = (*mono1Ptr & mono1Mask) ? 0xff : 0x00; - mono1Ptr += mono1Mask & 1; - mono1Mask = (Guchar)((mono1Mask << 7) | (mono1Mask >> 1)); - } - (this->*pipe.run)(&pipe, xDest, xDest + w - 1, yDest + y, - NULL, - scanBuf); - } - } - } else { - x0 = xDest; - if ((t = state->clip->getXMinI(state->strokeAdjust)) > x0) { - x0 = t; - } - x1 = xDest + w; - if ((t = state->clip->getXMaxI(state->strokeAdjust) + 1) < x1) { - x1 = t; - } - y0 = yDest; - if ((t = state->clip->getYMinI(state->strokeAdjust)) > y0) { - y0 = t; - } - y1 = yDest + h; - if ((t = state->clip->getYMaxI(state->strokeAdjust) + 1) < y1) { - y1 = t; - } - if (x0 < x1 && y0 < y1) { - if (src->alpha) { - for (y = y0; y < y1; ++y) { - mono1Ptr = src->data - + (ySrc + y - yDest) * src->rowSize - + ((xSrc + x0 - xDest) >> 3); - mono1Mask = (Guchar)(0x80 >> ((xSrc + x0 - xDest) & 7)); - for (x = x0; x < x1; ++x) { - scanBuf[x] = (*mono1Ptr & mono1Mask) ? 0xff : 0x00; - mono1Ptr += mono1Mask & 1; - mono1Mask = (Guchar)((mono1Mask << 7) | (mono1Mask >> 1)); - } - memcpy(scanBuf2 + x0, - src->alpha + (ySrc + y - yDest) * src->alphaRowSize + - (xSrc + x0 - xDest), - x1 - x0); - if (!state->clip->clipSpanBinary(scanBuf2, y, x0, x1 - 1, - state->strokeAdjust)) { - continue; - } - // this uses shape instead of alpha, which isn't technically - // correct, but works out the same - (this->*pipe.run)(&pipe, x0, x1 - 1, y, - scanBuf2 + x0, - scanBuf + x0); - } - } else { - for (y = y0; y < y1; ++y) { - mono1Ptr = src->data - + (ySrc + y - yDest) * src->rowSize - + ((xSrc + x0 - xDest) >> 3); - mono1Mask = (Guchar)(0x80 >> ((xSrc + x0 - xDest) & 7)); - for (x = x0; x < x1; ++x) { - scanBuf[x] = (*mono1Ptr & mono1Mask) ? 0xff : 0x00; - mono1Ptr += mono1Mask & 1; - mono1Mask = (Guchar)((mono1Mask << 7) | (mono1Mask >> 1)); - } - memset(scanBuf2 + x0, 0xff, x1 - x0); - if (!state->clip->clipSpanBinary(scanBuf2, y, x0, x1 - 1, - state->strokeAdjust)) { - continue; - } - (this->*pipe.run)(&pipe, x0, x1 - 1, y, - scanBuf2 + x0, - scanBuf + x0); - } - } - } - } - - } else if (src->mode == splashModeBGR8) { - // in BGR8 mode, pipeRun expects the source to be in RGB8 format, - // so we need to swap bytes - lineBuf = (Guchar *)gmallocn(w, 3); - if (noClip) { - if (src->alpha) { - for (y = 0; y < h; ++y) { - memcpy(lineBuf, - src->data + (ySrc + y) * src->rowSize + xSrc * 3, - w * 3); - for (x = 0, linePtr = lineBuf; x < w; ++x, linePtr += 3) { - b = linePtr[0]; - linePtr[0] = linePtr[2]; - linePtr[2] = b; - } - // this uses shape instead of alpha, which isn't technically - // correct, but works out the same - (this->*pipe.run)(&pipe, xDest, xDest + w - 1, yDest + y, - src->alpha + - (ySrc + y) * src->alphaRowSize + xSrc, - lineBuf); - } - } else { - for (y = 0; y < h; ++y) { - memcpy(lineBuf, - src->data + (ySrc + y) * src->rowSize + xSrc * 3, - w * 3); - for (x = 0, linePtr = lineBuf; x < w; ++x, linePtr += 3) { - b = linePtr[0]; - linePtr[0] = linePtr[2]; - linePtr[2] = b; - } - (this->*pipe.run)(&pipe, xDest, xDest + w - 1, yDest + y, - NULL, lineBuf); - } - } - } else { - x0 = xDest; - if ((t = state->clip->getXMinI(state->strokeAdjust)) > x0) { - x0 = t; - } - x1 = xDest + w; - if ((t = state->clip->getXMaxI(state->strokeAdjust) + 1) < x1) { - x1 = t; - } - y0 = yDest; - if ((t = state->clip->getYMinI(state->strokeAdjust)) > y0) { - y0 = t; - } - y1 = yDest + h; - if ((t = state->clip->getYMaxI(state->strokeAdjust) + 1) < y1) { - y1 = t; - } - if (x0 < x1 && y0 < y1) { - if (src->alpha) { - for (y = y0; y < y1; ++y) { - memcpy(scanBuf + x0, - src->alpha + (ySrc + y - yDest) * src->alphaRowSize + - (xSrc + x0 - xDest), - x1 - x0); - state->clip->clipSpan(scanBuf, y, x0, x1 - 1, state->strokeAdjust); - memcpy(lineBuf, - src->data + - (ySrc + y - yDest) * src->rowSize + - (xSrc + x0 - xDest) * 3, - (x1 - x0) * 3); - for (x = 0, linePtr = lineBuf; x < x1 - x0; ++x, linePtr += 3) { - b = linePtr[0]; - linePtr[0] = linePtr[2]; - linePtr[2] = b; - } - // this uses shape instead of alpha, which isn't technically - // correct, but works out the same - (this->*pipe.run)(&pipe, x0, x1 - 1, y, - scanBuf + x0, lineBuf); - } - } else { - for (y = y0; y < y1; ++y) { - memset(scanBuf + x0, 0xff, x1 - x0); - state->clip->clipSpan(scanBuf, y, x0, x1 - 1, state->strokeAdjust); - memcpy(lineBuf, - src->data + - (ySrc + y - yDest) * src->rowSize + - (xSrc + x0 - xDest) * 3, - (x1 - x0) * 3); - for (x = 0, linePtr = lineBuf; x < x1 - x0; ++x, linePtr += 3) { - b = linePtr[0]; - linePtr[0] = linePtr[2]; - linePtr[2] = b; - } - (this->*pipe.run)(&pipe, x0, x1 - 1, yDest + y, - scanBuf + x0, - src->data + - (ySrc + y - yDest) * src->rowSize + - (xSrc + x0 - xDest) * bitmapComps); - } - } - } - } - gfree(lineBuf); - - } else { // src->mode not mono1 or BGR8 - if (noClip) { - if (src->alpha) { - for (y = 0; y < h; ++y) { - // this uses shape instead of alpha, which isn't technically - // correct, but works out the same - (this->*pipe.run)(&pipe, xDest, xDest + w - 1, yDest + y, - src->alpha + - (ySrc + y) * src->alphaRowSize + xSrc, - src->data + (ySrc + y) * src->rowSize + - xSrc * bitmapComps); - } - } else { - for (y = 0; y < h; ++y) { - (this->*pipe.run)(&pipe, xDest, xDest + w - 1, yDest + y, - NULL, - src->data + (ySrc + y) * src->rowSize + - xSrc * bitmapComps); - } - } - } else { - x0 = xDest; - if ((t = state->clip->getXMinI(state->strokeAdjust)) > x0) { - x0 = t; - } - x1 = xDest + w; - if ((t = state->clip->getXMaxI(state->strokeAdjust) + 1) < x1) { - x1 = t; - } - y0 = yDest; - if ((t = state->clip->getYMinI(state->strokeAdjust)) > y0) { - y0 = t; - } - y1 = yDest + h; - if ((t = state->clip->getYMaxI(state->strokeAdjust) + 1) < y1) { - y1 = t; - } - if (x0 < x1 && y0 < y1) { - if (src->alpha) { - for (y = y0; y < y1; ++y) { - memcpy(scanBuf + x0, - src->alpha + (ySrc + y - yDest) * src->alphaRowSize + - (xSrc + x0 - xDest), - x1 - x0); - state->clip->clipSpan(scanBuf, y, x0, x1 - 1, state->strokeAdjust); - // this uses shape instead of alpha, which isn't technically - // correct, but works out the same - (this->*pipe.run)(&pipe, x0, x1 - 1, y, - scanBuf + x0, - src->data + - (ySrc + y - yDest) * src->rowSize + - (xSrc + x0 - xDest) * bitmapComps); - } - } else { - for (y = y0; y < y1; ++y) { - memset(scanBuf + x0, 0xff, x1 - x0); - state->clip->clipSpan(scanBuf, y, x0, x1 - 1, state->strokeAdjust); - (this->*pipe.run)(&pipe, x0, x1 - 1, yDest + y, - scanBuf + x0, - src->data + - (ySrc + y - yDest) * src->rowSize + - (xSrc + x0 - xDest) * bitmapComps); - } - } - } - } - } - - return splashOk; -} - -SplashError Splash::compositeWithOverprint(SplashBitmap *src, - Guint *srcOverprintMaskBitmap, - int xSrc, int ySrc, - int xDest, int yDest, int w, int h, - GBool noClip, GBool nonIsolated) { - SplashPipe pipe; - int x0, x1, y0, y1, y, t; - - if (!(src->mode == bitmap->mode || - (src->mode == splashModeMono8 && bitmap->mode == splashModeMono1) || - (src->mode == splashModeRGB8 && bitmap->mode == splashModeBGR8))) { - return splashErrModeMismatch; - } - - pipeInit(&pipe, NULL, - (Guchar)splashRound(state->fillAlpha * 255), - !noClip || src->alpha != NULL, nonIsolated, gTrue); - - if (noClip) { - if (src->alpha) { - for (y = 0; y < h; ++y) { - pipe.srcOverprintMaskPtr = srcOverprintMaskBitmap + y * w + xSrc; - // this uses shape instead of alpha, which isn't technically - // correct, but works out the same - (this->*pipe.run)(&pipe, xDest, xDest + w - 1, yDest + y, - src->alpha + - (ySrc + y) * src->alphaRowSize + xSrc, - src->data + (ySrc + y) * src->rowSize + - xSrc * bitmapComps); - } - } else { - for (y = 0; y < h; ++y) { - pipe.srcOverprintMaskPtr = srcOverprintMaskBitmap + y * w + xSrc; - (this->*pipe.run)(&pipe, xDest, xDest + w - 1, yDest + y, - NULL, - src->data + (ySrc + y) * src->rowSize + - xSrc * bitmapComps); - } - } - } else { - x0 = xDest; - if ((t = state->clip->getXMinI(state->strokeAdjust)) > x0) { - x0 = t; - } - x1 = xDest + w; - if ((t = state->clip->getXMaxI(state->strokeAdjust) + 1) < x1) { - x1 = t; - } - y0 = yDest; - if ((t = state->clip->getYMinI(state->strokeAdjust)) > y0) { - y0 = t; - } - y1 = yDest + h; - if ((t = state->clip->getYMaxI(state->strokeAdjust) + 1) < y1) { - y1 = t; - } - if (x0 < x1 && y0 < y1) { - if (src->alpha) { - for (y = y0; y < y1; ++y) { - memcpy(scanBuf + x0, - src->alpha + (ySrc + y - yDest) * src->alphaRowSize + - (xSrc + x0 - xDest), - x1 - x0); - state->clip->clipSpan(scanBuf, y, x0, x1 - 1, state->strokeAdjust); - pipe.srcOverprintMaskPtr = srcOverprintMaskBitmap - + (ySrc + y - yDest) * w - + (xSrc + x0 - xDest); - // this uses shape instead of alpha, which isn't technically - // correct, but works out the same - (this->*pipe.run)(&pipe, x0, x1 - 1, y, - scanBuf + x0, - src->data + - (ySrc + y - yDest) * src->rowSize + - (xSrc + x0 - xDest) * bitmapComps); - } - } else { - for (y = y0; y < y1; ++y) { - memset(scanBuf + x0, 0xff, x1 - x0); - state->clip->clipSpan(scanBuf, y, x0, x1 - 1, state->strokeAdjust); - pipe.srcOverprintMaskPtr = srcOverprintMaskBitmap - + (ySrc + y - yDest) * w - + (xSrc + x0 - xDest); - (this->*pipe.run)(&pipe, x0, x1 - 1, y, - scanBuf + x0, - src->data + - (ySrc + y - yDest) * src->rowSize + - (xSrc + x0 - xDest) * bitmapComps); - } - } - } - } - - return splashOk; -} - -void Splash::compositeBackground(SplashColorPtr color) { - SplashColorPtr p; - Guchar *q; - Guchar alpha, alpha1, c, color0, color1, color2, mask; -#if SPLASH_CMYK - Guchar color3; -#endif - int x, y; - - switch (bitmap->mode) { - case splashModeMono1: - color0 = color[0]; - for (y = 0; y < bitmap->height; ++y) { - p = &bitmap->data[y * bitmap->rowSize]; - q = &bitmap->alpha[y * bitmap->alphaRowSize]; - mask = 0x80; - for (x = 0; x < bitmap->width; ++x) { - alpha = *q++; - if (alpha == 0) { - if (color0 & 0x80) { - *p |= mask; - } else { - *p &= (Guchar)~mask; - } - } else if (alpha != 255) { - alpha1 = (Guchar)(255 - alpha); - c = (*p & mask) ? 0xff : 0x00; - c = div255(alpha1 * color0 + alpha * c); - if (c & 0x80) { - *p |= mask; - } else { - *p &= (Guchar)~mask; - } - } - if (!(mask = (Guchar)(mask >> 1))) { - mask = 0x80; - ++p; - } - } - } - break; - case splashModeMono8: - color0 = color[0]; - for (y = 0; y < bitmap->height; ++y) { - p = &bitmap->data[y * bitmap->rowSize]; - q = &bitmap->alpha[y * bitmap->alphaRowSize]; - for (x = 0; x < bitmap->width; ++x) { - alpha = *q++; - if (alpha == 0) { - p[0] = color0; - } else if (alpha != 255) { - alpha1 = (Guchar)(255 - alpha); - p[0] = div255(alpha1 * color0 + alpha * p[0]); - } - ++p; - } - } - break; - case splashModeRGB8: - case splashModeBGR8: - color0 = color[0]; - color1 = color[1]; - color2 = color[2]; - for (y = 0; y < bitmap->height; ++y) { - p = &bitmap->data[y * bitmap->rowSize]; - q = &bitmap->alpha[y * bitmap->alphaRowSize]; - for (x = 0; x < bitmap->width; ++x) { - alpha = *q++; - if (alpha == 0) { - p[0] = color0; - p[1] = color1; - p[2] = color2; - } else if (alpha != 255) { - alpha1 = (Guchar)(255 - alpha); - p[0] = div255(alpha1 * color0 + alpha * p[0]); - p[1] = div255(alpha1 * color1 + alpha * p[1]); - p[2] = div255(alpha1 * color2 + alpha * p[2]); - } - p += 3; - } - } - break; -#if SPLASH_CMYK - case splashModeCMYK8: - color0 = color[0]; - color1 = color[1]; - color2 = color[2]; - color3 = color[3]; - for (y = 0; y < bitmap->height; ++y) { - p = &bitmap->data[y * bitmap->rowSize]; - q = &bitmap->alpha[y * bitmap->alphaRowSize]; - for (x = 0; x < bitmap->width; ++x) { - alpha = *q++; - if (alpha == 0) { - p[0] = color0; - p[1] = color1; - p[2] = color2; - p[3] = color3; - } else if (alpha != 255) { - alpha1 = (Guchar)(255 - alpha); - p[0] = div255(alpha1 * color0 + alpha * p[0]); - p[1] = div255(alpha1 * color1 + alpha * p[1]); - p[2] = div255(alpha1 * color2 + alpha * p[2]); - p[3] = div255(alpha1 * color3 + alpha * p[3]); - } - p += 4; - } - } - break; -#endif - } - memset(bitmap->alpha, 255, bitmap->alphaRowSize * bitmap->height); -} - -SplashError Splash::blitTransparent(SplashBitmap *src, int xSrc, int ySrc, - int xDest, int yDest, int w, int h) { - SplashColorPtr p, q; - Guchar mask, srcMask; - int x, y; - - if (src->mode != bitmap->mode) { - return splashErrModeMismatch; - } - - switch (bitmap->mode) { - case splashModeMono1: - for (y = 0; y < h; ++y) { - p = &bitmap->data[(yDest + y) * bitmap->rowSize + (xDest >> 3)]; - mask = (Guchar)(0x80 >> (xDest & 7)); - q = &src->data[(ySrc + y) * src->rowSize + (xSrc >> 3)]; - srcMask = (Guchar)(0x80 >> (xSrc & 7)); - for (x = 0; x < w; ++x) { - if (*q & srcMask) { - *p |= mask; - } else { - *p &= (Guchar)~mask; - } - if (!(mask = (Guchar)(mask >> 1))) { - mask = 0x80; - ++p; - } - if (!(srcMask = (Guchar)(srcMask >> 1))) { - srcMask = 0x80; - ++q; - } - } - } - break; - case splashModeMono8: - for (y = 0; y < h; ++y) { - p = &bitmap->data[(yDest + y) * bitmap->rowSize + xDest]; - q = &src->data[(ySrc + y) * src->rowSize + xSrc]; - memcpy(p, q, w); - } - break; - case splashModeRGB8: - case splashModeBGR8: - for (y = 0; y < h; ++y) { - p = &bitmap->data[(yDest + y) * bitmap->rowSize + 3 * xDest]; - q = &src->data[(ySrc + y) * src->rowSize + 3 * xSrc]; - memcpy(p, q, 3 * w); - } - break; -#if SPLASH_CMYK - case splashModeCMYK8: - for (y = 0; y < h; ++y) { - p = &bitmap->data[(yDest + y) * bitmap->rowSize + 4 * xDest]; - q = &src->data[(ySrc + y) * src->rowSize + 4 * xSrc]; - memcpy(p, q, 4 * w); - } - break; -#endif - } - - if (bitmap->alpha) { - for (y = 0; y < h; ++y) { - q = &bitmap->alpha[(yDest + y) * bitmap->alphaRowSize + xDest]; - memset(q, 0, w); - } - } - - return splashOk; -} - -SplashError Splash::blitCorrectedAlpha(SplashBitmap *dest, int xSrc, int ySrc, - int xDest, int yDest, int w, int h) { - SplashColorPtr p, q; - Guchar *alpha0Ptr; - Guchar alpha0, aSrc, mask, srcMask; - int x, y; - - if (bitmap->mode != dest->mode || - !bitmap->alpha || - !dest->alpha || - !groupBackBitmap) { - return splashErrModeMismatch; - } - - switch (bitmap->mode) { - case splashModeMono1: - for (y = 0; y < h; ++y) { - p = &dest->data[(yDest + y) * dest->rowSize + (xDest >> 3)]; - mask = (Guchar)(0x80 >> (xDest & 7)); - q = &bitmap->data[(ySrc + y) * bitmap->rowSize + (xSrc >> 3)]; - srcMask = (Guchar)(0x80 >> (xSrc & 7)); - for (x = 0; x < w; ++x) { - if (*q & srcMask) { - *p |= mask; - } else { - *p &= (Guchar)~mask; - } - if (!(mask = (Guchar)(mask >> 1))) { - mask = 0x80; - ++p; - } - if (!(srcMask = (Guchar)(srcMask >> 1))) { - srcMask = 0x80; - ++q; - } - } - } - break; - case splashModeMono8: - for (y = 0; y < h; ++y) { - p = &dest->data[(yDest + y) * dest->rowSize + xDest]; - q = &bitmap->data[(ySrc + y) * bitmap->rowSize + xSrc]; - memcpy(p, q, w); - } - break; - case splashModeRGB8: - case splashModeBGR8: - for (y = 0; y < h; ++y) { - p = &dest->data[(yDest + y) * dest->rowSize + 3 * xDest]; - q = &bitmap->data[(ySrc + y) * bitmap->rowSize + 3 * xSrc]; - memcpy(p, q, 3 * w); - } - break; -#if SPLASH_CMYK - case splashModeCMYK8: - for (y = 0; y < h; ++y) { - p = &dest->data[(yDest + y) * dest->rowSize + 4 * xDest]; - q = &bitmap->data[(ySrc + y) * bitmap->rowSize + 4 * xSrc]; - memcpy(p, q, 4 * w); - } - break; -#endif - } - - for (y = 0; y < h; ++y) { - p = &dest->alpha[(yDest + y) * dest->alphaRowSize + xDest]; - q = &bitmap->alpha[(ySrc + y) * bitmap->alphaRowSize + xSrc]; - alpha0Ptr = &groupBackBitmap->alpha[(groupBackY + ySrc + y) - * groupBackBitmap->alphaRowSize + - (groupBackX + xSrc)]; - for (x = 0; x < w; ++x) { - alpha0 = *alpha0Ptr++; - aSrc = *q++; - *p++ = (Guchar)(alpha0 + aSrc - div255(alpha0 * aSrc)); - } - } - - return splashOk; -} - -SplashPath *Splash::makeStrokePath(SplashPath *path, SplashCoord w, - int lineCap, int lineJoin, - GBool flatten) { - SplashPath *pathIn, *dashPath, *pathOut; - SplashCoord d, dx, dy, wdx, wdy, dxNext, dyNext, wdxNext, wdyNext; - SplashCoord crossprod, dotprod, miter, m; - SplashCoord angle, angleNext, dAngle, xc, yc; - SplashCoord dxJoin, dyJoin, dJoin, kappa; - SplashCoord cx1, cy1, cx2, cy2, cx3, cy3, cx4, cy4; - GBool first, last, closed; - int subpathStart0, subpathStart1, seg, i0, i1, j0, j1, k0, k1; - int left0, left1, left2, right0, right1, right2, join0, join1, join2; - int leftFirst, rightFirst, firstPt; - - pathOut = new SplashPath(); - - if (path->length == 0) { - return pathOut; - } - - if (flatten) { - pathIn = flattenPath(path, state->matrix, state->flatness); - if (state->lineDashLength > 0) { - dashPath = makeDashedPath(pathIn); - delete pathIn; - pathIn = dashPath; - if (pathIn->length == 0) { - delete pathIn; - return pathOut; - } - } - } else { - pathIn = path; - } - - subpathStart0 = subpathStart1 = 0; // make gcc happy - seg = 0; // make gcc happy - closed = gFalse; // make gcc happy - left0 = left1 = right0 = right1 = join0 = join1 = 0; // make gcc happy - leftFirst = rightFirst = firstPt = 0; // make gcc happy - - i0 = 0; - for (i1 = i0; - !(pathIn->flags[i1] & splashPathLast) && - i1 + 1 < pathIn->length && - pathIn->pts[i1+1].x == pathIn->pts[i1].x && - pathIn->pts[i1+1].y == pathIn->pts[i1].y; - ++i1) ; - - while (i1 < pathIn->length) { - if ((first = pathIn->flags[i0] & splashPathFirst)) { - subpathStart0 = i0; - subpathStart1 = i1; - seg = 0; - closed = pathIn->flags[i0] & splashPathClosed; - } - j0 = i1 + 1; - if (j0 < pathIn->length) { - for (j1 = j0; - !(pathIn->flags[j1] & splashPathLast) && - j1 + 1 < pathIn->length && - pathIn->pts[j1+1].x == pathIn->pts[j1].x && - pathIn->pts[j1+1].y == pathIn->pts[j1].y; - ++j1) ; - } else { - j1 = j0; - } - if (pathIn->flags[i1] & splashPathLast) { - if (first && lineCap == splashLineCapRound) { - // special case: zero-length subpath with round line caps --> - // draw a circle - pathOut->moveTo(pathIn->pts[i0].x + (SplashCoord)0.5 * w, - pathIn->pts[i0].y); - pathOut->curveTo(pathIn->pts[i0].x + (SplashCoord)0.5 * w, - pathIn->pts[i0].y + bezierCircle2 * w, - pathIn->pts[i0].x + bezierCircle2 * w, - pathIn->pts[i0].y + (SplashCoord)0.5 * w, - pathIn->pts[i0].x, - pathIn->pts[i0].y + (SplashCoord)0.5 * w); - pathOut->curveTo(pathIn->pts[i0].x - bezierCircle2 * w, - pathIn->pts[i0].y + (SplashCoord)0.5 * w, - pathIn->pts[i0].x - (SplashCoord)0.5 * w, - pathIn->pts[i0].y + bezierCircle2 * w, - pathIn->pts[i0].x - (SplashCoord)0.5 * w, - pathIn->pts[i0].y); - pathOut->curveTo(pathIn->pts[i0].x - (SplashCoord)0.5 * w, - pathIn->pts[i0].y - bezierCircle2 * w, - pathIn->pts[i0].x - bezierCircle2 * w, - pathIn->pts[i0].y - (SplashCoord)0.5 * w, - pathIn->pts[i0].x, - pathIn->pts[i0].y - (SplashCoord)0.5 * w); - pathOut->curveTo(pathIn->pts[i0].x + bezierCircle2 * w, - pathIn->pts[i0].y - (SplashCoord)0.5 * w, - pathIn->pts[i0].x + (SplashCoord)0.5 * w, - pathIn->pts[i0].y - bezierCircle2 * w, - pathIn->pts[i0].x + (SplashCoord)0.5 * w, - pathIn->pts[i0].y); - pathOut->close(); - } - i0 = j0; - i1 = j1; - continue; - } - last = pathIn->flags[j1] & splashPathLast; - if (last) { - k0 = subpathStart1 + 1; - } else { - k0 = j1 + 1; - } - for (k1 = k0; - !(pathIn->flags[k1] & splashPathLast) && - k1 + 1 < pathIn->length && - pathIn->pts[k1+1].x == pathIn->pts[k1].x && - pathIn->pts[k1+1].y == pathIn->pts[k1].y; - ++k1) ; - - // compute the deltas for segment (i1, j0) -#if USE_FIXEDPOINT - // the 1/d value can be small, which introduces significant - // inaccuracies in fixed point mode - d = splashDist(pathIn->pts[i1].x, pathIn->pts[i1].y, - pathIn->pts[j0].x, pathIn->pts[j0].y); - dx = (pathIn->pts[j0].x - pathIn->pts[i1].x) / d; - dy = (pathIn->pts[j0].y - pathIn->pts[i1].y) / d; -#else - d = (SplashCoord)1 / splashDist(pathIn->pts[i1].x, pathIn->pts[i1].y, - pathIn->pts[j0].x, pathIn->pts[j0].y); - dx = d * (pathIn->pts[j0].x - pathIn->pts[i1].x); - dy = d * (pathIn->pts[j0].y - pathIn->pts[i1].y); -#endif - wdx = (SplashCoord)0.5 * w * dx; - wdy = (SplashCoord)0.5 * w * dy; - - // draw the start cap - if (i0 == subpathStart0) { - firstPt = pathOut->length; - } - if (first && !closed) { - switch (lineCap) { - case splashLineCapButt: - pathOut->moveTo(pathIn->pts[i0].x - wdy, pathIn->pts[i0].y + wdx); - pathOut->lineTo(pathIn->pts[i0].x + wdy, pathIn->pts[i0].y - wdx); - break; - case splashLineCapRound: - pathOut->moveTo(pathIn->pts[i0].x - wdy, pathIn->pts[i0].y + wdx); - pathOut->curveTo(pathIn->pts[i0].x - wdy - bezierCircle * wdx, - pathIn->pts[i0].y + wdx - bezierCircle * wdy, - pathIn->pts[i0].x - wdx - bezierCircle * wdy, - pathIn->pts[i0].y - wdy + bezierCircle * wdx, - pathIn->pts[i0].x - wdx, - pathIn->pts[i0].y - wdy); - pathOut->curveTo(pathIn->pts[i0].x - wdx + bezierCircle * wdy, - pathIn->pts[i0].y - wdy - bezierCircle * wdx, - pathIn->pts[i0].x + wdy - bezierCircle * wdx, - pathIn->pts[i0].y - wdx - bezierCircle * wdy, - pathIn->pts[i0].x + wdy, - pathIn->pts[i0].y - wdx); - break; - case splashLineCapProjecting: - pathOut->moveTo(pathIn->pts[i0].x - wdx - wdy, - pathIn->pts[i0].y + wdx - wdy); - pathOut->lineTo(pathIn->pts[i0].x - wdx + wdy, - pathIn->pts[i0].y - wdx - wdy); - break; - } - } else { - pathOut->moveTo(pathIn->pts[i0].x - wdy, pathIn->pts[i0].y + wdx); - pathOut->lineTo(pathIn->pts[i0].x + wdy, pathIn->pts[i0].y - wdx); - } - - // draw the left side of the segment rectangle and the end cap - left2 = pathOut->length - 1; - if (last && !closed) { - switch (lineCap) { - case splashLineCapButt: - pathOut->lineTo(pathIn->pts[j0].x + wdy, pathIn->pts[j0].y - wdx); - pathOut->lineTo(pathIn->pts[j0].x - wdy, pathIn->pts[j0].y + wdx); - break; - case splashLineCapRound: - pathOut->lineTo(pathIn->pts[j0].x + wdy, pathIn->pts[j0].y - wdx); - pathOut->curveTo(pathIn->pts[j0].x + wdy + bezierCircle * wdx, - pathIn->pts[j0].y - wdx + bezierCircle * wdy, - pathIn->pts[j0].x + wdx + bezierCircle * wdy, - pathIn->pts[j0].y + wdy - bezierCircle * wdx, - pathIn->pts[j0].x + wdx, - pathIn->pts[j0].y + wdy); - pathOut->curveTo(pathIn->pts[j0].x + wdx - bezierCircle * wdy, - pathIn->pts[j0].y + wdy + bezierCircle * wdx, - pathIn->pts[j0].x - wdy + bezierCircle * wdx, - pathIn->pts[j0].y + wdx + bezierCircle * wdy, - pathIn->pts[j0].x - wdy, - pathIn->pts[j0].y + wdx); - break; - case splashLineCapProjecting: - pathOut->lineTo(pathIn->pts[j0].x + wdy + wdx, - pathIn->pts[j0].y - wdx + wdy); - pathOut->lineTo(pathIn->pts[j0].x - wdy + wdx, - pathIn->pts[j0].y + wdx + wdy); - break; - } - } else { - pathOut->lineTo(pathIn->pts[j0].x + wdy, pathIn->pts[j0].y - wdx); - pathOut->lineTo(pathIn->pts[j0].x - wdy, pathIn->pts[j0].y + wdx); - } - - // draw the right side of the segment rectangle - // (NB: if stroke adjustment is enabled, the closepath operation MUST - // add a segment because this segment is used for a hint) - right2 = pathOut->length - 1; - pathOut->close(state->strokeAdjust != splashStrokeAdjustOff); - - // draw the join - join2 = pathOut->length; - if (!last || closed) { - - // compute the deltas for segment (j1, k0) -#if USE_FIXEDPOINT - // the 1/d value can be small, which introduces significant - // inaccuracies in fixed point mode - d = splashDist(pathIn->pts[j1].x, pathIn->pts[j1].y, - pathIn->pts[k0].x, pathIn->pts[k0].y); - dxNext = (pathIn->pts[k0].x - pathIn->pts[j1].x) / d; - dyNext = (pathIn->pts[k0].y - pathIn->pts[j1].y) / d; -#else - d = (SplashCoord)1 / splashDist(pathIn->pts[j1].x, pathIn->pts[j1].y, - pathIn->pts[k0].x, pathIn->pts[k0].y); - dxNext = d * (pathIn->pts[k0].x - pathIn->pts[j1].x); - dyNext = d * (pathIn->pts[k0].y - pathIn->pts[j1].y); -#endif - wdxNext = (SplashCoord)0.5 * w * dxNext; - wdyNext = (SplashCoord)0.5 * w * dyNext; - - // compute the join parameters - crossprod = dx * dyNext - dy * dxNext; - dotprod = -(dx * dxNext + dy * dyNext); - if (dotprod > 0.9999) { - // avoid a divide-by-zero -- set miter to something arbitrary - // such that sqrt(miter) will exceed miterLimit (and m is never - // used in that situation) - // (note: the comparison value (0.9999) has to be less than - // 1-epsilon, where epsilon is the smallest value - // representable in the fixed point format) - miter = (state->miterLimit + 1) * (state->miterLimit + 1); - m = 0; - } else { - miter = (SplashCoord)2 / ((SplashCoord)1 - dotprod); - if (miter < 1) { - // this can happen because of floating point inaccuracies - miter = 1; - } - m = splashSqrt(miter - 1); - } - - // round join - if (lineJoin == splashLineJoinRound) { - // join angle < 180 - if (crossprod < 0) { - angle = atan2((double)dx, (double)-dy); - angleNext = atan2((double)dxNext, (double)-dyNext); - if (angle < angleNext) { - angle += 2 * M_PI; - } - dAngle = (angle - angleNext) / M_PI; - if (dAngle < 0.501) { - // span angle is <= 90 degrees -> draw a single arc - kappa = dAngle * bezierCircle * w; - cx1 = pathIn->pts[j0].x - wdy + kappa * dx; - cy1 = pathIn->pts[j0].y + wdx + kappa * dy; - cx2 = pathIn->pts[j0].x - wdyNext - kappa * dxNext; - cy2 = pathIn->pts[j0].y + wdxNext - kappa * dyNext; - pathOut->moveTo(pathIn->pts[j0].x, pathIn->pts[j0].y); - pathOut->lineTo(pathIn->pts[j0].x - wdyNext, - pathIn->pts[j0].y + wdxNext); - pathOut->curveTo(cx2, cy2, cx1, cy1, - pathIn->pts[j0].x - wdy, - pathIn->pts[j0].y + wdx); - } else { - // span angle is > 90 degrees -> split into two arcs - dJoin = splashDist(-wdy, wdx, -wdyNext, wdxNext); - if (dJoin > 0) { - dxJoin = (-wdyNext + wdy) / dJoin; - dyJoin = (wdxNext - wdx) / dJoin; - xc = pathIn->pts[j0].x - + (SplashCoord)0.5 * w - * cos((double)((SplashCoord)0.5 * (angle + angleNext))); - yc = pathIn->pts[j0].y - + (SplashCoord)0.5 * w - * sin((double)((SplashCoord)0.5 * (angle + angleNext))); - kappa = dAngle * bezierCircle2 * w; - cx1 = pathIn->pts[j0].x - wdy + kappa * dx; - cy1 = pathIn->pts[j0].y + wdx + kappa * dy; - cx2 = xc - kappa * dxJoin; - cy2 = yc - kappa * dyJoin; - cx3 = xc + kappa * dxJoin; - cy3 = yc + kappa * dyJoin; - cx4 = pathIn->pts[j0].x - wdyNext - kappa * dxNext; - cy4 = pathIn->pts[j0].y + wdxNext - kappa * dyNext; - pathOut->moveTo(pathIn->pts[j0].x, pathIn->pts[j0].y); - pathOut->lineTo(pathIn->pts[j0].x - wdyNext, - pathIn->pts[j0].y + wdxNext); - pathOut->curveTo(cx4, cy4, cx3, cy3, xc, yc); - pathOut->curveTo(cx2, cy2, cx1, cy1, - pathIn->pts[j0].x - wdy, - pathIn->pts[j0].y + wdx); - } - } - - // join angle >= 180 - } else { - angle = atan2((double)-dx, (double)dy); - angleNext = atan2((double)-dxNext, (double)dyNext); - if (angleNext < angle) { - angleNext += 2 * M_PI; - } - dAngle = (angleNext - angle) / M_PI; - if (dAngle < 0.501) { - // span angle is <= 90 degrees -> draw a single arc - kappa = dAngle * bezierCircle * w; - cx1 = pathIn->pts[j0].x + wdy + kappa * dx; - cy1 = pathIn->pts[j0].y - wdx + kappa * dy; - cx2 = pathIn->pts[j0].x + wdyNext - kappa * dxNext; - cy2 = pathIn->pts[j0].y - wdxNext - kappa * dyNext; - pathOut->moveTo(pathIn->pts[j0].x, pathIn->pts[j0].y); - pathOut->lineTo(pathIn->pts[j0].x + wdy, - pathIn->pts[j0].y - wdx); - pathOut->curveTo(cx1, cy1, cx2, cy2, - pathIn->pts[j0].x + wdyNext, - pathIn->pts[j0].y - wdxNext); - } else { - // span angle is > 90 degrees -> split into two arcs - dJoin = splashDist(wdy, -wdx, wdyNext, -wdxNext); - if (dJoin > 0) { - dxJoin = (wdyNext - wdy) / dJoin; - dyJoin = (-wdxNext + wdx) / dJoin; - xc = pathIn->pts[j0].x - + (SplashCoord)0.5 * w - * cos((double)((SplashCoord)0.5 * (angle + angleNext))); - yc = pathIn->pts[j0].y - + (SplashCoord)0.5 * w - * sin((double)((SplashCoord)0.5 * (angle + angleNext))); - kappa = dAngle * bezierCircle2 * w; - cx1 = pathIn->pts[j0].x + wdy + kappa * dx; - cy1 = pathIn->pts[j0].y - wdx + kappa * dy; - cx2 = xc - kappa * dxJoin; - cy2 = yc - kappa * dyJoin; - cx3 = xc + kappa * dxJoin; - cy3 = yc + kappa * dyJoin; - cx4 = pathIn->pts[j0].x + wdyNext - kappa * dxNext; - cy4 = pathIn->pts[j0].y - wdxNext - kappa * dyNext; - pathOut->moveTo(pathIn->pts[j0].x, pathIn->pts[j0].y); - pathOut->lineTo(pathIn->pts[j0].x + wdy, - pathIn->pts[j0].y - wdx); - pathOut->curveTo(cx1, cy1, cx2, cy2, xc, yc); - pathOut->curveTo(cx3, cy3, cx4, cy4, - pathIn->pts[j0].x + wdyNext, - pathIn->pts[j0].y - wdxNext); - } - } - } - - } else { - pathOut->moveTo(pathIn->pts[j0].x, pathIn->pts[j0].y); - - // join angle < 180 - if (crossprod < 0) { - pathOut->lineTo(pathIn->pts[j0].x - wdyNext, - pathIn->pts[j0].y + wdxNext); - // miter join inside limit - if (lineJoin == splashLineJoinMiter && - splashSqrt(miter) <= state->miterLimit) { - pathOut->lineTo(pathIn->pts[j0].x - wdy + wdx * m, - pathIn->pts[j0].y + wdx + wdy * m); - pathOut->lineTo(pathIn->pts[j0].x - wdy, - pathIn->pts[j0].y + wdx); - // bevel join or miter join outside limit - } else { - pathOut->lineTo(pathIn->pts[j0].x - wdy, - pathIn->pts[j0].y + wdx); - } - - // join angle >= 180 - } else { - pathOut->lineTo(pathIn->pts[j0].x + wdy, - pathIn->pts[j0].y - wdx); - // miter join inside limit - if (lineJoin == splashLineJoinMiter && - splashSqrt(miter) <= state->miterLimit) { - pathOut->lineTo(pathIn->pts[j0].x + wdy + wdx * m, - pathIn->pts[j0].y - wdx + wdy * m); - pathOut->lineTo(pathIn->pts[j0].x + wdyNext, - pathIn->pts[j0].y - wdxNext); - // bevel join or miter join outside limit - } else { - pathOut->lineTo(pathIn->pts[j0].x + wdyNext, - pathIn->pts[j0].y - wdxNext); - } - } - } - - pathOut->close(); - } - - // add stroke adjustment hints - if (state->strokeAdjust != splashStrokeAdjustOff) { - - // subpath with one segment - if (seg == 0 && last) { - switch (lineCap) { - case splashLineCapButt: - pathOut->addStrokeAdjustHint(firstPt, left2 + 1, - firstPt, pathOut->length - 1); - break; - case splashLineCapProjecting: - pathOut->addStrokeAdjustHint(firstPt, left2 + 1, - firstPt, pathOut->length - 1, gTrue); - break; - case splashLineCapRound: - break; - } - pathOut->addStrokeAdjustHint(left2, right2, - firstPt, pathOut->length - 1); - } else { - - // start of subpath - if (seg == 1) { - - // start cap - if (!closed) { - switch (lineCap) { - case splashLineCapButt: - pathOut->addStrokeAdjustHint(firstPt, left1 + 1, - firstPt, firstPt + 1); - pathOut->addStrokeAdjustHint(firstPt, left1 + 1, - right1 + 1, right1 + 1); - break; - case splashLineCapProjecting: - pathOut->addStrokeAdjustHint(firstPt, left1 + 1, - firstPt, firstPt + 1, gTrue); - pathOut->addStrokeAdjustHint(firstPt, left1 + 1, - right1 + 1, right1 + 1, gTrue); - break; - case splashLineCapRound: - break; - } - } - - // first segment - pathOut->addStrokeAdjustHint(left1, right1, firstPt, left2); - pathOut->addStrokeAdjustHint(left1, right1, right2 + 1, right2 + 1); - } - - // middle of subpath - if (seg > 1) { - pathOut->addStrokeAdjustHint(left1, right1, left0 + 1, right0); - pathOut->addStrokeAdjustHint(left1, right1, join0, left2); - pathOut->addStrokeAdjustHint(left1, right1, right2 + 1, right2 + 1); - } - - // end of subpath - if (last) { - - if (closed) { - // first segment - pathOut->addStrokeAdjustHint(leftFirst, rightFirst, - left2 + 1, right2); - pathOut->addStrokeAdjustHint(leftFirst, rightFirst, - join2, pathOut->length - 1); - - // last segment - pathOut->addStrokeAdjustHint(left2, right2, - left1 + 1, right1); - pathOut->addStrokeAdjustHint(left2, right2, - join1, pathOut->length - 1); - pathOut->addStrokeAdjustHint(left2, right2, - leftFirst - 1, leftFirst); - pathOut->addStrokeAdjustHint(left2, right2, - rightFirst + 1, rightFirst + 1); - - } else { - - // last segment - pathOut->addStrokeAdjustHint(left2, right2, - left1 + 1, right1); - pathOut->addStrokeAdjustHint(left2, right2, - join1, pathOut->length - 1); - - // end cap - switch (lineCap) { - case splashLineCapButt: - pathOut->addStrokeAdjustHint(left2 - 1, left2 + 1, - left2 + 1, left2 + 2); - break; - case splashLineCapProjecting: - pathOut->addStrokeAdjustHint(left2 - 1, left2 + 1, - left2 + 1, left2 + 2, gTrue); - break; - case splashLineCapRound: - break; - } - } - } - } - - left0 = left1; - left1 = left2; - right0 = right1; - right1 = right2; - join0 = join1; - join1 = join2; - if (seg == 0) { - leftFirst = left2; - rightFirst = right2; - } - } - - i0 = j0; - i1 = j1; - ++seg; - } - - if (pathIn != path) { - delete pathIn; - } - - return pathOut; -} - -SplashClipResult Splash::limitRectToClipRect(int *xMin, int *yMin, - int *xMax, int *yMax) { - int t; - - if ((t = state->clip->getXMinI(state->strokeAdjust)) > *xMin) { - *xMin = t; - } - if ((t = state->clip->getXMaxI(state->strokeAdjust) + 1) < *xMax) { - *xMax = t; - } - if ((t = state->clip->getYMinI(state->strokeAdjust)) > *yMin) { - *yMin = t; - } - if ((t = state->clip->getYMaxI(state->strokeAdjust) + 1) < *yMax) { - *yMax = t; - } - if (*xMin >= *xMax || *yMin >= *yMax) { - return splashClipAllOutside; - } - return state->clip->testRect(*xMin, *yMin, *xMax - 1, *yMax - 1, - state->strokeAdjust); -} - -void Splash::dumpPath(SplashPath *path) { - int i; - - for (i = 0; i < path->length; ++i) { - printf(" %3d: x=%8.2f y=%8.2f%s%s%s%s\n", - i, (double)path->pts[i].x, (double)path->pts[i].y, - (path->flags[i] & splashPathFirst) ? " first" : "", - (path->flags[i] & splashPathLast) ? " last" : "", - (path->flags[i] & splashPathClosed) ? " closed" : "", - (path->flags[i] & splashPathCurve) ? " curve" : ""); - } - if (path->hintsLength == 0) { - printf(" no hints\n"); - } else { - for (i = 0; i < path->hintsLength; ++i) { - printf(" hint %3d: ctrl0=%d ctrl1=%d pts=%d..%d\n", - i, path->hints[i].ctrl0, path->hints[i].ctrl1, - path->hints[i].firstPt, path->hints[i].lastPt); - } - } -} - -void Splash::dumpXPath(SplashXPath *path) { - int i; - - for (i = 0; i < path->length; ++i) { - printf(" %4d: x0=%8.2f y0=%8.2f x1=%8.2f y1=%8.2f count=%d\n", - i, (double)path->segs[i].x0, (double)path->segs[i].y0, - (double)path->segs[i].x1, (double)path->segs[i].y1, - path->segs[i].count); - } -} - diff --git a/Build/source/libs/xpdf/xpdf-src/splash/Splash.h b/Build/source/libs/xpdf/xpdf-src/splash/Splash.h deleted file mode 100644 index d6cc33a5fad..00000000000 --- a/Build/source/libs/xpdf/xpdf-src/splash/Splash.h +++ /dev/null @@ -1,532 +0,0 @@ -//======================================================================== -// -// Splash.h -// -// Copyright 2003-2013 Glyph & Cog, LLC -// -//======================================================================== - -#ifndef SPLASH_H -#define SPLASH_H - -#include <aconf.h> - -#ifdef USE_GCC_PRAGMAS -#pragma interface -#endif - -#include "SplashTypes.h" -#include "SplashClip.h" - -class GString; -class Splash; -class SplashBitmap; -struct SplashGlyphBitmap; -class SplashState; -class SplashPattern; -class SplashScreen; -class SplashPath; -class SplashXPath; -class SplashFont; -struct SplashPipe; -struct SplashDrawImageMaskRowData; -class ImageScaler; -typedef void (Splash::*SplashDrawImageMaskRowFunc)( - SplashDrawImageMaskRowData *data, - Guchar *maskData, - int x, int y, int width); -struct SplashDrawImageRowData; -typedef void (Splash::*SplashDrawImageRowFunc)(SplashDrawImageRowData *data, - Guchar *colorData, - Guchar *alphaData, - int x, int y, int width); - -//------------------------------------------------------------------------ - -// Retrieves the next line of pixels in an image mask. Normally, -// fills in *<line> and returns true. If the image stream is -// exhausted, returns false. -typedef GBool (*SplashImageMaskSource)(void *data, Guchar *pixel); - -// Retrieves the next line of pixels in an image. Normally, fills in -// *<line> and returns true. If the image stream is exhausted, -// returns false. -typedef GBool (*SplashImageSource)(void *data, SplashColorPtr colorLine, - Guchar *alphaLine); - - -//------------------------------------------------------------------------ - -enum SplashPipeResultColorCtrl { - splashPipeResultColorNoAlphaBlendMono, - splashPipeResultColorNoAlphaBlendRGB, -#if SPLASH_CMYK - splashPipeResultColorNoAlphaBlendCMYK, -#endif - splashPipeResultColorAlphaNoBlendMono, - splashPipeResultColorAlphaNoBlendRGB, -#if SPLASH_CMYK - splashPipeResultColorAlphaNoBlendCMYK, -#endif - splashPipeResultColorAlphaBlendMono, - splashPipeResultColorAlphaBlendRGB -#if SPLASH_CMYK - , - splashPipeResultColorAlphaBlendCMYK -#endif -}; - -//------------------------------------------------------------------------ - -// Transparency group destination bitmap initialization control. -enum SplashGroupDestInitMode { - splashGroupDestPreInit, // dest is already initialized - splashGroupDestInitZero, // initialize to zero (isolated group) - splashGroupDestInitCopy // copy backdrop (non-isolated group) -}; - -//------------------------------------------------------------------------ -// SplashImageCache -//------------------------------------------------------------------------ - -// This holds a cached image, and is shared by multiple Splash objects -// in the same thread. -class SplashImageCache { -public: - - SplashImageCache(); - ~SplashImageCache(); - GBool match(GString *aTag, int aWidth, int aHeight, - SplashColorMode aMode, GBool aAlpha, - GBool aInterpolate); - void reset(GString *aTag, int aWidth, int aHeight, - SplashColorMode aMode, GBool aAlpha, - GBool aInterpolate); - void incRefCount(); - void decRefCount(); - - GString *tag; - int width; - int height; - SplashColorMode mode; - GBool alpha; - GBool interpolate; - Guchar *colorData; - Guchar *alphaData; - - int refCount; -}; - -//------------------------------------------------------------------------ -// Splash -//------------------------------------------------------------------------ - -class Splash { -public: - - // Create a new rasterizer object. - Splash(SplashBitmap *bitmapA, GBool vectorAntialiasA, - SplashImageCache *imageCacheA, - SplashScreenParams *screenParams = NULL); - Splash(SplashBitmap *bitmapA, GBool vectorAntialiasA, - SplashImageCache *imageCacheA, SplashScreen *screenA); - - ~Splash(); - - //----- state read - - SplashCoord *getMatrix(); - SplashPattern *getStrokePattern(); - SplashPattern *getFillPattern(); - SplashScreen *getScreen(); - SplashBlendFunc getBlendFunc(); - SplashCoord getStrokeAlpha(); - SplashCoord getFillAlpha(); - SplashCoord getLineWidth(); - int getLineCap(); - int getLineJoin(); - SplashCoord getMiterLimit(); - SplashCoord getFlatness(); - SplashCoord *getLineDash(); - int getLineDashLength(); - SplashCoord getLineDashPhase(); - SplashStrokeAdjustMode getStrokeAdjust(); - SplashClip *getClip(); - SplashBitmap *getSoftMask(); - GBool getInNonIsolatedGroup(); - GBool getInKnockoutGroup(); - - //----- state write - - void setMatrix(SplashCoord *matrix); - void setStrokePattern(SplashPattern *strokeColor); - void setFillPattern(SplashPattern *fillColor); - void setScreen(SplashScreen *screen); - void setBlendFunc(SplashBlendFunc func); - void setStrokeAlpha(SplashCoord alpha); - void setFillAlpha(SplashCoord alpha); - void setLineWidth(SplashCoord lineWidth); - void setLineCap(int lineCap); - void setLineJoin(int lineJoin); - void setMiterLimit(SplashCoord miterLimit); - void setFlatness(SplashCoord flatness); - // the <lineDash> array will be copied - void setLineDash(SplashCoord *lineDash, int lineDashLength, - SplashCoord lineDashPhase); - void setStrokeAdjust(SplashStrokeAdjustMode strokeAdjust); - // NB: uses transformed coordinates. - void clipResetToRect(SplashCoord x0, SplashCoord y0, - SplashCoord x1, SplashCoord y1); - // NB: uses transformed coordinates. - SplashError clipToRect(SplashCoord x0, SplashCoord y0, - SplashCoord x1, SplashCoord y1); - // NB: uses untransformed coordinates. - SplashError clipToPath(SplashPath *path, GBool eo); - void setSoftMask(SplashBitmap *softMask); - void setInTransparencyGroup(SplashBitmap *groupBackBitmapA, - int groupBackXA, int groupBackYA, - SplashGroupDestInitMode groupDestInitModeA, - GBool nonIsolated, GBool knockout); - void forceDeferredInit(int y, int h); - void setTransfer(Guchar *red, Guchar *green, Guchar *blue, Guchar *gray); - void setOverprintMask(Guint overprintMask); - void setEnablePathSimplification(GBool en); - - //----- state save/restore - - void saveState(); - SplashError restoreState(); - - //----- drawing operations - - // Fill the bitmap with <color>. This is not subject to clipping. - void clear(SplashColorPtr color, Guchar alpha = 0x00); - - // Stroke a path using the current stroke pattern. - SplashError stroke(SplashPath *path); - - // Fill a path using the current fill pattern. - SplashError fill(SplashPath *path, GBool eo); - - // Draw a character, using the current fill pattern. - SplashError fillChar(SplashCoord x, SplashCoord y, int c, SplashFont *font); - - // Draw a glyph, using the current fill pattern. This function does - // not free any data, i.e., it ignores glyph->freeData. - SplashError fillGlyph(SplashCoord x, SplashCoord y, - SplashGlyphBitmap *glyph); - - // Draws an image mask using the fill color. This will read <h> - // lines of <w> pixels from <src>, starting with the top line. "1" - // pixels will be drawn with the current fill color; "0" pixels are - // transparent. The matrix: - // [ mat[0] mat[1] 0 ] - // [ mat[2] mat[3] 0 ] - // [ mat[4] mat[5] 1 ] - // maps a unit square to the desired destination for the image, in - // PostScript style: - // [x' y' 1] = [x y 1] * mat - // Note that the Splash y axis points downward, and the image source - // is assumed to produce pixels in raster order, starting from the - // top line. - SplashError fillImageMask(GString *imageTag, - SplashImageMaskSource src, void *srcData, - int w, int h, SplashCoord *mat, - GBool glyphMode, GBool interpolate); - - // Draw an image. This will read <h> lines of <w> pixels from - // <src>, starting with the top line. These pixels are assumed to - // be in the source mode, <srcMode>. If <srcAlpha> is true, the - // alpha values returned by <src> are used; otherwise they are - // ignored. The following combinations of source and target modes - // are supported: - // source target - // ------ ------ - // Mono8 Mono1 -- with dithering - // Mono8 Mono8 - // RGB8 RGB8 - // BGR8 RGB8 - // CMYK8 CMYK8 - // The matrix behaves as for fillImageMask. - SplashError drawImage(GString *imageTag, - SplashImageSource src, void *srcData, - SplashColorMode srcMode, GBool srcAlpha, - int w, int h, SplashCoord *mat, - GBool interpolate); - - // Composite a rectangular region from <src> onto this Splash - // object. - SplashError composite(SplashBitmap *src, int xSrc, int ySrc, - int xDest, int yDest, int w, int h, - GBool noClip, GBool nonIsolated); - - // Composite a rectangular region from <src> onto this Splash - // object, using <srcOverprintMaskBitmap> as the overprint mask per - // pixel. This is only supported for CMYK and DeviceN bitmaps. - SplashError compositeWithOverprint(SplashBitmap *src, - Guint *srcOverprintMaskBitmap, - int xSrc, int ySrc, - int xDest, int yDest, int w, int h, - GBool noClip, GBool nonIsolated); - - // Composite this Splash object onto a background color. The - // background alpha is assumed to be 1. - void compositeBackground(SplashColorPtr color); - - // Copy a rectangular region from <src> onto the bitmap belonging to - // this Splash object. The destination alpha values are all set to - // zero. - SplashError blitTransparent(SplashBitmap *src, int xSrc, int ySrc, - int xDest, int yDest, int w, int h); - - // Copy a rectangular region from the bitmap belonging to this - // Splash object to <dest>. The alpha values are corrected for a - // non-isolated group. - SplashError blitCorrectedAlpha(SplashBitmap *dest, int xSrc, int ySrc, - int xDest, int yDest, int w, int h); - - //----- misc - - // Construct a path for a stroke, given the path to be stroked and - // the line width <w>. All other stroke parameters are taken from - // the current state. If <flatten> is true, this function will - // first flatten the path and handle the linedash. - SplashPath *makeStrokePath(SplashPath *path, SplashCoord w, - int lineCap, int lineJoin, - GBool flatten = gTrue); - - // Reduce the size of a rectangle as much as possible by moving any - // edges that are completely outside the clip region. Returns the - // clipping status of the resulting rectangle. - SplashClipResult limitRectToClipRect(int *xMin, int *yMin, - int *xMax, int *yMax); - - // Return the associated bitmap. - SplashBitmap *getBitmap() { return bitmap; } - - // Enable writing the per-pixel overprint mask to a separate bitmap. - void setOverprintMaskBitmap(Guint *overprintMaskBitmapA) - { overprintMaskBitmap = overprintMaskBitmapA; } - - // Set the minimum line width. - void setMinLineWidth(SplashCoord w) { minLineWidth = w; } - - // Get a bounding box which includes all modifications since the - // last call to clearModRegion. - void getModRegion(int *xMin, int *yMin, int *xMax, int *yMax) - { *xMin = modXMin; *yMin = modYMin; *xMax = modXMax; *yMax = modYMax; } - - // Clear the modified region bounding box. - void clearModRegion(); - - // Get clipping status for the last drawing operation subject to - // clipping. - SplashClipResult getClipRes() { return opClipRes; } - - // Toggle debug mode on or off. - void setDebugMode(GBool debugModeA) { debugMode = debugModeA; } - - SplashImageCache *getImageCache() { return imageCache; } - -#if 1 //~tmp: turn off anti-aliasing temporarily - void setInShading(GBool sh) { inShading = sh; } -#endif - - -private: - - void pipeInit(SplashPipe *pipe, SplashPattern *pattern, - Guchar aInput, GBool usesShape, - GBool nonIsolatedGroup, GBool usesSrcOverprint = gFalse); - void pipeRun(SplashPipe *pipe, int x0, int x1, int y, - Guchar *shapePtr, SplashColorPtr cSrcPtr); - void pipeRunSimpleMono1(SplashPipe *pipe, int x0, int x1, int y, - Guchar *shapePtr, SplashColorPtr cSrcPtr); - void pipeRunSimpleMono8(SplashPipe *pipe, int x0, int x1, int y, - Guchar *shapePtr, SplashColorPtr cSrcPtr); - void pipeRunSimpleRGB8(SplashPipe *pipe, int x0, int x1, int y, - Guchar *shapePtr, SplashColorPtr cSrcPtr); - void pipeRunSimpleBGR8(SplashPipe *pipe, int x0, int x1, int y, - Guchar *shapePtr, SplashColorPtr cSrcPtr); -#if SPLASH_CMYK - void pipeRunSimpleCMYK8(SplashPipe *pipe, int x0, int x1, int y, - Guchar *shapePtr, SplashColorPtr cSrcPtr); -#endif - void pipeRunShapeMono1(SplashPipe *pipe, int x0, int x1, int y, - Guchar *shapePtr, SplashColorPtr cSrcPtr); - void pipeRunShapeMono8(SplashPipe *pipe, int x0, int x1, int y, - Guchar *shapePtr, SplashColorPtr cSrcPtr); - void pipeRunShapeRGB8(SplashPipe *pipe, int x0, int x1, int y, - Guchar *shapePtr, SplashColorPtr cSrcPtr); - void pipeRunShapeBGR8(SplashPipe *pipe, int x0, int x1, int y, - Guchar *shapePtr, SplashColorPtr cSrcPtr); -#if SPLASH_CMYK - void pipeRunShapeCMYK8(SplashPipe *pipe, int x0, int x1, int y, - Guchar *shapePtr, SplashColorPtr cSrcPtr); -#endif - void pipeRunShapeNoAlphaMono8(SplashPipe *pipe, int x0, int x1, int y, - Guchar *shapePtr, SplashColorPtr cSrcPtr); - void pipeRunAAMono1(SplashPipe *pipe, int x0, int x1, int y, - Guchar *shapePtr, SplashColorPtr cSrcPtr); - void pipeRunAAMono8(SplashPipe *pipe, int x0, int x1, int y, - Guchar *shapePtr, SplashColorPtr cSrcPtr); - void pipeRunAARGB8(SplashPipe *pipe, int x0, int x1, int y, - Guchar *shapePtr, SplashColorPtr cSrcPtr); - void pipeRunAABGR8(SplashPipe *pipe, int x0, int x1, int y, - Guchar *shapePtr, SplashColorPtr cSrcPtr); -#if SPLASH_CMYK - void pipeRunAACMYK8(SplashPipe *pipe, int x0, int x1, int y, - Guchar *shapePtr, SplashColorPtr cSrcPtr); -#endif - void pipeRunSoftMaskMono8(SplashPipe *pipe, int x0, int x1, int y, - Guchar *shapePtr, SplashColorPtr cSrcPtr); - void pipeRunSoftMaskRGB8(SplashPipe *pipe, int x0, int x1, int y, - Guchar *shapePtr, SplashColorPtr cSrcPtr); - void pipeRunSoftMaskBGR8(SplashPipe *pipe, int x0, int x1, int y, - Guchar *shapePtr, SplashColorPtr cSrcPtr); -#if SPLASH_CMYK - void pipeRunSoftMaskCMYK8(SplashPipe *pipe, int x0, int x1, int y, - Guchar *shapePtr, SplashColorPtr cSrcPtr); -#endif - void pipeRunNonIsoMono8(SplashPipe *pipe, int x0, int x1, int y, - Guchar *shapePtr, SplashColorPtr cSrcPtr); - void pipeRunNonIsoRGB8(SplashPipe *pipe, int x0, int x1, int y, - Guchar *shapePtr, SplashColorPtr cSrcPtr); - void pipeRunNonIsoBGR8(SplashPipe *pipe, int x0, int x1, int y, - Guchar *shapePtr, SplashColorPtr cSrcPtr); -#if SPLASH_CMYK - void pipeRunNonIsoCMYK8(SplashPipe *pipe, int x0, int x1, int y, - Guchar *shapePtr, SplashColorPtr cSrcPtr); -#endif - void useDestRow(int y); - void copyGroupBackdropRow(int y); - void transform(SplashCoord *matrix, SplashCoord xi, SplashCoord yi, - SplashCoord *xo, SplashCoord *yo); - void updateModX(int x); - void updateModY(int y); - void strokeNarrow(SplashPath *path); - void drawStrokeSpan(SplashPipe *pipe, int x0, int x1, int y, GBool noClip); - void strokeWide(SplashPath *path, SplashCoord w, - int lineCap, int lineJoin); - SplashPath *flattenPath(SplashPath *path, SplashCoord *matrix, - SplashCoord flatness); - void flattenCurve(SplashCoord x0, SplashCoord y0, - SplashCoord x1, SplashCoord y1, - SplashCoord x2, SplashCoord y2, - SplashCoord x3, SplashCoord y3, - SplashCoord *matrix, SplashCoord flatness2, - SplashPath *fPath); - SplashPath *makeDashedPath(SplashPath *xPath); - SplashError fillWithPattern(SplashPath *path, GBool eo, - SplashPattern *pattern, SplashCoord alpha); - SplashPath *tweakFillPath(SplashPath *path); - GBool pathAllOutside(SplashPath *path); - SplashError fillGlyph2(int x0, int y0, SplashGlyphBitmap *glyph); - void getImageBounds(SplashCoord xyMin, SplashCoord xyMax, - int *xyMinI, int *xyMaxI); - void drawImageMaskArbitraryNoInterp(Guchar *scaledMask, - SplashDrawImageMaskRowData *dd, - SplashDrawImageMaskRowFunc drawRowFunc, - SplashCoord *invMat, - int scaledWidth, int scaledHeight, - int xMin, int yMin, int xMax, int yMax); - void drawImageMaskArbitraryInterp(Guchar *scaledMask, - SplashDrawImageMaskRowData *dd, - SplashDrawImageMaskRowFunc drawRowFunc, - SplashCoord *invMat, - int scaledWidth, int scaledHeight, - int xMin, int yMin, int xMax, int yMax); - void mirrorImageMaskRow(Guchar *maskIn, Guchar *maskOut, int width); - void drawImageMaskRowNoClip(SplashDrawImageMaskRowData *data, - Guchar *maskData, - int x, int y, int width); - void drawImageMaskRowClipNoAA(SplashDrawImageMaskRowData *data, - Guchar *maskData, - int x, int y, int width); - void drawImageMaskRowClipAA(SplashDrawImageMaskRowData *data, - Guchar *maskData, - int x, int y, int width); - ImageScaler *getImageScaler(GString *imageTag, - SplashImageSource src, void *srcData, - int w, int h, int nComps, - int scaledWidth, int scaledHeight, - SplashColorMode srcMode, - GBool srcAlpha, GBool interpolate); - void getScaledImage(GString *imageTag, - SplashImageSource src, void *srcData, - int w, int h, int nComps, - int scaledWidth, int scaledHeight, - SplashColorMode srcMode, - GBool srcAlpha, GBool interpolate, - Guchar **scaledColor, Guchar **scaledAlpha, - GBool *freeScaledImage); - void drawImageArbitraryNoInterp(Guchar *scaledColor, Guchar *scaledAlpha, - SplashDrawImageRowData *dd, - SplashDrawImageRowFunc drawRowFunc, - SplashCoord *invMat, - int scaledWidth, int scaledHeight, - int xMin, int yMin, int xMax, int yMax, - int nComps, GBool srcAlpha); - void drawImageArbitraryInterp(Guchar *scaledColor, Guchar *scaledAlpha, - SplashDrawImageRowData *dd, - SplashDrawImageRowFunc drawRowFunc, - SplashCoord *invMat, - int scaledWidth, int scaledHeight, - int xMin, int yMin, int xMax, int yMax, - int nComps, GBool srcAlpha); - void mirrorImageRow(Guchar *colorIn, Guchar *alphaIn, - Guchar *colorOut, Guchar *alphaOut, - int width, int nComps, GBool srcAlpha); - void drawImageRowNoClipNoAlpha(SplashDrawImageRowData *data, - Guchar *colorData, Guchar *alphaData, - int x, int y, int width); - void drawImageRowNoClipAlpha(SplashDrawImageRowData *data, - Guchar *colorData, Guchar *alphaData, - int x, int y, int width); - void drawImageRowClipNoAlphaNoAA(SplashDrawImageRowData *data, - Guchar *colorData, - Guchar *alphaData, - int x, int y, int width); - void drawImageRowClipNoAlphaAA(SplashDrawImageRowData *data, - Guchar *colorData, - Guchar *alphaData, - int x, int y, int width); - void drawImageRowClipAlphaNoAA(SplashDrawImageRowData *data, - Guchar *colorData, - Guchar *alphaData, - int x, int y, int width); - void drawImageRowClipAlphaAA(SplashDrawImageRowData *data, - Guchar *colorData, - Guchar *alphaData, - int x, int y, int width); - void dumpPath(SplashPath *path); - void dumpXPath(SplashXPath *path); - - - static SplashPipeResultColorCtrl pipeResultColorNoAlphaBlend[]; - static SplashPipeResultColorCtrl pipeResultColorAlphaNoBlend[]; - static SplashPipeResultColorCtrl pipeResultColorAlphaBlend[]; - static int pipeNonIsoGroupCorrection[]; - - SplashBitmap *bitmap; - int bitmapComps; - SplashState *state; - Guchar *scanBuf; - Guchar *scanBuf2; - SplashBitmap // for transparency groups, this is the bitmap - *groupBackBitmap; // containing the alpha0/color0 values - int groupBackX, groupBackY; // offset within groupBackBitmap - SplashGroupDestInitMode groupDestInitMode; - int groupDestInitYMin, groupDestInitYMax; - Guint *overprintMaskBitmap; - SplashCoord minLineWidth; - int modXMin, modYMin, modXMax, modYMax; - SplashClipResult opClipRes; - GBool vectorAntialias; - GBool inShading; - GBool debugMode; - - SplashImageCache *imageCache; -}; - -#endif diff --git a/Build/source/libs/xpdf/xpdf-src/splash/SplashBitmap.cc b/Build/source/libs/xpdf/xpdf-src/splash/SplashBitmap.cc deleted file mode 100644 index db341d7c733..00000000000 --- a/Build/source/libs/xpdf/xpdf-src/splash/SplashBitmap.cc +++ /dev/null @@ -1,288 +0,0 @@ -//======================================================================== -// -// SplashBitmap.cc -// -// Copyright 2003-2013 Glyph & Cog, LLC -// -//======================================================================== - -#include <aconf.h> - -#ifdef USE_GCC_PRAGMAS -#pragma implementation -#endif - -#include <stdio.h> -#include <limits.h> -#include "gmem.h" -#include "gmempp.h" -#include "gfile.h" -#include "Trace.h" -#include "SplashErrorCodes.h" -#include "SplashBitmap.h" - -//------------------------------------------------------------------------ -// SplashBitmap -//------------------------------------------------------------------------ - -SplashBitmap::SplashBitmap(int widthA, int heightA, int rowPad, - SplashColorMode modeA, GBool alphaA, - GBool topDown, SplashBitmap *parentA) { - // NB: this code checks that rowSize fits in a signed 32-bit - // integer, because some code (outside this class) makes that - // assumption - width = widthA; - height = heightA; - mode = modeA; - switch (mode) { - case splashModeMono1: - if (width <= 0) { - gMemError("invalid bitmap width"); - } - rowSize = (width + 7) >> 3; - break; - case splashModeMono8: - if (width <= 0) { - gMemError("invalid bitmap width"); - } - rowSize = width; - break; - case splashModeRGB8: - case splashModeBGR8: - if (width <= 0 || width > INT_MAX / 3) { - gMemError("invalid bitmap width"); - } - rowSize = (SplashBitmapRowSize)width * 3; - break; -#if SPLASH_CMYK - case splashModeCMYK8: - if (width <= 0 || width > INT_MAX / 4) { - gMemError("invalid bitmap width"); - } - rowSize = (SplashBitmapRowSize)width * 4; - break; -#endif - } - rowSize += rowPad - 1; - rowSize -= rowSize % rowPad; - - traceAlloc(this, "alloc bitmap: %d x %d x %d %s -> %lld bytes", - width, height, splashColorModeNComps[mode], - alphaA ? "with alpha" : "without alpha", - height * rowSize + (alphaA ? height * width : 0)); - - parent = parentA; - oldData = NULL; - oldAlpha = NULL; - oldRowSize = 0; - oldAlphaRowSize = 0; - oldHeight = 0; - if (parent && parent->oldData && - parent->oldRowSize == rowSize && - parent->oldHeight == height) { - data = parent->oldData; - parent->oldData = NULL; - traceMessage("reusing bitmap memory"); - } else { - data = (SplashColorPtr)gmallocn64(height, rowSize); - traceMessage("not reusing bitmap memory" - " (parent=%p parent->oldData=%p same-size=%d)", - parent, parent ? parent->oldData : NULL, - parent ? (parent->oldRowSize == rowSize && - parent->oldHeight == height) : 0); - } - if (!topDown) { - data += (height - 1) * rowSize; - rowSize = -rowSize; - } - if (alphaA) { - alphaRowSize = width; - if (parent && parent->oldAlpha && - parent->oldAlphaRowSize == alphaRowSize && - parent->oldHeight == height) { - alpha = parent->oldAlpha; - parent->oldAlpha = NULL; - } else { - alpha = (Guchar *)gmallocn64(height, alphaRowSize); - } - } else { - alphaRowSize = 0; - alpha = NULL; - } -} - -SplashBitmap::~SplashBitmap() { - traceFree(this, "free bitmap"); - if (data && rowSize < 0) { - rowSize = -rowSize; - data -= (height - 1) * rowSize; - } - if (parent && rowSize > 4000000 / height) { - gfree(parent->oldData); - gfree(parent->oldAlpha); - parent->oldData = data; - parent->oldAlpha = alpha; - parent->oldRowSize = rowSize; - parent->oldAlphaRowSize = alphaRowSize; - parent->oldHeight = height; - } else { - gfree(data); - gfree(alpha); - } - gfree(oldData); - gfree(oldAlpha); -} - -SplashError SplashBitmap::writePNMFile(char *fileName) { - FILE *f; - SplashError err; - - if (!(f = openFile(fileName, "wb"))) { - return splashErrOpenFile; - } - err = writePNMFile(f); - fclose(f); - return err; -} - -SplashError SplashBitmap::writePNMFile(FILE *f) { - SplashColorPtr row, p; - int x, y; - - switch (mode) { - - case splashModeMono1: - fprintf(f, "P4\n%d %d\n", width, height); - row = data; - for (y = 0; y < height; ++y) { - p = row; - for (x = 0; x < width; x += 8) { - fputc(*p ^ 0xff, f); - ++p; - } - row += rowSize; - } - break; - - case splashModeMono8: - fprintf(f, "P5\n%d %d\n255\n", width, height); - row = data; - for (y = 0; y < height; ++y) { - fwrite(row, 1, width, f); - row += rowSize; - } - break; - - case splashModeRGB8: - fprintf(f, "P6\n%d %d\n255\n", width, height); - row = data; - for (y = 0; y < height; ++y) { - fwrite(row, 1, 3 * width, f); - row += rowSize; - } - break; - - case splashModeBGR8: - fprintf(f, "P6\n%d %d\n255\n", width, height); - row = data; - for (y = 0; y < height; ++y) { - p = row; - for (x = 0; x < width; ++x) { - fputc(splashBGR8R(p), f); - fputc(splashBGR8G(p), f); - fputc(splashBGR8B(p), f); - p += 3; - } - row += rowSize; - } - break; - -#if SPLASH_CMYK - case splashModeCMYK8: - fprintf(f, "P7\n"); - fprintf(f, "WIDTH %d\n", width); - fprintf(f, "HEIGHT %d\n", height); - fprintf(f, "DEPTH 4\n"); - fprintf(f, "MAXVAL 255\n"); - fprintf(f, "TUPLTYPE CMYK\n"); - fprintf(f, "ENDHDR\n"); - row = data; - for (y = 0; y < height; ++y) { - fwrite(row, 1, 4 * width, f); - row += rowSize; - } - break; -#endif - - } - - return splashOk; -} - -SplashError SplashBitmap::writeAlphaPGMFile(char *fileName) { - FILE *f; - - if (!alpha) { - return splashErrModeMismatch; - } - if (!(f = openFile(fileName, "wb"))) { - return splashErrOpenFile; - } - fprintf(f, "P5\n%d %d\n255\n", width, height); - fwrite(alpha, 1, width * height, f); - fclose(f); - return splashOk; -} - - -void SplashBitmap::getPixel(int x, int y, SplashColorPtr pixel) { - SplashColorPtr p; - - if (y < 0 || y >= height || x < 0 || x >= width) { - return; - } - switch (mode) { - case splashModeMono1: - p = &data[y * rowSize + (x >> 3)]; - pixel[0] = (p[0] & (0x80 >> (x & 7))) ? 0xff : 0x00; - break; - case splashModeMono8: - p = &data[y * rowSize + x]; - pixel[0] = p[0]; - break; - case splashModeRGB8: - p = &data[y * rowSize + 3 * x]; - pixel[0] = p[0]; - pixel[1] = p[1]; - pixel[2] = p[2]; - break; - case splashModeBGR8: - p = &data[y * rowSize + 3 * x]; - pixel[0] = p[2]; - pixel[1] = p[1]; - pixel[2] = p[0]; - break; -#if SPLASH_CMYK - case splashModeCMYK8: - p = &data[y * rowSize + 4 * x]; - pixel[0] = p[0]; - pixel[1] = p[1]; - pixel[2] = p[2]; - pixel[3] = p[3]; - break; -#endif - } -} - -Guchar SplashBitmap::getAlpha(int x, int y) { - return alpha[y * (size_t)width + x]; -} - -SplashColorPtr SplashBitmap::takeData() { - SplashColorPtr data2; - - data2 = data; - data = NULL; - return data2; -} - diff --git a/Build/source/libs/xpdf/xpdf-src/splash/SplashBitmap.h b/Build/source/libs/xpdf/xpdf-src/splash/SplashBitmap.h deleted file mode 100644 index 54975a377a2..00000000000 --- a/Build/source/libs/xpdf/xpdf-src/splash/SplashBitmap.h +++ /dev/null @@ -1,98 +0,0 @@ -//======================================================================== -// -// SplashBitmap.h -// -// Copyright 2003-2013 Glyph & Cog, LLC -// -//======================================================================== - -#ifndef SPLASHBITMAP_H -#define SPLASHBITMAP_H - -#include <aconf.h> - -#ifdef USE_GCC_PRAGMAS -#pragma interface -#endif - -#include <stdio.h> -#include <limits.h> -// older compilers won't define SIZE_MAX in stdint.h without this -#ifndef __STDC_LIMIT_MACROS -# define __STDC_LIMIT_MACROS 1 -#endif -#include <stdint.h> -#include "SplashTypes.h" - -//------------------------------------------------------------------------ - -// ssize_t isn't well-defined, so define our own -#if SIZE_MAX == UINT_MAX - typedef int SplashBitmapRowSize; -# define SplashBitmapRowSizeMax INT_MAX -#else - typedef long long SplashBitmapRowSize; -# define SplashBitmapRowSizeMax LLONG_MAX -#endif - -//------------------------------------------------------------------------ -// SplashBitmap -//------------------------------------------------------------------------ - -class SplashBitmap { -public: - - // Create a new bitmap. It will have <widthA> x <heightA> pixels in - // color mode <modeA>. Rows will be padded out to a multiple of - // <rowPad> bytes. If <topDown> is false, the bitmap will be stored - // upside-down, i.e., with the last row first in memory. - SplashBitmap(int widthA, int heightA, int rowPad, - SplashColorMode modeA, GBool alphaA, - GBool topDown, SplashBitmap *parentA); - - ~SplashBitmap(); - - int getWidth() { return width; } - int getHeight() { return height; } - SplashBitmapRowSize getRowSize() { return rowSize; } - size_t getAlphaRowSize() { return alphaRowSize; } - SplashColorMode getMode() { return mode; } - SplashColorPtr getDataPtr() { return data; } - Guchar *getAlphaPtr() { return alpha; } - - SplashError writePNMFile(char *fileName); - SplashError writePNMFile(FILE *f); - SplashError writeAlphaPGMFile(char *fileName); - - void getPixel(int x, int y, SplashColorPtr pixel); - Guchar getAlpha(int x, int y); - - // Caller takes ownership of the bitmap data. The SplashBitmap - // object is no longer valid -- the next call should be to the - // destructor. - SplashColorPtr takeData(); - -private: - - int width, height; // size of bitmap - SplashBitmapRowSize rowSize; // size of one row of data, in bytes - // - negative for bottom-up bitmaps - size_t alphaRowSize; // size of one row of alpha, in bytes - SplashColorMode mode; // color mode - SplashColorPtr data; // pointer to row zero of the color data - Guchar *alpha; // pointer to row zero of the alpha data - // (always top-down) - - // save the last-allocated (large) bitmap data and reuse if possible - SplashBitmap *parent; - SplashColorPtr oldData; - Guchar *oldAlpha; - SplashBitmapRowSize oldRowSize; - size_t oldAlphaRowSize; - int oldHeight; - - friend class Splash; -}; - - -#endif diff --git a/Build/source/libs/xpdf/xpdf-src/splash/SplashClip.cc b/Build/source/libs/xpdf/xpdf-src/splash/SplashClip.cc deleted file mode 100644 index bf7b802cf0d..00000000000 --- a/Build/source/libs/xpdf/xpdf-src/splash/SplashClip.cc +++ /dev/null @@ -1,521 +0,0 @@ -//======================================================================== -// -// SplashClip.cc -// -// Copyright 2003-2013 Glyph & Cog, LLC -// -//======================================================================== - -#include <aconf.h> - -#ifdef USE_GCC_PRAGMAS -#pragma implementation -#endif - -#include <stdlib.h> -#include <string.h> -#include "gmem.h" -#include "gmempp.h" -#include "SplashErrorCodes.h" -#include "SplashPath.h" -#include "SplashXPath.h" -#include "SplashXPathScanner.h" -#include "SplashClip.h" - -//------------------------------------------------------------------------ - -// Compute x * y / 255, where x and y are in [0, 255]. -static inline Guchar mul255(Guchar x, Guchar y) { - int z; - - z = (int)x * (int)y; - return (Guchar)((z + (z >> 8) + 0x80) >> 8); -} - -//------------------------------------------------------------------------ -// SplashClip -//------------------------------------------------------------------------ - -SplashClip::SplashClip(int hardXMinA, int hardYMinA, - int hardXMaxA, int hardYMaxA) { - int w; - - hardXMin = hardXMinA; - hardYMin = hardYMinA; - hardXMax = hardXMaxA; - hardYMax = hardYMaxA; - xMin = hardXMin; - yMin = hardYMin; - xMax = hardXMax; - yMax = hardYMax; - intBoundsValid = gFalse; - paths = NULL; - eo = NULL; - scanners = NULL; - length = size = 0; - isSimple = gTrue; - prev = NULL; - if ((w = hardXMax + 1) <= 0) { - w = 1; - } - buf = (Guchar *)gmalloc(w); -} - -SplashClip::SplashClip(SplashClip *clip) { - int w; - - hardXMin = clip->hardXMin; - hardYMin = clip->hardYMin; - hardXMax = clip->hardXMax; - hardYMax = clip->hardYMax; - xMin = clip->xMin; - yMin = clip->yMin; - xMax = clip->xMax; - yMax = clip->yMax; - xMinI = clip->xMinI; - yMinI = clip->yMinI; - xMaxI = clip->xMaxI; - yMaxI = clip->yMaxI; - intBoundsValid = clip->intBoundsValid; - intBoundsStrokeAdjust = clip->intBoundsStrokeAdjust; - paths = NULL; - eo = NULL; - scanners = NULL; - length = size = 0; - isSimple = clip->isSimple; - prev = clip; - if ((w = splashCeil(xMax)) <= 0) { - w = 1; - } - buf = (Guchar *)gmalloc(w); -} - -SplashClip::~SplashClip() { - int i; - - for (i = 0; i < length; ++i) { - delete scanners[i]; - delete paths[i]; - } - gfree(paths); - gfree(eo); - gfree(scanners); - gfree(buf); -} - -void SplashClip::grow(int nPaths) { - if (length + nPaths > size) { - if (size == 0) { - size = 32; - } - while (size < length + nPaths) { - size *= 2; - } - paths = (SplashXPath **)greallocn(paths, size, sizeof(SplashXPath *)); - eo = (Guchar *)greallocn(eo, size, sizeof(Guchar)); - scanners = (SplashXPathScanner **) - greallocn(scanners, size, sizeof(SplashXPathScanner *)); - } -} - -void SplashClip::resetToRect(SplashCoord x0, SplashCoord y0, - SplashCoord x1, SplashCoord y1) { - int w, i; - - for (i = 0; i < length; ++i) { - delete paths[i]; - delete scanners[i]; - } - gfree(paths); - gfree(eo); - gfree(scanners); - gfree(buf); - paths = NULL; - eo = NULL; - scanners = NULL; - length = size = 0; - isSimple = gTrue; - prev = NULL; - - if (x0 < x1) { - xMin = x0; - xMax = x1; - } else { - xMin = x1; - xMax = x0; - } - if (y0 < y1) { - yMin = y0; - yMax = y1; - } else { - yMin = y1; - yMax = y0; - } - intBoundsValid = gFalse; - if ((w = splashCeil(xMax)) <= 0) { - w = 1; - } - buf = (Guchar *)gmalloc(w); -} - -SplashError SplashClip::clipToRect(SplashCoord x0, SplashCoord y0, - SplashCoord x1, SplashCoord y1) { - if (x0 < x1) { - if (x0 > xMin) { - xMin = x0; - intBoundsValid = gFalse; - } - if (x1 < xMax) { - xMax = x1; - intBoundsValid = gFalse; - } - } else { - if (x1 > xMin) { - xMin = x1; - intBoundsValid = gFalse; - } - if (x0 < xMax) { - xMax = x0; - intBoundsValid = gFalse; - } - } - if (y0 < y1) { - if (y0 > yMin) { - yMin = y0; - intBoundsValid = gFalse; - } - if (y1 < yMax) { - yMax = y1; - intBoundsValid = gFalse; - } - } else { - if (y1 > yMin) { - yMin = y1; - intBoundsValid = gFalse; - } - if (y0 < yMax) { - yMax = y0; - intBoundsValid = gFalse; - } - } - return splashOk; -} - -SplashError SplashClip::clipToPath(SplashPath *path, SplashCoord *matrix, - SplashCoord flatness, GBool eoA, - GBool enablePathSimplification, - SplashStrokeAdjustMode strokeAdjust) { - SplashXPath *xPath; - SplashCoord t; - - xPath = new SplashXPath(path, matrix, flatness, gTrue, - enablePathSimplification, - strokeAdjust); - - // check for an empty path - if (xPath->length == 0) { - xMin = yMin = 1; - xMax = yMax = 0; - intBoundsValid = gFalse; - delete xPath; - return splashOk; - } - - // check for a rectangle - if (xPath->isRect) { - clipToRect(xPath->rectX0, xPath->rectY0, xPath->rectX1, xPath->rectY1); - delete xPath; - return splashOk; - } - - grow(1); - paths[length] = xPath; - eo[length] = (Guchar)eoA; - if ((t = xPath->getXMin()) > xMin) { - xMin = t; - } - if ((t = xPath->getYMin()) > yMin) { - yMin = t; - } - if ((t = xPath->getXMax() + 1) < xMax) { - xMax = t; - } - if ((t = xPath->getYMax() + 1) < yMax) { - yMax = t; - } - intBoundsValid = gFalse; - scanners[length] = new SplashXPathScanner(xPath, eoA, splashFloor(yMin), - splashCeil(yMax) - 1); - ++length; - isSimple = gFalse; - - return splashOk; -} - -SplashClipResult SplashClip::testRect(int rectXMin, int rectYMin, - int rectXMax, int rectYMax, - SplashStrokeAdjustMode strokeAdjust) { - // In general, this function tests the rectangle: - // x = [rectXMin, rectXMax + 1) (note: coords are ints) - // y = [rectYMin, rectYMax + 1) - // against the clipping region: - // x = [xMin, xMax) (note: coords are fp) - // y = [yMin, yMax) - - if (strokeAdjust != splashStrokeAdjustOff && isSimple) { - // special case for stroke adjustment with a simple clipping - // rectangle -- the clipping region is: - // x = [xMinI, xMaxI + 1) - // y = [yMinI, yMaxI + 1) - updateIntBounds(strokeAdjust); - if (xMinI > xMaxI || yMinI > yMaxI) { - return splashClipAllOutside; - } - if (rectXMax + 1 <= xMinI || - rectXMin >= xMaxI + 1 || - rectYMax + 1 <= yMinI || - rectYMin >= yMaxI + 1) { - return splashClipAllOutside; - } - if (rectXMin >= xMinI && - rectXMax <= xMaxI && - rectYMin >= yMinI && - rectYMax <= yMaxI) { - return splashClipAllInside; - } - } else { - if (xMin >= xMax || yMin >= yMax) { - return splashClipAllOutside; - } - if ((SplashCoord)(rectXMax + 1) <= xMin || - (SplashCoord)rectXMin >= xMax || - (SplashCoord)(rectYMax + 1) <= yMin || - (SplashCoord)rectYMin >= yMax) { - return splashClipAllOutside; - } - if (isSimple && - (SplashCoord)rectXMin >= xMin && - (SplashCoord)(rectXMax + 1) <= xMax && - (SplashCoord)rectYMin >= yMin && - (SplashCoord)(rectYMax + 1) <= yMax) { - return splashClipAllInside; - } - } - return splashClipPartial; -} - -void SplashClip::clipSpan(Guchar *line, int y, int x0, int x1, - SplashStrokeAdjustMode strokeAdjust) { - SplashClip *clip; - SplashCoord d; - int x0a, x1a, x0b, x1b, x, i; - - updateIntBounds(strokeAdjust); - - //--- clip to the integer rectangle - - if (y < yMinI || y > yMaxI || - x1 < xMinI || x0 > xMaxI) { - memset(line + x0, 0, x1 - x0 + 1); - return; - } - - if (x0 > xMinI) { - x0a = x0; - } else { - x0a = xMinI; - memset(line + x0, 0, x0a - x0); - } - - if (x1 < xMaxI) { - x1a = x1; - } else { - x1a = xMaxI; - memset(line + x1a + 1, 0, x1 - x1a); - } - - if (x0a > x1a) { - return; - } - - //--- clip to the floating point rectangle - // (if stroke adjustment is disabled) - - if (strokeAdjust == splashStrokeAdjustOff) { - - // clip left edge (xMin) - if (x0a == xMinI) { - d = (SplashCoord)(xMinI + 1) - xMin; - line[x0a] = (Guchar)(int)((SplashCoord)line[x0a] * d); - } - - // clip right edge (xMax) - if (x1a == xMaxI) { - d = xMax - (SplashCoord)xMaxI; - line[x1a] = (Guchar)(int)((SplashCoord)line[x1a] * d); - } - - // clip top edge (yMin) - if (y == yMinI) { - d = (SplashCoord)(yMinI + 1) - yMin; - for (x = x0a; x <= x1a; ++x) { - line[x] = (Guchar)(int)((SplashCoord)line[x] * d); - } - } - - // clip bottom edge (yMax) - if (y == yMaxI) { - d = yMax - (SplashCoord)yMaxI; - for (x = x0a; x <= x1a; ++x) { - line[x] = (Guchar)(int)((SplashCoord)line[x] * d); - } - } - } - - if (isSimple) { - return; - } - - //--- clip to the paths - - for (clip = this; clip; clip = clip->prev) { - for (i = 0; i < clip->length; ++i) { - clip->scanners[i]->getSpan(buf, y, x0a, x1a, &x0b, &x1b); - if (x0a < x0b) { - memset(line + x0a, 0, x0b - x0a); - } - for (x = x0b; x <= x1b; ++x) { - line[x] = mul255(line[x], buf[x]); - } - if (x1b < x1a) { - memset(line + x1b + 1, 0, x1a - x1b); - } - } - } -} - -GBool SplashClip::clipSpanBinary(Guchar *line, int y, int x0, int x1, - SplashStrokeAdjustMode strokeAdjust) { - SplashClip *clip; - int x0a, x1a, x0b, x1b, x, i; - Guchar any; - - updateIntBounds(strokeAdjust); - - if (y < yMinI || y > yMaxI || - x1 < xMinI || x0 > xMaxI) { - if (x0 <= x1) { - memset(line + x0, 0, x1 - x0 + 1); - } - return gFalse; - } - - if (x0 > xMinI) { - x0a = x0; - } else { - x0a = xMinI; - memset(line + x0, 0, x0a - x0); - } - - if (x1 < xMaxI) { - x1a = x1; - } else { - x1a = xMaxI; - memset(line + x1a + 1, 0, x1 - x1a); - } - - if (x0a > x1a) { - return gFalse; - } - - if (isSimple) { - for (x = x0a; x <= x1a; ++x) { - if (line[x]) { - return gTrue; - } - } - return gFalse; - } - - any = 0; - for (clip = this; clip; clip = clip->prev) { - for (i = 0; i < clip->length; ++i) { - clip->scanners[i]->getSpanBinary(buf, y, x0a, x1a, &x0b, &x1b); - if (x0a < x0b) { - memset(line + x0a, 0, x0b - x0a); - } - for (x = x0b; x <= x1b; ++x) { - line[x] &= buf[x]; - any |= line[x]; - } - if (x1b < x1a) { - memset(line + x1b + 1, 0, x1a - x1b); - } - } - } - - return any != 0; -} - -int SplashClip::getXMinI(SplashStrokeAdjustMode strokeAdjust) { - updateIntBounds(strokeAdjust); - return xMinI; -} - -int SplashClip::getXMaxI(SplashStrokeAdjustMode strokeAdjust) { - updateIntBounds(strokeAdjust); - return xMaxI; -} - -int SplashClip::getYMinI(SplashStrokeAdjustMode strokeAdjust) { - updateIntBounds(strokeAdjust); - return yMinI; -} - -int SplashClip::getYMaxI(SplashStrokeAdjustMode strokeAdjust) { - updateIntBounds(strokeAdjust); - return yMaxI; -} - -int SplashClip::getNumPaths() { - SplashClip *clip; - int n; - - n = 0; - for (clip = this; clip; clip = clip->prev) { - n += clip->length; - } - return n; -} - -void SplashClip::updateIntBounds(SplashStrokeAdjustMode strokeAdjust) { - if (intBoundsValid && strokeAdjust == intBoundsStrokeAdjust) { - return; - } - if (strokeAdjust != splashStrokeAdjustOff && isSimple) { - splashStrokeAdjust(xMin, xMax, &xMinI, &xMaxI, strokeAdjust); - splashStrokeAdjust(yMin, yMax, &yMinI, &yMaxI, strokeAdjust); - } else { - xMinI = splashFloor(xMin); - yMinI = splashFloor(yMin); - xMaxI = splashCeil(xMax); - yMaxI = splashCeil(yMax); - } - if (xMinI < hardXMin) { - xMinI = hardXMin; - } - if (yMinI < hardYMin) { - yMinI = hardYMin; - } - if (xMaxI > hardXMax) { - xMaxI = hardXMax; - } - if (yMaxI > hardYMax) { - yMaxI = hardYMax; - } - // the clipping code uses [xMinI, xMaxI] instead of [xMinI, xMaxI) - --xMaxI; - --yMaxI; - intBoundsValid = gTrue; - intBoundsStrokeAdjust = strokeAdjust; -} diff --git a/Build/source/libs/xpdf/xpdf-src/splash/SplashClip.h b/Build/source/libs/xpdf/xpdf-src/splash/SplashClip.h deleted file mode 100644 index fb86ed8fd72..00000000000 --- a/Build/source/libs/xpdf/xpdf-src/splash/SplashClip.h +++ /dev/null @@ -1,130 +0,0 @@ -//======================================================================== -// -// SplashClip.h -// -// Copyright 2003-2013 Glyph & Cog, LLC -// -//======================================================================== - -#ifndef SPLASHCLIP_H -#define SPLASHCLIP_H - -#include <aconf.h> - -#ifdef USE_GCC_PRAGMAS -#pragma interface -#endif - -#include "SplashTypes.h" -#include "SplashMath.h" - -class SplashPath; -class SplashXPath; -class SplashXPathScanner; -class SplashBitmap; - -//------------------------------------------------------------------------ - -enum SplashClipResult { - splashClipAllInside, - splashClipAllOutside, - splashClipPartial -}; - -//------------------------------------------------------------------------ -// SplashClip -//------------------------------------------------------------------------ - -class SplashClip { -public: - - // Create a clip, for the given rectangle. - SplashClip(int hardXMinA, int hardYMinA, - int hardXMaxA, int hardYMaxA); - - // Copy a clip. - SplashClip *copy() { return new SplashClip(this); } - - ~SplashClip(); - - // Reset the clip to a rectangle. - void resetToRect(SplashCoord x0, SplashCoord y0, - SplashCoord x1, SplashCoord y1); - - // Intersect the clip with a rectangle. - SplashError clipToRect(SplashCoord x0, SplashCoord y0, - SplashCoord x1, SplashCoord y1); - - // Interesect the clip with <path>. - SplashError clipToPath(SplashPath *path, SplashCoord *matrix, - SplashCoord flatness, GBool eoA, - GBool enablePathSimplification, - SplashStrokeAdjustMode strokeAdjust); - - // Tests a rectangle against the clipping region. Returns one of: - // - splashClipAllInside if the entire rectangle is inside the - // clipping region, i.e., all pixels in the rectangle are - // visible - // - splashClipAllOutside if the entire rectangle is outside the - // clipping region, i.e., all the pixels in the rectangle are - // clipped - // - splashClipPartial if the rectangle is part inside and part - // outside the clipping region - SplashClipResult testRect(int rectXMin, int rectYMin, - int rectXMax, int rectYMax, - SplashStrokeAdjustMode strokeAdjust); - - // Clip a scan line. Modifies line[] by multiplying with clipping - // shape values for one scan line: ([x0, x1], y). - void clipSpan(Guchar *line, int y, int x0, int x1, - SplashStrokeAdjustMode strokeAdjust); - - // Like clipSpan(), but uses the values 0 and 255 only. - // Returns true if there are any non-zero values in the result - // (i.e., returns false if the entire line is clipped out). - GBool clipSpanBinary(Guchar *line, int y, int x0, int x1, - SplashStrokeAdjustMode strokeAdjust); - - // Get the rectangle part of the clip region. - SplashCoord getXMin() { return xMin; } - SplashCoord getXMax() { return xMax; } - SplashCoord getYMin() { return yMin; } - SplashCoord getYMax() { return yMax; } - - // Get the rectangle part of the clip region, in integer coordinates. - int getXMinI(SplashStrokeAdjustMode strokeAdjust); - int getXMaxI(SplashStrokeAdjustMode strokeAdjust); - int getYMinI(SplashStrokeAdjustMode strokeAdjust); - int getYMaxI(SplashStrokeAdjustMode strokeAdjust); - - // Get the number of arbitrary paths used by the clip region. - int getNumPaths(); - -private: - - SplashClip(SplashClip *clip); - void grow(int nPaths); - void updateIntBounds(SplashStrokeAdjustMode strokeAdjust); - - int hardXMin, hardYMin, // coordinates cannot fall outside of - hardXMax, hardYMax; // [hardXMin, hardXMax), [hardYMin, hardYMax) - - SplashCoord xMin, yMin, // current clip bounding rectangle - xMax, yMax; // (these coordinates may be adjusted if - // stroke adjustment is enabled) - - int xMinI, yMinI, xMaxI, yMaxI; - GBool intBoundsValid; // true if xMinI, etc. are valid - GBool intBoundsStrokeAdjust; // value of strokeAdjust used to compute - // xMinI, etc. - - SplashXPath **paths; - Guchar *eo; - SplashXPathScanner **scanners; - int length, size; - GBool isSimple; - SplashClip *prev; - Guchar *buf; -}; - -#endif diff --git a/Build/source/libs/xpdf/xpdf-src/splash/SplashErrorCodes.h b/Build/source/libs/xpdf/xpdf-src/splash/SplashErrorCodes.h deleted file mode 100644 index ebe6091faa2..00000000000 --- a/Build/source/libs/xpdf/xpdf-src/splash/SplashErrorCodes.h +++ /dev/null @@ -1,34 +0,0 @@ -//======================================================================== -// -// SplashErrorCodes.h -// -// Copyright 2003-2013 Glyph & Cog, LLC -// -//======================================================================== - -#ifndef SPLASHERRORCODES_H -#define SPLASHERRORCODES_H - -#include <aconf.h> - -//------------------------------------------------------------------------ - -#define splashOk 0 // no error - -#define splashErrNoCurPt 1 // no current point - -#define splashErrEmptyPath 2 // zero points in path - -#define splashErrBogusPath 3 // only one point in subpath - -#define splashErrNoSave 4 // state stack is empty - -#define splashErrOpenFile 5 // couldn't open file - -#define splashErrNoGlyph 6 // couldn't get the requested glyph - -#define splashErrModeMismatch 7 // invalid combination of color modes - -#define splashErrSingularMatrix 8 // matrix is singular - -#endif diff --git a/Build/source/libs/xpdf/xpdf-src/splash/SplashFTFont.cc b/Build/source/libs/xpdf/xpdf-src/splash/SplashFTFont.cc deleted file mode 100644 index 91481444bca..00000000000 --- a/Build/source/libs/xpdf/xpdf-src/splash/SplashFTFont.cc +++ /dev/null @@ -1,460 +0,0 @@ -//======================================================================== -// -// SplashFTFont.cc -// -// Copyright 2003-2013 Glyph & Cog, LLC -// -//======================================================================== - -#include <aconf.h> - -#if HAVE_FREETYPE_H - -#ifdef USE_GCC_PRAGMAS -#pragma implementation -#endif - -#include <ft2build.h> -#include FT_OUTLINE_H -#include FT_SIZES_H -#include FT_GLYPH_H -#include "gmem.h" -#include "gmempp.h" -#include "SplashMath.h" -#include "SplashGlyphBitmap.h" -#include "SplashPath.h" -#include "SplashFontEngine.h" -#include "SplashFTFontEngine.h" -#include "SplashFTFontFile.h" -#include "SplashFTFont.h" - -//------------------------------------------------------------------------ - -static int glyphPathMoveTo(const FT_Vector *pt, void *path); -static int glyphPathLineTo(const FT_Vector *pt, void *path); -static int glyphPathConicTo(const FT_Vector *ctrl, const FT_Vector *pt, - void *path); -static int glyphPathCubicTo(const FT_Vector *ctrl1, const FT_Vector *ctrl2, - const FT_Vector *pt, void *path); - -//------------------------------------------------------------------------ -// SplashFTFont -//------------------------------------------------------------------------ - -SplashFTFont::SplashFTFont(SplashFTFontFile *fontFileA, SplashCoord *matA, - SplashCoord *textMatA): - SplashFont(fontFileA, matA, textMatA, fontFileA->engine->aa) -{ - FT_Face face; - int size, div; - int x, y; -#if USE_FIXEDPOINT - SplashCoord scale; -#endif - - face = fontFileA->face; - if (FT_New_Size(face, &sizeObj)) { - return; - } - face->size = sizeObj; - size = splashRound(splashDist(0, 0, mat[2], mat[3])); - if (size < 1) { - size = 1; - } - if (FT_Set_Pixel_Sizes(face, 0, size)) { - return; - } - // if the textMat values are too small, FreeType's fixed point - // arithmetic doesn't work so well - textScale = splashDist(0, 0, textMat[2], textMat[3]) / size; - // avoid problems with singular (or close-to-singular) matrices - if (textScale < 0.00001) { - textScale = 0.00001; - } - - div = face->bbox.xMax > 20000 ? 65536 : 1; - -#if USE_FIXEDPOINT - scale = (SplashCoord)1 / (SplashCoord)face->units_per_EM; - - // transform the four corners of the font bounding box -- the min - // and max values form the bounding box of the transformed font - x = (int)(mat[0] * (scale * (face->bbox.xMin / div)) + - mat[2] * (scale * (face->bbox.yMin / div))); - xMin = xMax = x; - y = (int)(mat[1] * (scale * (face->bbox.xMin / div)) + - mat[3] * (scale * (face->bbox.yMin / div))); - yMin = yMax = y; - x = (int)(mat[0] * (scale * (face->bbox.xMin / div)) + - mat[2] * (scale * (face->bbox.yMax / div))); - if (x < xMin) { - xMin = x; - } else if (x > xMax) { - xMax = x; - } - y = (int)(mat[1] * (scale * (face->bbox.xMin / div)) + - mat[3] * (scale * (face->bbox.yMax / div))); - if (y < yMin) { - yMin = y; - } else if (y > yMax) { - yMax = y; - } - x = (int)(mat[0] * (scale * (face->bbox.xMax / div)) + - mat[2] * (scale * (face->bbox.yMin / div))); - if (x < xMin) { - xMin = x; - } else if (x > xMax) { - xMax = x; - } - y = (int)(mat[1] * (scale * (face->bbox.xMax / div)) + - mat[3] * (scale * (face->bbox.yMin / div))); - if (y < yMin) { - yMin = y; - } else if (y > yMax) { - yMax = y; - } - x = (int)(mat[0] * (scale * (face->bbox.xMax / div)) + - mat[2] * (scale * (face->bbox.yMax / div))); - if (x < xMin) { - xMin = x; - } else if (x > xMax) { - xMax = x; - } - y = (int)(mat[1] * (scale * (face->bbox.xMax / div)) + - mat[3] * (scale * (face->bbox.yMax / div))); - if (y < yMin) { - yMin = y; - } else if (y > yMax) { - yMax = y; - } -#else // USE_FIXEDPOINT - // transform the four corners of the font bounding box -- the min - // and max values form the bounding box of the transformed font - x = (int)((mat[0] * (SplashCoord)face->bbox.xMin - + mat[2] * (SplashCoord)face->bbox.yMin) / - (div * face->units_per_EM)); - xMin = xMax = x; - y = (int)((mat[1] * (SplashCoord)face->bbox.xMin - + mat[3] * (SplashCoord)face->bbox.yMin) / - (div * face->units_per_EM)); - yMin = yMax = y; - x = (int)((mat[0] * (SplashCoord)face->bbox.xMin - + mat[2] * (SplashCoord)face->bbox.yMax) / - (div * face->units_per_EM)); - if (x < xMin) { - xMin = x; - } else if (x > xMax) { - xMax = x; - } - y = (int)((mat[1] * (SplashCoord)face->bbox.xMin - + mat[3] * (SplashCoord)face->bbox.yMax) / - (div * face->units_per_EM)); - if (y < yMin) { - yMin = y; - } else if (y > yMax) { - yMax = y; - } - x = (int)((mat[0] * (SplashCoord)face->bbox.xMax - + mat[2] * (SplashCoord)face->bbox.yMin) / - (div * face->units_per_EM)); - if (x < xMin) { - xMin = x; - } else if (x > xMax) { - xMax = x; - } - y = (int)((mat[1] * (SplashCoord)face->bbox.xMax - + mat[3] * (SplashCoord)face->bbox.yMin) / - (div * face->units_per_EM)); - if (y < yMin) { - yMin = y; - } else if (y > yMax) { - yMax = y; - } - x = (int)((mat[0] * (SplashCoord)face->bbox.xMax - + mat[2] * (SplashCoord)face->bbox.yMax) / - (div * face->units_per_EM)); - if (x < xMin) { - xMin = x; - } else if (x > xMax) { - xMax = x; - } - y = (int)((mat[1] * (SplashCoord)face->bbox.xMax - + mat[3] * (SplashCoord)face->bbox.yMax) / - (div * face->units_per_EM)); - if (y < yMin) { - yMin = y; - } else if (y > yMax) { - yMax = y; - } -#endif // USE_FIXEDPOINT - // This is a kludge: some buggy PDF generators embed fonts with - // zero bounding boxes. - if (xMax == xMin) { - xMin = 0; - xMax = size; - } - if (yMax == yMin) { - yMin = 0; - yMax = (int)((SplashCoord)1.2 * size); - } - - // compute the transform matrix -#if USE_FIXEDPOINT - matrix.xx = (FT_Fixed)((mat[0] / size).get16Dot16()); - matrix.yx = (FT_Fixed)((mat[1] / size).get16Dot16()); - matrix.xy = (FT_Fixed)((mat[2] / size).get16Dot16()); - matrix.yy = (FT_Fixed)((mat[3] / size).get16Dot16()); - textMatrix.xx = (FT_Fixed)((textMat[0] / (textScale * size)).get16Dot16()); - textMatrix.yx = (FT_Fixed)((textMat[1] / (textScale * size)).get16Dot16()); - textMatrix.xy = (FT_Fixed)((textMat[2] / (textScale * size)).get16Dot16()); - textMatrix.yy = (FT_Fixed)((textMat[3] / (textScale * size)).get16Dot16()); -#else - matrix.xx = (FT_Fixed)((mat[0] / size) * 65536); - matrix.yx = (FT_Fixed)((mat[1] / size) * 65536); - matrix.xy = (FT_Fixed)((mat[2] / size) * 65536); - matrix.yy = (FT_Fixed)((mat[3] / size) * 65536); - textMatrix.xx = (FT_Fixed)((textMat[0] / (textScale * size)) * 65536); - textMatrix.yx = (FT_Fixed)((textMat[1] / (textScale * size)) * 65536); - textMatrix.xy = (FT_Fixed)((textMat[2] / (textScale * size)) * 65536); - textMatrix.yy = (FT_Fixed)((textMat[3] / (textScale * size)) * 65536); -#endif -} - -SplashFTFont::~SplashFTFont() { -} - -GBool SplashFTFont::getGlyph(int c, int xFrac, int yFrac, - SplashGlyphBitmap *bitmap) { - return SplashFont::getGlyph(c, xFrac, 0, bitmap); -} - -GBool SplashFTFont::makeGlyph(int c, int xFrac, int yFrac, - SplashGlyphBitmap *bitmap) { - SplashFTFontFile *ff; - FT_Vector offset; - FT_GlyphSlot slot; - int gid; - FT_Int32 flags; - int rowSize; - Guchar *p, *q; - int i; - - ff = (SplashFTFontFile *)fontFile; - - ff->face->size = sizeObj; - offset.x = (FT_Pos)(int)((SplashCoord)xFrac * splashFontFractionMul * 64); - offset.y = 0; - FT_Set_Transform(ff->face, &matrix, &offset); - slot = ff->face->glyph; - - if (ff->codeToGID && c < ff->codeToGIDLen) { - gid = ff->codeToGID[c]; - } else { - gid = c; - } - if (ff->fontType == splashFontTrueType && gid < 0) { - // skip the TrueType notdef glyph - return gFalse; - } - - // Set up the load flags: - // * disable bitmaps because they look ugly when scaled, rotated, - // etc. - // * disable autohinting because it can fail badly with font subsets - // that use invalid glyph names (the FreeType autohinter depends - // on the glyph name to figure out how to autohint the glyph) - // * but enable light autohinting for Type 1 fonts because regular - // hinting looks pretty bad, and the invalid glyph name issue - // seems to be very rare (Type 1 fonts are mostly used for - // substitution, in which case the full font is being used, which - // means we have the glyph names) - // This also sets the "pedantic" flag, running the FreeType hinter - // in paranoid mode. If that triggers any errors, we disable - // hinting below. - flags = FT_LOAD_NO_BITMAP | FT_LOAD_PEDANTIC; - if (ff->engine->flags & splashFTNoHinting) { - flags |= FT_LOAD_NO_HINTING; - } else if (ff->fontType == splashFontType1) { - flags |= FT_LOAD_TARGET_LIGHT; - } else { - flags |= FT_LOAD_NO_AUTOHINT; - } - if (FT_Load_Glyph(ff->face, (FT_UInt)gid, flags)) { - // fonts with broken hinting instructions can cause errors here; - // try again with no hinting (this is probably only relevant for - // TrueType fonts) - flags = FT_LOAD_NO_BITMAP | FT_LOAD_NO_HINTING; - if (FT_Load_Glyph(ff->face, (FT_UInt)gid, flags)) { - return gFalse; - } - } - if (FT_Render_Glyph(slot, aa ? FT_RENDER_MODE_NORMAL - : FT_RENDER_MODE_MONO)) { - return gFalse; - } - if (slot->bitmap.width == 0 || slot->bitmap.rows == 0) { - // this can happen if (a) the glyph is really tiny or (b) the - // metrics in the TrueType file are broken - return gFalse; - } - - bitmap->x = -slot->bitmap_left; - bitmap->y = slot->bitmap_top; - bitmap->w = slot->bitmap.width; - bitmap->h = slot->bitmap.rows; - bitmap->aa = aa; - if (aa) { - rowSize = bitmap->w; - } else { - rowSize = (bitmap->w + 7) >> 3; - } - bitmap->data = (Guchar *)gmallocn(bitmap->h, rowSize); - bitmap->freeData = gTrue; - for (i = 0, p = bitmap->data, q = slot->bitmap.buffer; - i < bitmap->h; - ++i, p += rowSize, q += slot->bitmap.pitch) { - memcpy(p, q, rowSize); - } - - return gTrue; -} - -struct SplashFTFontPath { - SplashPath *path; - SplashCoord textScale; - GBool needClose; -}; - -SplashPath *SplashFTFont::getGlyphPath(int c) { - static FT_Outline_Funcs outlineFuncs = { -#if FREETYPE_MINOR <= 1 - (int (*)(FT_Vector *, void *))&glyphPathMoveTo, - (int (*)(FT_Vector *, void *))&glyphPathLineTo, - (int (*)(FT_Vector *, FT_Vector *, void *))&glyphPathConicTo, - (int (*)(FT_Vector *, FT_Vector *, FT_Vector *, void *))&glyphPathCubicTo, -#else - &glyphPathMoveTo, - &glyphPathLineTo, - &glyphPathConicTo, - &glyphPathCubicTo, -#endif - 0, 0 - }; - SplashFTFontFile *ff; - SplashFTFontPath path; - FT_GlyphSlot slot; - int gid; - FT_Glyph glyph; - - ff = (SplashFTFontFile *)fontFile; - ff->face->size = sizeObj; - FT_Set_Transform(ff->face, &textMatrix, NULL); - slot = ff->face->glyph; - if (ff->codeToGID && c < ff->codeToGIDLen) { - gid = ff->codeToGID[c]; - } else { - gid = c; - } - if (ff->fontType == splashFontTrueType && gid < 0) { - // skip the TrueType notdef glyph - return NULL; - } - if (FT_Load_Glyph(ff->face, (FT_UInt)gid, FT_LOAD_NO_BITMAP)) { - // fonts with broken hinting instructions can cause errors here; - // try again with no hinting (this is probably only relevant for - // TrueType fonts) - if (FT_Load_Glyph(ff->face, (FT_UInt)gid, - FT_LOAD_NO_BITMAP | FT_LOAD_NO_HINTING)) { - return NULL; - } - } - if (FT_Get_Glyph(slot, &glyph)) { - return NULL; - } - path.path = new SplashPath(); - path.textScale = textScale; - path.needClose = gFalse; - FT_Outline_Decompose(&((FT_OutlineGlyph)glyph)->outline, - &outlineFuncs, &path); - if (path.needClose) { - path.path->close(); - } - FT_Done_Glyph(glyph); - return path.path; -} - -static int glyphPathMoveTo(const FT_Vector *pt, void *path) { - SplashFTFontPath *p = (SplashFTFontPath *)path; - - if (p->needClose) { - p->path->close(); - p->needClose = gFalse; - } - p->path->moveTo((SplashCoord)pt->x * p->textScale / 64.0, - (SplashCoord)pt->y * p->textScale / 64.0); - return 0; -} - -static int glyphPathLineTo(const FT_Vector *pt, void *path) { - SplashFTFontPath *p = (SplashFTFontPath *)path; - - p->path->lineTo((SplashCoord)pt->x * p->textScale / 64.0, - (SplashCoord)pt->y * p->textScale / 64.0); - p->needClose = gTrue; - return 0; -} - -static int glyphPathConicTo(const FT_Vector *ctrl, const FT_Vector *pt, - void *path) { - SplashFTFontPath *p = (SplashFTFontPath *)path; - SplashCoord x0, y0, x1, y1, x2, y2, x3, y3, xc, yc; - - if (!p->path->getCurPt(&x0, &y0)) { - return 0; - } - xc = (SplashCoord)ctrl->x * p->textScale / 64.0; - yc = (SplashCoord)ctrl->y * p->textScale / 64.0; - x3 = (SplashCoord)pt->x * p->textScale / 64.0; - y3 = (SplashCoord)pt->y * p->textScale / 64.0; - - // A second-order Bezier curve is defined by two endpoints, p0 and - // p3, and one control point, pc: - // - // p(t) = (1-t)^2*p0 + t*(1-t)*pc + t^2*p3 - // - // A third-order Bezier curve is defined by the same two endpoints, - // p0 and p3, and two control points, p1 and p2: - // - // p(t) = (1-t)^3*p0 + 3t*(1-t)^2*p1 + 3t^2*(1-t)*p2 + t^3*p3 - // - // Applying some algebra, we can convert a second-order curve to a - // third-order curve: - // - // p1 = (1/3) * (p0 + 2pc) - // p2 = (1/3) * (2pc + p3) - - x1 = (SplashCoord)(1.0 / 3.0) * (x0 + (SplashCoord)2 * xc); - y1 = (SplashCoord)(1.0 / 3.0) * (y0 + (SplashCoord)2 * yc); - x2 = (SplashCoord)(1.0 / 3.0) * ((SplashCoord)2 * xc + x3); - y2 = (SplashCoord)(1.0 / 3.0) * ((SplashCoord)2 * yc + y3); - - p->path->curveTo(x1, y1, x2, y2, x3, y3); - p->needClose = gTrue; - return 0; -} - -static int glyphPathCubicTo(const FT_Vector *ctrl1, const FT_Vector *ctrl2, - const FT_Vector *pt, void *path) { - SplashFTFontPath *p = (SplashFTFontPath *)path; - - p->path->curveTo((SplashCoord)ctrl1->x * p->textScale / 64.0, - (SplashCoord)ctrl1->y * p->textScale / 64.0, - (SplashCoord)ctrl2->x * p->textScale / 64.0, - (SplashCoord)ctrl2->y * p->textScale / 64.0, - (SplashCoord)pt->x * p->textScale / 64.0, - (SplashCoord)pt->y * p->textScale / 64.0); - p->needClose = gTrue; - return 0; -} - -#endif // HAVE_FREETYPE_H diff --git a/Build/source/libs/xpdf/xpdf-src/splash/SplashFTFont.h b/Build/source/libs/xpdf/xpdf-src/splash/SplashFTFont.h deleted file mode 100644 index ac08b007747..00000000000 --- a/Build/source/libs/xpdf/xpdf-src/splash/SplashFTFont.h +++ /dev/null @@ -1,60 +0,0 @@ -//======================================================================== -// -// SplashFTFont.h -// -// Copyright 2003-2013 Glyph & Cog, LLC -// -//======================================================================== - -#ifndef SPLASHFTFONT_H -#define SPLASHFTFONT_H - -#include <aconf.h> - -#if HAVE_FREETYPE_H - -#ifdef USE_GCC_PRAGMAS -#pragma interface -#endif - -#include <ft2build.h> -#include FT_FREETYPE_H -#include "SplashFont.h" - -class SplashFTFontFile; - -//------------------------------------------------------------------------ -// SplashFTFont -//------------------------------------------------------------------------ - -class SplashFTFont: public SplashFont { -public: - - SplashFTFont(SplashFTFontFile *fontFileA, SplashCoord *matA, - SplashCoord *textMatA); - - virtual ~SplashFTFont(); - - // Munge xFrac and yFrac before calling SplashFont::getGlyph. - virtual GBool getGlyph(int c, int xFrac, int yFrac, - SplashGlyphBitmap *bitmap); - - // Rasterize a glyph. The <xFrac> and <yFrac> values are the same - // as described for getGlyph. - virtual GBool makeGlyph(int c, int xFrac, int yFrac, - SplashGlyphBitmap *bitmap); - - // Return the path for a glyph. - virtual SplashPath *getGlyphPath(int c); - -private: - - FT_Size sizeObj; - FT_Matrix matrix; - FT_Matrix textMatrix; - SplashCoord textScale; -}; - -#endif // HAVE_FREETYPE_H - -#endif diff --git a/Build/source/libs/xpdf/xpdf-src/splash/SplashFTFontEngine.cc b/Build/source/libs/xpdf/xpdf-src/splash/SplashFTFontEngine.cc deleted file mode 100644 index 33939541051..00000000000 --- a/Build/source/libs/xpdf/xpdf-src/splash/SplashFTFontEngine.cc +++ /dev/null @@ -1,392 +0,0 @@ -//======================================================================== -// -// SplashFTFontEngine.cc -// -// Copyright 2003-2013 Glyph & Cog, LLC -// -//======================================================================== - -#include <aconf.h> - -#if HAVE_FREETYPE_H - -#ifdef USE_GCC_PRAGMAS -#pragma implementation -#endif - -#include <stdio.h> -#ifndef _WIN32 -# include <unistd.h> -#endif -#include "gmem.h" -#include "gmempp.h" -#include "GString.h" -#include "gfile.h" -#include "FoFiTrueType.h" -#include "FoFiType1C.h" -#include "SplashFTFontFile.h" -#include "SplashFTFontEngine.h" -#include FT_MODULE_H -#ifdef FT_CFF_DRIVER_H -# include FT_CFF_DRIVER_H -#endif - -#ifdef VMS -#if (__VMS_VER < 70000000) -extern "C" int unlink(char *filename); -#endif -#endif - -//------------------------------------------------------------------------ - -static void fileWrite(void *stream, const char *data, int len) { - fwrite(data, 1, len, (FILE *)stream); -} - -#if LOAD_FONTS_FROM_MEM -static void gstringWrite(void *stream, const char *data, int len) { - ((GString *)stream)->append(data, len); -} -#endif - -//------------------------------------------------------------------------ -// SplashFTFontEngine -//------------------------------------------------------------------------ - -SplashFTFontEngine::SplashFTFontEngine(GBool aaA, Guint flagsA, - FT_Library libA) { - FT_Int major, minor, patch; - - aa = aaA; - flags = flagsA; - lib = libA; - - // as of FT 2.1.8, CID fonts are indexed by CID instead of GID - FT_Library_Version(lib, &major, &minor, &patch); - useCIDs = major > 2 || - (major == 2 && (minor > 1 || (minor == 1 && patch > 7))); -} - -SplashFTFontEngine *SplashFTFontEngine::init(GBool aaA, Guint flagsA) { - FT_Library libA; - - if (FT_Init_FreeType(&libA)) { - return NULL; - } - return new SplashFTFontEngine(aaA, flagsA, libA); -} - -SplashFTFontEngine::~SplashFTFontEngine() { - FT_Done_FreeType(lib); -} - -SplashFontFile *SplashFTFontEngine::loadType1Font(SplashFontFileID *idA, -#if LOAD_FONTS_FROM_MEM - GString *fontBuf, -#else - char *fileName, - GBool deleteFile, -#endif - const char **enc) { - return SplashFTFontFile::loadType1Font(this, idA, splashFontType1, -#if LOAD_FONTS_FROM_MEM - fontBuf, -#else - fileName, deleteFile, -#endif - enc); -} - -SplashFontFile *SplashFTFontEngine::loadType1CFont(SplashFontFileID *idA, -#if LOAD_FONTS_FROM_MEM - GString *fontBuf, -#else - char *fileName, - GBool deleteFile, -#endif - const char **enc) { - return SplashFTFontFile::loadType1Font(this, idA, splashFontType1C, -#if LOAD_FONTS_FROM_MEM - fontBuf, -#else - fileName, deleteFile, -#endif - enc); -} - -SplashFontFile *SplashFTFontEngine::loadOpenTypeT1CFont(SplashFontFileID *idA, -#if LOAD_FONTS_FROM_MEM - GString *fontBuf, -#else - char *fileName, - GBool deleteFile, -#endif - const char **enc) { - FoFiTrueType *ff; -#if LOAD_FONTS_FROM_MEM - GString *fontBuf2; -#else - GString *tmpFileName; - FILE *tmpFile; -#endif - SplashFontFile *ret; - -#if LOAD_FONTS_FROM_MEM - if (!(ff = FoFiTrueType::make(fontBuf->getCString(), fontBuf->getLength(), - 0, gTrue))) { -#else - if (!(ff = FoFiTrueType::load(fileName, 0, gTrue))) { -#endif - return NULL; - } - if (ff->isHeadlessCFF()) { -#if LOAD_FONTS_FROM_MEM - fontBuf2 = new GString(); - ff->convertToType1(NULL, enc, gFalse, &gstringWrite, fontBuf2); - delete ff; - ret = SplashFTFontFile::loadType1Font(this, idA, splashFontType1, - fontBuf2, enc); - if (ret) { - delete fontBuf; - } else { - delete fontBuf2; - } -#else - tmpFileName = NULL; - if (!openTempFile(&tmpFileName, &tmpFile, "wb", NULL)) { - delete ff; - return NULL; - } - ff->convertToType1(NULL, enc, gFalse, &fileWrite, tmpFile); - delete ff; - fclose(tmpFile); - ret = SplashFTFontFile::loadType1Font(this, idA, splashFontType1, - tmpFileName->getCString(), - gTrue, enc); - if (ret) { - if (deleteFile) { - unlink(fileName); - } - } else { - unlink(tmpFileName->getCString()); - } - delete tmpFileName; -#endif - } else { - delete ff; - ret = SplashFTFontFile::loadType1Font(this, idA, splashFontOpenTypeT1C, -#if LOAD_FONTS_FROM_MEM - fontBuf, -#else - fileName, deleteFile, -#endif - enc); - } - return ret; -} - -SplashFontFile *SplashFTFontEngine::loadCIDFont(SplashFontFileID *idA, -#if LOAD_FONTS_FROM_MEM - GString *fontBuf, -#else - char *fileName, - GBool deleteFile, -#endif - int *codeToGID, - int codeToGIDLen) { - FoFiType1C *ff; - int *cidToGIDMap; - int nCIDs; - SplashFontFile *ret; - - // check for a CFF font - if (codeToGID) { - cidToGIDMap = NULL; - nCIDs = 0; - } else if (useCIDs) { - cidToGIDMap = NULL; - nCIDs = 0; -#if LOAD_FONTS_FROM_MEM - } else if ((ff = FoFiType1C::make(fontBuf->getCString(), - fontBuf->getLength()))) { -#else - } else if ((ff = FoFiType1C::load(fileName))) { -#endif - cidToGIDMap = ff->getCIDToGIDMap(&nCIDs); - delete ff; - } else { - cidToGIDMap = NULL; - nCIDs = 0; - } - ret = SplashFTFontFile::loadCIDFont(this, idA, splashFontCID, -#if LOAD_FONTS_FROM_MEM - fontBuf, -#else - fileName, deleteFile, -#endif - codeToGID ? codeToGID : cidToGIDMap, - codeToGID ? codeToGIDLen : nCIDs); - if (!ret) { - gfree(cidToGIDMap); - } - return ret; -} - -SplashFontFile *SplashFTFontEngine::loadOpenTypeCFFFont(SplashFontFileID *idA, -#if LOAD_FONTS_FROM_MEM - GString *fontBuf, -#else - char *fileName, - GBool deleteFile, -#endif - int *codeToGID, - int codeToGIDLen) { - FoFiTrueType *ff; -#if LOAD_FONTS_FROM_MEM - GString *fontBuf2; -#else - GString *tmpFileName; - FILE *tmpFile; -#endif - char *cffStart; - int cffLength; - int *cidToGIDMap; - int nCIDs; - SplashFontFile *ret; - -#if LOAD_FONTS_FROM_MEM - if (!(ff = FoFiTrueType::make(fontBuf->getCString(), fontBuf->getLength(), - 0, gTrue))) { -#else - if (!(ff = FoFiTrueType::load(fileName, 0, gTrue))) { -#endif - return NULL; - } - cidToGIDMap = NULL; - nCIDs = 0; - if (ff->isHeadlessCFF()) { - if (!ff->getCFFBlock(&cffStart, &cffLength)) { - return NULL; - } -#if LOAD_FONTS_FROM_MEM - fontBuf2 = new GString(cffStart, cffLength); - if (!useCIDs) { - cidToGIDMap = ff->getCIDToGIDMap(&nCIDs); - } - ret = SplashFTFontFile::loadCIDFont(this, idA, splashFontOpenTypeCFF, - fontBuf2, cidToGIDMap, nCIDs); - if (ret) { - delete fontBuf; - } else { - delete fontBuf2; - } -#else - tmpFileName = NULL; - if (!openTempFile(&tmpFileName, &tmpFile, "wb", NULL)) { - delete ff; - return NULL; - } - fwrite(cffStart, 1, cffLength, tmpFile); - fclose(tmpFile); - if (!useCIDs) { - cidToGIDMap = ff->getCIDToGIDMap(&nCIDs); - } - ret = SplashFTFontFile::loadCIDFont(this, idA, splashFontOpenTypeCFF, - tmpFileName->getCString(), gTrue, - cidToGIDMap, nCIDs); - if (ret) { - if (deleteFile) { - unlink(fileName); - } - } else { - unlink(tmpFileName->getCString()); - } - delete tmpFileName; -#endif - } else { - if (!codeToGID && !useCIDs && ff->isOpenTypeCFF()) { - cidToGIDMap = ff->getCIDToGIDMap(&nCIDs); - } - ret = SplashFTFontFile::loadCIDFont(this, idA, splashFontOpenTypeCFF, -#if LOAD_FONTS_FROM_MEM - fontBuf, -#else - fileName, deleteFile, -#endif - codeToGID ? codeToGID : cidToGIDMap, - codeToGID ? codeToGIDLen : nCIDs); - } - delete ff; - if (!ret) { - gfree(cidToGIDMap); - } - return ret; -} - -SplashFontFile *SplashFTFontEngine::loadTrueTypeFont(SplashFontFileID *idA, -#if LOAD_FONTS_FROM_MEM - GString *fontBuf, -#else - char *fileName, - GBool deleteFile, -#endif - int fontNum, - int *codeToGID, - int codeToGIDLen) { - FoFiTrueType *ff; -#if LOAD_FONTS_FROM_MEM - GString *fontBuf2; -#else - GString *tmpFileName; - FILE *tmpFile; -#endif - SplashFontFile *ret; - -#if LOAD_FONTS_FROM_MEM - if (!(ff = FoFiTrueType::make(fontBuf->getCString(), fontBuf->getLength(), - fontNum))) { -#else - if (!(ff = FoFiTrueType::load(fileName, fontNum))) { -#endif - return NULL; - } -#if LOAD_FONTS_FROM_MEM - fontBuf2 = new GString; - ff->writeTTF(&gstringWrite, fontBuf2); -#else - tmpFileName = NULL; - if (!openTempFile(&tmpFileName, &tmpFile, "wb", NULL)) { - delete ff; - return NULL; - } - ff->writeTTF(&fileWrite, tmpFile); - fclose(tmpFile); -#endif - delete ff; - ret = SplashFTFontFile::loadTrueTypeFont(this, idA, splashFontTrueType, -#if LOAD_FONTS_FROM_MEM - fontBuf2, -#else - tmpFileName->getCString(), gTrue, -#endif - 0, codeToGID, codeToGIDLen); -#if LOAD_FONTS_FROM_MEM - if (ret) { - delete fontBuf; - } else { - delete fontBuf2; - } -#else - if (ret) { - if (deleteFile) { - unlink(fileName); - } - } else { - unlink(tmpFileName->getCString()); - } - delete tmpFileName; -#endif - return ret; -} - -#endif // HAVE_FREETYPE_H diff --git a/Build/source/libs/xpdf/xpdf-src/splash/SplashFTFontEngine.h b/Build/source/libs/xpdf/xpdf-src/splash/SplashFTFontEngine.h deleted file mode 100644 index 24db3c6cdba..00000000000 --- a/Build/source/libs/xpdf/xpdf-src/splash/SplashFTFontEngine.h +++ /dev/null @@ -1,99 +0,0 @@ -//======================================================================== -// -// SplashFTFontEngine.h -// -// Copyright 2003-2013 Glyph & Cog, LLC -// -//======================================================================== - -#ifndef SPLASHFTFONTENGINE_H -#define SPLASHFTFONTENGINE_H - -#include <aconf.h> - -#if HAVE_FREETYPE_H - -#ifdef USE_GCC_PRAGMAS -#pragma interface -#endif - -#include <ft2build.h> -#include FT_FREETYPE_H -#include "gtypes.h" -class GString; - -class SplashFontFile; -class SplashFontFileID; - -//------------------------------------------------------------------------ -// SplashFTFontEngine -//------------------------------------------------------------------------ - -class SplashFTFontEngine { -public: - - static SplashFTFontEngine *init(GBool aaA, Guint flagsA); - - ~SplashFTFontEngine(); - - // Load fonts. - SplashFontFile *loadType1Font(SplashFontFileID *idA, -#if LOAD_FONTS_FROM_MEM - GString *fontBuf, -#else - char *fileName, GBool deleteFile, -#endif - const char **enc); - SplashFontFile *loadType1CFont(SplashFontFileID *idA, -#if LOAD_FONTS_FROM_MEM - GString *fontBuf, -#else - char *fileName, GBool deleteFile, -#endif - const char **enc); - SplashFontFile *loadOpenTypeT1CFont(SplashFontFileID *idA, -#if LOAD_FONTS_FROM_MEM - GString *fontBuf, -#else - char *fileName, GBool deleteFile, -#endif - const char **enc); - SplashFontFile *loadCIDFont(SplashFontFileID *idA, -#if LOAD_FONTS_FROM_MEM - GString *fontBuf, -#else - char *fileName, GBool deleteFile, -#endif - int *codeToGID, int codeToGIDLen); - SplashFontFile *loadOpenTypeCFFFont(SplashFontFileID *idA, -#if LOAD_FONTS_FROM_MEM - GString *fontBuf, -#else - char *fileName, GBool deleteFile, -#endif - int *codeToGID, int codeToGIDLen); - SplashFontFile *loadTrueTypeFont(SplashFontFileID *idA, -#if LOAD_FONTS_FROM_MEM - GString *fontBuf, -#else - char *fileName, GBool deleteFile, -#endif - int fontNum, - int *codeToGID, int codeToGIDLen); - -private: - - SplashFTFontEngine(GBool aaA, Guint flagsA, FT_Library libA); - - GBool aa; - Guint flags; - FT_Library lib; - GBool useCIDs; - - friend class SplashFTFontFile; - friend class SplashFTFont; -}; - -#endif // HAVE_FREETYPE_H - -#endif diff --git a/Build/source/libs/xpdf/xpdf-src/splash/SplashFTFontFile.cc b/Build/source/libs/xpdf/xpdf-src/splash/SplashFTFontFile.cc deleted file mode 100644 index b5fd02af4a0..00000000000 --- a/Build/source/libs/xpdf/xpdf-src/splash/SplashFTFontFile.cc +++ /dev/null @@ -1,171 +0,0 @@ -//======================================================================== -// -// SplashFTFontFile.cc -// -// Copyright 2003-2013 Glyph & Cog, LLC -// -//======================================================================== - -#include <aconf.h> - -#if HAVE_FREETYPE_H - -#ifdef USE_GCC_PRAGMAS -#pragma implementation -#endif - -#include "gmem.h" -#include "gmempp.h" -#include "GString.h" -#include "SplashFTFontEngine.h" -#include "SplashFTFont.h" -#include "SplashFTFontFile.h" - -//------------------------------------------------------------------------ -// SplashFTFontFile -//------------------------------------------------------------------------ - -SplashFontFile *SplashFTFontFile::loadType1Font(SplashFTFontEngine *engineA, - SplashFontFileID *idA, - SplashFontType fontTypeA, -#if LOAD_FONTS_FROM_MEM - GString *fontBufA, -#else - char *fileNameA, - GBool deleteFileA, -#endif - const char **encA) { - FT_Face faceA; - int *codeToGIDA; - const char *name; - int i; - -#if LOAD_FONTS_FROM_MEM - if (FT_New_Memory_Face(engineA->lib, (FT_Byte *)fontBufA->getCString(), - fontBufA->getLength(), 0, &faceA)) { -#else - if (FT_New_Face(engineA->lib, fileNameA, 0, &faceA)) { -#endif - return NULL; - } - codeToGIDA = (int *)gmallocn(256, sizeof(int)); - for (i = 0; i < 256; ++i) { - codeToGIDA[i] = 0; - if ((name = encA[i])) { - codeToGIDA[i] = (int)FT_Get_Name_Index(faceA, (char *)name); - } - } - - return new SplashFTFontFile(engineA, idA, fontTypeA, -#if LOAD_FONTS_FROM_MEM - fontBufA, -#else - fileNameA, deleteFileA, -#endif - faceA, codeToGIDA, 256); -} - -SplashFontFile *SplashFTFontFile::loadCIDFont(SplashFTFontEngine *engineA, - SplashFontFileID *idA, - SplashFontType fontTypeA, -#if LOAD_FONTS_FROM_MEM - GString *fontBufA, -#else - char *fileNameA, - GBool deleteFileA, -#endif - int *codeToGIDA, - int codeToGIDLenA) { - FT_Face faceA; - -#if LOAD_FONTS_FROM_MEM - if (FT_New_Memory_Face(engineA->lib, (FT_Byte *)fontBufA->getCString(), - fontBufA->getLength(), 0, &faceA)) { -#else - if (FT_New_Face(engineA->lib, fileNameA, 0, &faceA)) { -#endif - return NULL; - } - - return new SplashFTFontFile(engineA, idA, fontTypeA, -#if LOAD_FONTS_FROM_MEM - fontBufA, -#else - fileNameA, deleteFileA, -#endif - faceA, codeToGIDA, codeToGIDLenA); -} - -SplashFontFile *SplashFTFontFile::loadTrueTypeFont(SplashFTFontEngine *engineA, - SplashFontFileID *idA, - SplashFontType fontTypeA, -#if LOAD_FONTS_FROM_MEM - GString *fontBufA, -#else - char *fileNameA, - GBool deleteFileA, -#endif - int fontNum, - int *codeToGIDA, - int codeToGIDLenA) { - FT_Face faceA; - -#if LOAD_FONTS_FROM_MEM - if (FT_New_Memory_Face(engineA->lib, (FT_Byte *)fontBufA->getCString(), - fontBufA->getLength(), fontNum, &faceA)) { -#else - if (FT_New_Face(engineA->lib, fileNameA, fontNum, &faceA)) { -#endif - return NULL; - } - - return new SplashFTFontFile(engineA, idA, fontTypeA, -#if LOAD_FONTS_FROM_MEM - fontBufA, -#else - fileNameA, deleteFileA, -#endif - faceA, codeToGIDA, codeToGIDLenA); -} - -SplashFTFontFile::SplashFTFontFile(SplashFTFontEngine *engineA, - SplashFontFileID *idA, - SplashFontType fontTypeA, -#if LOAD_FONTS_FROM_MEM - GString *fontBufA, -#else - char *fileNameA, GBool deleteFileA, -#endif - FT_Face faceA, - int *codeToGIDA, int codeToGIDLenA): -#if LOAD_FONTS_FROM_MEM - SplashFontFile(idA, fontTypeA, fontBufA) -#else - SplashFontFile(idA, fontTypeA, fileNameA, deleteFileA) -#endif -{ - engine = engineA; - face = faceA; - codeToGID = codeToGIDA; - codeToGIDLen = codeToGIDLenA; -} - -SplashFTFontFile::~SplashFTFontFile() { - if (face) { - FT_Done_Face(face); - } - if (codeToGID) { - gfree(codeToGID); - } -} - -SplashFont *SplashFTFontFile::makeFont(SplashCoord *mat, - SplashCoord *textMat) { - SplashFont *font; - - font = new SplashFTFont(this, mat, textMat); - font->initCache(); - return font; -} - -#endif // HAVE_FREETYPE_H diff --git a/Build/source/libs/xpdf/xpdf-src/splash/SplashFTFontFile.h b/Build/source/libs/xpdf/xpdf-src/splash/SplashFTFontFile.h deleted file mode 100644 index 3a6b9b7aa43..00000000000 --- a/Build/source/libs/xpdf/xpdf-src/splash/SplashFTFontFile.h +++ /dev/null @@ -1,95 +0,0 @@ -//======================================================================== -// -// SplashFTFontFile.h -// -// Copyright 2003-2013 Glyph & Cog, LLC -// -//======================================================================== - -#ifndef SPLASHFTFONTFILE_H -#define SPLASHFTFONTFILE_H - -#include <aconf.h> - -#if HAVE_FREETYPE_H - -#ifdef USE_GCC_PRAGMAS -#pragma interface -#endif - -#include <ft2build.h> -#include FT_FREETYPE_H -#include "SplashFontFile.h" - -class SplashFontFileID; -class SplashFTFontEngine; - -//------------------------------------------------------------------------ -// SplashFTFontFile -//------------------------------------------------------------------------ - -class SplashFTFontFile: public SplashFontFile { -public: - - static SplashFontFile *loadType1Font(SplashFTFontEngine *engineA, - SplashFontFileID *idA, - SplashFontType fontTypeA, -#if LOAD_FONTS_FROM_MEM - GString *fontBufA, -#else - char *fileNameA, GBool deleteFileA, -#endif - const char **encA); - static SplashFontFile *loadCIDFont(SplashFTFontEngine *engineA, - SplashFontFileID *idA, - SplashFontType fontTypeA, -#if LOAD_FONTS_FROM_MEM - GString *fontBufA, -#else - char *fileNameA, GBool deleteFileA, -#endif - int *codeToGIDA, int codeToGIDLenA); - static SplashFontFile *loadTrueTypeFont(SplashFTFontEngine *engineA, - SplashFontFileID *idA, - SplashFontType fontTypeA, -#if LOAD_FONTS_FROM_MEM - GString *fontBufA, -#else - char *fileNameA, - GBool deleteFileA, -#endif - int fontNum, - int *codeToGIDA, - int codeToGIDLenA); - - virtual ~SplashFTFontFile(); - - // Create a new SplashFTFont, i.e., a scaled instance of this font - // file. - virtual SplashFont *makeFont(SplashCoord *mat, - SplashCoord *textMat); - -private: - - SplashFTFontFile(SplashFTFontEngine *engineA, - SplashFontFileID *idA, - SplashFontType fontTypeA, -#if LOAD_FONTS_FROM_MEM - GString *fontBufA, -#else - char *fileNameA, GBool deleteFileA, -#endif - FT_Face faceA, - int *codeToGIDA, int codeToGIDLenA); - - SplashFTFontEngine *engine; - FT_Face face; - int *codeToGID; - int codeToGIDLen; - - friend class SplashFTFont; -}; - -#endif // HAVE_FREETYPE_H - -#endif diff --git a/Build/source/libs/xpdf/xpdf-src/splash/SplashFont.cc b/Build/source/libs/xpdf/xpdf-src/splash/SplashFont.cc deleted file mode 100644 index 2fcd83d1266..00000000000 --- a/Build/source/libs/xpdf/xpdf-src/splash/SplashFont.cc +++ /dev/null @@ -1,195 +0,0 @@ -//======================================================================== -// -// SplashFont.cc -// -// Copyright 2003-2013 Glyph & Cog, LLC -// -//======================================================================== - -#include <aconf.h> - -#ifdef USE_GCC_PRAGMAS -#pragma implementation -#endif - -#include <string.h> -#include "gmem.h" -#include "gmempp.h" -#include "SplashMath.h" -#include "SplashGlyphBitmap.h" -#include "SplashFontFile.h" -#include "SplashFont.h" - -//------------------------------------------------------------------------ - -// font cache size parameters -#define splashFontCacheAssoc 8 -#define splashFontCacheMaxSets 8 -#define splashFontCacheSize (128*1024) - -//------------------------------------------------------------------------ - -struct SplashFontCacheTag { - int c; - short xFrac, yFrac; // x and y fractions - int mru; // valid bit (0x80000000) and MRU index - int x, y, w, h; // offset and size of glyph -}; - -//------------------------------------------------------------------------ -// SplashFont -//------------------------------------------------------------------------ - -SplashFont::SplashFont(SplashFontFile *fontFileA, SplashCoord *matA, - SplashCoord *textMatA, GBool aaA) { - fontFile = fontFileA; - fontFile->incRefCnt(); - mat[0] = matA[0]; - mat[1] = matA[1]; - mat[2] = matA[2]; - mat[3] = matA[3]; - textMat[0] = textMatA[0]; - textMat[1] = textMatA[1]; - textMat[2] = textMatA[2]; - textMat[3] = textMatA[3]; - aa = aaA; - - cache = NULL; - cacheTags = NULL; - - xMin = yMin = xMax = yMax = 0; -} - -void SplashFont::initCache() { - int i; - - // this should be (max - min + 1), but we add some padding to - // deal with rounding errors - glyphW = xMax - xMin + 3; - glyphH = yMax - yMin + 3; - if (glyphW > 1000 || glyphH > 1000) { - // if the glyphs are too large, don't cache them -- setting the - // cache bitmap size to something tiny will cause getGlyph() to - // fall back to the uncached case - glyphW = glyphH = 0; - glyphSize = 0; - cacheSets = 0; - cacheAssoc = 0; - return; - } - if (aa) { - glyphSize = glyphW * glyphH; - } else { - glyphSize = ((glyphW + 7) >> 3) * glyphH; - } - - // set up the glyph pixmap cache - cacheAssoc = splashFontCacheAssoc; - for (cacheSets = splashFontCacheMaxSets; - cacheSets > 1 && - glyphSize > splashFontCacheSize / (cacheSets * cacheAssoc); - cacheSets >>= 1) ; - cache = (Guchar *)gmallocn(cacheSets * cacheAssoc, glyphSize); - cacheTags = (SplashFontCacheTag *)gmallocn(cacheSets * cacheAssoc, - sizeof(SplashFontCacheTag)); - for (i = 0; i < cacheSets * cacheAssoc; ++i) { - cacheTags[i].mru = i & (cacheAssoc - 1); - } -} - -SplashFont::~SplashFont() { - fontFile->decRefCnt(); - if (cache) { - gfree(cache); - } - if (cacheTags) { - gfree(cacheTags); - } -} - -GBool SplashFont::getGlyph(int c, int xFrac, int yFrac, - SplashGlyphBitmap *bitmap) { - SplashGlyphBitmap bitmap2; - int size; - Guchar *p; - int i, j, k; - - // no fractional coordinates for large glyphs or non-anti-aliased - // glyphs - if (!aa || glyphH > 50) { - xFrac = yFrac = 0; - } - - // check the cache - if (cache) { - i = (c & (cacheSets - 1)) * cacheAssoc; - for (j = 0; j < cacheAssoc; ++j) { - if ((cacheTags[i+j].mru & 0x80000000) && - cacheTags[i+j].c == c && - (int)cacheTags[i+j].xFrac == xFrac && - (int)cacheTags[i+j].yFrac == yFrac) { - bitmap->x = cacheTags[i+j].x; - bitmap->y = cacheTags[i+j].y; - bitmap->w = cacheTags[i+j].w; - bitmap->h = cacheTags[i+j].h; - for (k = 0; k < cacheAssoc; ++k) { - if (k != j && - (cacheTags[i+k].mru & 0x7fffffff) < - (cacheTags[i+j].mru & 0x7fffffff)) { - ++cacheTags[i+k].mru; - } - } - cacheTags[i+j].mru = 0x80000000; - bitmap->aa = aa; - bitmap->data = cache + (i+j) * glyphSize; - bitmap->freeData = gFalse; - return gTrue; - } - } - } else { - i = 0; // make gcc happy - } - - // generate the glyph bitmap - if (!makeGlyph(c, xFrac, yFrac, &bitmap2)) { - return gFalse; - } - - // if the glyph doesn't fit in the bounding box, return a temporary - // uncached bitmap - if (!cache || bitmap2.w > glyphW || bitmap2.h > glyphH) { - *bitmap = bitmap2; - return gTrue; - } - - // insert glyph pixmap in cache - if (aa) { - size = bitmap2.w * bitmap2.h; - } else { - size = ((bitmap2.w + 7) >> 3) * bitmap2.h; - } - p = NULL; // make gcc happy - for (j = 0; j < cacheAssoc; ++j) { - if ((cacheTags[i+j].mru & 0x7fffffff) == cacheAssoc - 1) { - cacheTags[i+j].mru = 0x80000000; - cacheTags[i+j].c = c; - cacheTags[i+j].xFrac = (short)xFrac; - cacheTags[i+j].yFrac = (short)yFrac; - cacheTags[i+j].x = bitmap2.x; - cacheTags[i+j].y = bitmap2.y; - cacheTags[i+j].w = bitmap2.w; - cacheTags[i+j].h = bitmap2.h; - p = cache + (i+j) * glyphSize; - memcpy(p, bitmap2.data, size); - } else { - ++cacheTags[i+j].mru; - } - } - *bitmap = bitmap2; - bitmap->data = p; - bitmap->freeData = gFalse; - if (bitmap2.freeData) { - gfree(bitmap2.data); - } - return gTrue; -} diff --git a/Build/source/libs/xpdf/xpdf-src/splash/SplashFont.h b/Build/source/libs/xpdf/xpdf-src/splash/SplashFont.h deleted file mode 100644 index 2bb96545867..00000000000 --- a/Build/source/libs/xpdf/xpdf-src/splash/SplashFont.h +++ /dev/null @@ -1,111 +0,0 @@ -//======================================================================== -// -// SplashFont.h -// -// Copyright 2003-2013 Glyph & Cog, LLC -// -//======================================================================== - -#ifndef SPLASHFONT_H -#define SPLASHFONT_H - -#include <aconf.h> - -#ifdef USE_GCC_PRAGMAS -#pragma interface -#endif - -#include "gtypes.h" -#include "SplashTypes.h" -#include "SplashMath.h" - -struct SplashGlyphBitmap; -struct SplashFontCacheTag; -class SplashFontFile; -class SplashPath; - -//------------------------------------------------------------------------ - -// Fractional positioning uses this many bits to the right of the -// decimal points. -#define splashFontFractionBits 2 -#define splashFontFraction (1 << splashFontFractionBits) -#define splashFontFractionMul \ - ((SplashCoord)1 / (SplashCoord)splashFontFraction) - -//------------------------------------------------------------------------ -// SplashFont -//------------------------------------------------------------------------ - -class SplashFont { -public: - - SplashFont(SplashFontFile *fontFileA, SplashCoord *matA, - SplashCoord *textMatA, GBool aaA); - - // This must be called after the constructor, so that the subclass - // constructor has a chance to compute the bbox. - void initCache(); - - virtual ~SplashFont(); - - SplashFontFile *getFontFile() { return fontFile; } - - // Return true if <this> matches the specified font file and matrix. - GBool matches(SplashFontFile *fontFileA, SplashCoord *matA, - SplashCoord *textMatA) { - return fontFileA == fontFile && - splashAbs(matA[0] - mat[0]) < 0.0001 && - splashAbs(matA[1] - mat[1]) < 0.0001 && - splashAbs(matA[2] - mat[2]) < 0.0001 && - splashAbs(matA[3] - mat[3]) < 0.0001 && - splashAbs(textMatA[0] - textMat[0]) < 0.0001 && - splashAbs(textMatA[1] - textMat[1]) < 0.0001 && - splashAbs(textMatA[2] - textMat[2]) < 0.0001 && - splashAbs(textMatA[3] - textMat[3]) < 0.0001; - } - - // Get a glyph - this does a cache lookup first, and if not found, - // creates a new bitmap and adds it to the cache. The <xFrac> and - // <yFrac> values are splashFontFractionBits bits each, representing - // the numerators of fractions in [0, 1), where the denominator is - // splashFontFraction = 1 << splashFontFractionBits. Subclasses - // should override this to zero out xFrac and/or yFrac if they don't - // support fractional coordinates. - virtual GBool getGlyph(int c, int xFrac, int yFrac, - SplashGlyphBitmap *bitmap); - - // Rasterize a glyph. The <xFrac> and <yFrac> values are the same - // as described for getGlyph. - virtual GBool makeGlyph(int c, int xFrac, int yFrac, - SplashGlyphBitmap *bitmap) = 0; - - // Return the path for a glyph. - virtual SplashPath *getGlyphPath(int c) = 0; - - // Return the font transform matrix. - SplashCoord *getMatrix() { return mat; } - - // Return the glyph bounding box. - void getBBox(int *xMinA, int *yMinA, int *xMaxA, int *yMaxA) - { *xMinA = xMin; *yMinA = yMin; *xMaxA = xMax; *yMaxA = yMax; } - -protected: - - SplashFontFile *fontFile; - SplashCoord mat[4]; // font transform matrix - // (text space -> device space) - SplashCoord textMat[4]; // text transform matrix - // (text space -> user space) - GBool aa; // anti-aliasing - int xMin, yMin, xMax, yMax; // glyph bounding box - Guchar *cache; // glyph bitmap cache - SplashFontCacheTag * // cache tags - cacheTags; - int glyphW, glyphH; // size of glyph bitmaps - int glyphSize; // size of glyph bitmaps, in bytes - int cacheSets; // number of sets in cache - int cacheAssoc; // cache associativity (glyphs per set) -}; - -#endif diff --git a/Build/source/libs/xpdf/xpdf-src/splash/SplashFontEngine.cc b/Build/source/libs/xpdf/xpdf-src/splash/SplashFontEngine.cc deleted file mode 100644 index 81afe0cd914..00000000000 --- a/Build/source/libs/xpdf/xpdf-src/splash/SplashFontEngine.cc +++ /dev/null @@ -1,409 +0,0 @@ -//======================================================================== -// -// SplashFontEngine.cc -// -// Copyright 2003-2013 Glyph & Cog, LLC -// -//======================================================================== - -#include <aconf.h> - -#ifdef USE_GCC_PRAGMAS -#pragma implementation -#endif - -#include <stdlib.h> -#include <stdio.h> -#ifndef _WIN32 -# include <unistd.h> -#endif -#include "gmem.h" -#include "gmempp.h" -#include "GString.h" -#include "GList.h" -#include "SplashMath.h" -#include "SplashFTFontEngine.h" -#include "SplashFontFile.h" -#include "SplashFontFileID.h" -#include "SplashFont.h" -#include "SplashFontEngine.h" - -#ifdef VMS -#if (__VMS_VER < 70000000) -extern "C" int unlink(char *filename); -#endif -#endif - -//------------------------------------------------------------------------ -// SplashFontEngine -//------------------------------------------------------------------------ - -SplashFontEngine::SplashFontEngine( -#if HAVE_FREETYPE_H - GBool enableFreeType, - Guint freeTypeFlags, -#endif - GBool aa) { - int i; - - for (i = 0; i < splashFontCacheSize; ++i) { - fontCache[i] = NULL; - } - badFontFiles = new GList(); - -#if HAVE_FREETYPE_H - if (enableFreeType) { - ftEngine = SplashFTFontEngine::init(aa, freeTypeFlags); - } else { - ftEngine = NULL; - } -#endif -} - -SplashFontEngine::~SplashFontEngine() { - int i; - - for (i = 0; i < splashFontCacheSize; ++i) { - if (fontCache[i]) { - delete fontCache[i]; - } - } - deleteGList(badFontFiles, SplashFontFileID); - -#if HAVE_FREETYPE_H - if (ftEngine) { - delete ftEngine; - } -#endif -} - -SplashFontFile *SplashFontEngine::getFontFile(SplashFontFileID *id) { - SplashFontFile *fontFile; - int i; - - for (i = 0; i < splashFontCacheSize; ++i) { - if (fontCache[i]) { - fontFile = fontCache[i]->getFontFile(); - if (fontFile && fontFile->getID()->matches(id)) { - return fontFile; - } - } - } - return NULL; -} - -GBool SplashFontEngine::checkForBadFontFile(SplashFontFileID *id) { - for (int i = 0; i < badFontFiles->getLength(); ++i) { - if (((SplashFontFileID *)badFontFiles->get(i))->matches(id)) { - return gTrue; - } - } - return gFalse; -} - -SplashFontFile *SplashFontEngine::loadType1Font(SplashFontFileID *idA, -#if LOAD_FONTS_FROM_MEM - GString *fontBuf, -#else - char *fileName, - GBool deleteFile, -#endif - const char **enc) { - SplashFontFile *fontFile; - - fontFile = NULL; -#if HAVE_FREETYPE_H - if (!fontFile && ftEngine) { - fontFile = ftEngine->loadType1Font(idA, -#if LOAD_FONTS_FROM_MEM - fontBuf, -#else - fileName, deleteFile, -#endif - enc); - } -#endif - -#if !LOAD_FONTS_FROM_MEM && !defined(_WIN32) && !defined(__ANDROID__) - // delete the (temporary) font file -- with Unix hard link - // semantics, this will remove the last link; otherwise it will - // return an error, leaving the file to be deleted later (if - // loadXYZFont failed, the file will always be deleted) - if (deleteFile) { - unlink(fontFile ? fontFile->fileName->getCString() : fileName); - } -#endif - - if (!fontFile) { - badFontFiles->append(idA); - } - - return fontFile; -} - -SplashFontFile *SplashFontEngine::loadType1CFont(SplashFontFileID *idA, -#if LOAD_FONTS_FROM_MEM - GString *fontBuf, -#else - char *fileName, - GBool deleteFile, -#endif - int *codeToGID, - const char **enc) { - SplashFontFile *fontFile; - - fontFile = NULL; - if (!fontFile) { - gfree(codeToGID); - } -#if HAVE_FREETYPE_H - if (!fontFile && ftEngine) { - fontFile = ftEngine->loadType1CFont(idA, -#if LOAD_FONTS_FROM_MEM - fontBuf, -#else - fileName, deleteFile, -#endif - enc); - } -#endif - -#if !LOAD_FONTS_FROM_MEM && !defined(_WIN32) && !defined(__ANDROID__) - // delete the (temporary) font file -- with Unix hard link - // semantics, this will remove the last link; otherwise it will - // return an error, leaving the file to be deleted later (if - // loadXYZFont failed, the file will always be deleted) - if (deleteFile) { - unlink(fontFile ? fontFile->fileName->getCString() : fileName); - } -#endif - - if (!fontFile) { - badFontFiles->append(idA); - } - - return fontFile; -} - -SplashFontFile *SplashFontEngine::loadOpenTypeT1CFont(SplashFontFileID *idA, -#if LOAD_FONTS_FROM_MEM - GString *fontBuf, -#else - char *fileName, - GBool deleteFile, -#endif - int *codeToGID, - const char **enc) { - SplashFontFile *fontFile; - - fontFile = NULL; - if (!fontFile) { - gfree(codeToGID); - } -#if HAVE_FREETYPE_H - if (!fontFile && ftEngine) { - fontFile = ftEngine->loadOpenTypeT1CFont(idA, -#if LOAD_FONTS_FROM_MEM - fontBuf, -#else - fileName, deleteFile, -#endif - enc); - } -#endif - -#if !LOAD_FONTS_FROM_MEM && !defined(_WIN32) && !defined(__ANDROID__) - // delete the (temporary) font file -- with Unix hard link - // semantics, this will remove the last link; otherwise it will - // return an error, leaving the file to be deleted later (if - // loadXYZFont failed, the file will always be deleted) - if (deleteFile) { - unlink(fontFile ? fontFile->fileName->getCString() : fileName); - } -#endif - - if (!fontFile) { - badFontFiles->append(idA); - } - - return fontFile; -} - -SplashFontFile *SplashFontEngine::loadCIDFont(SplashFontFileID *idA, -#if LOAD_FONTS_FROM_MEM - GString *fontBuf, -#else - char *fileName, - GBool deleteFile, -#endif - int *codeToGID, - int codeToGIDLen) { - SplashFontFile *fontFile; - - fontFile = NULL; -#if HAVE_FREETYPE_H - if (!fontFile && ftEngine) { - fontFile = ftEngine->loadCIDFont(idA, -#if LOAD_FONTS_FROM_MEM - fontBuf, -#else - fileName, deleteFile, -#endif - codeToGID, codeToGIDLen); - } -#endif - - if (!fontFile) { - gfree(codeToGID); - } - -#if !LOAD_FONTS_FROM_MEM && !defined(_WIN32) && !defined(__ANDROID__) - // delete the (temporary) font file -- with Unix hard link - // semantics, this will remove the last link; otherwise it will - // return an error, leaving the file to be deleted later (if - // loadXYZFont failed, the file will always be deleted) - if (deleteFile) { - unlink(fontFile ? fontFile->fileName->getCString() : fileName); - } -#endif - - if (!fontFile) { - badFontFiles->append(idA); - } - - return fontFile; -} - -SplashFontFile *SplashFontEngine::loadOpenTypeCFFFont(SplashFontFileID *idA, -#if LOAD_FONTS_FROM_MEM - GString *fontBuf, -#else - char *fileName, - GBool deleteFile, -#endif - int *codeToGID, - int codeToGIDLen) { - SplashFontFile *fontFile; - - fontFile = NULL; -#if HAVE_FREETYPE_H - if (!fontFile && ftEngine) { - fontFile = ftEngine->loadOpenTypeCFFFont(idA, -#if LOAD_FONTS_FROM_MEM - fontBuf, -#else - fileName, deleteFile, -#endif - codeToGID, codeToGIDLen); - } -#endif - - if (!fontFile) { - gfree(codeToGID); - } - -#if !LOAD_FONTS_FROM_MEM && !defined(_WIN32) && !defined(__ANDROID__) - // delete the (temporary) font file -- with Unix hard link - // semantics, this will remove the last link; otherwise it will - // return an error, leaving the file to be deleted later (if - // loadXYZFont failed, the file will always be deleted) - if (deleteFile) { - unlink(fontFile ? fontFile->fileName->getCString() : fileName); - } -#endif - - if (!fontFile) { - badFontFiles->append(idA); - } - - return fontFile; -} - -SplashFontFile *SplashFontEngine::loadTrueTypeFont(SplashFontFileID *idA, -#if LOAD_FONTS_FROM_MEM - GString *fontBuf, -#else - char *fileName, - GBool deleteFile, -#endif - int fontNum, - int *codeToGID, - int codeToGIDLen, - char *fontName) { - SplashFontFile *fontFile; - - fontFile = NULL; -#if HAVE_FREETYPE_H - if (!fontFile && ftEngine) { - fontFile = ftEngine->loadTrueTypeFont(idA, -#if LOAD_FONTS_FROM_MEM - fontBuf, -#else - fileName, deleteFile, -#endif - fontNum, codeToGID, codeToGIDLen); - } -#endif - - if (!fontFile) { - gfree(codeToGID); - } - -#if !LOAD_FONTS_FROM_MEM && !defined(_WIN32) && !defined(__ANDROID__) - // delete the (temporary) font file -- with Unix hard link - // semantics, this will remove the last link; otherwise it will - // return an error, leaving the file to be deleted later (if - // loadXYZFont failed, the file will always be deleted) - if (deleteFile) { - unlink(fontFile ? fontFile->fileName->getCString() : fileName); - } -#endif - - if (!fontFile) { - badFontFiles->append(idA); - } - - return fontFile; -} - -SplashFont *SplashFontEngine::getFont(SplashFontFile *fontFile, - SplashCoord *textMat, - SplashCoord *ctm) { - SplashCoord mat[4]; - SplashFont *font; - int i, j; - - mat[0] = textMat[0] * ctm[0] + textMat[1] * ctm[2]; - mat[1] = -(textMat[0] * ctm[1] + textMat[1] * ctm[3]); - mat[2] = textMat[2] * ctm[0] + textMat[3] * ctm[2]; - mat[3] = -(textMat[2] * ctm[1] + textMat[3] * ctm[3]); - if (!splashCheckDet(mat[0], mat[1], mat[2], mat[3], 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 = fontCache[0]; - if (font && font->matches(fontFile, mat, textMat)) { - return font; - } - for (i = 1; i < splashFontCacheSize; ++i) { - font = fontCache[i]; - if (font && font->matches(fontFile, mat, textMat)) { - for (j = i; j > 0; --j) { - fontCache[j] = fontCache[j-1]; - } - fontCache[0] = font; - return font; - } - } - font = fontFile->makeFont(mat, textMat); - if (fontCache[splashFontCacheSize - 1]) { - delete fontCache[splashFontCacheSize - 1]; - } - for (j = splashFontCacheSize - 1; j > 0; --j) { - fontCache[j] = fontCache[j-1]; - } - fontCache[0] = font; - return font; -} diff --git a/Build/source/libs/xpdf/xpdf-src/splash/SplashFontEngine.h b/Build/source/libs/xpdf/xpdf-src/splash/SplashFontEngine.h deleted file mode 100644 index 59adb95858a..00000000000 --- a/Build/source/libs/xpdf/xpdf-src/splash/SplashFontEngine.h +++ /dev/null @@ -1,129 +0,0 @@ -//======================================================================== -// -// SplashFontEngine.h -// -// Copyright 2003-2013 Glyph & Cog, LLC -// -//======================================================================== - -#ifndef SPLASHFONTENGINE_H -#define SPLASHFONTENGINE_H - -#include <aconf.h> - -#ifdef USE_GCC_PRAGMAS -#pragma interface -#endif - -#include "gtypes.h" -class GString; -class GList; - -class SplashFTFontEngine; -class SplashDTFontEngine; -class SplashDT4FontEngine; -class SplashFontFile; -class SplashFontFileID; -class SplashFont; - -//------------------------------------------------------------------------ - -#define splashFontCacheSize 16 - -#if HAVE_FREETYPE_H -#define splashFTNoHinting (1 << 0) -#endif - -//------------------------------------------------------------------------ -// SplashFontEngine -//------------------------------------------------------------------------ - -class SplashFontEngine { -public: - - // Create a font engine. - SplashFontEngine( -#if HAVE_FREETYPE_H - GBool enableFreeType, - Guint freeTypeFlags, -#endif - GBool aa); - - ~SplashFontEngine(); - - // Get a font file from the cache. Returns NULL if there is no - // matching entry in the cache. - SplashFontFile *getFontFile(SplashFontFileID *id); - - // Returns true if [id] refers to a bad font file, i.e., if one of - // the loadXXXFont functions has returned NULL for that ID. - GBool checkForBadFontFile(SplashFontFileID *id); - - // Load fonts - these create new SplashFontFile objects. - SplashFontFile *loadType1Font(SplashFontFileID *idA, -#if LOAD_FONTS_FROM_MEM - GString *fontBuf, -#else - char *fileName, GBool deleteFile, -#endif - const char **enc); - SplashFontFile *loadType1CFont(SplashFontFileID *idA, -#if LOAD_FONTS_FROM_MEM - GString *fontBuf, -#else - char *fileName, GBool deleteFile, -#endif - int *codeToGID, const char **enc); - SplashFontFile *loadOpenTypeT1CFont(SplashFontFileID *idA, -#if LOAD_FONTS_FROM_MEM - GString *fontBuf, -#else - char *fileName, GBool deleteFile, -#endif - int *codeToGID, const char **enc); - SplashFontFile *loadCIDFont(SplashFontFileID *idA, -#if LOAD_FONTS_FROM_MEM - GString *fontBuf, -#else - char *fileName, GBool deleteFile, -#endif - int *codeToGID, int codeToGIDLen); - SplashFontFile *loadOpenTypeCFFFont(SplashFontFileID *idA, -#if LOAD_FONTS_FROM_MEM - GString *fontBuf, -#else - char *fileName, GBool deleteFile, -#endif - int *codeToGID, int codeToGIDLen); - SplashFontFile *loadTrueTypeFont(SplashFontFileID *idA, -#if LOAD_FONTS_FROM_MEM - GString *fontBuf, -#else - char *fileName, GBool deleteFile, -#endif - int fontNum, - int *codeToGID, int codeToGIDLen, - char *fontName); - - // Get a font - this does a cache lookup first, and if not found, - // creates a new SplashFont object and adds it to the cache. The - // matrix, mat = textMat * ctm: - // [ mat[0] mat[1] ] - // [ mat[2] mat[3] ] - // specifies the font transform in PostScript style: - // [x' y'] = [x y] * mat - // Note that the Splash y axis points downward. - SplashFont *getFont(SplashFontFile *fontFile, - SplashCoord *textMat, SplashCoord *ctm); - -private: - - SplashFont *fontCache[splashFontCacheSize]; - GList *badFontFiles; // [SplashFontFileID] - -#if HAVE_FREETYPE_H - SplashFTFontEngine *ftEngine; -#endif -}; - -#endif diff --git a/Build/source/libs/xpdf/xpdf-src/splash/SplashFontFile.cc b/Build/source/libs/xpdf/xpdf-src/splash/SplashFontFile.cc deleted file mode 100644 index 2d260e38239..00000000000 --- a/Build/source/libs/xpdf/xpdf-src/splash/SplashFontFile.cc +++ /dev/null @@ -1,84 +0,0 @@ -//======================================================================== -// -// SplashFontFile.cc -// -// Copyright 2003-2013 Glyph & Cog, LLC -// -//======================================================================== - -#include <aconf.h> - -#ifdef USE_GCC_PRAGMAS -#pragma implementation -#endif - -#include <stdio.h> -#ifndef _WIN32 -# include <unistd.h> -#endif -#include "gmempp.h" -#include "GString.h" -#include "SplashFontFile.h" -#include "SplashFontFileID.h" - -#ifdef VMS -#if (__VMS_VER < 70000000) -extern "C" int unlink(char *filename); -#endif -#endif - -//------------------------------------------------------------------------ -// SplashFontFile -//------------------------------------------------------------------------ - -SplashFontFile::SplashFontFile(SplashFontFileID *idA, - SplashFontType fontTypeA, -#if LOAD_FONTS_FROM_MEM - GString *fontBufA -#else - char *fileNameA, GBool deleteFileA -#endif - ) { - id = idA; - fontType = fontTypeA; -#if LOAD_FONTS_FROM_MEM - fontBuf = fontBufA; -#else - fileName = new GString(fileNameA); - deleteFile = deleteFileA; -#endif - refCnt = 0; -} - -SplashFontFile::~SplashFontFile() { -#if LOAD_FONTS_FROM_MEM - delete fontBuf; -#else - if (deleteFile) { - unlink(fileName->getCString()); - } - delete fileName; -#endif - delete id; -} - -void SplashFontFile::incRefCnt() { -#if MULTITHREADED - gAtomicIncrement(&refCnt); -#else - ++refCnt; -#endif -} - -void SplashFontFile::decRefCnt() { - GBool done; - -#if MULTITHREADED - done = gAtomicDecrement(&refCnt) == 0; -#else - done = --refCnt == 0; -#endif - if (done) { - delete this; - } -} diff --git a/Build/source/libs/xpdf/xpdf-src/splash/SplashFontFile.h b/Build/source/libs/xpdf/xpdf-src/splash/SplashFontFile.h deleted file mode 100644 index 133e6ab87dc..00000000000 --- a/Build/source/libs/xpdf/xpdf-src/splash/SplashFontFile.h +++ /dev/null @@ -1,95 +0,0 @@ -//======================================================================== -// -// SplashFontFile.h -// -// Copyright 2003-2013 Glyph & Cog, LLC -// -//======================================================================== - -#ifndef SPLASHFONTFILE_H -#define SPLASHFONTFILE_H - -#include <aconf.h> - -#ifdef USE_GCC_PRAGMAS -#pragma interface -#endif - -#include "gtypes.h" -#include "SplashTypes.h" - -#if MULTITHREADED -#include "GMutex.h" -#endif - -class GString; -class SplashFontEngine; -class SplashFont; -class SplashFontFileID; - -//------------------------------------------------------------------------ -// SplashFontType -//------------------------------------------------------------------------ - -enum SplashFontType { - splashFontType1, // GfxFontType.fontType1 - splashFontType1C, // GfxFontType.fontType1C - splashFontOpenTypeT1C, // GfxFontType.fontType1COT - splashFontCID, // GfxFontType.fontCIDType0/fontCIDType0C - splashFontOpenTypeCFF, // GfxFontType.fontCIDType0COT - splashFontTrueType // GfxFontType.fontTrueType/fontTrueTypeOT/ - // fontCIDType2/fontCIDType2OT -}; - -//------------------------------------------------------------------------ -// SplashFontFile -//------------------------------------------------------------------------ - -class SplashFontFile { -public: - - virtual ~SplashFontFile(); - - // Create a new SplashFont, i.e., a scaled instance of this font - // file. - virtual SplashFont *makeFont(SplashCoord *mat, SplashCoord *textMat) = 0; - - // Get the font file ID. - SplashFontFileID *getID() { return id; } - - // Increment the reference count. - void incRefCnt(); - - // Decrement the reference count. If the new value is zero, delete - // the SplashFontFile object. - void decRefCnt(); - -protected: - - SplashFontFile(SplashFontFileID *idA, - SplashFontType fontTypeA, -#if LOAD_FONTS_FROM_MEM - GString *fontBufA -#else - char *fileNameA, GBool deleteFileA -#endif - ); - - SplashFontFileID *id; - SplashFontType fontType; -#if LOAD_FONTS_FROM_MEM - GString *fontBuf; -#else - GString *fileName; - GBool deleteFile; -#endif -#if MULTITHREADED - GAtomicCounter refCnt; -#else - int refCnt; -#endif - - friend class SplashFontEngine; -}; - -#endif diff --git a/Build/source/libs/xpdf/xpdf-src/splash/SplashFontFileID.cc b/Build/source/libs/xpdf/xpdf-src/splash/SplashFontFileID.cc deleted file mode 100644 index 27f52031d50..00000000000 --- a/Build/source/libs/xpdf/xpdf-src/splash/SplashFontFileID.cc +++ /dev/null @@ -1,26 +0,0 @@ -//======================================================================== -// -// SplashFontFileID.cc -// -// Copyright 2003-2013 Glyph & Cog, LLC -// -//======================================================================== - -#include <aconf.h> - -#ifdef USE_GCC_PRAGMAS -#pragma implementation -#endif - -#include "gmempp.h" -#include "SplashFontFileID.h" - -//------------------------------------------------------------------------ -// SplashFontFileID -//------------------------------------------------------------------------ - -SplashFontFileID::SplashFontFileID() { -} - -SplashFontFileID::~SplashFontFileID() { -} diff --git a/Build/source/libs/xpdf/xpdf-src/splash/SplashFontFileID.h b/Build/source/libs/xpdf/xpdf-src/splash/SplashFontFileID.h deleted file mode 100644 index 384018a2f3a..00000000000 --- a/Build/source/libs/xpdf/xpdf-src/splash/SplashFontFileID.h +++ /dev/null @@ -1,32 +0,0 @@ -//======================================================================== -// -// SplashFontFileID.h -// -// Copyright 2003-2013 Glyph & Cog, LLC -// -//======================================================================== - -#ifndef SPLASHFONTFILEID_H -#define SPLASHFONTFILEID_H - -#include <aconf.h> - -#ifdef USE_GCC_PRAGMAS -#pragma interface -#endif - -#include "gtypes.h" - -//------------------------------------------------------------------------ -// SplashFontFileID -//------------------------------------------------------------------------ - -class SplashFontFileID { -public: - - SplashFontFileID(); - virtual ~SplashFontFileID(); - virtual GBool matches(SplashFontFileID *id) = 0; -}; - -#endif diff --git a/Build/source/libs/xpdf/xpdf-src/splash/SplashGlyphBitmap.h b/Build/source/libs/xpdf/xpdf-src/splash/SplashGlyphBitmap.h deleted file mode 100644 index d375b3ccb46..00000000000 --- a/Build/source/libs/xpdf/xpdf-src/splash/SplashGlyphBitmap.h +++ /dev/null @@ -1,28 +0,0 @@ -//======================================================================== -// -// SplashGlyphBitmap.h -// -// Copyright 2003-2013 Glyph & Cog, LLC -// -//======================================================================== - -#ifndef SPLASHGLYPHBITMAP_H -#define SPLASHGLYPHBITMAP_H - -#include <aconf.h> - -#include "gtypes.h" - -//------------------------------------------------------------------------ -// SplashGlyphBitmap -//------------------------------------------------------------------------ - -struct SplashGlyphBitmap { - int x, y, w, h; // offset and size of glyph - GBool aa; // anti-aliased: true means 8-bit alpha - // bitmap; false means 1-bit - Guchar *data; // bitmap data - GBool freeData; // true if data memory should be freed -}; - -#endif diff --git a/Build/source/libs/xpdf/xpdf-src/splash/SplashMath.h b/Build/source/libs/xpdf/xpdf-src/splash/SplashMath.h deleted file mode 100644 index 45f4e53e6bb..00000000000 --- a/Build/source/libs/xpdf/xpdf-src/splash/SplashMath.h +++ /dev/null @@ -1,378 +0,0 @@ -//======================================================================== -// -// SplashMath.h -// -// Copyright 2003-2013 Glyph & Cog, LLC -// -//======================================================================== - -#ifndef SPLASHMATH_H -#define SPLASHMATH_H - -#include <aconf.h> - -#if USE_FIXEDPONT -# include "FixedPoint.h" -#else -# include <math.h> -# if (defined(__GNUC__) && defined(__SSE2__)) || \ - (defined(_WIN32) && (_M_IX86_FP == 2 || defined(_M_X64))) -# include <emmintrin.h> -# endif -#endif -#include "SplashTypes.h" - -static inline SplashCoord splashAbs(SplashCoord x) { -#if USE_FIXEDPOINT - return FixedPoint::abs(x); -#else - return fabs(x); -#endif -} - -// floor() and (int)() are implemented separately, which results -// in changing the FPCW multiple times - so we optimize it with -// some inline assembly or SSE intrinsics. -static inline int splashFloor(SplashCoord x) { -#if USE_FIXEDPOINT - - //--- fixed point - - return FixedPoint::floor(x); - -#elif (defined(__GNUC__) && defined(__SSE2__)) || \ - (defined(_WIN32) && (_M_IX86_FP == 2 || defined(_M_X64))) - - //--- SSE2 intrinsics - // NB: 64-bit x86 guarantees availability of SSE2. - - __m128d m1, m2; - int i, s; - - m1 = _mm_set_sd(x); - i = _mm_cvttsd_si32(m1); - m2 = _mm_cvtsi32_sd(m1, i); - s = _mm_ucomigt_sd(m2, m1); - return i - s; - -#elif defined(__GNUC__) && defined(__i386__) && !defined(__APPLE__) - - //--- x87 inline assembly (gcc/clang) - // (this code fails on OSX for reasons I don't understand) - - Gushort oldCW, newCW, t; - int result; - - __asm__ volatile("fnstcw %0\n" - "movw %0, %3\n" - "andw $0xf3ff, %3\n" - "orw $0x0400, %3\n" - "movw %3, %1\n" // round down - "fldcw %1\n" - "fistl %2\n" - "fldcw %0\n" - : "=m" (oldCW), "=m" (newCW), "=m" (result), "=r" (t) - : "t" (x)); - return result; - -#elif defined(_WIN32) && defined(_M_IX86) - - //--- x87 inline assembly (VC) - - Gushort oldCW, newCW; - int result; - - __asm fld QWORD PTR x - __asm fnstcw WORD PTR oldCW - __asm mov ax, WORD PTR oldCW - __asm and ax, 0xf3ff - __asm or ax, 0x0400 - __asm mov WORD PTR newCW, ax // round down - __asm fldcw WORD PTR newCW - __asm fistp DWORD PTR result - __asm fldcw WORD PTR oldCW - return result; - -#else - - //--- all others - - return (int)floor(x); - -#endif -} - -// ceil() and (int)() are implemented separately, which results -// in changing the FPCW multiple times - so we optimize it with -// some inline assembly or SSE intrinsics. -static inline int splashCeil(SplashCoord x) { -#if USE_FIXEDPOINT - - //--- fixed point - - return FixedPoint::ceil(x); - -#elif (defined(__GNUC__) && defined(__SSE2__)) || \ - (defined(_WIN32) && (_M_IX86_FP == 2 || defined(_M_X64))) - - //--- SSE2 intrinsics - // NB: 64-bit x86 guarantees availability of SSE2. - - __m128d m1, m2; - int i, s; - - m1 = _mm_set_sd(x); - i = _mm_cvttsd_si32(m1); - m2 = _mm_cvtsi32_sd(m1, i); - s = _mm_ucomilt_sd(m2, m1); - return i + s; - -#elif defined(__GNUC__) && defined(__i386__) && !defined(__APPLE__) - - //--- x87 inline assembly (gcc/clang) - // (this code fails on OSX for reasons I don't understand) - - Gushort oldCW, newCW, t; - int result; - - __asm__ volatile("fnstcw %0\n" - "movw %0, %3\n" - "andw $0xf3ff, %3\n" - "orw $0x0800, %3\n" - "movw %3, %1\n" // round up - "fldcw %1\n" - "fistl %2\n" - "fldcw %0\n" - : "=m" (oldCW), "=m" (newCW), "=m" (result), "=r" (t) - : "t" (x)); - return result; - -#elif defined(_WIN32) && defined(_M_IX86) - - //--- x87 inline assembly (VC) - - // ceil() and (int)() are implemented separately, which results - // in changing the FPCW multiple times - so we optimize it with - // some inline assembly - Gushort oldCW, newCW; - int result; - - __asm fld QWORD PTR x - __asm fnstcw WORD PTR oldCW - __asm mov ax, WORD PTR oldCW - __asm and ax, 0xf3ff - __asm or ax, 0x0800 - __asm mov WORD PTR newCW, ax // round up - __asm fldcw WORD PTR newCW - __asm fistp DWORD PTR result - __asm fldcw WORD PTR oldCW - return result; - -#else - - //--- all others - - return (int)ceil(x); - -#endif -} - -static inline int splashRound(SplashCoord x) { -#if USE_FIXEDPOINT - - //--- fixed point - - return FixedPoint::round(x); - -#else - - //--- all others - - return splashFloor(x + 0.5); - -#endif -} - -static inline SplashCoord splashAvg(SplashCoord x, SplashCoord y) { -#if USE_FIXEDPOINT - return FixedPoint::avg(x, y); -#else - return 0.5 * (x + y); -#endif -} - -static inline SplashCoord splashSqrt(SplashCoord x) { -#if USE_FIXEDPOINT - return FixedPoint::sqrt(x); -#else - return sqrt(x); -#endif -} - -static inline SplashCoord splashPow(SplashCoord x, SplashCoord y) { -#if USE_FIXEDPOINT - return FixedPoint::pow(x, y); -#else - return pow(x, y); -#endif -} - -static inline SplashCoord splashDist(SplashCoord x0, SplashCoord y0, - SplashCoord x1, SplashCoord y1) { - SplashCoord dx, dy; - dx = x1 - x0; - dy = y1 - y0; -#if USE_FIXEDPOINT - // this handles the situation where dx*dx or dy*dy is too large to - // fit in the 16.16 fixed point format - SplashCoord dxa, dya, d; - dxa = splashAbs(dx); - dya = splashAbs(dy); - if (dxa == 0 && dya == 0) { - return 0; - } else if (dxa > dya) { - d = dya / dxa; - return dxa * FixedPoint::sqrt(d*d + 1); - } else { - d = dxa / dya; - return dya * FixedPoint::sqrt(d*d + 1); - } -#else - return sqrt(dx * dx + dy * dy); -#endif -} - -static inline GBool splashCheckDet(SplashCoord m11, SplashCoord m12, - SplashCoord m21, SplashCoord m22, - SplashCoord epsilon) { -#if USE_FIXEDPOINT - return FixedPoint::checkDet(m11, m12, m21, m22, epsilon); -#else - return fabs(m11 * m22 - m12 * m21) >= epsilon; -#endif -} - -// Perform stroke adjustment on a SplashCoord range [xMin, xMax), -// resulting in an int range [*xMinI, *xMaxI). -// -// There are several options: -// -// 1. Round both edge coordinates. -// Pro: adjacent strokes/fills line up without any gaps or -// overlaps -// Con: lines with the same original floating point width can -// end up with different integer widths, e.g.: -// xMin = 10.1 xMax = 11.3 (width = 1.2) -// --> xMinI = 10 xMaxI = 11 (width = 1) -// but -// xMin = 10.4 xMax = 11.6 (width = 1.2) -// --> xMinI = 10 xMaxI = 12 (width = 2) -// -// 2. Round the min coordinate; add the ceiling of the width. -// Pro: lines with the same original floating point width will -// always end up with the same integer width -// Con: adjacent strokes/fills can have overlaps (which is -// problematic with transparency) -// (This could use floor on the min coordinate, instead of -// rounding, with similar results.) -// (If the width is rounded instead of using ceiling, the results -// Are similar, except that adjacent strokes/fills can have gaps -// as well as overlaps.) -// -// 3. Use floor on the min coordinate and ceiling on the max -// coordinate. -// Pro: lines always end up at least as wide as the original -// floating point width -// Con: adjacent strokes/fills can have overlaps, and lines with -// the same original floating point width can end up with -// different integer widths; the integer width can be more -// than one pixel wider than the original width, e.g.: -// xMin = 10.9 xMax = 12.1 (width = 1.2) -// --> xMinI = 10 xMaxI = 13 (width = 3) -// but -// xMin = 10.1 xMax = 11.3 (width = 1.2) -// --> xMinI = 10 xMaxI = 12 (width = 2) -// -// 4. Use a hybrid approach, choosing between two of the above -// options, based on width. E.g., use #2 if width <= 4, and use #1 -// if width > 4. -// -// If w >= 0 and strokeAdjMode is splashStrokeAdjustCAD then a special -// mode for projecting line caps is enabled, with w being the -// transformed line width. - -static inline void splashStrokeAdjust(SplashCoord xMin, SplashCoord xMax, - int *xMinI, int *xMaxI, - SplashStrokeAdjustMode strokeAdjMode, - SplashCoord w = -1) { - int x0, x1; - - // make sure the coords fit in 32-bit ints -#if USE_FIXEDPOINT - if (xMin < -32767) { - xMin = -32767; - } else if (xMin > 32767) { - xMin = 32767; - } - if (xMax < -32767) { - xMax = -32767; - } else if (xMax > 32767) { - xMax = 32767; - } -#else - if (xMin < -1e9) { - xMin = -1e9; - } else if (xMin > 1e9) { - xMin = 1e9; - } - if (xMax < -1e9) { - xMax = -1e9; - } else if (xMax > 1e9) { - xMax = 1e9; - } -#endif - - // this will never be called with strokeAdjMode == splashStrokeAdjustOff - if (strokeAdjMode == splashStrokeAdjustCAD) { - x0 = splashRound(xMin); - if (w >= 0) { - x1 = splashRound(xMax - w) + splashRound(w); - } else { - x1 = x0 + splashRound(xMax - xMin); - } - } else { - // NB: enable exactly one of these. -#if 1 // 1. Round both edge coordinates. - x0 = splashRound(xMin); - x1 = splashRound(xMax); -#endif -#if 0 // 2. Round the min coordinate; add the ceiling of the width. - x0 = splashRound(xMin); - x1 = x0 + splashCeil(xMax - xMin); -#endif -#if 0 // 3. Use floor on the min coord and ceiling on the max coord. - x0 = splashFloor(xMin); - x1 = splashCeil(xMax); -#endif -#if 0 // 4. Hybrid. - SplashCoord w = xMax - xMin; - x0 = splashRound(xMin); - if (w > 4) { - x1 = splashRound(xMax); - } else { - x1 = x0 + splashRound(w); - } -#endif - } - if (x0 == x1) { - if (xMin + xMax < 2 * x0) { - --x0; - } else { - ++x1; - } - } - *xMinI = x0; - *xMaxI = x1; -} - -#endif diff --git a/Build/source/libs/xpdf/xpdf-src/splash/SplashPath.cc b/Build/source/libs/xpdf/xpdf-src/splash/SplashPath.cc deleted file mode 100644 index 792166715e5..00000000000 --- a/Build/source/libs/xpdf/xpdf-src/splash/SplashPath.cc +++ /dev/null @@ -1,213 +0,0 @@ -//======================================================================== -// -// SplashPath.cc -// -// Copyright 2003-2013 Glyph & Cog, LLC -// -//======================================================================== - -#include <aconf.h> - -#ifdef USE_GCC_PRAGMAS -#pragma implementation -#endif - -#include <string.h> -#include "gmem.h" -#include "gmempp.h" -#include "SplashErrorCodes.h" -#include "SplashPath.h" - -//------------------------------------------------------------------------ -// SplashPath -//------------------------------------------------------------------------ - -// A path can be in three possible states: -// -// 1. no current point -- zero or more finished subpaths -// [curSubpath == length] -// -// 2. one point in subpath -// [curSubpath == length - 1] -// -// 3. open subpath with two or more points -// [curSubpath < length - 1] - -SplashPath::SplashPath() { - pts = NULL; - flags = NULL; - length = size = 0; - curSubpath = 0; - hints = NULL; - hintsLength = hintsSize = 0; -} - -SplashPath::SplashPath(SplashPath *path) { - length = path->length; - size = path->size; - pts = (SplashPathPoint *)gmallocn(size, sizeof(SplashPathPoint)); - flags = (Guchar *)gmallocn(size, sizeof(Guchar)); - memcpy(pts, path->pts, length * sizeof(SplashPathPoint)); - memcpy(flags, path->flags, length * sizeof(Guchar)); - curSubpath = path->curSubpath; - if (path->hints) { - hintsLength = hintsSize = path->hintsLength; - hints = (SplashPathHint *)gmallocn(hintsSize, sizeof(SplashPathHint)); - memcpy(hints, path->hints, hintsLength * sizeof(SplashPathHint)); - } else { - hints = NULL; - hintsLength = hintsSize = 0; - } -} - -SplashPath::~SplashPath() { - gfree(pts); - gfree(flags); - gfree(hints); -} - -// Add space for <nPts> more points. -void SplashPath::grow(int nPts) { - if (length + nPts > size) { - if (size == 0) { - size = 32; - } - while (size < length + nPts) { - size *= 2; - } - pts = (SplashPathPoint *)greallocn(pts, size, sizeof(SplashPathPoint)); - flags = (Guchar *)greallocn(flags, size, sizeof(Guchar)); - } -} - -void SplashPath::append(SplashPath *path) { - int i; - - curSubpath = length + path->curSubpath; - grow(path->length); - for (i = 0; i < path->length; ++i) { - pts[length] = path->pts[i]; - flags[length] = path->flags[i]; - ++length; - } -} - -SplashError SplashPath::moveTo(SplashCoord x, SplashCoord y) { - if (onePointSubpath()) { - return splashErrBogusPath; - } - grow(1); - pts[length].x = x; - pts[length].y = y; - flags[length] = splashPathFirst | splashPathLast; - curSubpath = length++; - return splashOk; -} - -SplashError SplashPath::lineTo(SplashCoord x, SplashCoord y) { - if (noCurrentPoint()) { - return splashErrNoCurPt; - } - flags[length-1] &= (Guchar)~splashPathLast; - grow(1); - pts[length].x = x; - pts[length].y = y; - flags[length] = splashPathLast; - ++length; - return splashOk; -} - -SplashError SplashPath::curveTo(SplashCoord x1, SplashCoord y1, - SplashCoord x2, SplashCoord y2, - SplashCoord x3, SplashCoord y3) { - if (noCurrentPoint()) { - return splashErrNoCurPt; - } - flags[length-1] &= (Guchar)~splashPathLast; - grow(3); - pts[length].x = x1; - pts[length].y = y1; - flags[length] = splashPathCurve; - ++length; - pts[length].x = x2; - pts[length].y = y2; - flags[length] = splashPathCurve; - ++length; - pts[length].x = x3; - pts[length].y = y3; - flags[length] = splashPathLast; - ++length; - return splashOk; -} - -SplashError SplashPath::close(GBool force) { - if (noCurrentPoint()) { - return splashErrNoCurPt; - } - if (force || - curSubpath == length - 1 || - pts[length - 1].x != pts[curSubpath].x || - pts[length - 1].y != pts[curSubpath].y) { - lineTo(pts[curSubpath].x, pts[curSubpath].y); - } - flags[curSubpath] |= splashPathClosed; - flags[length - 1] |= splashPathClosed; - curSubpath = length; - return splashOk; -} - -void SplashPath::addStrokeAdjustHint(int ctrl0, int ctrl1, - int firstPt, int lastPt, - GBool projectingCap) { - if (hintsLength == hintsSize) { - hintsSize = hintsLength ? 2 * hintsLength : 8; - hints = (SplashPathHint *)greallocn(hints, hintsSize, - sizeof(SplashPathHint)); - } - hints[hintsLength].ctrl0 = ctrl0; - hints[hintsLength].ctrl1 = ctrl1; - hints[hintsLength].firstPt = firstPt; - hints[hintsLength].lastPt = lastPt; - hints[hintsLength].projectingCap = projectingCap; - ++hintsLength; -} - -void SplashPath::offset(SplashCoord dx, SplashCoord dy) { - int i; - - for (i = 0; i < length; ++i) { - pts[i].x += dx; - pts[i].y += dy; - } -} - -GBool SplashPath::getCurPt(SplashCoord *x, SplashCoord *y) { - if (noCurrentPoint()) { - return gFalse; - } - *x = pts[length - 1].x; - *y = pts[length - 1].y; - return gTrue; -} - -GBool SplashPath::containsZeroLengthSubpaths() { - GBool zeroLength; - int i; - - zeroLength = gTrue; // make gcc happy - for (i = 0; i < length; ++i) { - if (flags[i] & splashPathFirst) { - zeroLength = gTrue; - } else { - if (pts[i].x != pts[i-1].x || pts[i].y != pts[i-1].y) { - zeroLength = gFalse; - } - if (flags[i] & splashPathLast) { - if (zeroLength) { - return gTrue; - } - } - } - } - return gFalse; -} diff --git a/Build/source/libs/xpdf/xpdf-src/splash/SplashPath.h b/Build/source/libs/xpdf/xpdf-src/splash/SplashPath.h deleted file mode 100644 index b5732b8b408..00000000000 --- a/Build/source/libs/xpdf/xpdf-src/splash/SplashPath.h +++ /dev/null @@ -1,133 +0,0 @@ -//======================================================================== -// -// SplashPath.h -// -// Copyright 2003-2013 Glyph & Cog, LLC -// -//======================================================================== - -#ifndef SPLASHPATH_H -#define SPLASHPATH_H - -#include <aconf.h> - -#ifdef USE_GCC_PRAGMAS -#pragma interface -#endif - -#include "SplashTypes.h" - -//------------------------------------------------------------------------ -// SplashPathPoint -//------------------------------------------------------------------------ - -struct SplashPathPoint { - SplashCoord x, y; -}; - -//------------------------------------------------------------------------ -// SplashPath.flags -//------------------------------------------------------------------------ - -// first point on each subpath sets this flag -#define splashPathFirst 0x01 - -// last point on each subpath sets this flag -#define splashPathLast 0x02 - -// if the subpath is closed, its first and last points must be -// identical, and must set this flag -#define splashPathClosed 0x04 - -// curve control points set this flag -#define splashPathCurve 0x08 - -//------------------------------------------------------------------------ -// SplashPathHint -//------------------------------------------------------------------------ - -struct SplashPathHint { - int ctrl0, ctrl1; - int firstPt, lastPt; - GBool projectingCap; -}; - -//------------------------------------------------------------------------ -// SplashPath -//------------------------------------------------------------------------ - -class SplashPath { -public: - - // Create an empty path. - SplashPath(); - - // Copy a path. - SplashPath *copy() { return new SplashPath(this); } - - ~SplashPath(); - - // Append <path> to <this>. - void append(SplashPath *path); - - // Start a new subpath. - SplashError moveTo(SplashCoord x, SplashCoord y); - - // Add a line segment to the last subpath. - SplashError lineTo(SplashCoord x, SplashCoord y); - - // Add a third-order (cubic) Bezier curve segment to the last - // subpath. - SplashError curveTo(SplashCoord x1, SplashCoord y1, - SplashCoord x2, SplashCoord y2, - SplashCoord x3, SplashCoord y3); - - // Close the last subpath, adding a line segment if necessary. If - // <force> is true, this adds a line segment even if the current - // point is equal to the first point in the subpath. - SplashError close(GBool force = gFalse); - - // Add a stroke adjustment hint. The controlling segments are - // <ctrl0> and <ctrl1> (where segments are identified by their first - // point), and the points to be adjusted are <firstPt> .. <lastPt>. - // <projectingCap> is true if the points are part of a projecting - // line cap. - void addStrokeAdjustHint(int ctrl0, int ctrl1, int firstPt, int lastPt, - GBool projectingCap = gFalse); - - // Add (<dx>, <dy>) to every point on this path. - void offset(SplashCoord dx, SplashCoord dy); - - // Get the points on the path. - int getLength() { return length; } - void getPoint(int i, SplashCoord *x, SplashCoord *y, Guchar *f) - { *x = pts[i].x; *y = pts[i].y; *f = flags[i]; } - - // Get the current point. - GBool getCurPt(SplashCoord *x, SplashCoord *y); - - // Returns true if the path contains one or more zero length - // subpaths. - GBool containsZeroLengthSubpaths(); - -private: - - SplashPath(SplashPath *path); - void grow(int nPts); - GBool noCurrentPoint() { return curSubpath == length; } - GBool onePointSubpath() { return curSubpath == length - 1; } - GBool openSubpath() { return curSubpath < length - 1; } - - SplashPathPoint *pts; // array of points - Guchar *flags; // array of flags - int length, size; // length/size of the pts and flags arrays - int curSubpath; // index of first point in last subpath - - SplashPathHint *hints; // list of hints - int hintsLength, hintsSize; - - friend class SplashXPath; - friend class Splash; -}; - -#endif diff --git a/Build/source/libs/xpdf/xpdf-src/splash/SplashPattern.cc b/Build/source/libs/xpdf/xpdf-src/splash/SplashPattern.cc deleted file mode 100644 index 0c5b5093fd5..00000000000 --- a/Build/source/libs/xpdf/xpdf-src/splash/SplashPattern.cc +++ /dev/null @@ -1,44 +0,0 @@ -//======================================================================== -// -// SplashPattern.cc -// -// Copyright 2003-2013 Glyph & Cog, LLC -// -//======================================================================== - -#include <aconf.h> - -#ifdef USE_GCC_PRAGMAS -#pragma implementation -#endif - -#include "gmempp.h" -#include "SplashMath.h" -#include "SplashScreen.h" -#include "SplashPattern.h" - -//------------------------------------------------------------------------ -// SplashPattern -//------------------------------------------------------------------------ - -SplashPattern::SplashPattern() { -} - -SplashPattern::~SplashPattern() { -} - -//------------------------------------------------------------------------ -// SplashSolidColor -//------------------------------------------------------------------------ - -SplashSolidColor::SplashSolidColor(SplashColorPtr colorA) { - splashColorCopy(color, colorA); -} - -SplashSolidColor::~SplashSolidColor() { -} - -void SplashSolidColor::getColor(int x, int y, SplashColorPtr c) { - splashColorCopy(c, color); -} - diff --git a/Build/source/libs/xpdf/xpdf-src/splash/SplashPattern.h b/Build/source/libs/xpdf/xpdf-src/splash/SplashPattern.h deleted file mode 100644 index fcbe21d31cb..00000000000 --- a/Build/source/libs/xpdf/xpdf-src/splash/SplashPattern.h +++ /dev/null @@ -1,69 +0,0 @@ -//======================================================================== -// -// SplashPattern.h -// -// Copyright 2003-2013 Glyph & Cog, LLC -// -//======================================================================== - -#ifndef SPLASHPATTERN_H -#define SPLASHPATTERN_H - -#include <aconf.h> - -#ifdef USE_GCC_PRAGMAS -#pragma interface -#endif - -#include "SplashTypes.h" - -class SplashScreen; - -//------------------------------------------------------------------------ -// SplashPattern -//------------------------------------------------------------------------ - -class SplashPattern { -public: - - SplashPattern(); - - virtual SplashPattern *copy() = 0; - - virtual ~SplashPattern(); - - // Return the color value for a specific pixel. - virtual void getColor(int x, int y, SplashColorPtr c) = 0; - - - // Returns true if this pattern object will return the same color - // value for all pixels. - virtual GBool isStatic() = 0; - -private: -}; - -//------------------------------------------------------------------------ -// SplashSolidColor -//------------------------------------------------------------------------ - -class SplashSolidColor: public SplashPattern { -public: - - SplashSolidColor(SplashColorPtr colorA); - - virtual SplashPattern *copy() { return new SplashSolidColor(color); } - - virtual ~SplashSolidColor(); - - virtual void getColor(int x, int y, SplashColorPtr c); - - virtual GBool isStatic() { return gTrue; } - -private: - - SplashColor color; -}; - - -#endif diff --git a/Build/source/libs/xpdf/xpdf-src/splash/SplashScreen.cc b/Build/source/libs/xpdf/xpdf-src/splash/SplashScreen.cc deleted file mode 100644 index 9993edc2a38..00000000000 --- a/Build/source/libs/xpdf/xpdf-src/splash/SplashScreen.cc +++ /dev/null @@ -1,383 +0,0 @@ -//======================================================================== -// -// SplashScreen.cc -// -// Copyright 2003-2013 Glyph & Cog, LLC -// -//======================================================================== - -#include <aconf.h> - -#ifdef USE_GCC_PRAGMAS -#pragma implementation -#endif - -#include <stdlib.h> -#include <string.h> -#if HAVE_STD_SORT -#include <algorithm> -#endif -#include "gmem.h" -#include "gmempp.h" -#include "SplashMath.h" -#include "SplashScreen.h" - -//------------------------------------------------------------------------ - -static SplashScreenParams defaultParams = { - splashScreenDispersed, // type - 2, // size - 2, // dotRadius - 1.0, // gamma - 0.0, // blackThreshold - 1.0 // whiteThreshold -}; - -//------------------------------------------------------------------------ - -struct SplashScreenPoint { - int x, y; - int dist; -}; - -#if HAVE_STD_SORT - -struct cmpDistancesFunctor { - bool operator()(const SplashScreenPoint &p0, const SplashScreenPoint &p1) { - return p0.dist < p1.dist; - } -}; - -#else // HAVE_STD_SORT - -static int cmpDistances(const void *p0, const void *p1) { - return ((SplashScreenPoint *)p0)->dist - ((SplashScreenPoint *)p1)->dist; -} - -#endif - -//------------------------------------------------------------------------ -// SplashScreen -//------------------------------------------------------------------------ - -// If <clustered> is true, this generates a 45 degree screen using a -// circular dot spot function. DPI = resolution / ((size / 2) * -// sqrt(2)). If <clustered> is false, this generates an optimal -// threshold matrix using recursive tesselation. Gamma correction -// (gamma = 1 / 1.33) is also computed here. -SplashScreen::SplashScreen(SplashScreenParams *params) { - Guchar u; - int black, white, i; - - if (!params) { - params = &defaultParams; - } - - // size must be a power of 2, and at least 2 - for (size = 2, log2Size = 1; size < params->size; size <<= 1, ++log2Size) ; - - switch (params->type) { - - case splashScreenDispersed: - mat = (Guchar *)gmallocn(size * size, sizeof(Guchar)); - buildDispersedMatrix(size/2, size/2, 1, size/2, 1); - break; - - case splashScreenClustered: - mat = (Guchar *)gmallocn(size * size, sizeof(Guchar)); - buildClusteredMatrix(); - break; - - case splashScreenStochasticClustered: - // size must be at least 2*r - while (size < (params->dotRadius << 1)) { - size <<= 1; - ++log2Size; - } - mat = (Guchar *)gmallocn(size * size, sizeof(Guchar)); - buildSCDMatrix(params->dotRadius); - break; - } - - sizeM1 = size - 1; - - // do gamma correction and compute minVal/maxVal - minVal = 255; - maxVal = 0; - black = splashRound((SplashCoord)255.0 * params->blackThreshold); - if (black < 1) { - black = 1; - } - white = splashRound((SplashCoord)255.0 * params->whiteThreshold); - if (white > 255) { - white = 255; - } - for (i = 0; i < size * size; ++i) { - u = (Guchar)splashRound((SplashCoord)255.0 * - splashPow((SplashCoord)mat[i] / 255.0, - params->gamma)); - if (u < black) { - u = (Guchar)black; - } else if (u >= white) { - u = (Guchar)white; - } - mat[i] = u; - if (u < minVal) { - minVal = u; - } else if (u > maxVal) { - maxVal = u; - } - } -} - -void SplashScreen::buildDispersedMatrix(int i, int j, int val, - int delta, int offset) { - if (delta == 0) { - // map values in [1, size^2] --> [1, 255] - mat[(i << log2Size) + j] = - (Guchar)(1 + (254 * (val - 1)) / (size * size - 1)); - } else { - buildDispersedMatrix(i, j, - val, delta / 2, 4*offset); - buildDispersedMatrix((i + delta) % size, (j + delta) % size, - val + offset, delta / 2, 4*offset); - buildDispersedMatrix((i + delta) % size, j, - val + 2*offset, delta / 2, 4*offset); - buildDispersedMatrix((i + 2*delta) % size, (j + delta) % size, - val + 3*offset, delta / 2, 4*offset); - } -} - -void SplashScreen::buildClusteredMatrix() { - SplashCoord *dist; - SplashCoord u, v, d; - Guchar val; - int size2, x, y, x1, y1, i; - - size2 = size >> 1; - - // initialize the threshold matrix - for (y = 0; y < size; ++y) { - for (x = 0; x < size; ++x) { - mat[(y << log2Size) + x] = 0; - } - } - - // build the distance matrix - dist = (SplashCoord *)gmallocn(size * size2, sizeof(SplashCoord)); - for (y = 0; y < size2; ++y) { - for (x = 0; x < size2; ++x) { - if (x + y < size2 - 1) { - u = (SplashCoord)x + 0.5 - 0; - v = (SplashCoord)y + 0.5 - 0; - } else { - u = (SplashCoord)x + 0.5 - (SplashCoord)size2; - v = (SplashCoord)y + 0.5 - (SplashCoord)size2; - } - dist[y * size2 + x] = u*u + v*v; - } - } - for (y = 0; y < size2; ++y) { - for (x = 0; x < size2; ++x) { - if (x < y) { - u = (SplashCoord)x + 0.5 - 0; - v = (SplashCoord)y + 0.5 - (SplashCoord)size2; - } else { - u = (SplashCoord)x + 0.5 - (SplashCoord)size2; - v = (SplashCoord)y + 0.5 - 0; - } - dist[(size2 + y) * size2 + x] = u*u + v*v; - } - } - - // build the threshold matrix - x1 = y1 = 0; // make gcc happy - for (i = 0; i < size * size2; ++i) { - d = -1; - for (y = 0; y < size; ++y) { - for (x = 0; x < size2; ++x) { - if (mat[(y << log2Size) + x] == 0 && - dist[y * size2 + x] > d) { - x1 = x; - y1 = y; - d = dist[y1 * size2 + x1]; - } - } - } - // map values in [0, 2*size*size2-1] --> [1, 255] - val = (Guchar)(1 + (254 * (2*i)) / (2*size*size2 - 1)); - mat[(y1 << log2Size) + x1] = val; - val = (Guchar)(1 + (254 * (2*i+1)) / (2*size*size2 - 1)); - if (y1 < size2) { - mat[((y1 + size2) << log2Size) + x1 + size2] = val; - } else { - mat[((y1 - size2) << log2Size) + x1 + size2] = val; - } - } - - gfree(dist); -} - -// Compute the distance between two points on a toroid. -int SplashScreen::distance(int x0, int y0, int x1, int y1) { - int dx0, dx1, dx, dy0, dy1, dy; - - dx0 = abs(x0 - x1); - dx1 = size - dx0; - dx = dx0 < dx1 ? dx0 : dx1; - dy0 = abs(y0 - y1); - dy1 = size - dy0; - dy = dy0 < dy1 ? dy0 : dy1; - return dx * dx + dy * dy; -} - -// Algorithm taken from: -// Victor Ostromoukhov and Roger D. Hersch, "Stochastic Clustered-Dot -// Dithering" in Color Imaging: Device-Independent Color, Color -// Hardcopy, and Graphic Arts IV, SPIE Vol. 3648, pp. 496-505, 1999. -void SplashScreen::buildSCDMatrix(int r) { - SplashScreenPoint *dots, *pts; - int dotsLen, dotsSize; - char *tmpl; - char *grid; - int *region, *dist; - int x, y, xx, yy, x0, x1, y0, y1, i, j, d, iMin, dMin, n; - - //~ this should probably happen somewhere else - srand(123); - - // generate the random space-filling curve - pts = (SplashScreenPoint *)gmallocn(size * size, sizeof(SplashScreenPoint)); - i = 0; - for (y = 0; y < size; ++y) { - for (x = 0; x < size; ++x) { - pts[i].x = x; - pts[i].y = y; - ++i; - } - } - for (i = 0; i < size * size; ++i) { - j = i + (int)((double)(size * size - i) * - (double)rand() / ((double)RAND_MAX + 1.0)); - x = pts[i].x; - y = pts[i].y; - pts[i].x = pts[j].x; - pts[i].y = pts[j].y; - pts[j].x = x; - pts[j].y = y; - } - - // construct the circle template - tmpl = (char *)gmallocn((r+1)*(r+1), sizeof(char)); - for (y = 0; y <= r; ++y) { - for (x = 0; x <= r; ++x) { - tmpl[y*(r+1) + x] = (x * y <= r * r) ? 1 : 0; - } - } - - // mark all grid cells as free - grid = (char *)gmallocn(size * size, sizeof(char)); - for (y = 0; y < size; ++y) { - for (x = 0; x < size; ++x) { - grid[(y << log2Size) + x] = 0; - } - } - - // walk the space-filling curve, adding dots - dotsLen = 0; - dotsSize = 32; - dots = (SplashScreenPoint *)gmallocn(dotsSize, sizeof(SplashScreenPoint)); - for (i = 0; i < size * size; ++i) { - x = pts[i].x; - y = pts[i].y; - if (!grid[(y << log2Size) + x]) { - if (dotsLen == dotsSize) { - dotsSize *= 2; - dots = (SplashScreenPoint *)greallocn(dots, dotsSize, - sizeof(SplashScreenPoint)); - } - dots[dotsLen++] = pts[i]; - for (yy = 0; yy <= r; ++yy) { - y0 = (y + yy) % size; - y1 = (y - yy + size) % size; - for (xx = 0; xx <= r; ++xx) { - if (tmpl[yy*(r+1) + xx]) { - x0 = (x + xx) % size; - x1 = (x - xx + size) % size; - grid[(y0 << log2Size) + x0] = 1; - grid[(y0 << log2Size) + x1] = 1; - grid[(y1 << log2Size) + x0] = 1; - grid[(y1 << log2Size) + x1] = 1; - } - } - } - } - } - - gfree(tmpl); - gfree(grid); - - // assign each cell to a dot, compute distance to center of dot - region = (int *)gmallocn(size * size, sizeof(int)); - dist = (int *)gmallocn(size * size, sizeof(int)); - for (y = 0; y < size; ++y) { - for (x = 0; x < size; ++x) { - iMin = 0; - dMin = distance(dots[0].x, dots[0].y, x, y); - for (i = 1; i < dotsLen; ++i) { - d = distance(dots[i].x, dots[i].y, x, y); - if (d < dMin) { - iMin = i; - dMin = d; - } - } - region[(y << log2Size) + x] = iMin; - dist[(y << log2Size) + x] = dMin; - } - } - - // compute threshold values - for (i = 0; i < dotsLen; ++i) { - n = 0; - for (y = 0; y < size; ++y) { - for (x = 0; x < size; ++x) { - if (region[(y << log2Size) + x] == i) { - pts[n].x = x; - pts[n].y = y; - pts[n].dist = distance(dots[i].x, dots[i].y, x, y); - ++n; - } - } - } -#if HAVE_STD_SORT - std::sort(pts, pts + n, cmpDistancesFunctor()); -#else - qsort(pts, n, sizeof(SplashScreenPoint), &cmpDistances); -#endif - for (j = 0; j < n; ++j) { - // map values in [0 .. n-1] --> [255 .. 1] - mat[(pts[j].y << log2Size) + pts[j].x] = - (Guchar)(255 - (254 * j) / (n - 1)); - } - } - - gfree(pts); - gfree(region); - gfree(dist); - - gfree(dots); -} - -SplashScreen::SplashScreen(SplashScreen *screen) { - size = screen->size; - sizeM1 = screen->sizeM1; - log2Size = screen->log2Size; - mat = (Guchar *)gmallocn(size * size, sizeof(Guchar)); - memcpy(mat, screen->mat, size * size * sizeof(Guchar)); - minVal = screen->minVal; - maxVal = screen->maxVal; -} - -SplashScreen::~SplashScreen() { - gfree(mat); -} diff --git a/Build/source/libs/xpdf/xpdf-src/splash/SplashScreen.h b/Build/source/libs/xpdf/xpdf-src/splash/SplashScreen.h deleted file mode 100644 index 560e2759d82..00000000000 --- a/Build/source/libs/xpdf/xpdf-src/splash/SplashScreen.h +++ /dev/null @@ -1,81 +0,0 @@ -//======================================================================== -// -// SplashScreen.h -// -// Copyright 2003-2013 Glyph & Cog, LLC -// -//======================================================================== - -#ifndef SPLASHSCREEN_H -#define SPLASHSCREEN_H - -#include <aconf.h> - -#ifdef USE_GCC_PRAGMAS -#pragma interface -#endif - -#include "SplashTypes.h" - -//------------------------------------------------------------------------ -// SplashScreen -//------------------------------------------------------------------------ - -typedef Guchar *SplashScreenCursor; - -class SplashScreen { -public: - - SplashScreen(SplashScreenParams *params); - SplashScreen(SplashScreen *screen); - ~SplashScreen(); - - SplashScreen *copy() { return new SplashScreen(this); } - - // Return the computed pixel value (0=black, 1=white) for the gray - // level <value> at (<x>, <y>). - int test(int x, int y, Guchar value) { - int xx, yy; - xx = x & sizeM1; - yy = y & sizeM1; - return value < mat[(yy << log2Size) + xx] ? 0 : 1; - } - - // To do a series of tests with the same y value, call - // getTestCursor(y), and then call testWithCursor(cursor, x, value) - // for each x. - SplashScreenCursor getTestCursor(int y) { - int yy; - yy = y & sizeM1; - return &mat[yy << log2Size]; - } - - int testWithCursor(SplashScreenCursor cursor, int x, Guchar value) { - int xx = x & sizeM1; - return value >= cursor[xx]; - } - - // Returns true if value is above the white threshold or below the - // black threshold, i.e., if the corresponding halftone will be - // solid white or black. - GBool isStatic(Guchar value) { return value < minVal || value >= maxVal; } - -private: - - void buildDispersedMatrix(int i, int j, int val, - int delta, int offset); - void buildClusteredMatrix(); - int distance(int x0, int y0, int x1, int y1); - void buildSCDMatrix(int r); - - Guchar *mat; // threshold matrix - int size; // size of the threshold matrix - int sizeM1; // size - 1 - int log2Size; // log2(size) - Guchar minVal; // any pixel value below minVal generates - // solid black - Guchar maxVal; // any pixel value above maxVal generates - // solid white -}; - -#endif diff --git a/Build/source/libs/xpdf/xpdf-src/splash/SplashState.cc b/Build/source/libs/xpdf/xpdf-src/splash/SplashState.cc deleted file mode 100644 index 74421c48a4a..00000000000 --- a/Build/source/libs/xpdf/xpdf-src/splash/SplashState.cc +++ /dev/null @@ -1,295 +0,0 @@ -//======================================================================== -// -// SplashState.cc -// -// Copyright 2003-2013 Glyph & Cog, LLC -// -//======================================================================== - -#include <aconf.h> - -#ifdef USE_GCC_PRAGMAS -#pragma implementation -#endif - -#include <string.h> -#include "gmem.h" -#include "gmempp.h" -#include "SplashPattern.h" -#include "SplashScreen.h" -#include "SplashClip.h" -#include "SplashBitmap.h" -#include "SplashState.h" - -//------------------------------------------------------------------------ -// SplashState -//------------------------------------------------------------------------ - -// number of components in each color mode -int splashColorModeNComps[] = { - 1, 1, 3, 3 -#if SPLASH_CMYK - , 4 -#endif -}; - -SplashState::SplashState(int width, int height, GBool vectorAntialias, - SplashScreenParams *screenParams) { - SplashColor color; - int i; - - matrix[0] = 1; matrix[1] = 0; - matrix[2] = 0; matrix[3] = 1; - matrix[4] = 0; matrix[5] = 0; - memset(&color, 0, sizeof(SplashColor)); - strokePattern = new SplashSolidColor(color); - fillPattern = new SplashSolidColor(color); - screen = new SplashScreen(screenParams); - blendFunc = NULL; - strokeAlpha = 1; - fillAlpha = 1; - lineWidth = 1; - lineCap = splashLineCapButt; - lineJoin = splashLineJoinMiter; - miterLimit = 10; - flatness = 1; - lineDash = NULL; - lineDashLength = 0; - lineDashPhase = 0; - strokeAdjust = splashStrokeAdjustOff; - clip = new SplashClip(0, 0, width, height); - clipIsShared = gFalse; - softMask = NULL; - deleteSoftMask = gFalse; - inNonIsolatedGroup = gFalse; - inKnockoutGroup = gFalse; - for (i = 0; i < 256; ++i) { - rgbTransferR[i] = (Guchar)i; - rgbTransferG[i] = (Guchar)i; - rgbTransferB[i] = (Guchar)i; - grayTransfer[i] = (Guchar)i; -#if SPLASH_CMYK - cmykTransferC[i] = (Guchar)i; - cmykTransferM[i] = (Guchar)i; - cmykTransferY[i] = (Guchar)i; - cmykTransferK[i] = (Guchar)i; -#endif - } - overprintMask = 0xffffffff; - enablePathSimplification = gFalse; - next = NULL; -} - -SplashState::SplashState(int width, int height, GBool vectorAntialias, - SplashScreen *screenA) { - SplashColor color; - int i; - - matrix[0] = 1; matrix[1] = 0; - matrix[2] = 0; matrix[3] = 1; - matrix[4] = 0; matrix[5] = 0; - memset(&color, 0, sizeof(SplashColor)); - strokePattern = new SplashSolidColor(color); - fillPattern = new SplashSolidColor(color); - screen = screenA->copy(); - blendFunc = NULL; - strokeAlpha = 1; - fillAlpha = 1; - lineWidth = 1; - lineCap = splashLineCapButt; - lineJoin = splashLineJoinMiter; - miterLimit = 10; - flatness = 1; - lineDash = NULL; - lineDashLength = 0; - lineDashPhase = 0; - strokeAdjust = splashStrokeAdjustOff; - clip = new SplashClip(0, 0, width, height); - clipIsShared = gFalse; - softMask = NULL; - deleteSoftMask = gFalse; - inNonIsolatedGroup = gFalse; - inKnockoutGroup = gFalse; - for (i = 0; i < 256; ++i) { - rgbTransferR[i] = (Guchar)i; - rgbTransferG[i] = (Guchar)i; - rgbTransferB[i] = (Guchar)i; - grayTransfer[i] = (Guchar)i; -#if SPLASH_CMYK - cmykTransferC[i] = (Guchar)i; - cmykTransferM[i] = (Guchar)i; - cmykTransferY[i] = (Guchar)i; - cmykTransferK[i] = (Guchar)i; -#endif - } - overprintMask = 0xffffffff; - enablePathSimplification = gFalse; - next = NULL; -} - -SplashState::SplashState(SplashState *state) { - memcpy(matrix, state->matrix, 6 * sizeof(SplashCoord)); - strokePattern = state->strokePattern->copy(); - fillPattern = state->fillPattern->copy(); - screen = state->screen->copy(); - blendFunc = state->blendFunc; - strokeAlpha = state->strokeAlpha; - fillAlpha = state->fillAlpha; - lineWidth = state->lineWidth; - lineCap = state->lineCap; - lineJoin = state->lineJoin; - miterLimit = state->miterLimit; - flatness = state->flatness; - if (state->lineDash) { - lineDashLength = state->lineDashLength; - lineDash = (SplashCoord *)gmallocn(lineDashLength, sizeof(SplashCoord)); - memcpy(lineDash, state->lineDash, lineDashLength * sizeof(SplashCoord)); - } else { - lineDash = NULL; - lineDashLength = 0; - } - lineDashPhase = state->lineDashPhase; - strokeAdjust = state->strokeAdjust; - clip = state->clip; - clipIsShared = gTrue; - softMask = state->softMask; - deleteSoftMask = gFalse; - inNonIsolatedGroup = state->inNonIsolatedGroup; - inKnockoutGroup = state->inKnockoutGroup; - memcpy(rgbTransferR, state->rgbTransferR, 256); - memcpy(rgbTransferG, state->rgbTransferG, 256); - memcpy(rgbTransferB, state->rgbTransferB, 256); - memcpy(grayTransfer, state->grayTransfer, 256); -#if SPLASH_CMYK - memcpy(cmykTransferC, state->cmykTransferC, 256); - memcpy(cmykTransferM, state->cmykTransferM, 256); - memcpy(cmykTransferY, state->cmykTransferY, 256); - memcpy(cmykTransferK, state->cmykTransferK, 256); -#endif - overprintMask = state->overprintMask; - enablePathSimplification = state->enablePathSimplification; - next = NULL; -} - -SplashState::~SplashState() { - delete strokePattern; - delete fillPattern; - delete screen; - gfree(lineDash); - if (!clipIsShared) { - delete clip; - } - if (deleteSoftMask && softMask) { - delete softMask; - } -} - -void SplashState::setStrokePattern(SplashPattern *strokePatternA) { - delete strokePattern; - strokePattern = strokePatternA; -} - -void SplashState::setFillPattern(SplashPattern *fillPatternA) { - delete fillPattern; - fillPattern = fillPatternA; -} - -void SplashState::setScreen(SplashScreen *screenA) { - delete screen; - screen = screenA; -} - -void SplashState::setLineDash(SplashCoord *lineDashA, int lineDashLengthA, - SplashCoord lineDashPhaseA) { - gfree(lineDash); - lineDashLength = lineDashLengthA; - if (lineDashLength > 0) { - lineDash = (SplashCoord *)gmallocn(lineDashLength, sizeof(SplashCoord)); - memcpy(lineDash, lineDashA, lineDashLength * sizeof(SplashCoord)); - } else { - lineDash = NULL; - } - lineDashPhase = lineDashPhaseA; -} - -GBool SplashState::lineDashContainsZeroLengthDashes() { - int i; - - if (lineDashLength == 0) { - return gFalse; - } - - // if the line dash array has an odd number of elements, we need to - // check all of the elements; if the length is even, we only need to - // check even-number elements - if (lineDashLength & 1) { - for (i = 0; i < lineDashLength; ++i) { - if (lineDash[i] == 0) { - return gTrue; - } - } - } else { - for (i = 0; i < lineDashLength; i += 2) { - if (lineDash[i] == 0) { - return gTrue; - } - } - } - return gFalse; -} - -void SplashState::clipResetToRect(SplashCoord x0, SplashCoord y0, - SplashCoord x1, SplashCoord y1) { - if (clipIsShared) { - clip = clip->copy(); - clipIsShared = gFalse; - } - clip->resetToRect(x0, y0, x1, y1); -} - -SplashError SplashState::clipToRect(SplashCoord x0, SplashCoord y0, - SplashCoord x1, SplashCoord y1) { - if (clipIsShared) { - clip = clip->copy(); - clipIsShared = gFalse; - } - return clip->clipToRect(x0, y0, x1, y1); -} - -SplashError SplashState::clipToPath(SplashPath *path, GBool eo) { - if (clipIsShared) { - clip = clip->copy(); - clipIsShared = gFalse; - } - return clip->clipToPath(path, matrix, flatness, eo, - enablePathSimplification, strokeAdjust); -} - -void SplashState::setSoftMask(SplashBitmap *softMaskA) { - if (deleteSoftMask) { - delete softMask; - } - softMask = softMaskA; - deleteSoftMask = gTrue; -} - -void SplashState::setTransfer(Guchar *red, Guchar *green, Guchar *blue, - Guchar *gray) { -#if SPLASH_CMYK - int i; -#endif - - memcpy(rgbTransferR, red, 256); - memcpy(rgbTransferG, green, 256); - memcpy(rgbTransferB, blue, 256); - memcpy(grayTransfer, gray, 256); -#if SPLASH_CMYK - for (i = 0; i < 256; ++i) { - cmykTransferC[i] = (Guchar)(255 - rgbTransferR[255 - i]); - cmykTransferM[i] = (Guchar)(255 - rgbTransferG[255 - i]); - cmykTransferY[i] = (Guchar)(255 - rgbTransferB[255 - i]); - cmykTransferK[i] = (Guchar)(255 - grayTransfer[255 - i]); - } -#endif -} - diff --git a/Build/source/libs/xpdf/xpdf-src/splash/SplashState.h b/Build/source/libs/xpdf/xpdf-src/splash/SplashState.h deleted file mode 100644 index 38cb1188e94..00000000000 --- a/Build/source/libs/xpdf/xpdf-src/splash/SplashState.h +++ /dev/null @@ -1,135 +0,0 @@ -//======================================================================== -// -// SplashState.h -// -// Copyright 2003-2013 Glyph & Cog, LLC -// -//======================================================================== - -#ifndef SPLASHSTATE_H -#define SPLASHSTATE_H - -#include <aconf.h> - -#ifdef USE_GCC_PRAGMAS -#pragma interface -#endif - -#include "SplashTypes.h" - -class SplashPattern; -class SplashScreen; -class SplashClip; -class SplashBitmap; -class SplashPath; - -//------------------------------------------------------------------------ -// line cap values -//------------------------------------------------------------------------ - -#define splashLineCapButt 0 -#define splashLineCapRound 1 -#define splashLineCapProjecting 2 - -//------------------------------------------------------------------------ -// line join values -//------------------------------------------------------------------------ - -#define splashLineJoinMiter 0 -#define splashLineJoinRound 1 -#define splashLineJoinBevel 2 - -//------------------------------------------------------------------------ -// SplashState -//------------------------------------------------------------------------ - -class SplashState { -public: - - // Create a new state object, initialized with default settings. - SplashState(int width, int height, GBool vectorAntialias, - SplashScreenParams *screenParams); - SplashState(int width, int height, GBool vectorAntialias, - SplashScreen *screenA); - - // Copy a state object. - SplashState *copy() { return new SplashState(this); } - - ~SplashState(); - - // Set the stroke pattern. This does not copy <strokePatternA>. - void setStrokePattern(SplashPattern *strokePatternA); - - // Set the fill pattern. This does not copy <fillPatternA>. - void setFillPattern(SplashPattern *fillPatternA); - - // Set the screen. This does not copy <screenA>. - void setScreen(SplashScreen *screenA); - - // Set the line dash pattern. This copies the <lineDashA> array. - void setLineDash(SplashCoord *lineDashA, int lineDashLengthA, - SplashCoord lineDashPhaseA); - - // Returns true if the current line dash pattern contains one or - // more zero-length "on" sections (dashes). - GBool lineDashContainsZeroLengthDashes(); - - void clipResetToRect(SplashCoord x0, SplashCoord y0, - SplashCoord x1, SplashCoord y1); - SplashError clipToRect(SplashCoord x0, SplashCoord y0, - SplashCoord x1, SplashCoord y1); - SplashError clipToPath(SplashPath *path, GBool eo); - - // Set the soft mask bitmap. - void setSoftMask(SplashBitmap *softMaskA); - - // Set the transfer function. - void setTransfer(Guchar *red, Guchar *green, Guchar *blue, Guchar *gray); - - -private: - - SplashState(SplashState *state); - - SplashCoord matrix[6]; - SplashPattern *strokePattern; - SplashPattern *fillPattern; - SplashScreen *screen; - SplashBlendFunc blendFunc; - SplashCoord strokeAlpha; - SplashCoord fillAlpha; - SplashCoord lineWidth; - int lineCap; - int lineJoin; - SplashCoord miterLimit; - SplashCoord flatness; - SplashCoord *lineDash; - int lineDashLength; - SplashCoord lineDashPhase; - SplashStrokeAdjustMode strokeAdjust; - SplashClip *clip; - GBool clipIsShared; - SplashBitmap *softMask; - GBool deleteSoftMask; - GBool inNonIsolatedGroup; - GBool inKnockoutGroup; - Guchar rgbTransferR[256], - rgbTransferG[256], - rgbTransferB[256]; - Guchar grayTransfer[256]; -#if SPLASH_CMYK - Guchar cmykTransferC[256], - cmykTransferM[256], - cmykTransferY[256], - cmykTransferK[256]; -#endif - Guint overprintMask; - GBool enablePathSimplification; - - - SplashState *next; // used by Splash class - - friend class Splash; -}; - -#endif diff --git a/Build/source/libs/xpdf/xpdf-src/splash/SplashTypes.h b/Build/source/libs/xpdf/xpdf-src/splash/SplashTypes.h deleted file mode 100644 index 5860884a30b..00000000000 --- a/Build/source/libs/xpdf/xpdf-src/splash/SplashTypes.h +++ /dev/null @@ -1,145 +0,0 @@ -//======================================================================== -// -// SplashTypes.h -// -// Copyright 2003-2013 Glyph & Cog, LLC -// -//======================================================================== - -#ifndef SPLASHTYPES_H -#define SPLASHTYPES_H - -#include <aconf.h> -#include "gtypes.h" - -//------------------------------------------------------------------------ -// coordinates -//------------------------------------------------------------------------ - -#if USE_FIXEDPOINT -#include "FixedPoint.h" -typedef FixedPoint SplashCoord; -#else -typedef double SplashCoord; -#endif - -//------------------------------------------------------------------------ -// antialiasing -//------------------------------------------------------------------------ - -#define splashAASize 4 - -//------------------------------------------------------------------------ -// colors -//------------------------------------------------------------------------ - -enum SplashColorMode { - splashModeMono1, // 1 bit per component, 8 pixels per byte, - // MSbit is on the left - splashModeMono8, // 1 byte per component, 1 byte per pixel - splashModeRGB8, // 1 byte per component, 3 bytes per pixel: - // RGBRGB... - splashModeBGR8 // 1 byte per component, 3 bytes per pixel: - // BGRBGR... - -#if SPLASH_CMYK - , - splashModeCMYK8 // 1 byte per component, 4 bytes per pixel: - // CMYKCMYK... -#endif -}; - -// number of components in each color mode -// (defined in SplashState.cc) -extern int splashColorModeNComps[]; - -// max number of components in any SplashColor -#define splashMaxColorComps 3 -#if SPLASH_CMYK -# undef splashMaxColorComps -# define splashMaxColorComps 4 -#endif - -typedef Guchar SplashColor[splashMaxColorComps]; -typedef Guchar *SplashColorPtr; - -// RGB8 -static inline Guchar splashRGB8R(SplashColorPtr rgb8) { return rgb8[0]; } -static inline Guchar splashRGB8G(SplashColorPtr rgb8) { return rgb8[1]; } -static inline Guchar splashRGB8B(SplashColorPtr rgb8) { return rgb8[2]; } - -// BGR8 -static inline Guchar splashBGR8R(SplashColorPtr bgr8) { return bgr8[2]; } -static inline Guchar splashBGR8G(SplashColorPtr bgr8) { return bgr8[1]; } -static inline Guchar splashBGR8B(SplashColorPtr bgr8) { return bgr8[0]; } - -#if SPLASH_CMYK -// CMYK8 -static inline Guchar splashCMYK8C(SplashColorPtr cmyk8) { return cmyk8[0]; } -static inline Guchar splashCMYK8M(SplashColorPtr cmyk8) { return cmyk8[1]; } -static inline Guchar splashCMYK8Y(SplashColorPtr cmyk8) { return cmyk8[2]; } -static inline Guchar splashCMYK8K(SplashColorPtr cmyk8) { return cmyk8[3]; } -#endif - -static inline void splashColorCopy(SplashColorPtr dest, SplashColorPtr src) { - dest[0] = src[0]; - dest[1] = src[1]; - dest[2] = src[2]; -#if SPLASH_CMYK - dest[3] = src[3]; -#endif -} - -static inline void splashColorXor(SplashColorPtr dest, SplashColorPtr src) { - dest[0] ^= src[0]; - dest[1] ^= src[1]; - dest[2] ^= src[2]; -#if SPLASH_CMYK - dest[3] ^= src[3]; -#endif -} - -//------------------------------------------------------------------------ -// blend functions -//------------------------------------------------------------------------ - -typedef void (*SplashBlendFunc)(SplashColorPtr src, SplashColorPtr dest, - SplashColorPtr blend, SplashColorMode cm); - -//------------------------------------------------------------------------ -// stroke adjustment mode -//------------------------------------------------------------------------ - -enum SplashStrokeAdjustMode { - splashStrokeAdjustOff, - splashStrokeAdjustNormal, - splashStrokeAdjustCAD -}; - -//------------------------------------------------------------------------ -// screen parameters -//------------------------------------------------------------------------ - -enum SplashScreenType { - splashScreenDispersed, - splashScreenClustered, - splashScreenStochasticClustered -}; - -struct SplashScreenParams { - SplashScreenType type; - int size; - int dotRadius; - SplashCoord gamma; - SplashCoord blackThreshold; - SplashCoord whiteThreshold; -}; - -//------------------------------------------------------------------------ -// error results -//------------------------------------------------------------------------ - -typedef int SplashError; - - -#endif diff --git a/Build/source/libs/xpdf/xpdf-src/splash/SplashXPath.cc b/Build/source/libs/xpdf/xpdf-src/splash/SplashXPath.cc deleted file mode 100644 index 4c77765723e..00000000000 --- a/Build/source/libs/xpdf/xpdf-src/splash/SplashXPath.cc +++ /dev/null @@ -1,645 +0,0 @@ -//======================================================================== -// -// SplashXPath.cc -// -// Copyright 2003-2013 Glyph & Cog, LLC -// -//======================================================================== - -#include <aconf.h> - -#ifdef USE_GCC_PRAGMAS -#pragma implementation -#endif - -#include <stdlib.h> -#include <string.h> -#if HAVE_STD_SORT -#include <algorithm> -#endif -#include "gmem.h" -#include "gmempp.h" -#include "SplashMath.h" -#include "SplashPath.h" -#include "SplashXPath.h" - -//------------------------------------------------------------------------ - -#define minCosSquaredJoinAngle 0.75 -#define maxPointToLineDistanceSquared 0.04 - -//------------------------------------------------------------------------ - -struct SplashXPathPoint { - SplashCoord x, y; -}; - -struct SplashXPathAdjust { - int firstPt, lastPt; // range of points - GBool vert; // vertical or horizontal hint - SplashCoord x0a, x0b, // hint boundaries - xma, xmb, - x1a, x1b; - SplashCoord x0, x1, xm; // adjusted coordinates -}; - -//------------------------------------------------------------------------ - -// Transform a point from user space to device space. -inline void SplashXPath::transform(SplashCoord *matrix, - SplashCoord xi, SplashCoord yi, - SplashCoord *xo, SplashCoord *yo) { - // [ m[0] m[1] 0 ] - // [xo yo 1] = [xi yi 1] * [ m[2] m[3] 0 ] - // [ m[4] m[5] 1 ] - *xo = xi * matrix[0] + yi * matrix[2] + matrix[4]; - *yo = xi * matrix[1] + yi * matrix[3] + matrix[5]; -} - -//------------------------------------------------------------------------ -// SplashXPath -//------------------------------------------------------------------------ - -// SplashXPath segment coords are clipped to +/-maxCoord to avoid -// problems. The xMin/yMin/xMax/yMax fields are 32-bit integers, so -// coords need to be < 2^31 / aa{Horiz,Vert}. -#define maxCoord 100000000.0 - -void SplashXPath::clampCoords(SplashCoord *x, SplashCoord *y) { -#if !USE_FIXEDPOINT - if (*x > maxCoord) { - *x = maxCoord; - } else if (*x < -maxCoord) { - *x = -maxCoord; - } - if (*y > maxCoord) { - *y = maxCoord; - } else if (*y < -maxCoord) { - *y = -maxCoord; - } -#endif -} - -SplashXPath::SplashXPath(SplashPath *path, SplashCoord *matrix, - SplashCoord flatness, GBool closeSubpaths, - GBool simplify, - SplashStrokeAdjustMode strokeAdjMode) { - SplashXPathPoint *pts; - SplashCoord x0, y0, x1, y1, x2, y2, x3, y3, xsp, ysp, t; - int curSubpath, firstSegInSubpath, i; - GBool adjusted; - - //--- transform the points - pts = (SplashXPathPoint *)gmallocn(path->length, sizeof(SplashXPathPoint)); - for (i = 0; i < path->length; ++i) { - transform(matrix, path->pts[i].x, path->pts[i].y, &pts[i].x, &pts[i].y); - clampCoords(&pts[i].x, &pts[i].y); - } - - //--- do stroke adjustment - if (path->hints) { - adjusted = strokeAdjust(pts, path->hints, path->hintsLength, - strokeAdjMode); - } else { - adjusted = gFalse; - } - - //--- construct the segments - - segs = NULL; - length = size = 0; - - x0 = y0 = xsp = ysp = 0; // make gcc happy - curSubpath = 0; - firstSegInSubpath = 0; - i = 0; - while (i < path->length) { - - // first point in subpath - skip it - if (path->flags[i] & splashPathFirst) { - x0 = pts[i].x; - y0 = pts[i].y; - xsp = x0; - ysp = y0; - curSubpath = i; - ++i; - - } else { - - // curve segment - if (path->flags[i] & splashPathCurve) { - x1 = pts[i].x; - y1 = pts[i].y; - x2 = pts[i+1].x; - y2 = pts[i+1].y; - x3 = pts[i+2].x; - y3 = pts[i+2].y; - addCurve(x0, y0, x1, y1, x2, y2, x3, y3, - flatness, - (path->flags[i-1] & splashPathFirst), - (path->flags[i+2] & splashPathLast), - !closeSubpaths && - (path->flags[i-1] & splashPathFirst) && - !(path->flags[i-1] & splashPathClosed), - !closeSubpaths && - (path->flags[i+2] & splashPathLast) && - !(path->flags[i+2] & splashPathClosed)); - x0 = x3; - y0 = y3; - i += 3; - - // line segment - } else { - x1 = pts[i].x; - y1 = pts[i].y; - addSegment(x0, y0, x1, y1); - x0 = x1; - y0 = y1; - ++i; - } - - // end a subpath - if (path->flags[i-1] & splashPathLast) { - if (closeSubpaths && - (pts[i-1].x != pts[curSubpath].x || - pts[i-1].y != pts[curSubpath].y)) { - addSegment(x0, y0, xsp, ysp); - } - if (simplify && !adjusted) { - mergeSegments(firstSegInSubpath); - } - firstSegInSubpath = length; - } - } - } - - gfree(pts); - - finishSegments(); - - //--- check for a rectangle - isRect = gFalse; - rectX0 = rectY0 = rectX1 = rectY1 = 0; - if (length == 4) { -#if HAVE_STD_SORT - std::sort(segs, segs + length, SplashXPathSeg::cmpY); -#else - qsort(segs, length, sizeof(SplashXPathSeg), &SplashXPathSeg::cmpY); -#endif - if (segs[0].y0 == segs[0].y1 && - segs[1].x0 == segs[1].x1 && - segs[2].x0 == segs[2].x1 && - segs[3].y0 == segs[3].y1) { - isRect = gTrue; - rectX0 = segs[1].x0; - rectX1 = segs[2].x0; - rectY0 = segs[0].y0; - rectY1 = segs[3].y0; - } else if (segs[0].x0 == segs[0].x1 && - segs[1].y0 == segs[1].y1 && - segs[2].x0 == segs[2].x1 && - segs[3].y0 == segs[3].y1) { - isRect = gTrue; - rectX0 = segs[0].x0; - rectX1 = segs[2].x0; - rectY0 = segs[1].y0; - rectY1 = segs[3].y0; - } else if (segs[0].x0 == segs[0].x1 && - segs[1].x0 == segs[1].x1 && - segs[2].y0 == segs[2].y1 && - segs[3].y0 == segs[3].y1) { - isRect = gTrue; - rectX0 = segs[0].x0; - rectX1 = segs[1].x0; - rectY0 = segs[2].y0; - rectY1 = segs[3].y0; - } - if (isRect) { - if (rectX0 > rectX1) { - t = rectX0; rectX0 = rectX1; rectX1 = t; - } - if (rectY0 > rectY1) { - t = rectY0; rectY0 = rectY1; rectY1 = t; - } - } - } -} - -GBool SplashXPath::strokeAdjust(SplashXPathPoint *pts, - SplashPathHint *hints, int nHints, - SplashStrokeAdjustMode strokeAdjMode) { - SplashXPathAdjust *adjusts, *adjust; - SplashPathHint *hint; - SplashCoord x0, y0, x1, y1, x2, y2, x3, y3; - SplashCoord adj0, adj1, w, d; - int xi0, xi1; - int i, j; - GBool adjusted; - - adjusted = gFalse; - - // set up the stroke adjustment hints - adjusts = (SplashXPathAdjust *)gmallocn(nHints, sizeof(SplashXPathAdjust)); - for (i = 0; i < nHints; ++i) { - hint = &hints[i]; - x0 = pts[hint->ctrl0 ].x; y0 = pts[hint->ctrl0 ].y; - x1 = pts[hint->ctrl0 + 1].x; y1 = pts[hint->ctrl0 + 1].y; - x2 = pts[hint->ctrl1 ].x; y2 = pts[hint->ctrl1 ].y; - x3 = pts[hint->ctrl1 + 1].x; y3 = pts[hint->ctrl1 + 1].y; - w = -1; - if (splashAbs(x0 - x1) < 0.01 && splashAbs(x2 - x3) < 0.01) { - adjusts[i].vert = gTrue; - adj0 = x0; - adj1 = x2; - if (hint->projectingCap) { - w = splashAbs(y1 - y0); - } - } else if (splashAbs(y0 - y1) < 0.01 && splashAbs(y2 - y3) < 0.01) { - adjusts[i].vert = gFalse; - adj0 = y0; - adj1 = y2; - if (hint->projectingCap) { - w = splashAbs(x1 - x0); - } - } else { - goto done; - } - if (adj0 > adj1) { - x0 = adj0; - adj0 = adj1; - adj1 = x0; - } - d = adj1 - adj0; - if (d > 0.04) { - d = 0.01; - } else { - d *= 0.25; - } - adjusts[i].x0a = adj0 - d; - adjusts[i].x0b = adj0 + d; - adjusts[i].xma = (SplashCoord)0.5 * (adj0 + adj1) - d; - adjusts[i].xmb = (SplashCoord)0.5 * (adj0 + adj1) + d; - adjusts[i].x1a = adj1 - d; - adjusts[i].x1b = adj1 + d; - splashStrokeAdjust(adj0, adj1, &xi0, &xi1, strokeAdjMode, w); - adjusts[i].x0 = (SplashCoord)xi0; - // the "minus epsilon" thing here is needed when vector - // antialiasing is turned off -- otherwise stroke adjusted lines - // will touch an extra pixel on one edge - adjusts[i].x1 = (SplashCoord)xi1 - 0.001; - adjusts[i].xm = (SplashCoord)0.5 * (adjusts[i].x0 + adjusts[i].x1); - adjusts[i].firstPt = hint->firstPt; - adjusts[i].lastPt = hint->lastPt; - } - - // perform stroke adjustment - for (i = 0, adjust = adjusts; i < nHints; ++i, ++adjust) { - for (j = adjust->firstPt; j <= adjust->lastPt; ++j) { - if (adjust->vert) { - x0 = pts[j].x; - if (x0 > adjust->x0a && x0 < adjust->x0b) { - pts[j].x = adjust->x0; - } else if (x0 > adjust->xma && x0 < adjust->xmb) { - pts[j].x = adjust->xm; - } else if (x0 > adjust->x1a && x0 < adjust->x1b) { - pts[j].x = adjust->x1; - } - } else { - y0 = pts[j].y; - if (y0 > adjust->x0a && y0 < adjust->x0b) { - pts[j].y = adjust->x0; - } else if (y0 > adjust->xma && y0 < adjust->xmb) { - pts[j].y = adjust->xm; - } else if (y0 > adjust->x1a && y0 < adjust->x1b) { - pts[j].y = adjust->x1; - } - } - } - } - adjusted = gTrue; - - done: - gfree(adjusts); - return adjusted; -} - -SplashXPath::SplashXPath(SplashXPath *xPath) { - length = xPath->length; - size = xPath->size; - segs = (SplashXPathSeg *)gmallocn(size, sizeof(SplashXPathSeg)); - memcpy(segs, xPath->segs, length * sizeof(SplashXPathSeg)); - xMin = xPath->xMin; - yMin = xPath->yMin; - xMax = xPath->xMax; - yMax = xPath->yMax; -} - -SplashXPath::~SplashXPath() { - gfree(segs); -} - -// Add space for <nSegs> more segments -void SplashXPath::grow(int nSegs) { - if (length + nSegs > size) { - if (size == 0) { - size = 32; - } - while (size < length + nSegs) { - size *= 2; - } - segs = (SplashXPathSeg *)greallocn(segs, size, sizeof(SplashXPathSeg)); - } -} - -void SplashXPath::addCurve(SplashCoord x0, SplashCoord y0, - SplashCoord x1, SplashCoord y1, - SplashCoord x2, SplashCoord y2, - SplashCoord x3, SplashCoord y3, - SplashCoord flatness, - GBool first, GBool last, GBool end0, GBool end1) { - SplashCoord cx[splashMaxCurveSplits + 1][3]; - SplashCoord cy[splashMaxCurveSplits + 1][3]; - int cNext[splashMaxCurveSplits + 1]; - SplashCoord xl0, xl1, xl2, xr0, xr1, xr2, xr3, xx1, xx2, xh; - SplashCoord yl0, yl1, yl2, yr0, yr1, yr2, yr3, yy1, yy2, yh; - SplashCoord dx, dy, mx, my, d1, d2, flatness2; - int p1, p2, p3; - -#if USE_FIXEDPOINT - flatness2 = flatness; -#else - flatness2 = flatness * flatness; -#endif - - // initial segment - p1 = 0; - p2 = splashMaxCurveSplits; - cx[p1][0] = x0; cy[p1][0] = y0; - cx[p1][1] = x1; cy[p1][1] = y1; - cx[p1][2] = x2; cy[p1][2] = y2; - cx[p2][0] = x3; cy[p2][0] = y3; - cNext[p1] = p2; - - while (p1 < splashMaxCurveSplits) { - - // get the next segment - xl0 = cx[p1][0]; yl0 = cy[p1][0]; - xx1 = cx[p1][1]; yy1 = cy[p1][1]; - xx2 = cx[p1][2]; yy2 = cy[p1][2]; - p2 = cNext[p1]; - xr3 = cx[p2][0]; yr3 = cy[p2][0]; - - // compute the distances from the control points to the - // midpoint of the straight line (this is a bit of a hack, but - // it's much faster than computing the actual distances to the - // line) - mx = (xl0 + xr3) * 0.5; - my = (yl0 + yr3) * 0.5; -#if USE_FIXEDPOINT - d1 = splashDist(xx1, yy1, mx, my); - d2 = splashDist(xx2, yy2, mx, my); -#else - dx = xx1 - mx; - dy = yy1 - my; - d1 = dx*dx + dy*dy; - dx = xx2 - mx; - dy = yy2 - my; - d2 = dx*dx + dy*dy; -#endif - - // if the curve is flat enough, or no more subdivisions are - // allowed, add the straight line segment - if (p2 - p1 == 1 || (d1 <= flatness2 && d2 <= flatness2)) { - addSegment(xl0, yl0, xr3, yr3); - p1 = p2; - - // otherwise, subdivide the curve - } else { - xl1 = (xl0 + xx1) * 0.5; - yl1 = (yl0 + yy1) * 0.5; - xh = (xx1 + xx2) * 0.5; - yh = (yy1 + yy2) * 0.5; - xl2 = (xl1 + xh) * 0.5; - yl2 = (yl1 + yh) * 0.5; - xr2 = (xx2 + xr3) * 0.5; - yr2 = (yy2 + yr3) * 0.5; - xr1 = (xh + xr2) * 0.5; - yr1 = (yh + yr2) * 0.5; - xr0 = (xl2 + xr1) * 0.5; - yr0 = (yl2 + yr1) * 0.5; - // add the new subdivision points - p3 = (p1 + p2) / 2; - cx[p1][1] = xl1; cy[p1][1] = yl1; - cx[p1][2] = xl2; cy[p1][2] = yl2; - cNext[p1] = p3; - cx[p3][0] = xr0; cy[p3][0] = yr0; - cx[p3][1] = xr1; cy[p3][1] = yr1; - cx[p3][2] = xr2; cy[p3][2] = yr2; - cNext[p3] = p2; - } - } -} - -void SplashXPath::addSegment(SplashCoord x0, SplashCoord y0, - SplashCoord x1, SplashCoord y1) { - grow(1); - segs[length].x0 = x0; - segs[length].y0 = y0; - segs[length].x1 = x1; - segs[length].y1 = y1; - ++length; -} - -// Returns true if the angle between (x0,y0)-(x1,y1) and -// (x1,y1)-(x2,y2) is close to 180 degrees. -static GBool joinAngleIsFlat(SplashCoord x0, SplashCoord y0, - SplashCoord x1, SplashCoord y1, - SplashCoord x2, SplashCoord y2) { - SplashCoord dx1, dy1, dx2, dy2, d, len1, len2; - - dx1 = x1 - x0; - dy1 = y1 - y0; - dx2 = x2 - x1; - dy2 = y2 - y1; - d = dx1 * dx2 + dy1 * dy2; - len1 = dx1 * dx1 + dy1 * dy1; - len2 = dx2 * dx2 + dy2 * dy2; - return d > 0 && d * d > len1 * len2 * minCosSquaredJoinAngle; -} - -// Returns true if (x1,y1) is sufficiently close to the segment -// (x0,y0)-(x2,y2), looking at the perpendicular point-to-line -// distance. -static GBool pointCloseToSegment(SplashCoord x0, SplashCoord y0, - SplashCoord x1, SplashCoord y1, - SplashCoord x2, SplashCoord y2) { - SplashCoord t1, t2, dx, dy; - - // compute the perpendicular distance from the point to the segment, - // i.e., the projection of (x0,y0)-(x1,y1) onto a unit normal to the - // segment (this actually computes the square of the distance) - dx = x2 - x0; - dy = y2 - y0; - t1 = dx*dx + dy*dy; - if (t1 < 0.0001) { - // degenerate case: (x0,y0) and (x2,y2) are (nearly) identical -- - // just compute the distance to (x1,y1) - dx = x0 - x1; - dy = y0 - y1; - t2 = dx*dx + dy*dy; - return t2 < maxPointToLineDistanceSquared; - } - t2 = x1 * dy - dx * y1 - x0 * y2 + x2 * y0; - // actual distance = t2 / sqrt(t1) - return t2 * t2 < t1 * maxPointToLineDistanceSquared; -} - -// Attempt to simplify the path by merging sequences of consecutive -// segments in [first] .. [length]-1. -void SplashXPath::mergeSegments(int first) { - GBool horiz, vert; - int in, out, prev, i, j; - - in = out = first; - while (in < length) { - - // skip zero-length segments - if (segs[in].x0 == segs[in].x1 && segs[in].y0 == segs[in].y1) { - ++in; - continue; - } - - horiz = segs[in].y0 == segs[in].y1; - vert = segs[in].x0 == segs[in].x1; - - // check for a sequence of mergeable segments: in .. i - prev = in; - for (i = in + 1; i < length; ++i) { - - // skip zero-length segments - if (segs[i].x0 == segs[i].x1 && segs[i].y0 == segs[i].y1) { - continue; - } - - // check for a horizontal or vertical segment - if ((horiz && segs[in].y0 != segs[in].y1) || - (vert && segs[in].x0 != segs[in].x1)) { - break; - } - - // check the angle between segs i-1 and i - // (actually, we compare seg i to the previous non-zero-length - // segment, which may not be i-1) - if (!joinAngleIsFlat(segs[prev].x0, segs[prev].y0, - segs[i].x0, segs[i].y0, - segs[i].x1, segs[i].y1)) { - break; - } - - // check the distances from the ends of segs in .. i-1 to the - // proposed new segment - for (j = in; j < i; ++j) { - if (!pointCloseToSegment(segs[in].x0, segs[in].y0, - segs[j].x1, segs[j].y1, - segs[i].x1, segs[i].y1)) { - break; - } - } - if (j < i) { - break; - } - - prev = i; - } - - // we can merge segs: in .. i-1 - // (this may be the single segment: in) - segs[out].x0 = segs[in].x0; - segs[out].y0 = segs[in].y0; - segs[out].x1 = segs[i-1].x1; - segs[out].y1 = segs[i-1].y1; - in = i; - ++out; - } - - length = out; -} - -void SplashXPath::finishSegments() { - SplashXPathSeg *seg; - SplashCoord xMinFP, xMaxFP, yMinFP, yMaxFP, t; - int i; - - xMinFP = yMinFP = xMaxFP = yMaxFP = 0; - - for (i = 0; i < length; ++i) { - seg = &segs[i]; - - //--- compute the slopes - if (seg->y0 <= seg->y1) { - seg->count = 1; - } else { - t = seg->x0; seg->x0 = seg->x1; seg->x1 = t; - t = seg->y0; seg->y0 = seg->y1; seg->y1 = t; - seg->count = -1; - } -#if USE_FIXEDPOINT - if (seg->y0 == seg->y1 || seg->x0 == seg->x1 || - !FixedPoint::divCheck(seg->x1 - seg->x0, seg->y1 - seg->y0, - &seg->dxdy) || - !FixedPoint::divCheck(seg->y1 - seg->y0, seg->x1 - seg->x0, - &seg->dydx)) { - seg->dxdy = 0; - seg->dydx = 0; - } -#else - if (splashAbs(seg->y1 - seg->y0) < 1e-200 || - splashAbs(seg->x1 - seg->x0) < 1e-200) { - seg->dxdy = 0; - seg->dydx = 0; - } else { - seg->dxdy = (seg->x1 - seg->x0) / (seg->y1 - seg->y0); - if (seg->dxdy == 0) { - seg->dydx = 0; - } else { - seg->dydx = 1 / seg->dxdy; - } - } -#endif - - //--- update bbox - if (i == 0) { - if (seg->x0 <= seg->x1) { - xMinFP = seg->x0; - xMaxFP = seg->x1; - } else { - xMinFP = seg->x1; - xMaxFP = seg->x0; - } - yMinFP = seg->y0; - yMaxFP = seg->y1; - } else { - if (seg->x0 < xMinFP) { - xMinFP = seg->x0; - } else if (seg->x0 > xMaxFP) { - xMaxFP = seg->x0; - } - if (seg->x1 < xMinFP) { - xMinFP = seg->x1; - } else if (seg->x1 > xMaxFP) { - xMaxFP = seg->x1; - } - if (seg->y0 < yMinFP) { - yMinFP = seg->y0; - } - if (seg->y1 > yMaxFP) { - yMaxFP = seg->y1; - } - } - } - - xMin = splashFloor(xMinFP); - yMin = splashFloor(yMinFP); - xMax = splashFloor(xMaxFP); - yMax = splashFloor(yMaxFP); -} diff --git a/Build/source/libs/xpdf/xpdf-src/splash/SplashXPath.h b/Build/source/libs/xpdf/xpdf-src/splash/SplashXPath.h deleted file mode 100644 index 82d7889c447..00000000000 --- a/Build/source/libs/xpdf/xpdf-src/splash/SplashXPath.h +++ /dev/null @@ -1,143 +0,0 @@ -//======================================================================== -// -// SplashXPath.h -// -// Copyright 2003-2013 Glyph & Cog, LLC -// -//======================================================================== - -#ifndef SPLASHXPATH_H -#define SPLASHXPATH_H - -#include <aconf.h> - -#ifdef USE_GCC_PRAGMAS -#pragma interface -#endif - -#include "SplashTypes.h" - -class SplashPath; -struct SplashXPathPoint; -struct SplashPathHint; - -//------------------------------------------------------------------------ - -#define splashMaxCurveSplits (1 << 10) - -//------------------------------------------------------------------------ -// SplashXPathSeg -//------------------------------------------------------------------------ - -struct SplashXPathSeg { - SplashCoord x0, y0; // first endpoint (y0 <= y1) - SplashCoord x1, y1; // second endpoint - SplashCoord dxdy; // slope: delta-x / delta-y - SplashCoord dydx; // slope: delta-y / delta-x - int count; // EO/NZWN counter increment - - //----- used by SplashXPathScanner - int iy; - SplashCoord sx0, sx1, mx; - SplashXPathSeg *prev, *next; - -#if HAVE_STD_SORT - - static bool cmpMX(const SplashXPathSeg &s0, - const SplashXPathSeg &s1) { - if (s0.iy != s1.iy) { - return s0.iy < s1.iy; - } - return s0.mx < s1.mx; - } - - static bool cmpY(const SplashXPathSeg &seg0, - const SplashXPathSeg &seg1) { - return seg0.y0 < seg1.y0; - } - -#else - - static int cmpMX(const void *p0, const void *p1) { - SplashXPathSeg *s0 = (SplashXPathSeg *)p0; - SplashXPathSeg *s1 = (SplashXPathSeg *)p1; - SplashCoord cmp; - - if (s0->iy != s1->iy) { - return s0->iy - s1->iy; - } - cmp = s0->mx - s1->mx; - return (cmp < 0) ? -1 : (cmp > 0) ? 1 : 0; - } - - static int cmpY(const void *seg0, const void *seg1) { - SplashCoord cmp; - - cmp = ((SplashXPathSeg *)seg0)->y0 - - ((SplashXPathSeg *)seg1)->y0; - return (cmp > 0) ? 1 : (cmp < 0) ? -1 : 0; - } - -#endif -}; - -//------------------------------------------------------------------------ -// SplashXPath -//------------------------------------------------------------------------ - -class SplashXPath { -public: - - // Expands (converts to segments) and flattens (converts curves to - // lines) <path>. Transforms all points from user space to device - // space, via <matrix>. If <closeSubpaths> is true, closes all open - // subpaths. - SplashXPath(SplashPath *path, SplashCoord *matrix, - SplashCoord flatness, GBool closeSubpaths, - GBool simplify, SplashStrokeAdjustMode strokeAdjMode); - - // Copy an expanded path. - SplashXPath *copy() { return new SplashXPath(this); } - - ~SplashXPath(); - - int getXMin() { return xMin; } - int getXMax() { return xMax; } - int getYMin() { return yMin; } - int getYMax() { return yMax; } - -private: - - static void clampCoords(SplashCoord *x, SplashCoord *y); - SplashXPath(SplashXPath *xPath); - void transform(SplashCoord *matrix, SplashCoord xi, SplashCoord yi, - SplashCoord *xo, SplashCoord *yo); - GBool strokeAdjust(SplashXPathPoint *pts, - SplashPathHint *hints, int nHints, - SplashStrokeAdjustMode strokeAdjMode); - void grow(int nSegs); - void addCurve(SplashCoord x0, SplashCoord y0, - SplashCoord x1, SplashCoord y1, - SplashCoord x2, SplashCoord y2, - SplashCoord x3, SplashCoord y3, - SplashCoord flatness, - GBool first, GBool last, GBool end0, GBool end1); - void mergeSegments(int first); - void addSegment(SplashCoord x0, SplashCoord y0, - SplashCoord x1, SplashCoord y1); - void finishSegments(); - - SplashXPathSeg *segs; - int length, size; // length and size of segs array - int xMin, xMax; - int yMin, yMax; - - GBool isRect; - SplashCoord rectX0, rectY0, rectX1, rectY1; - - friend class SplashXPathScanner; - friend class SplashClip; - friend class Splash; -}; - -#endif diff --git a/Build/source/libs/xpdf/xpdf-src/splash/SplashXPathScanner.cc b/Build/source/libs/xpdf/xpdf-src/splash/SplashXPathScanner.cc deleted file mode 100644 index 3f167b8b311..00000000000 --- a/Build/source/libs/xpdf/xpdf-src/splash/SplashXPathScanner.cc +++ /dev/null @@ -1,620 +0,0 @@ -//======================================================================== -// -// SplashXPathScanner.cc -// -// Copyright 2003-2013 Glyph & Cog, LLC -// -//======================================================================== - -#include <aconf.h> - -#ifdef USE_GCC_PRAGMAS -#pragma implementation -#endif - -#include <stdlib.h> -#include <string.h> -#if HAVE_STD_SORT -#include <algorithm> -#endif -#include "gmem.h" -#include "gmempp.h" -#include "GList.h" -#include "SplashMath.h" -#include "SplashXPath.h" -#include "SplashXPathScanner.h" - -//------------------------------------------------------------------------ - -#if ANTIALIAS_256 - -#define aaVert 15 -#define aaHoriz 17 - -#else - -#define aaVert 4 -#define aaHoriz 4 - -static Guchar map16to255[17] = { - 0, - 16, - 32, - 48, - 64, - 80, - 96, - 112, - 128, - 143, - 159, - 175, - 191, - 207, - 223, - 239, - 255 -}; - -#endif - -//------------------------------------------------------------------------ - -SplashXPathScanner::SplashXPathScanner(SplashXPath *xPathA, GBool eo, - int yMinA, int yMaxA) { - xPath = xPathA; - eoMask = eo ? 1 : 0xffffffff; - yMin = yMinA; - yMax = yMaxA; - if (xPath->isRect) { - rectX0I = splashFloor(xPath->rectX0); - rectY0I = splashFloor(xPath->rectY0); - rectX1I = splashFloor(xPath->rectX1); - rectY1I = splashFloor(xPath->rectY1); - } - - pre = &preSeg; - post = &postSeg; - pre->mx = xPath->xMin - 1; - post->mx = xPath->xMax + 1; - - resetDone = gFalse; - resetAA = gFalse; -} - -SplashXPathScanner::~SplashXPathScanner() { -} - -void SplashXPathScanner::insertSegmentBefore(SplashXPathSeg *s, - SplashXPathSeg *sNext) { - SplashXPathSeg *sPrev; - - sPrev = sNext->prev; - sPrev->next = s; - s->prev = sPrev; - s->next = sNext; - sNext->prev = s; -} - -void SplashXPathScanner::removeSegment(SplashXPathSeg *s) { - SplashXPathSeg *sPrev, *sNext; - - sPrev = s->prev; - sNext = s->next; - sPrev->next = sNext; - sNext->prev = sPrev; - s->prev = s->next = NULL; -} - -void SplashXPathScanner::moveSegmentAfter(SplashXPathSeg *s, - SplashXPathSeg *sPrev) { - SplashXPathSeg *sNext; - - s->prev->next = s->next; - s->next->prev = s->prev; - - sNext = sPrev->next; - sPrev->next = s; - s->prev = sPrev; - s->next = sNext; - sNext->prev = s; -} - -void SplashXPathScanner::reset(GBool aa, GBool aaChanged) { - SplashXPathSeg *seg; - SplashCoord y; - int i; - - //--- initialize segment parameters - for (i = 0; i < xPath->length; ++i) { - seg = &xPath->segs[i]; - if (aa) { - if (aaChanged) { - seg->iy = splashFloor(seg->y0 * aaVert); - } - y = (SplashCoord)(seg->iy + 1) / (SplashCoord)aaVert; - } else { - if (aaChanged) { - seg->iy = splashFloor(seg->y0); - } - y = (SplashCoord)(seg->iy + 1); - } - seg->sx0 = seg->x0; - if (seg->y1 <= y) { - seg->sx1 = seg->x1; - } else { - seg->sx1 = seg->x0 + (y - seg->y0) * seg->dxdy; - } - seg->mx = (seg->sx0 <= seg->sx1) ? seg->sx0 : seg->sx1; - seg->prev = seg->next = NULL; - } - - //--- sort the inactive segments by iy, mx - if (aaChanged) { -#if HAVE_STD_SORT - std::sort(xPath->segs, xPath->segs + xPath->length, &SplashXPathSeg::cmpMX); -#else - qsort(xPath->segs, xPath->length, sizeof(SplashXPathSeg), - &SplashXPathSeg::cmpMX); -#endif - } - - //--- initialize the active list - pre->prev = NULL; - pre->next = post; - post->prev = pre; - post->next = NULL; - - //--- initialize the scan state - nextSeg = 0; - if (xPath->length) { - yBottomI = xPath->segs[0].iy; - if (aa) { - yBottomI -= yBottomI % aaVert; - } - } else { - yBottomI = 0; - } - yTopI = yBottomI - 1; - if (aa) { - yTop = (SplashCoord)yTopI / (SplashCoord)aaVert; - yBottom = (SplashCoord)yBottomI / (SplashCoord)aaVert; - } else { - yTop = (SplashCoord)yTopI; - yBottom = (SplashCoord)yBottomI; - } - - resetDone = gTrue; - resetAA = aa; -} - -void SplashXPathScanner::skip(int newYBottomI, GBool aa) { - SplashXPathSeg *s0, *s1,*s2; - int iy; - - yTopI = newYBottomI - 1; - yBottomI = newYBottomI; - if (aa) { - yTop = (SplashCoord)yTopI / (SplashCoord)aaVert; - yBottom = (SplashCoord)yBottomI / (SplashCoord)aaVert; - } else { - yTop = (SplashCoord)yTopI; - yBottom = (SplashCoord)yBottomI; - } - - //--- remove finished segments; update sx0, sx1, mx for active segments - s0 = pre->next; - while (s0 != post) { - s1 = s0->next; - - // check for a finished segment - if (s0->y1 < yTop) { - removeSegment(s0); - - // compute sx0, sx1, mx - } else { - if (s0->y0 >= yTop) { - s0->sx0 = s0->x0; - } else { - s0->sx0 = s0->x0 + (yTop - s0->y0) * s0->dxdy; - } - if (s0->y1 <= yBottom) { - s0->sx1 = s0->x1; - } else { - s0->sx1 = s0->x0 + (yBottom - s0->y0) * s0->dxdy; - } - s0->mx = (s0->sx0 <= s0->sx1) ? s0->sx0 : s0->sx1; - } - - s0 = s1; - } - - //--- check for intersections - s0 = pre->next; - if (s0 != post) { - s1 = s0->next; - while (s1 != post) { - if (s1->mx < s0->mx) { - for (s2 = s0->prev; s1->mx < s2->mx; s2 = s2->prev) ; - moveSegmentAfter(s1, s2); - } else { - s0 = s1; - } - s1 = s0->next; - } - } - - //--- insert new segments with a merge sort - // - this has to be done one (sub)scanline at a time, because the - // inactive list is bin-sorted by (sub)scanline - while (nextSeg < xPath->length && xPath->segs[nextSeg].iy <= yTopI) { - // the first inactive segment determines the next scanline to process - iy = xPath->segs[nextSeg].iy; - s0 = pre->next; - do { - s1 = &xPath->segs[nextSeg]; - ++nextSeg; - if (s1->y1 < yTop) { - continue; - } - if (s1->y0 >= yTop) { - s1->sx0 = s1->x0; - } else { - s1->sx0 = s1->x0 + (yTop - s1->y0) * s1->dxdy; - } - if (s1->y1 <= yBottom) { - s1->sx1 = s1->x1; - } else { - s1->sx1 = s1->x0 + (yBottom - s1->y0) * s1->dxdy; - } - s1->mx = (s1->sx0 <= s1->sx1) ? s1->sx0 : s1->sx1; - insertSegmentBefore(s1, s0); - } while (nextSeg < xPath->length && xPath->segs[nextSeg].iy <= iy); - } -} - -void SplashXPathScanner::advance(GBool aa) { - SplashXPathSeg *s, *sNext, *s1; - - yTopI = yBottomI; - yTop = yBottom; - yBottomI = yTopI + 1; - if (aa) { - yBottom = (SplashCoord)yBottomI / (SplashCoord)aaVert; - } else { - yBottom = (SplashCoord)yBottomI; - } - - s = pre->next; - while (s != post) { - sNext = s->next; - - // check for a finished segment - if (s->y1 < yTop) { - removeSegment(s); - - } else { - - // compute sx0, sx1, mx - s->sx0 = s->sx1; - if (s->y1 <= yBottom) { - s->sx1 = s->x1; - } else { - s->sx1 = s->x0 + (yBottom - s->y0) * s->dxdy; - } - s->mx = (s->sx0 <= s->sx1) ? s->sx0 : s->sx1; - - // check for intersection - if (s->mx < s->prev->mx) { - for (s1 = s->prev->prev; s->mx < s1->mx; s1 = s1->prev) ; - moveSegmentAfter(s, s1); - } - } - - s = sNext; - } - - // insert new segments - s = pre->next; - while (nextSeg < xPath->length && xPath->segs[nextSeg].iy <= yTopI) { - s1 = &xPath->segs[nextSeg]; - ++nextSeg; - while (s1->mx > s->mx) { - s = s->next; - } - insertSegmentBefore(s1, s); - } -} - -void SplashXPathScanner::generatePixels(int x0, int x1, Guchar *line, - int *xMin, int *xMax) { - SplashXPathSeg *s; - int fillCount, x, xEnd, ix0, ix1, t; - - fillCount = 0; - x = x0 * aaHoriz; - xEnd = (x1 + 1) * aaHoriz; - for (s = pre->next; s != post && x < xEnd; s = s->next) { - ix0 = splashFloor(s->sx0 * aaHoriz); - ix1 = splashFloor(s->sx1 * aaHoriz); - if (ix0 > ix1) { - t = ix0; ix0 = ix1; ix1 = t; - } - if (!(fillCount & eoMask)) { - if (ix0 > x) { - x = ix0; - } - } - if (ix1 >= xEnd) { - ix1 = xEnd - 1; - } - if (x / aaHoriz < *xMin) { - *xMin = x / aaHoriz; - } - if (ix1 / aaHoriz > *xMax) { - *xMax = ix1 / aaHoriz; - } - for (; x <= ix1; ++x) { - ++line[x / aaHoriz]; - } - if (s->y0 <= yTop && s->y1 > yTop) { - fillCount += s->count; - } - } -} - -void SplashXPathScanner::generatePixelsBinary(int x0, int x1, Guchar *line, - int *xMin, int *xMax) { - SplashXPathSeg *s; - int fillCount, x, xEnd, ix0, ix1, t; - - fillCount = 0; - x = x0; - xEnd = x1 + 1; - for (s = pre->next; s != post && x < xEnd; s = s->next) { - ix0 = splashFloor(s->sx0); - ix1 = splashFloor(s->sx1); - if (ix0 > ix1) { - t = ix0; ix0 = ix1; ix1 = t; - } - if (!(fillCount & eoMask)) { - if (ix0 > x) { - x = ix0; - } - } - if (ix1 >= xEnd) { - ix1 = xEnd - 1; - } - if (x < *xMin) { - *xMin = x; - } - if (ix1 > *xMax) { - *xMax = ix1; - } - for (; x <= ix1; ++x) { - line[x] = 255; - } - if (s->y0 <= yTop && s->y1 > yTop) { - fillCount += s->count; - } - } -} - -void SplashXPathScanner::drawRectangleSpan(Guchar *line, int y, - int x0, int x1, - int *xMin, int *xMax) { - SplashCoord edge; - Guchar pix; - int xe, x; - - if (rectX0I > x1 || rectX1I < x0) { - return; - } - - *xMin = x0 <= rectX0I ? rectX0I : x0; - *xMax = rectX1I <= x1 ? rectX1I : x1; - - //--- upper edge - if (y == rectY0I) { - - // handle a rectangle less than one pixel high - if (rectY0I == rectY1I) { - edge = xPath->rectY1 - xPath->rectY0; - } else { - edge = (SplashCoord)1 - (xPath->rectY0 - rectY0I); - } - - // upper left corner - if (x0 <= rectX0I) { - pix = (Guchar)splashCeil(edge - * ((SplashCoord)1 - (xPath->rectX0 - rectX0I)) - * 255); - if (pix < 16) { - pix = 16; - } - line[rectX0I] = pix; - x = rectX0I + 1; - } else { - x = x0; - } - - // upper right corner - if (rectX1I <= x1) { - pix = (Guchar)splashCeil(edge * (xPath->rectX1 - rectX1I) * 255); - if (pix < 16) { - pix = 16; - } - line[rectX1I] = pix; - xe = rectX1I - 1; - } else { - xe = x1; - } - - // upper edge - pix = (Guchar)splashCeil(edge * 255); - if (pix < 16) { - pix = 16; - } - for (; x <= xe; ++x) { - line[x] = pix; - } - - //--- lower edge - } else if (y == rectY1I) { - edge = xPath->rectY1 - rectY1I; - - // lower left corner - if (x0 <= rectX0I) { - pix = (Guchar)splashCeil(edge - * ((SplashCoord)1 - (xPath->rectX0 - rectX0I)) - * 255); - if (pix < 16) { - pix = 16; - } - line[rectX0I] = pix; - x = rectX0I + 1; - } else { - x = x0; - } - - // lower right corner - if (rectX1I <= x1) { - pix = (Guchar)splashCeil(edge * (xPath->rectX1 - rectX1I) * 255); - if (pix < 16) { - pix = 16; - } - line[rectX1I] = pix; - xe = rectX1I - 1; - } else { - xe = x1; - } - - // lower edge - pix = (Guchar)splashCeil(edge * 255); - if (pix < 16) { - pix = 16; - } - for (; x <= xe; ++x) { - line[x] = pix; - } - - //--- between the upper and lower edges - } else if (y > rectY0I && y < rectY1I) { - - // left edge - if (x0 <= rectX0I) { - pix = (Guchar)splashCeil(((SplashCoord)1 - (xPath->rectX0 - rectX0I)) - * 255); - if (pix < 16) { - pix = 16; - } - line[rectX0I] = pix; - x = rectX0I + 1; - } else { - x = x0; - } - - // right edge - if (rectX1I <= x1) { - pix = (Guchar)splashCeil((xPath->rectX1 - rectX1I) * 255); - if (pix < 16) { - pix = 16; - } - line[rectX1I] = pix; - xe = rectX1I - 1; - } else { - xe = x1; - } - - // middle - for (; x <= xe; ++x) { - line[x] = 255; - } - } -} - -void SplashXPathScanner::drawRectangleSpanBinary(Guchar *line, int y, - int x0, int x1, - int *xMin, int *xMax) { - int xe, x; - - if (y >= rectY0I && y <= rectY1I) { - if (x0 <= rectX0I) { - x = rectX0I; - } else { - x = x0; - } - *xMin = x; - if (rectX1I <= x1) { - xe = rectX1I; - } else { - xe = x1; - } - *xMax = xe; - for (; x <= xe; ++x) { - line[x] = 255; - } - } -} - -void SplashXPathScanner::getSpan(Guchar *line, int y, int x0, int x1, - int *xMin, int *xMax) { - int iy, x, k; - - iy = y * aaVert; - if (!resetDone || !resetAA) { - reset(gTrue, gTrue); - } else if (yBottomI > iy) { - reset(gTrue, gFalse); - } - memset(line + x0, 0, x1 - x0 + 1); - - *xMin = x1 + 1; - *xMax = x0 - 1; - - if (xPath->isRect) { - drawRectangleSpan(line, y, x0, x1, xMin, xMax); - return; - } - - if (yBottomI < iy) { - skip(iy, gTrue); - } - for (k = 0; k < aaVert; ++k, ++iy) { - advance(gTrue); - generatePixels(x0, x1, line, xMin, xMax); - } - -#if !ANTIALIAS_256 - for (x = *xMin; x <= *xMax; ++x) { - line[x] = map16to255[line[x]]; - } -#endif -} - -void SplashXPathScanner::getSpanBinary(Guchar *line, int y, int x0, int x1, - int *xMin, int *xMax) { - int iy; - - iy = y; - if (!resetDone || resetAA) { - reset(gFalse, gTrue); - } else if (yBottomI > iy) { - reset(gFalse, gFalse); - } - memset(line + x0, 0, x1 - x0 + 1); - - *xMin = x1 + 1; - *xMax = x0 - 1; - - if (xPath->isRect) { - drawRectangleSpanBinary(line, y, x0, x1, xMin, xMax); - return; - } - - if (yBottomI < iy) { - skip(iy, gFalse); - } - advance(gFalse); - generatePixelsBinary(x0, x1, line, xMin, xMax); -} diff --git a/Build/source/libs/xpdf/xpdf-src/splash/SplashXPathScanner.h b/Build/source/libs/xpdf/xpdf-src/splash/SplashXPathScanner.h deleted file mode 100644 index 39cc0eb022a..00000000000 --- a/Build/source/libs/xpdf/xpdf-src/splash/SplashXPathScanner.h +++ /dev/null @@ -1,84 +0,0 @@ -//======================================================================== -// -// SplashXPathScanner.h -// -// Copyright 2003-2013 Glyph & Cog, LLC -// -//======================================================================== - -#ifndef SPLASHXPATHSCANNER_H -#define SPLASHXPATHSCANNER_H - -#include <aconf.h> - -#ifdef USE_GCC_PRAGMAS -#pragma interface -#endif - -#include "SplashTypes.h" -#include "SplashXPath.h" - -class GList; - -//------------------------------------------------------------------------ - -// Set this to 0 for antialiasing with 16 levels of gray. -// Set it to 1 for (much slower) antialiasing with 256 levels of gray. -#define ANTIALIAS_256 0 - -//------------------------------------------------------------------------ -// SplashXPathScanner -//------------------------------------------------------------------------ - -class SplashXPathScanner { -public: - - // Create a new SplashXPathScanner object. <xPathA> must be sorted. - SplashXPathScanner(SplashXPath *xPathA, GBool eo, - int yMinA, int yMaxA); - - ~SplashXPathScanner(); - - // Compute shape values for a scan line. Fills in line[] with shape - // values for one scan line: ([x0, x1], y). The values are in [0, - // 255]. Also returns the min/max x positions with non-zero shape - // values. - void getSpan(Guchar *line, int y, int x0, int x1, int *xMin, int *xMax); - - // Like getSpan(), but uses the values 0 and 255 only. Writes 255 - // for all pixels which include non-zero area inside the path. - void getSpanBinary(Guchar *line, int y, int x0, int x1, - int *xMin, int *xMax); - -private: - - void insertSegmentBefore(SplashXPathSeg *s, SplashXPathSeg *sNext); - void removeSegment(SplashXPathSeg *s); - void moveSegmentAfter(SplashXPathSeg *s, SplashXPathSeg *sPrev); - void reset(GBool aa, GBool aaChanged); - void skip(int newYBottomI, GBool aa); - void advance(GBool aa); - void generatePixels(int x0, int x1, Guchar *line, int *xMin, int *xMax); - void generatePixelsBinary(int x0, int x1, Guchar *line, - int *xMin, int *xMax); - void drawRectangleSpan(Guchar *line, int y, int x0, int x1, - int *xMin, int *xMax); - void drawRectangleSpanBinary(Guchar *line, int y, int x0, int x1, - int *xMin, int *xMax); - - SplashXPath *xPath; - int eoMask; - int yMin, yMax; - int rectX0I, rectY0I, rectX1I, rectY1I; - - SplashXPathSeg preSeg, postSeg; - SplashXPathSeg *pre, *post; - - GBool resetDone; - GBool resetAA; - int nextSeg; - int yTopI, yBottomI; - SplashCoord yTop, yBottom; -}; - -#endif |