summaryrefslogtreecommitdiff
path: root/Build/source/libs/xpdf/xpdf-src/splash
diff options
context:
space:
mode:
authorAkira Kakuto <kakuto@fuk.kindai.ac.jp>2019-09-29 10:00:12 +0000
committerAkira Kakuto <kakuto@fuk.kindai.ac.jp>2019-09-29 10:00:12 +0000
commit268dff1b06a01bd6be5f1ae08216c0beff08336c (patch)
treec8f90365823a9711e674704157dff65babb709b9 /Build/source/libs/xpdf/xpdf-src/splash
parentee6ffc65c0eb84ded1fc7d19eeb90a87541f896d (diff)
xpdf 4.02
git-svn-id: svn://tug.org/texlive/trunk@52203 c570f23f-e606-0410-a88d-b1316a301751
Diffstat (limited to 'Build/source/libs/xpdf/xpdf-src/splash')
-rw-r--r--Build/source/libs/xpdf/xpdf-src/splash/Splash.cc777
-rw-r--r--Build/source/libs/xpdf/xpdf-src/splash/Splash.h64
-rw-r--r--Build/source/libs/xpdf/xpdf-src/splash/SplashBitmap.cc51
-rw-r--r--Build/source/libs/xpdf/xpdf-src/splash/SplashBitmap.h10
-rw-r--r--Build/source/libs/xpdf/xpdf-src/splash/SplashFontEngine.cc16
-rw-r--r--Build/source/libs/xpdf/xpdf-src/splash/SplashFontEngine.h4
-rw-r--r--Build/source/libs/xpdf/xpdf-src/splash/SplashMath.h61
-rw-r--r--Build/source/libs/xpdf/xpdf-src/splash/SplashXPath.cc4
8 files changed, 862 insertions, 125 deletions
diff --git a/Build/source/libs/xpdf/xpdf-src/splash/Splash.cc b/Build/source/libs/xpdf/xpdf-src/splash/Splash.cc
index 77718abbe70..44f87a9dcd2 100644
--- a/Build/source/libs/xpdf/xpdf-src/splash/Splash.cc
+++ b/Build/source/libs/xpdf/xpdf-src/splash/Splash.cc
@@ -18,6 +18,7 @@
#include <math.h>
#include "gmem.h"
#include "gmempp.h"
+#include "GString.h"
#include "SplashErrorCodes.h"
#include "SplashMath.h"
#include "SplashBitmap.h"
@@ -257,6 +258,22 @@ inline void Splash::pipeInit(SplashPipe *pipe, SplashPattern *pattern,
pipe->run = &Splash::pipeRunAACMYK8;
#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
+ }
}
}
@@ -276,6 +293,7 @@ void Splash::pipeRun(SplashPipe *pipe, int x0, int x1, int y,
Guchar *alpha0Ptr;
SplashColorPtr softMaskPtr;
#if SPLASH_CMYK
+ Guchar aPrev;
SplashColor cSrc2, cDest2;
#endif
@@ -514,25 +532,38 @@ void Splash::pipeRun(SplashPipe *pipe, int x0, int x1, int y,
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 (state->overprintMask & 0x01) {
cSrc[0] = state->cmykTransferC[cSrcPtr[0]];
} else {
- cSrc[0] = div255(aDest * cDest[0]);
+ cSrc[0] = div255(aPrev * cDest[0]);
}
if (state->overprintMask & 0x02) {
cSrc[1] = state->cmykTransferM[cSrcPtr[1]];
} else {
- cSrc[1] = div255(aDest * cDest[1]);
+ cSrc[1] = div255(aPrev * cDest[1]);
}
if (state->overprintMask & 0x04) {
cSrc[2] = state->cmykTransferY[cSrcPtr[2]];
} else {
- cSrc[2] = div255(aDest * cDest[2]);
+ cSrc[2] = div255(aPrev * cDest[2]);
}
if (state->overprintMask & 0x08) {
cSrc[3] = state->cmykTransferK[cSrcPtr[3]];
} else {
- cSrc[3] = div255(aDest * cDest[3]);
+ cSrc[3] = div255(aPrev * cDest[3]);
}
break;
#endif
@@ -1986,6 +2017,398 @@ void Splash::pipeRunAACMYK8(SplashPipe *pipe, int x0, int x1, int y,
#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;
+
+ 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;
+
+ 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;
+
+ 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;
+
+ 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
+
+
//------------------------------------------------------------------------
// Transform a point from user space to device space.
@@ -2000,10 +2423,41 @@ inline void Splash::transform(SplashCoord *matrix,
}
//------------------------------------------------------------------------
+// SplashImageCache
+//------------------------------------------------------------------------
+
+SplashImageCache::SplashImageCache() {
+ tag = NULL;
+ image = NULL;
+ refCount = 1;
+}
+
+SplashImageCache::~SplashImageCache() {
+ if (tag) {
+ delete tag;
+ }
+ if (image) {
+ delete image;
+ }
+}
+
+void SplashImageCache::incRefCount() {
+ ++refCount;
+}
+
+void SplashImageCache::decRefCount() {
+ --refCount;
+ if (refCount == 0) {
+ delete this;
+ }
+}
+
+//------------------------------------------------------------------------
// Splash
//------------------------------------------------------------------------
Splash::Splash(SplashBitmap *bitmapA, GBool vectorAntialiasA,
+ SplashImageCache *imageCacheA,
SplashScreenParams *screenParams) {
bitmap = bitmapA;
bitmapComps = splashColorModeNComps[bitmap->mode];
@@ -2021,10 +2475,17 @@ Splash::Splash(SplashBitmap *bitmapA, GBool vectorAntialiasA,
minLineWidth = 0;
clearModRegion();
debugMode = gFalse;
+
+ if (imageCacheA) {
+ imageCache = imageCacheA;
+ imageCache->incRefCount();
+ } else {
+ imageCache = new SplashImageCache();
+ }
}
Splash::Splash(SplashBitmap *bitmapA, GBool vectorAntialiasA,
- SplashScreen *screenA) {
+ SplashImageCache *imageCacheA, SplashScreen *screenA) {
bitmap = bitmapA;
bitmapComps = splashColorModeNComps[bitmap->mode];
vectorAntialias = vectorAntialiasA;
@@ -2041,9 +2502,18 @@ Splash::Splash(SplashBitmap *bitmapA, GBool vectorAntialiasA,
minLineWidth = 0;
clearModRegion();
debugMode = gFalse;
+
+ if (imageCacheA) {
+ imageCache = imageCacheA;
+ imageCache->incRefCount();
+ } else {
+ imageCache = new SplashImageCache();
+ }
}
Splash::~Splash() {
+ imageCache->decRefCount();
+
while (state->next) {
restoreState();
}
@@ -3335,6 +3805,30 @@ SplashError Splash::fillGlyph2(int x0, int y0, SplashGlyphBitmap *glyph) {
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) {
@@ -3347,7 +3841,8 @@ void Splash::getImageBounds(SplashCoord xyMin, SplashCoord xyMax,
// The glyphMode flag is not currently used, but may be useful if the
// stroke adjustment behavior is changed.
-SplashError Splash::fillImageMask(SplashImageMaskSource src, void *srcData,
+SplashError Splash::fillImageMask(GString *imageTag,
+ SplashImageMaskSource src, void *srcData,
int w, int h, SplashCoord *mat,
GBool glyphMode, GBool interpolate) {
SplashBitmap *scaledMask;
@@ -3401,10 +3896,17 @@ SplashError Splash::fillImageMask(SplashImageMaskSource src, void *srcData,
if (clipRes != splashClipAllOutside) {
scaledWidth = x1 - x0;
scaledHeight = y1 - y0;
- scaledMask = scaleMask(src, srcData, w, h, scaledWidth, scaledHeight,
- interpolate);
+ scaledMask = scaleMask(imageTag, src, srcData, w, h,
+ scaledWidth, scaledHeight, interpolate);
+ if (imageCache->vertFlip) {
+ vertFlipImage(scaledMask, scaledWidth, scaledHeight, 1);
+ imageCache->vertFlip = gFalse;
+ }
+ if (imageCache->horizFlip) {
+ horizFlipImage(scaledMask, scaledWidth, scaledHeight, 1);
+ imageCache->horizFlip = gFalse;
+ }
blitMask(scaledMask, x0, y0, clipRes);
- delete scaledMask;
}
// scaling plus vertical flip
@@ -3417,11 +3919,17 @@ SplashError Splash::fillImageMask(SplashImageMaskSource src, void *srcData,
if (clipRes != splashClipAllOutside) {
scaledWidth = x1 - x0;
scaledHeight = y1 - y0;
- scaledMask = scaleMask(src, srcData, w, h, scaledWidth, scaledHeight,
- interpolate);
- vertFlipImage(scaledMask, scaledWidth, scaledHeight, 1);
+ scaledMask = scaleMask(imageTag, src, srcData, w, h,
+ scaledWidth, scaledHeight, interpolate);
+ if (!imageCache->vertFlip) {
+ vertFlipImage(scaledMask, scaledWidth, scaledHeight, 1);
+ imageCache->vertFlip = gTrue;
+ }
+ if (imageCache->horizFlip) {
+ horizFlipImage(scaledMask, scaledWidth, scaledHeight, 1);
+ imageCache->horizFlip = gFalse;
+ }
blitMask(scaledMask, x0, y0, clipRes);
- delete scaledMask;
}
// scaling plus horizontal flip
@@ -3434,11 +3942,17 @@ SplashError Splash::fillImageMask(SplashImageMaskSource src, void *srcData,
if (clipRes != splashClipAllOutside) {
scaledWidth = x1 - x0;
scaledHeight = y1 - y0;
- scaledMask = scaleMask(src, srcData, w, h, scaledWidth, scaledHeight,
- interpolate);
- horizFlipImage(scaledMask, scaledWidth, scaledHeight, 1);
+ scaledMask = scaleMask(imageTag, src, srcData, w, h,
+ scaledWidth, scaledHeight, interpolate);
+ if (imageCache->vertFlip) {
+ vertFlipImage(scaledMask, scaledWidth, scaledHeight, 1);
+ imageCache->vertFlip = gFalse;
+ }
+ if (!imageCache->horizFlip) {
+ horizFlipImage(scaledMask, scaledWidth, scaledHeight, 1);
+ imageCache->horizFlip = gTrue;
+ }
blitMask(scaledMask, x0, y0, clipRes);
- delete scaledMask;
}
// scaling plus horizontal and vertical flips
@@ -3451,17 +3965,23 @@ SplashError Splash::fillImageMask(SplashImageMaskSource src, void *srcData,
if (clipRes != splashClipAllOutside) {
scaledWidth = x1 - x0;
scaledHeight = y1 - y0;
- scaledMask = scaleMask(src, srcData, w, h, scaledWidth, scaledHeight,
- interpolate);
- vertFlipImage(scaledMask, scaledWidth, scaledHeight, 1);
- horizFlipImage(scaledMask, scaledWidth, scaledHeight, 1);
+ scaledMask = scaleMask(imageTag, src, srcData, w, h,
+ scaledWidth, scaledHeight, interpolate);
+ if (!imageCache->vertFlip) {
+ vertFlipImage(scaledMask, scaledWidth, scaledHeight, 1);
+ imageCache->vertFlip = gTrue;
+ }
+ if (!imageCache->horizFlip) {
+ horizFlipImage(scaledMask, scaledWidth, scaledHeight, 1);
+ imageCache->horizFlip = gTrue;
+ }
blitMask(scaledMask, x0, y0, clipRes);
- delete scaledMask;
}
// all other cases
} else {
- arbitraryTransformMask(src, srcData, w, h, mat, glyphMode, interpolate);
+ arbitraryTransformMask(imageTag, src, srcData, w, h,
+ mat, glyphMode, interpolate);
}
return splashOk;
@@ -3634,7 +4154,8 @@ void Splash::upscaleMask(SplashImageMaskSource src, void *srcData,
// The glyphMode flag is not currently used, but may be useful if the
// stroke adjustment behavior is changed.
-void Splash::arbitraryTransformMask(SplashImageMaskSource src, void *srcData,
+void Splash::arbitraryTransformMask(GString *imageTag,
+ SplashImageMaskSource src, void *srcData,
int srcWidth, int srcHeight,
SplashCoord *mat, GBool glyphMode,
GBool interpolate) {
@@ -3727,8 +4248,16 @@ void Splash::arbitraryTransformMask(SplashImageMaskSource src, void *srcData,
ir11 = r00 / det;
// scale the input image
- scaledMask = scaleMask(src, srcData, srcWidth, srcHeight,
+ scaledMask = scaleMask(imageTag, src, srcData, srcWidth, srcHeight,
scaledWidth, scaledHeight, interpolate);
+ if (imageCache->vertFlip) {
+ vertFlipImage(scaledMask, scaledWidth, scaledHeight, 1);
+ imageCache->vertFlip = gFalse;
+ }
+ if (imageCache->horizFlip) {
+ horizFlipImage(scaledMask, scaledWidth, scaledHeight, 1);
+ imageCache->horizFlip = gFalse;
+ }
// construct the three sections
i = 0;
@@ -3901,42 +4430,61 @@ void Splash::arbitraryTransformMask(SplashImageMaskSource src, void *srcData,
(this->*pipe.run)(&pipe, xa, xb - 1, y, scanBuf + xa, NULL);
}
}
-
- delete scaledMask;
}
// Scale an image mask into a SplashBitmap.
-SplashBitmap *Splash::scaleMask(SplashImageMaskSource src, void *srcData,
+SplashBitmap *Splash::scaleMask(GString *imageTag,
+ SplashImageMaskSource src, void *srcData,
int srcWidth, int srcHeight,
int scaledWidth, int scaledHeight,
GBool interpolate) {
- SplashBitmap *dest;
-
- dest = new SplashBitmap(scaledWidth, scaledHeight, 1, splashModeMono8,
- gFalse);
+ if (imageCache->tag && imageTag &&
+ !imageCache->tag->cmp(imageTag) &&
+ imageCache->isMask &&
+ imageCache->width == scaledWidth &&
+ imageCache->height == scaledHeight &&
+ imageCache->interpolate == interpolate) {
+ return imageCache->image;
+ }
+ if (imageCache->tag) {
+ delete imageCache->tag;
+ }
+ if (imageCache->image) {
+ delete imageCache->image;
+ }
+ imageCache->tag = imageTag ? imageTag->copy() : (GString *)NULL;
+ imageCache->isMask = gTrue;
+ imageCache->width = scaledWidth;
+ imageCache->height = scaledHeight;
+ imageCache->interpolate = interpolate;
+ imageCache->vertFlip = gFalse;
+ imageCache->horizFlip = gFalse;
+ imageCache->image = new SplashBitmap(scaledWidth, scaledHeight,
+ 1, splashModeMono8, gFalse,
+ gTrue, NULL);
if (scaledHeight < srcHeight) {
if (scaledWidth < srcWidth) {
scaleMaskYdXd(src, srcData, srcWidth, srcHeight,
- scaledWidth, scaledHeight, dest);
+ scaledWidth, scaledHeight, imageCache->image);
} else {
scaleMaskYdXu(src, srcData, srcWidth, srcHeight,
- scaledWidth, scaledHeight, dest);
+ scaledWidth, scaledHeight, imageCache->image);
}
} else {
if (scaledWidth < srcWidth) {
scaleMaskYuXd(src, srcData, srcWidth, srcHeight,
- scaledWidth, scaledHeight, dest);
+ scaledWidth, scaledHeight, imageCache->image);
} else {
if (interpolate) {
scaleMaskYuXuI(src, srcData, srcWidth, srcHeight,
- scaledWidth, scaledHeight, dest);
+ scaledWidth, scaledHeight, imageCache->image);
} else {
scaleMaskYuXu(src, srcData, srcWidth, srcHeight,
- scaledWidth, scaledHeight, dest);
+ scaledWidth, scaledHeight, imageCache->image);
}
}
}
- return dest;
+ return imageCache->image;
}
void Splash::scaleMaskYdXd(SplashImageMaskSource src, void *srcData,
@@ -4009,7 +4557,7 @@ void Splash::scaleMaskYdXd(SplashImageMaskSource src, void *srcData,
pix += pixBuf[xx++];
}
// (255 * pix) / xStep * yStep
- pix = (pix * d) >> 23;
+ pix = (pix * d + (1 << 22)) >> 23;
// store the pixel
*destPtr++ = (Guchar)pix;
@@ -4083,7 +4631,7 @@ void Splash::scaleMaskYdXu(SplashImageMaskSource src, void *srcData,
// compute the final pixel
pix = pixBuf[x];
// (255 * pix) / yStep
- pix = (pix * d) >> 23;
+ pix = (pix * d + (1 << 22)) >> 23;
// store the pixel
for (i = 0; i < xStep; ++i) {
@@ -4158,7 +4706,7 @@ void Splash::scaleMaskYuXd(SplashImageMaskSource src, void *srcData,
pix += lineBuf[xx++];
}
// (255 * pix) / xStep
- pix = (pix * d) >> 23;
+ pix = (pix * d + (1 << 22)) >> 23;
// store the pixel
for (i = 0; i < yStep; ++i) {
@@ -4403,7 +4951,8 @@ void Splash::blitMask(SplashBitmap *src, int xDest, int yDest,
}
}
-SplashError Splash::drawImage(SplashImageSource src, void *srcData,
+SplashError Splash::drawImage(GString *imageTag,
+ SplashImageSource src, void *srcData,
SplashColorMode srcMode, GBool srcAlpha,
int w, int h, SplashCoord *mat,
GBool interpolate) {
@@ -4489,10 +5038,18 @@ SplashError Splash::drawImage(SplashImageSource src, void *srcData,
if (clipRes != splashClipAllOutside) {
scaledWidth = x1 - x0;
scaledHeight = y1 - y0;
- scaledImg = scaleImage(src, srcData, srcMode, nComps, srcAlpha, w, h,
+ scaledImg = scaleImage(imageTag,
+ src, srcData, srcMode, nComps, srcAlpha, w, h,
scaledWidth, scaledHeight, interpolate);
+ if (imageCache->vertFlip) {
+ vertFlipImage(scaledImg, scaledWidth, scaledHeight, nComps);
+ imageCache->vertFlip = gFalse;
+ }
+ if (imageCache->horizFlip) {
+ horizFlipImage(scaledImg, scaledWidth, scaledHeight, nComps);
+ imageCache->horizFlip = gFalse;
+ }
blitImage(scaledImg, srcAlpha, x0, y0, clipRes);
- delete scaledImg;
}
// scaling plus vertical flip
@@ -4505,11 +5062,18 @@ SplashError Splash::drawImage(SplashImageSource src, void *srcData,
if (clipRes != splashClipAllOutside) {
scaledWidth = x1 - x0;
scaledHeight = y1 - y0;
- scaledImg = scaleImage(src, srcData, srcMode, nComps, srcAlpha, w, h,
+ scaledImg = scaleImage(imageTag,
+ src, srcData, srcMode, nComps, srcAlpha, w, h,
scaledWidth, scaledHeight, interpolate);
- vertFlipImage(scaledImg, scaledWidth, scaledHeight, nComps);
+ if (!imageCache->vertFlip) {
+ vertFlipImage(scaledImg, scaledWidth, scaledHeight, nComps);
+ imageCache->vertFlip = gTrue;
+ }
+ if (imageCache->horizFlip) {
+ horizFlipImage(scaledImg, scaledWidth, scaledHeight, nComps);
+ imageCache->horizFlip = gFalse;
+ }
blitImage(scaledImg, srcAlpha, x0, y0, clipRes);
- delete scaledImg;
}
// scaling plus horizontal flip
@@ -4522,11 +5086,18 @@ SplashError Splash::drawImage(SplashImageSource src, void *srcData,
if (clipRes != splashClipAllOutside) {
scaledWidth = x1 - x0;
scaledHeight = y1 - y0;
- scaledImg = scaleImage(src, srcData, srcMode, nComps, srcAlpha, w, h,
+ scaledImg = scaleImage(imageTag,
+ src, srcData, srcMode, nComps, srcAlpha, w, h,
scaledWidth, scaledHeight, interpolate);
- horizFlipImage(scaledImg, scaledWidth, scaledHeight, nComps);
+ if (imageCache->vertFlip) {
+ vertFlipImage(scaledImg, scaledWidth, scaledHeight, nComps);
+ imageCache->vertFlip = gFalse;
+ }
+ if (!imageCache->horizFlip) {
+ horizFlipImage(scaledImg, scaledWidth, scaledHeight, nComps);
+ imageCache->horizFlip = gTrue;
+ }
blitImage(scaledImg, srcAlpha, x0, y0, clipRes);
- delete scaledImg;
}
// scaling plus horizontal and vertical flips
@@ -4539,17 +5110,23 @@ SplashError Splash::drawImage(SplashImageSource src, void *srcData,
if (clipRes != splashClipAllOutside) {
scaledWidth = x1 - x0;
scaledHeight = y1 - y0;
- scaledImg = scaleImage(src, srcData, srcMode, nComps, srcAlpha, w, h,
+ scaledImg = scaleImage(imageTag,
+ src, srcData, srcMode, nComps, srcAlpha, w, h,
scaledWidth, scaledHeight, interpolate);
- vertFlipImage(scaledImg, scaledWidth, scaledHeight, nComps);
- horizFlipImage(scaledImg, scaledWidth, scaledHeight, nComps);
+ if (!imageCache->vertFlip) {
+ vertFlipImage(scaledImg, scaledWidth, scaledHeight, nComps);
+ imageCache->vertFlip = gTrue;
+ }
+ if (!imageCache->horizFlip) {
+ horizFlipImage(scaledImg, scaledWidth, scaledHeight, nComps);
+ imageCache->horizFlip = gTrue;
+ }
blitImage(scaledImg, srcAlpha, x0, y0, clipRes);
- delete scaledImg;
}
// all other cases
} else {
- arbitraryTransformImage(src, srcData, srcMode, nComps, srcAlpha,
+ arbitraryTransformImage(imageTag, src, srcData, srcMode, nComps, srcAlpha,
w, h, mat, interpolate);
}
@@ -4765,7 +5342,8 @@ void Splash::upscaleImage(SplashImageSource src, void *srcData,
gfree(unscaledAlpha);
}
-void Splash::arbitraryTransformImage(SplashImageSource src, void *srcData,
+void Splash::arbitraryTransformImage(GString *imageTag,
+ SplashImageSource src, void *srcData,
SplashColorMode srcMode, int nComps,
GBool srcAlpha,
int srcWidth, int srcHeight,
@@ -4860,9 +5438,17 @@ void Splash::arbitraryTransformImage(SplashImageSource src, void *srcData,
ir11 = r00 / det;
// scale the input image
- scaledImg = scaleImage(src, srcData, srcMode, nComps, srcAlpha,
+ scaledImg = scaleImage(imageTag, src, srcData, srcMode, nComps, srcAlpha,
srcWidth, srcHeight, scaledWidth, scaledHeight,
interpolate);
+ if (imageCache->vertFlip) {
+ vertFlipImage(scaledImg, scaledWidth, scaledHeight, nComps);
+ imageCache->vertFlip = gFalse;
+ }
+ if (imageCache->horizFlip) {
+ horizFlipImage(scaledImg, scaledWidth, scaledHeight, nComps);
+ imageCache->horizFlip = gFalse;
+ }
// construct the three sections
i = 0;
@@ -5045,41 +5631,70 @@ void Splash::arbitraryTransformImage(SplashImageSource src, void *srcData,
}
gfree(pixelBuf);
- delete scaledImg;
}
// Scale an image into a SplashBitmap.
-SplashBitmap *Splash::scaleImage(SplashImageSource src, void *srcData,
+SplashBitmap *Splash::scaleImage(GString *imageTag,
+ SplashImageSource src, void *srcData,
SplashColorMode srcMode, int nComps,
GBool srcAlpha, int srcWidth, int srcHeight,
int scaledWidth, int scaledHeight,
GBool interpolate) {
- SplashBitmap *dest;
-
- dest = new SplashBitmap(scaledWidth, scaledHeight, 1, srcMode, srcAlpha);
+ if (imageCache->tag && imageTag &&
+ !imageCache->tag->cmp(imageTag) &&
+ !imageCache->isMask &&
+ imageCache->width == scaledWidth &&
+ imageCache->height == scaledHeight &&
+ imageCache->mode == srcMode &&
+ imageCache->alpha == srcAlpha &&
+ imageCache->interpolate == interpolate) {
+ return imageCache->image;
+ }
+ if (imageCache->tag) {
+ delete imageCache->tag;
+ }
+ if (imageCache->image) {
+ delete imageCache->image;
+ }
+ imageCache->tag = imageTag ? imageTag->copy() : (GString *)NULL;
+ imageCache->isMask = gFalse;
+ imageCache->width = scaledWidth;
+ imageCache->height = scaledHeight;
+ imageCache->mode = srcMode;
+ imageCache->alpha = srcAlpha;
+ imageCache->interpolate = interpolate;
+ imageCache->vertFlip = gFalse;
+ imageCache->horizFlip = gFalse;
+ imageCache->image = new SplashBitmap(scaledWidth, scaledHeight, 1,
+ srcMode, srcAlpha, gTrue, NULL);
if (scaledHeight < srcHeight) {
if (scaledWidth < srcWidth) {
scaleImageYdXd(src, srcData, srcMode, nComps, srcAlpha,
- srcWidth, srcHeight, scaledWidth, scaledHeight, dest);
+ srcWidth, srcHeight, scaledWidth, scaledHeight,
+ imageCache->image);
} else {
scaleImageYdXu(src, srcData, srcMode, nComps, srcAlpha,
- srcWidth, srcHeight, scaledWidth, scaledHeight, dest);
+ srcWidth, srcHeight, scaledWidth, scaledHeight,
+ imageCache->image);
}
} else {
if (scaledWidth < srcWidth) {
scaleImageYuXd(src, srcData, srcMode, nComps, srcAlpha,
- srcWidth, srcHeight, scaledWidth, scaledHeight, dest);
+ srcWidth, srcHeight, scaledWidth, scaledHeight,
+ imageCache->image);
} else {
if (interpolate) {
scaleImageYuXuI(src, srcData, srcMode, nComps, srcAlpha,
- srcWidth, srcHeight, scaledWidth, scaledHeight, dest);
+ srcWidth, srcHeight, scaledWidth, scaledHeight,
+ imageCache->image);
} else {
scaleImageYuXu(src, srcData, srcMode, nComps, srcAlpha,
- srcWidth, srcHeight, scaledWidth, scaledHeight, dest);
+ srcWidth, srcHeight, scaledWidth, scaledHeight,
+ imageCache->image);
}
}
}
- return dest;
+ return imageCache->image;
}
void Splash::scaleImageYdXd(SplashImageSource src, void *srcData,
@@ -5177,7 +5792,7 @@ void Splash::scaleImageYdXd(SplashImageSource src, void *srcData,
pix0 += pixBuf[xx++];
}
// pix / xStep * yStep
- pix0 = (pix0 * d) >> 23;
+ pix0 = (pix0 * d + (1 << 22)) >> 23;
// store the pixel
*destPtr++ = (Guchar)pix0;
@@ -5194,9 +5809,9 @@ void Splash::scaleImageYdXd(SplashImageSource src, void *srcData,
xx += 3;
}
// pix / xStep * yStep
- pix0 = (pix0 * d) >> 23;
- pix1 = (pix1 * d) >> 23;
- pix2 = (pix2 * d) >> 23;
+ pix0 = (pix0 * d + (1 << 22)) >> 23;
+ pix1 = (pix1 * d + (1 << 22)) >> 23;
+ pix2 = (pix2 * d + (1 << 22)) >> 23;
// store the pixel
*destPtr++ = (Guchar)pix0;
@@ -5217,10 +5832,10 @@ void Splash::scaleImageYdXd(SplashImageSource src, void *srcData,
xx += 4;
}
// pix / xStep * yStep
- pix0 = (pix0 * d) >> 23;
- pix1 = (pix1 * d) >> 23;
- pix2 = (pix2 * d) >> 23;
- pix3 = (pix3 * d) >> 23;
+ pix0 = (pix0 * d + (1 << 22)) >> 23;
+ pix1 = (pix1 * d + (1 << 22)) >> 23;
+ pix2 = (pix2 * d + (1 << 22)) >> 23;
+ pix3 = (pix3 * d + (1 << 22)) >> 23;
// store the pixel
*destPtr++ = (Guchar)pix0;
@@ -5244,7 +5859,7 @@ void Splash::scaleImageYdXd(SplashImageSource src, void *srcData,
alpha += alphaPixBuf[xxa];
}
// alpha / xStep * yStep
- alpha = (alpha * d) >> 23;
+ alpha = (alpha * d + (1 << 22)) >> 23;
*destAlphaPtr++ = (Guchar)alpha;
}
}
@@ -5343,7 +5958,7 @@ void Splash::scaleImageYdXu(SplashImageSource src, void *srcData,
// compute the final pixel
for (i = 0; i < nComps; ++i) {
// pixBuf[] / yStep
- pix[i] = (pixBuf[x * nComps + i] * d) >> 23;
+ pix[i] = (pixBuf[x * nComps + i] * d + (1 << 22)) >> 23;
}
// store the pixel
@@ -5379,7 +5994,7 @@ void Splash::scaleImageYdXu(SplashImageSource src, void *srcData,
// process alpha
if (srcAlpha) {
// alphaPixBuf[] / yStep
- alpha = (alphaPixBuf[x] * d) >> 23;
+ alpha = (alphaPixBuf[x] * d + (1 << 22)) >> 23;
for (i = 0; i < xStep; ++i) {
*destAlphaPtr++ = (Guchar)alpha;
}
@@ -5474,7 +6089,7 @@ void Splash::scaleImageYuXd(SplashImageSource src, void *srcData,
}
for (i = 0; i < nComps; ++i) {
// pix[] / xStep
- pix[i] = (pix[i] * d) >> 23;
+ pix[i] = (pix[i] * d + (1 << 22)) >> 23;
}
// store the pixel
@@ -5517,7 +6132,7 @@ void Splash::scaleImageYuXd(SplashImageSource src, void *srcData,
alpha += alphaLineBuf[xxa];
}
// alpha / xStep
- alpha = (alpha * d) >> 23;
+ alpha = (alpha * d + (1 << 22)) >> 23;
for (i = 0; i < yStep; ++i) {
destAlphaPtr = destAlphaPtr0 + i * scaledWidth + x;
*destAlphaPtr = (Guchar)alpha;
diff --git a/Build/source/libs/xpdf/xpdf-src/splash/Splash.h b/Build/source/libs/xpdf/xpdf-src/splash/Splash.h
index 423ed360573..f35aa7eafd9 100644
--- a/Build/source/libs/xpdf/xpdf-src/splash/Splash.h
+++ b/Build/source/libs/xpdf/xpdf-src/splash/Splash.h
@@ -18,6 +18,7 @@
#include "SplashTypes.h"
#include "SplashClip.h"
+class GString;
class Splash;
class SplashBitmap;
struct SplashGlyphBitmap;
@@ -65,6 +66,34 @@ enum SplashPipeResultColorCtrl {
};
//------------------------------------------------------------------------
+// SplashImageCache
+//------------------------------------------------------------------------
+
+// This holds a cached image, and is shared by multiple Splash objects
+// in the same thread.
+class SplashImageCache {
+public:
+
+ SplashImageCache();
+ ~SplashImageCache();
+ void incRefCount();
+ void decRefCount();
+
+ GString *tag;
+ GBool isMask;
+ int width;
+ int height;
+ SplashColorMode mode;
+ GBool alpha;
+ GBool interpolate;
+ GBool vertFlip;
+ GBool horizFlip;
+ SplashBitmap *image;
+
+ int refCount;
+};
+
+//------------------------------------------------------------------------
// Splash
//------------------------------------------------------------------------
@@ -73,9 +102,10 @@ public:
// Create a new rasterizer object.
Splash(SplashBitmap *bitmapA, GBool vectorAntialiasA,
+ SplashImageCache *imageCacheA,
SplashScreenParams *screenParams = NULL);
Splash(SplashBitmap *bitmapA, GBool vectorAntialiasA,
- SplashScreen *screenA);
+ SplashImageCache *imageCacheA, SplashScreen *screenA);
~Splash();
@@ -173,7 +203,8 @@ public:
// 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(SplashImageMaskSource src, void *srcData,
+ SplashError fillImageMask(GString *imageTag,
+ SplashImageMaskSource src, void *srcData,
int w, int h, SplashCoord *mat,
GBool glyphMode, GBool interpolate);
@@ -191,7 +222,8 @@ public:
// BGR8 RGB8
// CMYK8 CMYK8
// The matrix behaves as for fillImageMask.
- SplashError drawImage(SplashImageSource src, void *srcData,
+ SplashError drawImage(GString *imageTag,
+ SplashImageSource src, void *srcData,
SplashColorMode srcMode, GBool srcAlpha,
int w, int h, SplashCoord *mat,
GBool interpolate);
@@ -255,6 +287,8 @@ public:
// 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
@@ -303,6 +337,16 @@ private:
void pipeRunAACMYK8(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 transform(SplashCoord *matrix, SplashCoord xi, SplashCoord yi,
SplashCoord *xo, SplashCoord *yo);
void updateModX(int x);
@@ -331,11 +375,13 @@ private:
int srcWidth, int srcHeight,
SplashCoord *mat, GBool glyphMode,
GBool interpolate);
- void arbitraryTransformMask(SplashImageMaskSource src, void *srcData,
+ void arbitraryTransformMask(GString *imageTag,
+ SplashImageMaskSource src, void *srcData,
int srcWidth, int srcHeight,
SplashCoord *mat, GBool glyphMode,
GBool interpolate);
- SplashBitmap *scaleMask(SplashImageMaskSource src, void *srcData,
+ SplashBitmap *scaleMask(GString *imageTag,
+ SplashImageMaskSource src, void *srcData,
int srcWidth, int srcHeight,
int scaledWidth, int scaledHeight,
GBool interpolate);
@@ -365,12 +411,14 @@ private:
SplashColorMode srcMode, int nComps,
GBool srcAlpha, int srcWidth, int srcHeight,
SplashCoord *mat, GBool interpolate);
- void arbitraryTransformImage(SplashImageSource src, void *srcData,
+ void arbitraryTransformImage(GString *imageTag,
+ SplashImageSource src, void *srcData,
SplashColorMode srcMode, int nComps,
GBool srcAlpha,
int srcWidth, int srcHeight,
SplashCoord *mat, GBool interpolate);
- SplashBitmap *scaleImage(SplashImageSource src, void *srcData,
+ SplashBitmap *scaleImage(GString *imageTag,
+ SplashImageSource src, void *srcData,
SplashColorMode srcMode, int nComps,
GBool srcAlpha, int srcWidth, int srcHeight,
int scaledWidth, int scaledHeight,
@@ -432,6 +480,8 @@ private:
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
index aa916179df3..88ce49ca3b4 100644
--- a/Build/source/libs/xpdf/xpdf-src/splash/SplashBitmap.cc
+++ b/Build/source/libs/xpdf/xpdf-src/splash/SplashBitmap.cc
@@ -25,7 +25,7 @@
SplashBitmap::SplashBitmap(int widthA, int heightA, int rowPad,
SplashColorMode modeA, GBool alphaA,
- GBool topDown) {
+ 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
@@ -63,14 +63,35 @@ SplashBitmap::SplashBitmap(int widthA, int heightA, int rowPad,
}
rowSize += rowPad - 1;
rowSize -= rowSize % rowPad;
- data = (SplashColorPtr)gmallocn64(height, rowSize);
+
+ 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;
+ } else {
+ data = (SplashColorPtr)gmallocn64(height, rowSize);
+ }
if (!topDown) {
data += (height - 1) * rowSize;
rowSize = -rowSize;
}
if (alphaA) {
alphaRowSize = width;
- alpha = (Guchar *)gmallocn64(height, alphaRowSize);
+ 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;
@@ -78,14 +99,24 @@ SplashBitmap::SplashBitmap(int widthA, int heightA, int rowPad,
}
SplashBitmap::~SplashBitmap() {
- if (data) {
- if (rowSize < 0) {
- gfree(data + (height - 1) * rowSize);
- } else {
- gfree(data);
- }
+ if (data && rowSize < 0) {
+ rowSize = -rowSize;
+ data -= (height - 1) * rowSize;
+ }
+ if (parent && rowSize > 10000000 / 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(alpha);
+ gfree(oldData);
+ gfree(oldAlpha);
}
SplashError SplashBitmap::writePNMFile(char *fileName) {
diff --git a/Build/source/libs/xpdf/xpdf-src/splash/SplashBitmap.h b/Build/source/libs/xpdf/xpdf-src/splash/SplashBitmap.h
index d03f44c0884..44980833668 100644
--- a/Build/source/libs/xpdf/xpdf-src/splash/SplashBitmap.h
+++ b/Build/source/libs/xpdf/xpdf-src/splash/SplashBitmap.h
@@ -44,7 +44,7 @@ public:
// upside-down, i.e., with the last row first in memory.
SplashBitmap(int widthA, int heightA, int rowPad,
SplashColorMode modeA, GBool alphaA,
- GBool topDown = gTrue);
+ GBool topDown, SplashBitmap *parentA);
~SplashBitmap();
@@ -79,6 +79,14 @@ private:
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;
};
diff --git a/Build/source/libs/xpdf/xpdf-src/splash/SplashFontEngine.cc b/Build/source/libs/xpdf/xpdf-src/splash/SplashFontEngine.cc
index 2d0542d152b..fe377fe25f4 100644
--- a/Build/source/libs/xpdf/xpdf-src/splash/SplashFontEngine.cc
+++ b/Build/source/libs/xpdf/xpdf-src/splash/SplashFontEngine.cc
@@ -132,10 +132,14 @@ SplashFontFile *SplashFontEngine::loadType1CFont(SplashFontFileID *idA,
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,
@@ -168,10 +172,14 @@ SplashFontFile *SplashFontEngine::loadOpenTypeT1CFont(SplashFontFileID *idA,
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,
@@ -221,6 +229,10 @@ SplashFontFile *SplashFontEngine::loadCIDFont(SplashFontFileID *idA,
}
#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
@@ -258,6 +270,10 @@ SplashFontFile *SplashFontEngine::loadOpenTypeCFFFont(SplashFontFileID *idA,
}
#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
diff --git a/Build/source/libs/xpdf/xpdf-src/splash/SplashFontEngine.h b/Build/source/libs/xpdf/xpdf-src/splash/SplashFontEngine.h
index ac2558ee52d..f9eab4d00f4 100644
--- a/Build/source/libs/xpdf/xpdf-src/splash/SplashFontEngine.h
+++ b/Build/source/libs/xpdf/xpdf-src/splash/SplashFontEngine.h
@@ -68,14 +68,14 @@ public:
#else
char *fileName, GBool deleteFile,
#endif
- const char **enc);
+ int *codeToGID, const char **enc);
SplashFontFile *loadOpenTypeT1CFont(SplashFontFileID *idA,
#if LOAD_FONTS_FROM_MEM
GString *fontBuf,
#else
char *fileName, GBool deleteFile,
#endif
- const char **enc);
+ int *codeToGID, const char **enc);
SplashFontFile *loadCIDFont(SplashFontFileID *idA,
#if LOAD_FONTS_FROM_MEM
GString *fontBuf,
diff --git a/Build/source/libs/xpdf/xpdf-src/splash/SplashMath.h b/Build/source/libs/xpdf/xpdf-src/splash/SplashMath.h
index 71afa3cb5c7..45f4e53e6bb 100644
--- a/Build/source/libs/xpdf/xpdf-src/splash/SplashMath.h
+++ b/Build/source/libs/xpdf/xpdf-src/splash/SplashMath.h
@@ -47,17 +47,13 @@ static inline int splashFloor(SplashCoord x) {
// NB: 64-bit x86 guarantees availability of SSE2.
__m128d m1, m2;
- __m128i m3;
- int s, i;
-
- m1 = _mm_set_sd(x); // m1 = x
- i = _mm_cvttsd_si32(m1); // i = trunc(x)
- m2 = _mm_cvtsi32_sd(m1, i); // m2 = (double)trunc(x)
- m1 = _mm_sub_sd(m1, m2); // m1 = x - trunc(x)
- m3 = _mm_castpd_si128(m1); // m3 = m1 (as 64-bit int)
- m3 = _mm_srli_epi64(m3, 63); // m3 = m3 >> 63
- s = _mm_cvtsi128_si32(m3); // s = m3 = sign bit of x - trunc(x)
- return i - s; // trunc(x) - sign bit
+ 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__)
@@ -123,17 +119,13 @@ static inline int splashCeil(SplashCoord x) {
// NB: 64-bit x86 guarantees availability of SSE2.
__m128d m1, m2;
- __m128i m3;
- int s, i;
-
- m1 = _mm_set_sd(x); // m1 = x
- i = _mm_cvttsd_si32(m1); // i = trunc(x)
- m2 = _mm_cvtsi32_sd(m1, i); // m2 = (double)trunc(x)
- m2 = _mm_sub_sd(m2, m1); // m2 = trunc(x) - x
- m3 = _mm_castpd_si128(m2); // m3 = m2 (as 64-bit int)
- m3 = _mm_srli_epi64(m3, 63); // m3 = m3 >> 63
- s = _mm_cvtsi128_si32(m3); // s = m3 = sign bit of x - trunc(x)
- return i + s; // trunc(x) + sign bit
+ 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__)
@@ -315,6 +307,31 @@ static inline void splashStrokeAdjust(SplashCoord xMin, SplashCoord xMax,
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);
diff --git a/Build/source/libs/xpdf/xpdf-src/splash/SplashXPath.cc b/Build/source/libs/xpdf/xpdf-src/splash/SplashXPath.cc
index f0164a85bd4..01a94987637 100644
--- a/Build/source/libs/xpdf/xpdf-src/splash/SplashXPath.cc
+++ b/Build/source/libs/xpdf/xpdf-src/splash/SplashXPath.cc
@@ -247,14 +247,14 @@ GBool SplashXPath::strokeAdjust(SplashXPathPoint *pts,
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 (x0 == x1 && x2 == x3) {
+ 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 (y0 == y1 && y2 == y3) {
+ } else if (splashAbs(y0 - y1) < 0.01 && splashAbs(y2 - y3) < 0.01) {
adjusts[i].vert = gFalse;
adj0 = y0;
adj1 = y2;