summaryrefslogtreecommitdiff
path: root/source/fitz/draw-affine.c
diff options
context:
space:
mode:
Diffstat (limited to 'source/fitz/draw-affine.c')
-rw-r--r--source/fitz/draw-affine.c71
1 files changed, 60 insertions, 11 deletions
diff --git a/source/fitz/draw-affine.c b/source/fitz/draw-affine.c
index ec19d936..1c6c26d1 100644
--- a/source/fitz/draw-affine.c
+++ b/source/fitz/draw-affine.c
@@ -807,12 +807,31 @@ fz_paint_affine_color_near(byte *dp, byte *sp, int sw, int sh, int u, int v, int
*/
#define MY_EPSILON 0.001
+/* We have 2 possible ways of gridfitting images. The first way, considered
+ * 'safe' in all cases, is to expand an image out to fill a box that entirely
+ * covers all the pixels touched by the current image. This is our 'standard'
+ * mechanism.
+ * The alternative, used when we know images are tiled across a page, is to
+ * round the edge of each image to the closest integer pixel boundary. This
+ * would not be safe in the general case, but gives less distortion across
+ * neighbouring images when tiling is used. We use this for .gproof files.
+ */
void
-fz_gridfit_matrix(fz_matrix *m)
+fz_gridfit_matrix(int as_tiled, fz_matrix *m)
{
if (fabsf(m->b) < FLT_EPSILON && fabsf(m->c) < FLT_EPSILON)
{
- if (m->a > 0)
+ if (as_tiled)
+ {
+ float f;
+ /* Nearest boundary for left */
+ f = (float)(int)(m->e + 0.5);
+ m->a += m->e - f; /* Adjust width for change */
+ m->e = f;
+ /* Nearest boundary for right (width really) */
+ m->a = (float)(int)(m->a + 0.5);
+ }
+ else if (m->a > 0)
{
float f;
/* Adjust left hand side onto pixel boundary */
@@ -842,7 +861,17 @@ fz_gridfit_matrix(fz_matrix *m)
f -= 1.0; /* Ensure it moves left */
m->a = f;
}
- if (m->d > 0)
+ if (as_tiled)
+ {
+ float f;
+ /* Nearest boundary for top */
+ f = (float)(int)(m->f + 0.5);
+ m->d += m->f - f; /* Adjust width for change */
+ m->f = f;
+ /* Nearest boundary for bottom (height really) */
+ m->d = (float)(int)(m->d + 0.5);
+ }
+ else if (m->d > 0)
{
float f;
/* Adjust top onto pixel boundary */
@@ -875,7 +904,17 @@ fz_gridfit_matrix(fz_matrix *m)
}
else if (fabsf(m->a) < FLT_EPSILON && fabsf(m->d) < FLT_EPSILON)
{
- if (m->b > 0)
+ if (as_tiled)
+ {
+ float f;
+ /* Nearest boundary for left */
+ f = (float)(int)(m->e + 0.5);
+ m->b += m->e - f; /* Adjust width for change */
+ m->e = f;
+ /* Nearest boundary for right (width really) */
+ m->b = (float)(int)(m->b + 0.5);
+ }
+ else if (m->b > 0)
{
float f;
/* Adjust left hand side onto pixel boundary */
@@ -905,7 +944,17 @@ fz_gridfit_matrix(fz_matrix *m)
f -= 1.0; /* Ensure it moves left */
m->b = f;
}
- if (m->c > 0)
+ if (as_tiled)
+ {
+ float f;
+ /* Nearest boundary for left */
+ f = (float)(int)(m->f + 0.5);
+ m->c += m->f - f; /* Adjust width for change */
+ m->f = f;
+ /* Nearest boundary for right (width really) */
+ m->c = (float)(int)(m->c + 0.5);
+ }
+ else if (m->c > 0)
{
float f;
/* Adjust top onto pixel boundary */
@@ -941,7 +990,7 @@ fz_gridfit_matrix(fz_matrix *m)
/* Draw an image with an affine transform on destination */
static void
-fz_paint_image_imp(fz_pixmap *dst, const fz_irect *scissor, fz_pixmap *shape, fz_pixmap *img, const fz_matrix *ctm, byte *color, int alpha, int lerp_allowed)
+fz_paint_image_imp(fz_pixmap *dst, const fz_irect *scissor, fz_pixmap *shape, fz_pixmap *img, const fz_matrix *ctm, byte *color, int alpha, int lerp_allowed, int as_tiled)
{
byte *dp, *sp, *hp;
int u, v, fa, fb, fc, fd;
@@ -955,7 +1004,7 @@ fz_paint_image_imp(fz_pixmap *dst, const fz_irect *scissor, fz_pixmap *shape, fz
int is_rectilinear;
/* grid fit the image */
- fz_gridfit_matrix(&local_ctm);
+ fz_gridfit_matrix(as_tiled, &local_ctm);
/* turn on interpolation for upscaled and non-rectilinear transforms */
dolerp = 0;
@@ -1084,15 +1133,15 @@ fz_paint_image_imp(fz_pixmap *dst, const fz_irect *scissor, fz_pixmap *shape, fz
}
void
-fz_paint_image_with_color(fz_pixmap *dst, const fz_irect *scissor, fz_pixmap *shape, fz_pixmap *img, const fz_matrix *ctm, byte *color, int lerp_allowed)
+fz_paint_image_with_color(fz_pixmap *dst, const fz_irect *scissor, fz_pixmap *shape, fz_pixmap *img, const fz_matrix *ctm, byte *color, int lerp_allowed, int as_tiled)
{
assert(img->n == 1);
- fz_paint_image_imp(dst, scissor, shape, img, ctm, color, 255, lerp_allowed);
+ fz_paint_image_imp(dst, scissor, shape, img, ctm, color, 255, lerp_allowed, as_tiled);
}
void
-fz_paint_image(fz_pixmap *dst, const fz_irect *scissor, fz_pixmap *shape, fz_pixmap *img, const fz_matrix *ctm, int alpha, int lerp_allowed)
+fz_paint_image(fz_pixmap *dst, const fz_irect *scissor, fz_pixmap *shape, fz_pixmap *img, const fz_matrix *ctm, int alpha, int lerp_allowed, int as_tiled)
{
assert(dst->n == img->n || (dst->n == 4 && img->n == 2));
- fz_paint_image_imp(dst, scissor, shape, img, ctm, NULL, alpha, lerp_allowed);
+ fz_paint_image_imp(dst, scissor, shape, img, ctm, NULL, alpha, lerp_allowed, as_tiled);
}