Commit 69c281fd authored by Carlos Garcia Campos's avatar Carlos Garcia Campos

cairo: Fix the bounding box of images saved in CairoImageOutputDev

We were using the size of the original image instead of the rendered
size and asuming the scales were always positive.
parent 759e0266
......@@ -1736,27 +1736,26 @@ get_singular_values (const cairo_matrix_t *matrix,
*minor = sqrt (f - delta);
}
void CairoOutputDev::getScaledSize(int orig_width,
int orig_height,
int *scaledWidth,
int *scaledHeight) {
cairo_matrix_t matrix;
cairo_get_matrix(cairo, &matrix);
void CairoOutputDev::getScaledSize(const cairo_matrix_t *matrix,
int orig_width,
int orig_height,
int *scaledWidth,
int *scaledHeight)
{
double xScale;
double yScale;
if (orig_width > orig_height)
get_singular_values (&matrix, &xScale, &yScale);
get_singular_values (matrix, &xScale, &yScale);
else
get_singular_values (&matrix, &yScale, &xScale);
get_singular_values (matrix, &yScale, &xScale);
int tx, tx2, ty, ty2; /* the integer co-oridinates of the resulting image */
if (xScale >= 0) {
tx = splashRound(matrix.x0 - 0.01);
tx2 = splashRound(matrix.x0 + xScale + 0.01) - 1;
tx = splashRound(matrix->x0 - 0.01);
tx2 = splashRound(matrix->x0 + xScale + 0.01) - 1;
} else {
tx = splashRound(matrix.x0 + 0.01) - 1;
tx2 = splashRound(matrix.x0 + xScale - 0.01);
tx = splashRound(matrix->x0 + 0.01) - 1;
tx2 = splashRound(matrix->x0 + xScale - 0.01);
}
*scaledWidth = abs(tx2 - tx) + 1;
//scaledWidth = splashRound(fabs(xScale));
......@@ -1767,11 +1766,11 @@ void CairoOutputDev::getScaledSize(int orig_width,
*scaledWidth = 1;
}
if (yScale >= 0) {
ty = splashFloor(matrix.y0 + 0.01);
ty2 = splashCeil(matrix.y0 + yScale - 0.01);
ty = splashFloor(matrix->y0 + 0.01);
ty2 = splashCeil(matrix->y0 + yScale - 0.01);
} else {
ty = splashCeil(matrix.y0 - 0.01);
ty2 = splashFloor(matrix.y0 + yScale + 0.01);
ty = splashCeil(matrix->y0 - 0.01);
ty2 = splashFloor(matrix->y0 + yScale + 0.01);
}
*scaledHeight = abs(ty2 - ty);
if (*scaledHeight == 0) {
......@@ -1795,8 +1794,10 @@ CairoOutputDev::getFilterForSurface(cairo_surface_t *image,
if (printing)
return CAIRO_FILTER_NEAREST;
cairo_matrix_t matrix;
cairo_get_matrix(cairo, &matrix);
int scaled_width, scaled_height;
getScaledSize (orig_width, orig_height, &scaled_width, &scaled_height);
getScaledSize (&matrix, orig_width, orig_height, &scaled_width, &scaled_height);
/* When scale factor is >= 400% we don't interpolate. See bugs #25268, #9860 */
if (scaled_width / orig_width >= 4 || scaled_height / orig_height >= 4)
......@@ -2890,7 +2891,8 @@ void CairoOutputDev::drawImage(GfxState *state, Object *ref, Stream *str,
LOG (printf ("drawImage %dx%d\n", widthA, heightA));
getScaledSize (widthA, heightA, &scaledWidth, &scaledHeight);
cairo_get_matrix(cairo, &matrix);
getScaledSize (&matrix, widthA, heightA, &scaledWidth, &scaledHeight);
image = rescale.getSourceImage(str, widthA, heightA, scaledWidth, scaledHeight, printing, colorMap, maskColors);
if (!image)
return;
......@@ -2993,7 +2995,35 @@ void CairoImageOutputDev::saveImage(CairoImage *image)
images = (CairoImage **) greallocn (images, size, sizeof (CairoImage *));
}
images[numImages++] = image;
}
}
void CairoImageOutputDev::getBBox(GfxState *state, int width, int height,
double *x1, double *y1, double *x2, double *y2)
{
double *ctm = state->getCTM();
cairo_matrix_t matrix;
cairo_matrix_init(&matrix,
ctm[0], ctm[1],
-ctm[2], -ctm[3],
ctm[2] + ctm[4], ctm[3] + ctm[5]);
int scaledWidth, scaledHeight;
getScaledSize (&matrix, width, height, &scaledWidth, &scaledHeight);
if (matrix.xx >= 0) {
*x1 = matrix.x0;
} else {
*x1 = matrix.x0 - scaledWidth;
}
*x2 = *x1 + scaledWidth;
if (matrix.yy >= 0) {
*y1 = matrix.y0;
} else {
*y1 = matrix.y0 - scaledHeight;
}
*y2 = *y1 + scaledHeight;
}
void CairoImageOutputDev::drawImageMask(GfxState *state, Object *ref, Stream *str,
int width, int height, GBool invert,
......@@ -3002,22 +3032,9 @@ void CairoImageOutputDev::drawImageMask(GfxState *state, Object *ref, Stream *st
cairo_t *cr;
cairo_surface_t *surface;
double x1, y1, x2, y2;
double *ctm;
double mat[6];
CairoImage *image;
ctm = state->getCTM();
mat[0] = ctm[0];
mat[1] = ctm[1];
mat[2] = -ctm[2];
mat[3] = -ctm[3];
mat[4] = ctm[2] + ctm[4];
mat[5] = ctm[3] + ctm[5];
x1 = mat[4];
y1 = mat[5];
x2 = x1 + width;
y2 = y1 + height;
getBBox(state, width, height, &x1, &y1, &x2, &y2);
image = new CairoImage (x1, y1, x2, y2);
saveImage (image);
......@@ -3045,22 +3062,9 @@ void CairoImageOutputDev::setSoftMaskFromImageMask(GfxState *state, Object *ref,
cairo_t *cr;
cairo_surface_t *surface;
double x1, y1, x2, y2;
double *ctm;
double mat[6];
CairoImage *image;
ctm = state->getCTM();
mat[0] = ctm[0];
mat[1] = ctm[1];
mat[2] = -ctm[2];
mat[3] = -ctm[3];
mat[4] = ctm[2] + ctm[4];
mat[5] = ctm[3] + ctm[5];
x1 = mat[4];
y1 = mat[5];
x2 = x1 + width;
y2 = y1 + height;
getBBox(state, width, height, &x1, &y1, &x2, &y2);
image = new CairoImage (x1, y1, x2, y2);
saveImage (image);
......@@ -3091,22 +3095,9 @@ void CairoImageOutputDev::drawImage(GfxState *state, Object *ref, Stream *str,
cairo_t *cr;
cairo_surface_t *surface;
double x1, y1, x2, y2;
double *ctm;
double mat[6];
CairoImage *image;
ctm = state->getCTM();
mat[0] = ctm[0];
mat[1] = ctm[1];
mat[2] = -ctm[2];
mat[3] = -ctm[3];
mat[4] = ctm[2] + ctm[4];
mat[5] = ctm[3] + ctm[5];
x1 = mat[4];
y1 = mat[5];
x2 = x1 + width;
y2 = y1 + height;
getBBox(state, width, height, &x1, &y1, &x2, &y2);
image = new CairoImage (x1, y1, x2, y2);
saveImage (image);
......@@ -3139,22 +3130,9 @@ void CairoImageOutputDev::drawSoftMaskedImage(GfxState *state, Object *ref, Stre
cairo_t *cr;
cairo_surface_t *surface;
double x1, y1, x2, y2;
double *ctm;
double mat[6];
CairoImage *image;
ctm = state->getCTM();
mat[0] = ctm[0];
mat[1] = ctm[1];
mat[2] = -ctm[2];
mat[3] = -ctm[3];
mat[4] = ctm[2] + ctm[4];
mat[5] = ctm[3] + ctm[5];
x1 = mat[4];
y1 = mat[5];
x2 = x1 + width;
y2 = y1 + height;
getBBox(state, width, height, &x1, &y1, &x2, &y2);
image = new CairoImage (x1, y1, x2, y2);
saveImage (image);
......@@ -3187,22 +3165,9 @@ void CairoImageOutputDev::drawMaskedImage(GfxState *state, Object *ref, Stream *
cairo_t *cr;
cairo_surface_t *surface;
double x1, y1, x2, y2;
double *ctm;
double mat[6];
CairoImage *image;
ctm = state->getCTM();
mat[0] = ctm[0];
mat[1] = ctm[1];
mat[2] = -ctm[2];
mat[3] = -ctm[3];
mat[4] = ctm[2] + ctm[4];
mat[5] = ctm[3] + ctm[5];
x1 = mat[4];
y1 = mat[5];
x2 = x1 + width;
y2 = y1 + height;
getBBox(state, width, height, &x1, &y1, &x2, &y2);
image = new CairoImage (x1, y1, x2, y2);
saveImage (image);
......
......@@ -266,7 +266,8 @@ public:
protected:
void doPath(cairo_t *cairo, GfxState *state, GfxPath *path);
cairo_surface_t *downscaleSurface(cairo_surface_t *orig_surface);
void getScaledSize(int orig_width, int orig_height,
void getScaledSize(const cairo_matrix_t *matrix,
int orig_width, int orig_height,
int *scaledWidth, int *scaledHeight);
cairo_filter_t getFilterForSurface(cairo_surface_t *image,
GBool interpolate);
......@@ -493,6 +494,8 @@ public:
private:
void saveImage(CairoImage *image);
void getBBox(GfxState *state, int width, int height,
double *x1, double *y1, double *x2, double *y2);
CairoImage **images;
int numImages;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment