summaryrefslogtreecommitdiff
path: root/Build/source/libs/xpdf/xpdf-src/xpdf/SplashOutputDev.cc
diff options
context:
space:
mode:
Diffstat (limited to 'Build/source/libs/xpdf/xpdf-src/xpdf/SplashOutputDev.cc')
-rw-r--r--Build/source/libs/xpdf/xpdf-src/xpdf/SplashOutputDev.cc151
1 files changed, 102 insertions, 49 deletions
diff --git a/Build/source/libs/xpdf/xpdf-src/xpdf/SplashOutputDev.cc b/Build/source/libs/xpdf/xpdf-src/xpdf/SplashOutputDev.cc
index 89c7c02a7b6..d758e25b306 100644
--- a/Build/source/libs/xpdf/xpdf-src/xpdf/SplashOutputDev.cc
+++ b/Build/source/libs/xpdf/xpdf-src/xpdf/SplashOutputDev.cc
@@ -1882,10 +1882,10 @@ void SplashOutputDev::tilingPatternFill(GfxState *state, Gfx *gfx,
idet = 1 / idet;
clipXC = 0.5 * (clipXMin + clipXMax);
clipYC = 0.5 * (clipYMin + clipYMax);
- ix = (int)((yStepX * (tileYMin - clipYC) - (tileXMin - clipXC) * yStepY)
- * idet + 0.5);
- iy = (int)((xStepX * (clipYC - tileYMin) - (clipXC - tileXMin) * xStepY)
- * idet + 0.5);
+ ix = (int)floor((yStepX * (tileYMin - clipYC)
+ - (tileXMin - clipXC) * yStepY) * idet + 0.5);
+ iy = (int)floor((xStepX * (clipYC - tileYMin)
+ - (clipXC - tileXMin) * xStepY) * idet + 0.5);
adjXMin = (int)floor(tileXMin + ix * xStepX + iy * yStepX + 0.5);
adjYMin = (int)floor(tileYMin + ix * xStepY + iy * yStepY + 0.5);
sx = tileW / (tileXMax - tileXMin);
@@ -1896,38 +1896,6 @@ void SplashOutputDev::tilingPatternFill(GfxState *state, Gfx *gfx,
yStepY = (int)floor(sy * yStepY + 0.5);
}
- // compute tile matrix = PTM * BTM * Mtranslate * Mscale * iCTM
- // = mat * CTM * Mtranslate * Mscale * iCTM
- ctm = state->getCTM();
- idet = 1 / (ctm[0] * ctm[3] - ctm[1] * ctm[2]);
- ictm[0] = ctm[3] * idet;
- ictm[1] = -ctm[1] * idet;
- ictm[2] = -ctm[2] * idet;
- ictm[3] = ctm[0] * idet;
- ictm[4] = (ctm[2] * ctm[5] - ctm[3] * ctm[4]) * idet;
- ictm[5] = (ctm[1] * ctm[4] - ctm[0] * ctm[5]) * idet;
- // mat * CTM
- mat1[0] = mat[0] * ctm[0] + mat[1] * ctm[2];
- mat1[1] = mat[0] * ctm[1] + mat[1] * ctm[3];
- mat1[2] = mat[2] * ctm[0] + mat[3] * ctm[2];
- mat1[3] = mat[2] * ctm[1] + mat[3] * ctm[3];
- mat1[4] = mat[4] * ctm[0] + mat[5] * ctm[2] + ctm[4];
- mat1[5] = mat[4] * ctm[1] + mat[5] * ctm[3] + ctm[5];
- // mat * CTM * (Mtranslate * Mscale)
- mat2[0] = mat1[0] * sx;
- mat2[1] = mat1[1] * sy;
- mat2[2] = mat1[2] * sx;
- mat2[3] = mat1[3] * sy;
- mat2[4] = mat1[4] * sx - sx * tileXMin;
- mat2[5] = mat1[5] * sy - sy * tileYMin;
- // mat * CTM * (Mtranslate * Mscale) * iCTM
- tileMat[0] = mat2[0] * ictm[0] + mat2[1] * ictm[2];
- tileMat[1] = mat2[0] * ictm[1] + mat2[1] * ictm[3];
- tileMat[2] = mat2[2] * ictm[0] + mat2[3] * ictm[2];
- tileMat[3] = mat2[2] * ictm[1] + mat2[3] * ictm[3];
- tileMat[4] = mat2[4] * ictm[0] + mat2[5] * ictm[2] + ictm[4];
- tileMat[5] = mat2[4] * ictm[1] + mat2[5] * ictm[3] + ictm[5];
-
// compute tiling range:
// - look at the four corners of the clipping bbox
// - solve for the (ix,iy) tile position at each corner
@@ -1989,10 +1957,65 @@ void SplashOutputDev::tilingPatternFill(GfxState *state, Gfx *gfx,
} else if (ty > tyMax) {
tyMax = ty;
}
- ixMin = (int)floor(txMin);
- ixMax = (int)ceil(txMax);
- iyMin = (int)floor(tyMin);
- iyMax = (int)ceil(tyMax);
+ ixMin = (int)ceil(txMin);
+ ixMax = (int)floor(txMax) + 1;
+ iyMin = (int)ceil(tyMin);
+ iyMax = (int)floor(tyMax) + 1;
+
+ // special case: pattern tile is larger than clipping bbox
+ if (ixMax - ixMin == 1 && iyMax - iyMin == 1) {
+ // reduce the tile size to just the clipping bbox -- this improves
+ // performance in cases where just a small portion of one tile is
+ // needed
+ tileW = (int)(clipXMax - clipXMin + 0.5);
+ tileH = (int)(clipYMax - clipYMin + 0.5);
+ if (tileW < 1) {
+ tileW = 1;
+ }
+ if (tileH < 1) {
+ tileH = 1;
+ }
+ tileXMin += clipXMin - (adjXMin + ixMin * xStepX + iyMin * yStepX);
+ tileYMin += clipYMin - (adjYMin + ixMin * xStepY + iyMin * yStepY);
+ ixMin = 0;
+ iyMin = 0;
+ ixMax = 1;
+ iyMax = 1;
+ adjXMin = clipXMin;
+ adjYMin = clipYMin;
+ }
+
+ // compute tile matrix = PTM * BTM * Mtranslate * Mscale * iCTM
+ // = mat * CTM * Mtranslate * Mscale * iCTM
+ ctm = state->getCTM();
+ idet = 1 / (ctm[0] * ctm[3] - ctm[1] * ctm[2]);
+ ictm[0] = ctm[3] * idet;
+ ictm[1] = -ctm[1] * idet;
+ ictm[2] = -ctm[2] * idet;
+ ictm[3] = ctm[0] * idet;
+ ictm[4] = (ctm[2] * ctm[5] - ctm[3] * ctm[4]) * idet;
+ ictm[5] = (ctm[1] * ctm[4] - ctm[0] * ctm[5]) * idet;
+ // mat * CTM
+ mat1[0] = mat[0] * ctm[0] + mat[1] * ctm[2];
+ mat1[1] = mat[0] * ctm[1] + mat[1] * ctm[3];
+ mat1[2] = mat[2] * ctm[0] + mat[3] * ctm[2];
+ mat1[3] = mat[2] * ctm[1] + mat[3] * ctm[3];
+ mat1[4] = mat[4] * ctm[0] + mat[5] * ctm[2] + ctm[4];
+ mat1[5] = mat[4] * ctm[1] + mat[5] * ctm[3] + ctm[5];
+ // mat * CTM * (Mtranslate * Mscale)
+ mat2[0] = mat1[0] * sx;
+ mat2[1] = mat1[1] * sy;
+ mat2[2] = mat1[2] * sx;
+ mat2[3] = mat1[3] * sy;
+ mat2[4] = mat1[4] * sx - sx * tileXMin;
+ mat2[5] = mat1[5] * sy - sy * tileYMin;
+ // mat * CTM * (Mtranslate * Mscale) * iCTM
+ tileMat[0] = mat2[0] * ictm[0] + mat2[1] * ictm[2];
+ tileMat[1] = mat2[0] * ictm[1] + mat2[1] * ictm[3];
+ tileMat[2] = mat2[2] * ictm[0] + mat2[3] * ictm[2];
+ tileMat[3] = mat2[2] * ictm[1] + mat2[3] * ictm[3];
+ tileMat[4] = mat2[4] * ictm[0] + mat2[5] * ictm[2] + ictm[4];
+ tileMat[5] = mat2[4] * ictm[1] + mat2[5] * ictm[3] + ictm[5];
// create a temporary bitmap
origBitmap = bitmap;
@@ -2068,8 +2091,8 @@ void SplashOutputDev::tilingPatternFill(GfxState *state, Gfx *gfx,
} else {
for (iy = iyMin; iy < iyMax; ++iy) {
for (ix = ixMin; ix < ixMax; ++ix) {
- x = (int)(adjXMin + ix * xStepX + iy * yStepX + 0.5);
- y = (int)(adjYMin + ix * xStepY + iy * yStepY + 0.5);
+ x = (int)floor(adjXMin + ix * xStepX + iy * yStepX + 0.5);
+ y = (int)floor(adjYMin + ix * xStepY + iy * yStepY + 0.5);
if (overprintMaskBitmap) {
splash->compositeWithOverprint(tileBitmap, overprintMaskBitmap,
0, 0, x, y, tileW, tileH,
@@ -2722,7 +2745,8 @@ void SplashOutputDev::drawImageMask(GfxState *state, Object *ref, Stream *str,
imgTag = makeImageTag(ref, gfxRenderingIntentRelativeColorimetric, NULL);
splash->fillImageMask(imgTag,
&imageMaskSrc, &imgMaskData, width, height, mat,
- t3GlyphStack != NULL, interpolate);
+ t3GlyphStack != NULL, interpolate,
+ globalParams->getImageMaskAntialias());
if (inlineImg) {
while (imgMaskData.y < height) {
@@ -2772,12 +2796,16 @@ void SplashOutputDev::setSoftMaskFromImageMask(GfxState *state,
mapStrokeAdjustMode[globalParams->getStrokeAdjust()]);
maskSplash->setEnablePathSimplification(
globalParams->getEnablePathSimplification());
+ if (splash->getSoftMask()) {
+ maskSplash->setSoftMask(splash->getSoftMask(), gFalse);
+ }
clearMaskRegion(state, maskSplash, 0, 0, 1, 1);
maskColor[0] = 0xff;
maskSplash->setFillPattern(new SplashSolidColor(maskColor));
imgTag = makeImageTag(ref, gfxRenderingIntentRelativeColorimetric, NULL);
maskSplash->fillImageMask(imgTag, &imageMaskSrc, &imgMaskData,
- width, height, mat, gFalse, interpolate);
+ width, height, mat, gFalse, interpolate,
+ globalParams->getImageMaskAntialias());
delete imgTag;
delete imgMaskData.imgStr;
str->close();
@@ -3273,7 +3301,8 @@ void SplashOutputDev::drawMaskedImage(GfxState *state, Object *ref,
maskSplash->setFillPattern(new SplashSolidColor(maskColor));
// use "glyph mode" here to get the correct scaled size
maskSplash->fillImageMask(NULL, &imageMaskSrc, &imgMaskData,
- maskWidth, maskHeight, mat, gTrue, interpolate);
+ maskWidth, maskHeight, mat, gTrue, interpolate,
+ globalParams->getImageMaskAntialias());
delete imgMaskData.imgStr;
maskStr->close();
delete maskSplash;
@@ -3818,10 +3847,10 @@ void SplashOutputDev::clearMaskRegion(GfxState *state,
}
}
-void SplashOutputDev::beginTransparencyGroup(GfxState *state, double *bbox,
- GfxColorSpace *blendingColorSpace,
- GBool isolated, GBool knockout,
- GBool forSoftMask) {
+GBool SplashOutputDev::beginTransparencyGroup(GfxState *state, double *bbox,
+ GfxColorSpace *blendingColorSpace,
+ GBool isolated, GBool knockout,
+ GBool forSoftMask) {
SplashTransparencyGroup *transpGroup;
SplashBitmap *backdropBitmap;
SplashColor color;
@@ -3916,6 +3945,28 @@ void SplashOutputDev::beginTransparencyGroup(GfxState *state, double *bbox,
h = 1;
}
+ // optimization: a non-isolated group drawn with alpha=1 and
+ // Blend=Normal and backdrop alpha=0 is equivalent to drawing
+ // directly onto the backdrop (i.e., a regular non-t-group Form)
+ // notes:
+ // - if we are already in a non-isolated group, it means the
+ // backdrop alpha is non-zero (otherwise the parent non-isolated
+ // group would have been optimized away)
+ // - if there is a soft mask in place, then source alpha is not 1
+ // (i.e., source alpha = fillOpacity * softMask)
+ // - both the parent and child groups must be non-knockout
+ if (!isolated &&
+ !splash->getInNonIsolatedGroup() &&
+ !knockout &&
+ !splash->getInKnockoutGroup() &&
+ !forSoftMask &&
+ !splash->getSoftMask() &&
+ state->getFillOpacity() == 1 &&
+ state->getBlendMode() == gfxBlendNormal &&
+ splash->checkTransparentRect(tx, ty, w, h)) {
+ return gFalse;
+ }
+
// push a new stack entry
transpGroup = new SplashTransparencyGroup();
transpGroup->tx = tx;
@@ -4042,6 +4093,8 @@ void SplashOutputDev::beginTransparencyGroup(GfxState *state, double *bbox,
state->shiftCTM(-tx, -ty);
updateCTM(state, 0, 0, 0, 0, 0, 0);
++nestCount;
+
+ return gTrue;
}
void SplashOutputDev::endTransparencyGroup(GfxState *state) {