[poppler] poppler/CairoOutputDev.cc poppler/CairoOutputDev.h
Carlos Garcia Campos
carlosgc at kemper.freedesktop.org
Sun Jul 7 07:19:35 PDT 2013
poppler/CairoOutputDev.cc | 145 +++++++++++++++++-----------------------------
poppler/CairoOutputDev.h | 5 +
2 files changed, 59 insertions(+), 91 deletions(-)
New commits:
commit 69c281fdcf23520151c0eb5471a4259c73fa1273
Author: Carlos Garcia Campos <carlosgc at gnome.org>
Date: Sun Jul 7 11:51:27 2013 +0200
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.
diff --git a/poppler/CairoOutputDev.cc b/poppler/CairoOutputDev.cc
index a50e189..26760c8 100644
--- a/poppler/CairoOutputDev.cc
+++ b/poppler/CairoOutputDev.cc
@@ -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);
diff --git a/poppler/CairoOutputDev.h b/poppler/CairoOutputDev.h
index bbad744..d900561 100644
--- a/poppler/CairoOutputDev.h
+++ b/poppler/CairoOutputDev.h
@@ -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;
More information about the poppler
mailing list