summaryrefslogtreecommitdiff
path: root/Build/source/libs/xpdf/xpdf-src/splash/Splash.cc
diff options
context:
space:
mode:
Diffstat (limited to 'Build/source/libs/xpdf/xpdf-src/splash/Splash.cc')
-rw-r--r--Build/source/libs/xpdf/xpdf-src/splash/Splash.cc581
1 files changed, 329 insertions, 252 deletions
diff --git a/Build/source/libs/xpdf/xpdf-src/splash/Splash.cc b/Build/source/libs/xpdf/xpdf-src/splash/Splash.cc
index 4afe21b4a25..0ed8cf5d888 100644
--- a/Build/source/libs/xpdf/xpdf-src/splash/Splash.cc
+++ b/Build/source/libs/xpdf/xpdf-src/splash/Splash.cc
@@ -8,10 +8,6 @@
#include <aconf.h>
-#ifdef USE_GCC_PRAGMAS
-#pragma implementation
-#endif
-
#include <stdlib.h>
#include <string.h>
#include <limits.h>
@@ -4930,7 +4926,7 @@ void Splash::clear(SplashColorPtr color, Guchar alpha) {
SplashError Splash::stroke(SplashPath *path) {
SplashPath *path2, *dPath;
- SplashCoord t0, t1, t2, t3, w, w2, lineDashMax, lineDashTotal;
+ SplashCoord w, w2, lineDashMax, lineDashTotal;
int lineCap, lineJoin, i;
if (debugMode) {
@@ -4942,6 +4938,9 @@ SplashError Splash::stroke(SplashPath *path) {
if (path->length == 0) {
return splashErrEmptyPath;
}
+ if (pathAllOutside(path, gTrue)) {
+ return splashOk;
+ }
path2 = flattenPath(path, state->matrix, state->flatness);
// Compute an approximation of the transformed line width.
@@ -4953,15 +4952,13 @@ SplashError Splash::stroke(SplashPath *path) {
// [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;
- }
+ double t0 = splashAbs(state->matrix[0]);
+ double t1 = splashAbs(state->matrix[1]);
+ double t2 = splashAbs(state->matrix[2]);
+ double t3 = splashAbs(state->matrix[3]);
+ double t01 = t0 * t0 + t1 * t1;
+ double t23 = t2 * t2 + t3 * t3;
+ w = sqrt((t01 > t23) ? t01 : t23);
w2 = w * state->lineWidth;
// construct the dashed path
@@ -5056,7 +5053,7 @@ void Splash::strokeNarrow(SplashPath *path) {
xPath = new SplashXPath(path, state->matrix, state->flatness, gFalse,
state->enablePathSimplification,
- state->strokeAdjust);
+ state->strokeAdjust, state->clip);
pipeInit(&pipe, state->strokePattern,
(Guchar)splashRound(state->strokeAlpha * 255),
@@ -5074,6 +5071,44 @@ void Splash::strokeNarrow(SplashPath *path) {
x0 = splashFloor(seg->x1);
x1 = splashFloor(seg->x0);
}
+
+ // With CAD-mode stroke adjustment, and a simple rectangular clip
+ // region, horizontal and vertical stroke-adjusted edges that fall
+ // slightly outside the clip region are adjusted back inside the
+ // clip region. This avoids problems with narrow lines in
+ // slightly mismatched clip rectangles, which appear to be
+ // generated somewhat commonly by buggy CAD software. This is
+ // similar to the code in SplashXPath::strokeAdjust() -- narrow
+ // strokes aren't stroke-adjusted, so this tweak has to be done
+ // here.
+ if (y0 == y1 &&
+ seg->y0 == seg->y1 &&
+ state->clip->getIsSimple() &&
+ state->strokeAdjust == splashStrokeAdjustCAD) {
+ SplashCoord cy0 = state->clip->getYMin();
+ SplashCoord cy1 = state->clip->getYMax();
+ int cyi0 = state->clip->getYMinI(state->strokeAdjust);
+ int cyi1 = state->clip->getYMaxI(state->strokeAdjust);
+ if (y0 == cyi0 - 1 && cy0 - seg->y0 < 0.5) {
+ y0 = y1 = y0 + 1;
+ } else if (y0 == cyi1 + 1 && seg->y0 - cy1 < 0.5) {
+ y0 = y1 = y0 - 1;
+ }
+ } else if (x0 == x1 &&
+ seg->x0 == seg->x1 &&
+ state->clip->getIsSimple() &&
+ state->strokeAdjust == splashStrokeAdjustCAD) {
+ SplashCoord cx0 = state->clip->getXMin();
+ SplashCoord cx1 = state->clip->getXMax();
+ int cxi0 = state->clip->getXMinI(state->strokeAdjust);
+ int cxi1 = state->clip->getXMaxI(state->strokeAdjust);
+ if (x0 == cxi0 - 1 && cx0 - seg->x0 < 0.5) {
+ x0 = x1 = x0 + 1;
+ } else if (x0 == cxi1 + 1 && seg->x0 - cx1 < 0.5) {
+ x0 = x1 = x0 - 1;
+ }
+ }
+
if ((clipRes = state->clip->testRect(x0 <= x1 ? x0 : x1, y0,
x0 <= x1 ? x1 : x0, y1,
state->strokeAdjust))
@@ -5084,6 +5119,18 @@ void Splash::strokeNarrow(SplashPath *path) {
} else {
drawStrokeSpan(&pipe, x1, x0, y0, clipRes == splashClipAllInside);
}
+ } else if (x0 == x1) {
+ y = state->clip->getYMinI(state->strokeAdjust);
+ if (y0 < y) {
+ y0 = y;
+ }
+ y = state->clip->getYMaxI(state->strokeAdjust);
+ if (y1 > y) {
+ y1 = y;
+ }
+ for (y = y0; y <= y1; ++y) {
+ drawStrokeSpan(&pipe, x0, x0, y, clipRes == splashClipAllInside);
+ }
} else {
dxdy = seg->dxdy;
y = state->clip->getYMinI(state->strokeAdjust);
@@ -5094,7 +5141,7 @@ void Splash::strokeNarrow(SplashPath *path) {
y = state->clip->getYMaxI(state->strokeAdjust);
if (y1 > y) {
y1 = y;
- x1 = splashFloor(seg->x0 + ((SplashCoord)y1 - seg->y0) * dxdy);
+ x1 = splashFloor(seg->x0 + ((SplashCoord)y1 + 1 - seg->y0) * dxdy);
}
if (x0 <= x1) {
xa = x0;
@@ -5135,6 +5182,7 @@ void Splash::strokeNarrow(SplashPath *path) {
}
++nClipRes[clipRes];
}
+
if (nClipRes[splashClipPartial] ||
(nClipRes[splashClipAllInside] && nClipRes[splashClipAllOutside])) {
opClipRes = splashClipPartial;
@@ -5326,16 +5374,14 @@ SplashPath *Splash::makeDashedPath(SplashPath *path) {
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;
+ if (lineDashStartPhase > 0) {
+ i = splashFloor(lineDashStartPhase / lineDashTotal);
+ lineDashStartPhase -= lineDashTotal * i;
+ } else {
+ i = splashCeil(-lineDashStartPhase / lineDashTotal);
+ lineDashStartPhase += lineDashTotal * i;
+ }
+ lineDashStartOn = !((state->lineDashLength & 1) && (i & 1));
lineDashStartIdx = 0;
if (lineDashStartPhase > 0) {
while (lineDashStartPhase >= state->lineDash[lineDashStartIdx]) {
@@ -5377,6 +5423,14 @@ SplashPath *Splash::makeDashedPath(SplashPath *path) {
y1 = path->pts[k+1].y;
segLen = splashDist(x0, y0, x1, y1);
+ // Special case for zero-length subpath: copy the zero-length
+ // segment into the dashed path so that the round line cap
+ // special case is handled.
+ if (j == i+1 && segLen == 0) {
+ dPath->moveTo(x0, y0);
+ dPath->lineTo(x0, y0);
+ }
+
// process the segment
while (segLen > 0) {
@@ -5477,6 +5531,13 @@ SplashError Splash::fill(SplashPath *path, GBool eo) {
printf("fill [eo:%d]:\n", eo);
dumpPath(path);
}
+ if (path->length == 0) {
+ return splashErrEmptyPath;
+ }
+ if (pathAllOutside(path, gFalse)) {
+ opClipRes = splashClipAllOutside;
+ return splashOk;
+ }
return fillWithPattern(path, eo, state->fillPattern, state->fillAlpha);
}
@@ -5490,19 +5551,11 @@ SplashError Splash::fillWithPattern(SplashPath *path, GBool eo,
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);
+ state->strokeAdjust, state->clip);
if (path2 != path) {
delete path2;
}
@@ -5678,13 +5731,17 @@ SplashPath *Splash::tweakFillPath(SplashPath *path) {
return path2;
}
-GBool Splash::pathAllOutside(SplashPath *path) {
+// Returns true if [path] is entirely outside the current clipping
+// path. The path coordinates have not been stroke adjusted, so we
+// compare against the floating point clip rect. If [stroke] is true,
+// allow for the stroke width and miter limit.
+GBool Splash::pathAllOutside(SplashPath *path, GBool stroke) {
SplashCoord xMin1, yMin1, xMax1, yMax1;
SplashCoord xMin2, yMin2, xMax2, yMax2;
SplashCoord x, y;
- int xMinI, yMinI, xMaxI, yMaxI;
int i;
+ //--- compute the path's bbox in user space
xMin1 = xMax1 = path->pts[0].x;
yMin1 = yMax1 = path->pts[0].y;
for (i = 1; i < path->length; ++i) {
@@ -5700,6 +5757,19 @@ GBool Splash::pathAllOutside(SplashPath *path) {
}
}
+ //--- allow for stroke width and miter limit
+ if (stroke && state->lineWidth > 0) {
+ SplashCoord w = state->lineWidth * 0.5;
+ if (state->lineJoin == splashLineJoinMiter) {
+ w *= state->miterLimit;
+ }
+ xMin1 -= w;
+ yMin1 -= w;
+ xMax1 += w;
+ yMax1 += w;
+ }
+
+ //--- convert path bbox to device space
transform(state->matrix, xMin1, yMin1, &x, &y);
xMin2 = xMax2 = x;
yMin2 = yMax2 = y;
@@ -5736,18 +5806,20 @@ GBool Splash::pathAllOutside(SplashPath *path) {
} 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;
+ //--- handle zero-width strokes
+ if (stroke && state->lineWidth == 0) {
+ xMin1 -= 1;
+ yMin1 -= 1;
+ xMax1 += 1;
+ yMax1 += 1;
+ }
+
+ //--- check against the clip rect
+ return xMin2 > state->clip->getXMax() ||
+ xMax2 < state->clip->getXMin() ||
+ yMin2 > state->clip->getYMax() ||
+ yMax2 < state->clip->getYMin();
}
SplashError Splash::fillChar(SplashCoord x, SplashCoord y,
@@ -6022,6 +6094,9 @@ SplashError Splash::fillImageMask(GString *imageTag,
SplashClipResult clipRes =
state->clip->testRect(xMin, yMin, xMax - 1, yMax - 1,
state->strokeAdjust);
+ if (clipRes == splashClipAllOutside) {
+ return splashOk;
+ }
// 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
@@ -6054,93 +6129,89 @@ SplashError Splash::fillImageMask(GString *imageTag,
//--- 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, antialias);
- Guchar *tmpLine = NULL;
- if (horizFlip) {
- tmpLine = (Guchar *)gmalloc(scaledWidth);
+ int scaledWidth = xMax - xMin;
+ int scaledHeight = yMax - yMin;
+ ImageMaskScaler scaler(src, srcData, w, h,
+ scaledWidth, scaledHeight, interpolate, antialias);
+ 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);
+ }
}
- 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 {
- 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);
- }
+ } else { // top-down
+ for (int y = 0; y < scaledHeight; ++y) {
+ scaler.nextLine();
+ (this->*drawRowFunc)(&dd, scaler.data(),
+ xMin, yMin + y, scaledWidth);
}
}
- gfree(tmpLine);
}
+ gfree(tmpLine);
//--- 90/270 rotation
} else if (rot90Only && !veryLarge) {
- if (clipRes != splashClipAllOutside) {
- // scale the mask
- int scaledWidth = yMax - yMin;
- int scaledHeight = xMax - xMin;
- ImageMaskScaler scaler(src, srcData, w, h,
- scaledWidth, scaledHeight, interpolate, antialias);
- Guchar *scaledMask = (Guchar *)gmallocn(scaledHeight, scaledWidth);
- Guchar *ptr = scaledMask;
- for (int y = 0; y < scaledHeight; ++y) {
- scaler.nextLine();
- memcpy(ptr, scaler.data(), scaledWidth);
- ptr += scaledWidth;
- }
+ // scale the mask
+ int scaledWidth = yMax - yMin;
+ int scaledHeight = xMax - xMin;
+ ImageMaskScaler scaler(src, srcData, w, h,
+ scaledWidth, scaledHeight, interpolate, antialias);
+ Guchar *scaledMask = (Guchar *)gmallocn64(scaledHeight, scaledWidth);
+ Guchar *ptr = scaledMask;
+ for (int y = 0; y < scaledHeight; ++y) {
+ scaler.nextLine();
+ memcpy(ptr, scaler.data(), scaledWidth);
+ ptr += scaledWidth;
+ }
- // draw it
- Guchar *tmpLine = (Guchar *)gmalloc(scaledHeight);
- for (int y = 0; y < scaledWidth; ++y) {
- if (vertFlip) {
- ptr = scaledMask + (scaledWidth - 1 - y);
- } else {
- ptr = scaledMask + y;
+ // draw it
+ Guchar *tmpLine = (Guchar *)gmalloc(scaledHeight);
+ for (int y = 0; y < scaledWidth; ++y) {
+ if (vertFlip) {
+ ptr = scaledMask + (scaledWidth - 1 - y);
+ } else {
+ ptr = scaledMask + y;
+ }
+ if (horizFlip) {
+ ptr += (scaledHeight - 1) * scaledWidth;
+ for (int x = 0; x < scaledHeight; ++x) {
+ tmpLine[x] = *ptr;
+ ptr -= scaledWidth;
}
- if (horizFlip) {
- ptr += (scaledHeight - 1) * scaledWidth;
- for (int x = 0; x < scaledHeight; ++x) {
- tmpLine[x] = *ptr;
- ptr -= scaledWidth;
- }
- } else {
- for (int x = 0; x < scaledHeight; ++x) {
- tmpLine[x] = *ptr;
- ptr += scaledWidth;
- }
+ } else {
+ for (int x = 0; x < scaledHeight; ++x) {
+ tmpLine[x] = *ptr;
+ ptr += scaledWidth;
}
- (this->*drawRowFunc)(&dd, tmpLine, xMin, yMin + y, scaledHeight);
}
-
- gfree(tmpLine);
- gfree(scaledMask);
+ (this->*drawRowFunc)(&dd, tmpLine, xMin, yMin + y, scaledHeight);
}
+ gfree(tmpLine);
+ gfree(scaledMask);
+
//--- arbitrary transform
} else {
// estimate of size of scaled image
@@ -6189,7 +6260,7 @@ SplashError Splash::fillImageMask(GString *imageTag,
// if downscaling: store the downscaled image mask
// if upscaling: store the unscaled image mask
- Guchar *scaledMask = (Guchar *)gmallocn(scaledHeight, scaledWidth);
+ Guchar *scaledMask = (Guchar *)gmallocn64(scaledHeight, scaledWidth);
if (downscaling) {
ImageMaskScaler scaler(src, srcData, w, h,
scaledWidth, scaledHeight, interpolate, antialias);
@@ -6271,7 +6342,7 @@ void Splash::drawImageMaskArbitraryNoInterp(
+ (SplashCoord)y * invMat[3] + invMat[5]);
if (xx >= 0 && xx < scaledWidth &&
yy >= 0 && yy < scaledHeight) {
- Guchar *p = scaledMask + (yy * scaledWidth + xx);
+ Guchar *p = scaledMask + (yy * (SplashBitmapRowSize)scaledWidth + xx);
Guchar *q = buf + (x - xMin);
*q = *p;
if (x < rowMin) {
@@ -6349,10 +6420,10 @@ void Splash::drawImageMaskArbitraryInterp(
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 *p00 = scaledMask + (y0 * (SplashBitmapRowSize)scaledWidth + x0);
+ Guchar *p10 = scaledMask + (y0 * (SplashBitmapRowSize)scaledWidth + x1);
+ Guchar *p01 = scaledMask + (y1 * (SplashBitmapRowSize)scaledWidth + x0);
+ Guchar *p11 = scaledMask + (y1 * (SplashBitmapRowSize)scaledWidth + x1);
Guchar *q = buf + (x - xMin);
*q = (Guchar)(int)(sx0 * (sy0 * (int)*p00 + sy1 * (int)*p01) +
sx1 * (sy0 * (int)*p10 + sy1 * (int)*p11));
@@ -6569,6 +6640,9 @@ SplashError Splash::drawImage(GString *imageTag,
SplashClipResult clipRes =
state->clip->testRect(xMin, yMin, xMax - 1, yMax - 1,
state->strokeAdjust);
+ if (clipRes == splashClipAllOutside) {
+ return splashOk;
+ }
// 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
@@ -6616,136 +6690,133 @@ SplashError Splash::drawImage(GString *imageTag,
//--- 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);
+ 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);
}
}
- 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 {
- 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);
- }
+ } 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;
}
+ gfree(tmpLine);
+ gfree(tmpAlphaLine);
+ delete scaler;
//--- 90/270 rotation
} else if (rot90Only && !veryLarge) {
- if (clipRes != splashClipAllOutside) {
-
- // scale the image
- int scaledWidth = yMax - yMin;
- int scaledHeight = xMax - xMin;
- Guchar *scaledColor, *scaledAlpha;
- GBool freeScaledImage;
- getScaledImage(imageTag, src, srcData, w, h, nComps,
- scaledWidth, scaledHeight, srcMode, srcAlpha, interpolate,
- &scaledColor, &scaledAlpha, &freeScaledImage);
-
- // draw it
- Guchar *tmpLine = (Guchar *)gmallocn(scaledHeight, nComps);
- Guchar *tmpAlphaLine = NULL;
- if (srcAlpha) {
- tmpAlphaLine = (Guchar *)gmalloc(scaledHeight);
+
+ // scale the image
+ int scaledWidth = yMax - yMin;
+ int scaledHeight = xMax - xMin;
+ Guchar *scaledColor, *scaledAlpha;
+ GBool freeScaledImage;
+ getScaledImage(imageTag, src, srcData, w, h, nComps,
+ scaledWidth, scaledHeight, srcMode, srcAlpha, interpolate,
+ &scaledColor, &scaledAlpha, &freeScaledImage);
+
+ // draw it
+ Guchar *tmpLine = (Guchar *)gmallocn(scaledHeight, nComps);
+ Guchar *tmpAlphaLine = NULL;
+ if (srcAlpha) {
+ tmpAlphaLine = (Guchar *)gmalloc(scaledHeight);
+ }
+ for (int y = 0; y < scaledWidth; ++y) {
+ Guchar *ptr = NULL;
+ Guchar *alphaPtr = NULL;
+ if (vertFlip) {
+ ptr = scaledColor + ((SplashBitmapRowSize)scaledWidth - 1 - y) * nComps;
+ if (srcAlpha) {
+ alphaPtr = scaledAlpha + (scaledWidth - 1 - y);
+ }
+ } else {
+ ptr = scaledColor + y * nComps;
+ if (srcAlpha) {
+ alphaPtr = scaledAlpha + y;
+ }
}
- for (int y = 0; y < scaledWidth; ++y) {
- Guchar *ptr, *alphaPtr;
- if (vertFlip) {
- ptr = scaledColor + (scaledWidth - 1 - y) * nComps;
- if (srcAlpha) {
- alphaPtr = scaledAlpha + (scaledWidth - 1 - y);
- }
- } else {
- ptr = scaledColor + y * nComps;
- if (srcAlpha) {
- alphaPtr = scaledAlpha + y;
+ if (horizFlip) {
+ ptr += (scaledHeight - 1) * (SplashBitmapRowSize)scaledWidth * nComps;
+ Guchar *q = tmpLine;
+ for (int x = 0; x < scaledHeight; ++x) {
+ for (int i = 0; i < nComps; ++i) {
+ *q++ = ptr[i];
}
+ ptr -= scaledWidth * nComps;
}
- if (horizFlip) {
- ptr += (scaledHeight - 1) * scaledWidth * nComps;
- Guchar *q = tmpLine;
+ if (srcAlpha) {
+ alphaPtr += (scaledHeight - 1) * (SplashBitmapRowSize)scaledWidth;
+ q = tmpAlphaLine;
for (int x = 0; x < scaledHeight; ++x) {
- for (int i = 0; i < nComps; ++i) {
- *q++ = ptr[i];
- }
- ptr -= scaledWidth * nComps;
+ *q++ = *alphaPtr;
+ alphaPtr -= scaledWidth;
}
- if (srcAlpha) {
- alphaPtr += (scaledHeight - 1) * scaledWidth;
- q = tmpAlphaLine;
- for (int x = 0; x < scaledHeight; ++x) {
- *q++ = *alphaPtr;
- alphaPtr -= scaledWidth;
- }
+ }
+ } else {
+ Guchar *q = tmpLine;
+ for (int x = 0; x < scaledHeight; ++x) {
+ for (int i = 0; i < nComps; ++i) {
+ *q++ = ptr[i];
}
- } else {
- Guchar *q = tmpLine;
+ ptr += scaledWidth * nComps;
+ }
+ if (srcAlpha) {
+ q = tmpAlphaLine;
for (int x = 0; x < scaledHeight; ++x) {
- for (int i = 0; i < nComps; ++i) {
- *q++ = ptr[i];
- }
- ptr += scaledWidth * nComps;
- }
- if (srcAlpha) {
- q = tmpAlphaLine;
- for (int x = 0; x < scaledHeight; ++x) {
- *q++ = *alphaPtr;
- alphaPtr += scaledWidth;
- }
+ *q++ = *alphaPtr;
+ alphaPtr += scaledWidth;
}
}
- (this->*drawRowFunc)(&dd, tmpLine, tmpAlphaLine,
- xMin, yMin + y, scaledHeight);
}
+ (this->*drawRowFunc)(&dd, tmpLine, tmpAlphaLine,
+ xMin, yMin + y, scaledHeight);
+ }
- gfree(tmpLine);
- gfree(tmpAlphaLine);
- if (freeScaledImage) {
- gfree(scaledColor);
- gfree(scaledAlpha);
- }
+ gfree(tmpLine);
+ gfree(tmpAlphaLine);
+ if (freeScaledImage) {
+ gfree(scaledColor);
+ gfree(scaledAlpha);
}
//--- arbitrary transform
@@ -6851,9 +6922,9 @@ ImageScaler *Splash::getImageScaler(GString *imageTag,
} else {
lineSize = -1;
}
- imageCache->colorData = (Guchar *)gmallocn(scaledHeight, lineSize);
+ imageCache->colorData = (Guchar *)gmallocn64(scaledHeight, lineSize);
if (srcAlpha) {
- imageCache->alphaData = (Guchar *)gmallocn(scaledHeight, scaledWidth);
+ imageCache->alphaData = (Guchar *)gmallocn64(scaledHeight, scaledWidth);
}
return new SavingImageScaler(src, srcData,
w, h, nComps, srcAlpha,
@@ -6894,9 +6965,9 @@ void Splash::getScaledImage(GString *imageTag,
} else {
lineSize = -1;
}
- *scaledColor = (Guchar *)gmallocn(scaledHeight, lineSize);
+ *scaledColor = (Guchar *)gmallocn64(scaledHeight, lineSize);
if (srcAlpha) {
- *scaledAlpha = (Guchar *)gmallocn(scaledHeight, scaledWidth);
+ *scaledAlpha = (Guchar *)gmallocn64(scaledHeight, scaledWidth);
} else {
*scaledAlpha = NULL;
}
@@ -6938,9 +7009,9 @@ void Splash::getScaledImage(GString *imageTag,
} else {
lineSize = -1;
}
- imageCache->colorData = (Guchar *)gmallocn(scaledHeight, lineSize);
+ imageCache->colorData = (Guchar *)gmallocn64(scaledHeight, lineSize);
if (srcAlpha) {
- imageCache->alphaData = (Guchar *)gmallocn(scaledHeight, scaledWidth);
+ imageCache->alphaData = (Guchar *)gmallocn64(scaledHeight, scaledWidth);
}
if (scaledWidth == w && scaledHeight == h) {
Guchar *colorPtr = imageCache->colorData;
@@ -7021,13 +7092,15 @@ void Splash::drawImageArbitraryNoInterp(Guchar *scaledColor,
+ (SplashCoord)y * invMat[3] + invMat[5]);
if (xx >= 0 && xx < scaledWidth &&
yy >= 0 && yy < scaledHeight) {
- Guchar *p = scaledColor + (yy * scaledWidth + xx) * nComps;
+ Guchar *p = scaledColor +
+ (yy * (SplashBitmapRowSize)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];
+ alphaBuf[x - xMin] =
+ scaledAlpha[yy * (SplashBitmapRowSize)scaledWidth + xx];
}
if (x < rowMin) {
rowMin = x;
@@ -7111,20 +7184,24 @@ void Splash::drawImageArbitraryInterp(Guchar *scaledColor, Guchar *scaledAlpha,
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 *p00 = scaledColor +
+ (y0 * (SplashBitmapRowSize)scaledWidth + x0) * nComps;
+ Guchar *p10 = scaledColor +
+ (y0 * (SplashBitmapRowSize)scaledWidth + x1) * nComps;
+ Guchar *p01 = scaledColor +
+ (y1 * (SplashBitmapRowSize)scaledWidth + x0) * nComps;
+ Guchar *p11 = scaledColor +
+ (y1 * (SplashBitmapRowSize)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);
+ p00 = scaledAlpha + (y0 * (SplashBitmapRowSize)scaledWidth + x0);
+ p10 = scaledAlpha + (y0 * (SplashBitmapRowSize)scaledWidth + x1);
+ p01 = scaledAlpha + (y1 * (SplashBitmapRowSize)scaledWidth + x0);
+ p11 = scaledAlpha + (y1 * (SplashBitmapRowSize)scaledWidth + x1);
q = alphaBuf + (x - xMin);
*q = (Guchar)(int)(sx0 * (sy0 * (int)*p00 + sy1 * (int)*p01) +
sx1 * (sy0 * (int)*p10 + sy1 * (int)*p11));