summaryrefslogtreecommitdiff
path: root/draw
diff options
context:
space:
mode:
authorTor Andersson <tor@ghostscript.com>2010-07-22 15:14:56 +0000
committerTor Andersson <tor@ghostscript.com>2010-07-22 15:14:56 +0000
commit89b649be84883c4552193fb05a6e3e14dd6c344f (patch)
tree5d33c05de389c7ea0f2fa6ba65f33f64b9ff5f82 /draw
parentc7fb104134d05d442d8ee6a64af93e5d72b2ab35 (diff)
downloadmupdf-89b649be84883c4552193fb05a6e3e14dd6c344f.tar.xz
Prevent dropouts of small images.
Diffstat (limited to 'draw')
-rw-r--r--draw/imagedraw.c54
1 files changed, 36 insertions, 18 deletions
diff --git a/draw/imagedraw.c b/draw/imagedraw.c
index 1882096f..030c0e94 100644
--- a/draw/imagedraw.c
+++ b/draw/imagedraw.c
@@ -176,13 +176,17 @@ samplecolor(byte *s, int w, int h, int n, int u, int v, byte *out)
/* Blend source image scanline over destination */
+#define INSIDEU u >= 0 && u <= (sw << 16)
+#define INSIDEV v >= 0 && v <= (sh << 16)
+#define INSIDE INSIDEU && INSIDEV
+
static inline void
fz_blendscan1(unsigned char *dp, unsigned char *sp, int sw, int sh,
int u, int v, int fa, int fb, int w)
{
while (w--)
{
- if (u >= 0 && u < sw << 16 && v >= 0 && v < sh << 16)
+ if (INSIDE)
{
int a = samplemask(sp, sw, sh, u, v);
dp[0] = a + fz_mul255(dp[0], 255 - a);
@@ -199,7 +203,7 @@ fz_blendscan2(unsigned char *dp, unsigned char *sp, int sw, int sh,
{
while (w--)
{
- if (u >= 0 && u < sw << 16 && v >= 0 && v < sh << 16)
+ if (INSIDE)
{
int g, a, t;
samplega(sp, sw, sh, u, v, &g, &a);
@@ -219,7 +223,7 @@ fz_blendscan4(unsigned char *dp, unsigned char *sp, int sw, int sh,
{
while (w--)
{
- if (u >= 0 && u < sw << 16 && v >= 0 && v < sh << 16)
+ if (INSIDE)
{
int r, g, b, a, t;
samplergba(sp, sw, sh, u, v, &r, &g, &b, &a);
@@ -241,7 +245,7 @@ fz_blendscan(unsigned char *dp, unsigned char *sp, int sw, int sh,
{
while (w--)
{
- if (u >= 0 && u < sw << 16 && v >= 0 && v < sh << 16)
+ if (INSIDE)
{
unsigned char color[FZ_MAXCOLORS+1];
int k, t;
@@ -265,7 +269,7 @@ fz_blendscanwithcolor(unsigned char *dp, unsigned char *sp, int sw, int sh,
int sa = color[n-1];
while (w--)
{
- if (u >= 0 && u < sw << 16 && v >= 0 && v < sh << 16)
+ if (INSIDE)
{
int ma = samplemask(sp, sw, sh, u, v);
int masa = fz_mul255(sa, ma);
@@ -282,6 +286,15 @@ fz_blendscanwithcolor(unsigned char *dp, unsigned char *sp, int sw, int sh,
/* Draw an image with an affine transform on destination */
+static inline float nodropout(float x)
+{
+ if (x > 0.1 && x < 1)
+ return 1;
+ if (x < -0.1 && x > -1)
+ return -1;
+ return x;
+}
+
static void
fz_blendimageimp(fz_pixmap *dst, fz_bbox scissor, fz_pixmap *img, fz_matrix ctm,
unsigned char *color)
@@ -293,35 +306,40 @@ fz_blendimageimp(fz_pixmap *dst, fz_bbox scissor, fz_pixmap *img, fz_matrix ctm,
fz_matrix inv;
fz_bbox bbox;
+ if (fz_isrectilinear(ctm))
+ {
+ ctm.a = nodropout(ctm.a);
+ ctm.b = nodropout(ctm.b);
+ ctm.c = nodropout(ctm.c);
+ ctm.d = nodropout(ctm.d);
+ }
+
+ bbox = fz_roundrect(fz_transformrect(ctm, fz_unitrect));
+ bbox = fz_intersectbbox(bbox, scissor);
+ x = bbox.x0;
+ y = bbox.y0;
+ w = bbox.x1 - bbox.x0;
+ h = bbox.y1 - bbox.y0;
+
/* map from screen space (x,y) to image space (u,v) */
inv = fz_scale(1.0f / img->w, -1.0f / img->h);
inv = fz_concat(inv, fz_translate(0, 1));
inv = fz_concat(inv, ctm);
inv = fz_invertmatrix(inv);
- inv.e -= 0.5f;
- inv.f -= 0.5f;
fa = inv.a * 65536;
fb = inv.b * 65536;
fc = inv.c * 65536;
fd = inv.d * 65536;
+ u = (fa * x) + (fc * y) + inv.e * 65536;
+ v = (fb * x) + (fd * y) + inv.f * 65536;
- bbox = fz_roundrect(fz_transformrect(ctm, fz_unitrect));
- bbox = fz_intersectbbox(bbox, scissor);
- x = bbox.x0;
- y = bbox.y0;
- w = bbox.x1 - bbox.x0;
- h = bbox.y1 - bbox.y0;
-
- dp = dst->samples + ((bbox.y0 - dst->y) * dst->w + (bbox.x0 - dst->x)) * dst->n;
+ dp = dst->samples + ((y - dst->y) * dst->w + (x - dst->x)) * dst->n;
n = dst->n;
sp = img->samples;
sw = img->w;
sh = img->h;
- u = (inv.a * (x+0.5f) + inv.c * (y+0.5f) + inv.e) * 65536;
- v = (inv.b * (x+0.5f) + inv.d * (y+0.5f) + inv.f) * 65536;
-
while (h--)
{
if (color)