diff options
author | Tor Andersson <tor@ghostscript.com> | 2010-05-20 23:49:12 +0200 |
---|---|---|
committer | Tor Andersson <tor@ghostscript.com> | 2010-05-20 23:49:12 +0200 |
commit | 20191dcca2bde592da73db125193bb773c62f502 (patch) | |
tree | a11da9f79a120cbbfabe6e80605abe49a09a7b33 | |
parent | 30b8e3187fed0ad8f4c879cbe08fdd75f496e693 (diff) | |
download | mupdf-20191dcca2bde592da73db125193bb773c62f502.tar.xz |
Draw images with anti-aliased edges.
-rw-r--r-- | draw/archx86.c | 6 | ||||
-rw-r--r-- | draw/imagedraw.c | 295 | ||||
-rw-r--r-- | draw/pathscan.c | 32 | ||||
-rw-r--r-- | draw/porterduff.c | 137 | ||||
-rw-r--r-- | fitz/dev_draw.c | 197 | ||||
-rw-r--r-- | fitz/fitz_draw.h | 24 | ||||
-rw-r--r-- | mupdf/pdf_build.c | 13 |
7 files changed, 217 insertions, 487 deletions
diff --git a/draw/archx86.c b/draw/archx86.c index a32e54be..b75fb28f 100644 --- a/draw/archx86.c +++ b/draw/archx86.c @@ -77,6 +77,8 @@ static void duff_4i1o4mmx(byte *sp0, int sw, byte *mp0, int mw, byte *dp0, int d _mm_empty(); } +#if 0 /* TODO */ + static inline unsigned getargb(unsigned *s, int w, int h, int u, int v) { @@ -212,6 +214,8 @@ static void img_4o4mmx(FZ_PSRC, FZ_PDST, FZ_PCTM) _mm_empty(); } +#endif + #endif /* HAVE_MMX */ #if defined (ARCH_X86) || defined(ARCH_X86_64) @@ -222,7 +226,7 @@ fz_accelerate(void) if (fz_cpuflags & HAVE_MMX) { fz_duff_4i1o4 = duff_4i1o4mmx; - fz_img_4o4 = img_4o4mmx; +// TODO fz_img_4o4 = img_4o4mmx; } # endif } diff --git a/draw/imagedraw.c b/draw/imagedraw.c index 7ef4964f..7bdba6e0 100644 --- a/draw/imagedraw.c +++ b/draw/imagedraw.c @@ -1,59 +1,54 @@ #include "fitz.h" -#define CLAMPUV - typedef unsigned char byte; -#define lerp(a,b,t) (a + (((b - a) * t) >> 16)) - -static inline byte getcomp(byte *s, int w, int h, int u, int v, int n, int k) +static inline byte +getmask(byte *s, int w, int h, int u, int v) { -#ifdef CLAMPUV if (u < 0) u = 0; if (v < 0) v = 0; if (u >= w) u = w - 1; if (v >= h) v = h - 1; -#else - if (u < 0) return 0; - if (v < 0) return 0; - if (u >= w) return 0; - if (v >= h) return 0; -#endif - return s[(w * v + u) * n + k]; + return s[w * v + u]; } -static inline int samplecomp(byte *s, int w, int h, int u, int v, int n, int k) +static inline byte * +getargb(byte *s, int w, int h, int u, int v) { - int ui = u >> 16; - int vi = v >> 16; - int ud = u & 0xFFFF; - int vd = v & 0xFFFF; - int a = getcomp(s, w, h, ui, vi, n, k); - int b = getcomp(s, w, h, ui+1, vi, n, k); - int c = getcomp(s, w, h, ui, vi+1, n, k); - int d = getcomp(s, w, h, ui+1, vi+1, n, k); - int ab = lerp(a, b, ud); - int cd = lerp(c, d, ud); - return lerp(ab, cd, vd); + if (u < 0) u = 0; + if (v < 0) v = 0; + if (u >= w) u = w - 1; + if (v >= h) v = h - 1; + return s + ((w * v + u) << 2); } -static inline byte getmask(byte *s, int w, int h, int u, int v) +static inline int +getcolor(byte *s, int w, int h, int n, int u, int v, int k) { -#ifdef CLAMPUV if (u < 0) u = 0; if (v < 0) v = 0; if (u >= w) u = w - 1; if (v >= h) v = h - 1; -#else - if (u < 0) return 0; - if (v < 0) return 0; - if (u >= w) return 0; - if (v >= h) return 0; -#endif - return s[w * v + u]; + return s[w * v * n + u + k]; +} + +static inline int +lerp(int a, int b, int t) +{ + return a + (((b - a) * t) >> 16); +} + +static inline void +lerpargb(byte *dst, byte *a, byte *b, int t) +{ + dst[0] = lerp(a[0], b[0], t); + dst[1] = lerp(a[1], b[1], t); + dst[2] = lerp(a[2], b[2], t); + dst[3] = lerp(a[3], b[3], t); } -static inline int samplemask(byte *s, int w, int h, int u, int v) +static inline int +samplemask(byte *s, int w, int h, int u, int v) { int ui = u >> 16; int vi = v >> 16; @@ -68,32 +63,8 @@ static inline int samplemask(byte *s, int w, int h, int u, int v) return lerp(ab, cd, vd); } -static inline void lerpargb(byte *dst, byte *a, byte *b, int t) -{ - dst[0] = lerp(a[0], b[0], t); - dst[1] = lerp(a[1], b[1], t); - dst[2] = lerp(a[2], b[2], t); - dst[3] = lerp(a[3], b[3], t); -} - -static inline byte *getargb(byte *s, int w, int h, int u, int v) -{ -#ifdef CLAMPUV - if (u < 0) u = 0; - if (v < 0) v = 0; - if (u >= w) u = w - 1; - if (v >= h) v = h - 1; -#else - static byte t[4] = { 0, 0, 0, 0 }; - if (u < 0) return t; - if (v < 0) return t; - if (u >= w) return t; - if (v >= h) return t; -#endif - return s + ((w * v + u) << 2); -} - -static inline void sampleargb(byte *s, int w, int h, int u, int v, byte *abcd) +static inline void +sampleargb(byte *s, int w, int h, int u, int v, byte *out) { byte ab[4]; byte cd[4]; @@ -107,163 +78,101 @@ static inline void sampleargb(byte *s, int w, int h, int u, int v, byte *abcd) byte *d = getargb(s, w, h, ui+1, vi+1); lerpargb(ab, a, b, ud); lerpargb(cd, c, d, ud); - lerpargb(abcd, ab, cd, vd); + lerpargb(out, ab, cd, vd); } -static void img_ncn(FZ_PSRC, int srcn, FZ_PDST, FZ_PCTM) +static inline void +samplecolor(byte *s, int w, int h, int n, int u, int v, byte *out) { + int ui = u >> 16; + int vi = v >> 16; + int ud = u & 0xFFFF; + int vd = v & 0xFFFF; int k; - while (h--) - { - byte *dstp = dst0; - int u = u0; - int v = v0; - int w = w0; - while (w--) - { - for (k = 0; k < srcn; k++) - { - dstp[k] = samplecomp(src, srcw, srch, u, v, srcn, k); - dstp += srcn; - u += fa; - v += fb; - } - } - dst0 += dstw; - u0 += fc; - v0 += fd; - } -} - -static void img_1c1(FZ_PSRC, FZ_PDST, FZ_PCTM) -{ - while (h--) + for (k = 0; k < n; k++) { - byte *dstp = dst0; - int u = u0; - int v = v0; - int w = w0; - while (w--) - { - dstp[0] = samplemask(src, srcw, srch, u, v); - dstp ++; - u += fa; - v += fb; - } - dst0 += dstw; - u0 += fc; - v0 += fd; + int a = getcolor(s, w, h, n, ui, vi, k); + int b = getcolor(s, w, h, n, ui+1, vi, k); + int c = getcolor(s, w, h, n, ui, vi+1, k); + int d = getcolor(s, w, h, n, ui+1, vi+1, k); + int ab = lerp(a, b, ud); + int cd = lerp(c, d, ud); + out[k] = lerp(ab, cd, vd); } } -static void img_4c4(FZ_PSRC, FZ_PDST, FZ_PCTM) +static void +img_1o1(byte * restrict src, byte cov, int len, byte * restrict dst, + fz_pixmap *image, int u, int v, int fa, int fb) { - while (h--) + byte *samples = image->samples; + int w = image->w; + int h = image->h; + byte sa; + while (len--) { - byte *dstp = dst0; - int u = u0; - int v = v0; - int w = w0; - while (w--) - { - sampleargb(src, srcw, srch, u, v, dstp); - dstp += 4; - u += fa; - v += fb; - } - dst0 += dstw; - u0 += fc; - v0 += fd; + cov += *src; *src = 0; src++; + sa = fz_mul255(cov, samplemask(samples, w, h, u, v)); + dst[0] = sa + fz_mul255(dst[0], 255 - sa); + dst++; + u += fa; + v += fb; } } -static void img_1o1(FZ_PSRC, FZ_PDST, FZ_PCTM) -{ - byte srca; - while (h--) - { - byte *dstp = dst0; - int u = u0; - int v = v0; - int w = w0; - while (w--) - { - srca = samplemask(src, srcw, srch, u, v); - dstp[0] = srca + fz_mul255(dstp[0], 255 - srca); - dstp ++; - u += fa; - v += fb; - } - dst0 += dstw; - u0 += fc; - v0 += fd; - } -} - -static void img_4o4(FZ_PSRC, FZ_PDST, FZ_PCTM) +static void +img_4o4(byte * restrict src, byte cov, int len, byte * restrict dst, + fz_pixmap *image, int u, int v, int fa, int fb) { + byte *samples = image->samples; + int w = image->w; + int h = image->h; byte argb[4]; - byte ssa; - while (h--) + byte sa, ssa; + while (len--) { - byte *dstp = dst0; - int u = u0; - int v = v0; - int w = w0; - while (w--) - { - sampleargb(src, srcw, srch, u, v, argb); - ssa = 255 - argb[0]; - dstp[0] = argb[0] + fz_mul255(dstp[0], ssa); - dstp[1] = argb[1] + fz_mul255(dstp[1], ssa); - dstp[2] = argb[2] + fz_mul255(dstp[2], ssa); - dstp[3] = argb[3] + fz_mul255(dstp[3], ssa); - dstp += 4; - u += fa; - v += fb; - } - dst0 += dstw; - u0 += fc; - v0 += fd; + cov += *src; *src = 0; src++; + sampleargb(samples, w, h, u, v, argb); + sa = fz_mul255(argb[0], cov); + ssa = 255 - sa; + dst[0] = sa + fz_mul255(dst[0], ssa); + dst[1] = fz_mul255(argb[1], sa) + fz_mul255(dst[1], ssa); + dst[2] = fz_mul255(argb[2], sa) + fz_mul255(dst[2], ssa); + dst[3] = fz_mul255(argb[3], sa) + fz_mul255(dst[3], ssa); + dst += 4; + u += fa; + v += fb; } } -static void img_w4i1o4(byte *argb, FZ_PSRC, FZ_PDST, FZ_PCTM) +static void +img_w4i1o4(byte *argb, byte * restrict src, byte cov, int len, byte * restrict dst, + fz_pixmap *image, int u, int v, int fa, int fb) { + byte *samples = image->samples; + int w = image->w; + int h = image->h; byte alpha = argb[0]; byte r = argb[1]; byte g = argb[2]; byte b = argb[3]; - byte cov; - byte ca; - while (h--) + byte ca, cca; + while (len--) { - byte *dstp = dst0; - int u = u0; - int v = v0; - int w = w0; - while (w--) - { - cov = samplemask(src, srcw, srch, u, v); - ca = fz_mul255(cov, alpha); - dstp[0] = ca + fz_mul255(dstp[0], 255 - ca); - dstp[1] = fz_mul255((short)r - dstp[1], ca) + dstp[1]; - dstp[2] = fz_mul255((short)g - dstp[2], ca) + dstp[2]; - dstp[3] = fz_mul255((short)b - dstp[3], ca) + dstp[3]; - dstp += 4; - u += fa; - v += fb; - } - dst0 += dstw; - u0 += fc; - v0 += fd; + cov += *src; *src = 0; src++; + ca = fz_mul255(cov, samplemask(samples, w, h, u, v)); + ca = fz_mul255(ca, alpha); + cca = 255 - ca; + dst[0] = ca + fz_mul255(dst[0], cca); + dst[1] = fz_mul255(r, ca) + fz_mul255(dst[1], cca); + dst[2] = fz_mul255(g, ca) + fz_mul255(dst[2], cca); + dst[3] = fz_mul255(b, ca) + fz_mul255(dst[3], cca); + dst += 4; + u += fa; + v += fb; } } -void (*fz_img_ncn)(FZ_PSRC, int sn, FZ_PDST, FZ_PCTM) = img_ncn; -void (*fz_img_1c1)(FZ_PSRC, FZ_PDST, FZ_PCTM) = img_1c1; -void (*fz_img_4c4)(FZ_PSRC, FZ_PDST, FZ_PCTM) = img_4c4; -void (*fz_img_1o1)(FZ_PSRC, FZ_PDST, FZ_PCTM) = img_1o1; -void (*fz_img_4o4)(FZ_PSRC, FZ_PDST, FZ_PCTM) = img_4o4; -void (*fz_img_w4i1o4)(byte*,FZ_PSRC,FZ_PDST,FZ_PCTM) = img_w4i1o4; - +void (*fz_img_1o1)(byte*, byte, int, byte*, fz_pixmap *image, int u, int v, int fa, int fb) = img_1o1; +void (*fz_img_4o4)(byte*, byte, int, byte*, fz_pixmap *image, int u, int v, int fa, int fb) = img_4o4; +void (*fz_img_w4i1o4)(byte*, byte*, byte, int, byte*, fz_pixmap *image, int u, int v, int fa, int fb) = img_w4i1o4; diff --git a/draw/pathscan.c b/draw/pathscan.c index ebf9502a..b60eddd6 100644 --- a/draw/pathscan.c +++ b/draw/pathscan.c @@ -422,7 +422,7 @@ static inline void toalpha(unsigned char *list, int n) static inline void blit(fz_pixmap *pix, int x, int y, unsigned char *list, int skipx, int len, - unsigned char *argb, int over) + unsigned char *argb, fz_pixmap *image, fz_matrix *invmat) { unsigned char *dst; unsigned char cov; @@ -437,17 +437,31 @@ static inline void blit(fz_pixmap *pix, int x, int y, ++list; } - if (argb) - fz_path_w4i1o4(argb, list, cov, len, dst); - else if (over) - fz_path_1o1(list, cov, len, dst); + if (image) + { + int u = (invmat->a * (x + 0.5) + invmat->c * (y + 0.5) + invmat->e) * 65536; + int v = (invmat->b * (x + 0.5) + invmat->d * (y + 0.5) + invmat->f) * 65536; + int fa = invmat->a * 65536; + int fb = invmat->b * 65536; + if (argb) + fz_img_w4i1o4(argb, list, cov, len, dst, image, u, v, fa, fb); + else if (image->colorspace) + fz_img_4o4(list, cov, len, dst, image, u, v, fa, fb); + else + fz_img_1o1(list, cov, len, dst, image, u, v, fa, fb); + } else - fz_path_1c1(list, cov, len, dst); + { + if (argb) + fz_path_w4i1o4(argb, list, cov, len, dst); + else + fz_path_1o1(list, cov, len, dst); + } } fz_error fz_scanconvert(fz_gel *gel, fz_ael *ael, int eofill, fz_bbox clip, - fz_pixmap *pix, unsigned char *argb, int over) + fz_pixmap *pix, unsigned char *argb, fz_pixmap *image, fz_matrix *invmat) { fz_error error; unsigned char *deltas; @@ -483,7 +497,7 @@ fz_scanconvert(fz_gel *gel, fz_ael *ael, int eofill, fz_bbox clip, { if (yd >= clip.y0 && yd < clip.y1) { - blit(pix, xmin + skipx, yd, deltas, skipx, clipn, argb, over); + blit(pix, xmin + skipx, yd, deltas, skipx, clipn, argb, image, invmat); } } yd = yc; @@ -512,7 +526,7 @@ fz_scanconvert(fz_gel *gel, fz_ael *ael, int eofill, fz_bbox clip, if (yd >= clip.y0 && yd < clip.y1) { - blit(pix, xmin + skipx, yd, deltas, skipx, clipn, argb, over); + blit(pix, xmin + skipx, yd, deltas, skipx, clipn, argb, image, invmat); } fz_free(deltas); diff --git a/draw/porterduff.c b/draw/porterduff.c index 64fa842f..1441a358 100644 --- a/draw/porterduff.c +++ b/draw/porterduff.c @@ -32,32 +32,6 @@ duff_non(byte * restrict sp0, int sw, int sn, byte * restrict dp0, int dw, int w } } -/* dst = src in msk */ -static void -duff_nimcn(byte * restrict sp0, int sw, int sn, byte * restrict mp0, int mw, int mn, byte * restrict dp0, int dw, int w0, int h) -{ - int k; - while (h--) - { - byte *sp = sp0; - byte *mp = mp0; - byte *dp = dp0; - int w = w0; - while (w--) - { - byte ma = mp[0]; - for (k = 0; k < sn; k++) - dp[k] = fz_mul255(sp[k], ma); - sp += sn; - mp += mn; - dp += sn; - } - sp0 += sw; - mp0 += mw; - dp0 += dw; - } -} - /* dst = src in msk over dst */ static void duff_nimon(byte * restrict sp0, int sw, int sn, byte * restrict mp0, int mw, int mn, byte * restrict dp0, int dw, int w0, int h) @@ -89,7 +63,8 @@ duff_nimon(byte * restrict sp0, int sw, int sn, byte * restrict mp0, int mw, int } } -static void duff_1o1(byte * restrict sp0, int sw, byte * restrict dp0, int dw, int w0, int h) +static void +duff_1o1(byte * restrict sp0, int sw, byte * restrict dp0, int dw, int w0, int h) { /* duff_non(sp0, sw, 1, dp0, dw, w0, h); */ while (h--) @@ -108,7 +83,8 @@ static void duff_1o1(byte * restrict sp0, int sw, byte * restrict dp0, int dw, i } } -static void duff_4o4(byte *sp0, int sw, byte *dp0, int dw, int w0, int h) +static void +duff_4o4(byte *sp0, int sw, byte *dp0, int dw, int w0, int h) { /* duff_non(sp0, sw, 4, dp0, dw, w0, h); */ while (h--) @@ -131,55 +107,8 @@ static void duff_4o4(byte *sp0, int sw, byte *dp0, int dw, int w0, int h) } } -static void duff_1i1c1(byte * restrict sp0, int sw, byte * restrict mp0, int mw, byte * restrict dp0, int dw, int w0, int h) -{ - /* duff_nimcn(sp0, sw, 1, mp0, mw, 1, dp0, dw, w0, h); */ - while (h--) - { - byte *sp = sp0; - byte *mp = mp0; - byte *dp = dp0; - int w = w0; - while (w--) - { - dp[0] = fz_mul255(sp[0], mp[0]); - sp ++; - mp ++; - dp ++; - } - sp0 += sw; - mp0 += mw; - dp0 += dw; - } -} - -static void duff_4i1c4(byte * restrict sp0, int sw, byte * restrict mp0, int mw, byte * restrict dp0, int dw, int w0, int h) -{ - /* duff_nimcn(sp0, sw, 4, mp0, mw, 1, dp0, dw, w0, h); */ - while (h--) - { - byte *sp = sp0; - byte *mp = mp0; - byte *dp = dp0; - int w = w0; - while (w--) - { - byte ma = mp[0]; - dp[0] = fz_mul255(sp[0], ma); - dp[1] = fz_mul255(sp[1], ma); - dp[2] = fz_mul255(sp[2], ma); - dp[3] = fz_mul255(sp[3], ma); - sp += 4; - mp += 1; - dp += 4; - } - sp0 += sw; - mp0 += mw; - dp0 += dw; - } -} - -static void duff_1i1o1(byte * restrict sp0, int sw, byte * restrict mp0, int mw, byte * restrict dp0, int dw, int w0, int h) +static void +duff_1i1o1(byte * restrict sp0, int sw, byte * restrict mp0, int mw, byte * restrict dp0, int dw, int w0, int h) { /* duff_nimon(sp0, sw, 1, mp0, mw, 1, dp0, dw, w0, h); */ while (h--) @@ -204,7 +133,8 @@ static void duff_1i1o1(byte * restrict sp0, int sw, byte * restrict mp0, int mw, } } -static void duff_4i1o4(byte * restrict sp0, int sw, byte * restrict mp0, int mw, byte * restrict dp0, int dw, int w0, int h) +static void +duff_4i1o4(byte * restrict sp0, int sw, byte * restrict mp0, int mw, byte * restrict dp0, int dw, int w0, int h) { /* duff_nimon(sp0, sw, 4, mp0, mw, 1, dp0, dw, w0, h); */ while (h--) @@ -233,19 +163,11 @@ static void duff_4i1o4(byte * restrict sp0, int sw, byte * restrict mp0, int mw, } /* - * Path and text masks + * Path masks */ -static void path_1c1(byte * restrict src, byte cov, int len, byte * restrict dst) -{ - while (len--) - { - cov += *src; *src = 0; src++; - *dst++ = cov; - } -} - -static void path_1o1(byte * restrict src, byte cov, int len, byte * restrict dst) +static void +path_1o1(byte * restrict src, byte cov, int len, byte * restrict dst) { while (len--) { @@ -255,8 +177,8 @@ static void path_1o1(byte * restrict src, byte cov, int len, byte * restrict dst } } -// With 4 In 1 Over 4 -static void path_w4i1o4(byte * restrict argb, byte * restrict src, byte cov, int len, byte * restrict dst) +static void +path_w4i1o4(byte * restrict argb, byte * restrict src, byte cov, int len, byte * restrict dst) { byte alpha = argb[0]; byte r = argb[1]; @@ -268,7 +190,7 @@ static void path_w4i1o4(byte * restrict argb, byte * restrict src, byte cov, int cov += *src; *src = 0; src++; ca = fz_mul255(cov, alpha); cca = 255 - ca; - dst[0] = ca + fz_mul255(dst[0], 255 - ca); + dst[0] = ca + fz_mul255(dst[0], cca); dst[1] = fz_mul255(r, ca) + fz_mul255(dst[1], cca); dst[2] = fz_mul255(g, ca) + fz_mul255(dst[2], cca); dst[3] = fz_mul255(b, ca) + fz_mul255(dst[3], cca); @@ -276,23 +198,12 @@ static void path_w4i1o4(byte * restrict argb, byte * restrict src, byte cov, int } } -static void text_1c1(byte * restrict src0, int srcw, byte * restrict dst0, int dstw, int w0, int h) -{ - while (h--) - { - byte * restrict src = src0; - byte * restrict dst = dst0; - int w = w0; - while (w--) - { - *dst++ = *src++; - } - src0 += srcw; - dst0 += dstw; - } -} +/* + * Text masks + */ -static void text_1o1(byte * restrict src0, int srcw, byte * restrict dst0, int dstw, int w0, int h) +static void +text_1o1(byte * restrict src0, int srcw, byte * restrict dst0, int dstw, int w0, int h) { while (h--) { @@ -310,7 +221,8 @@ static void text_1o1(byte * restrict src0, int srcw, byte * restrict dst0, int d } } -static void text_w4i1o4(byte * restrict argb, byte * restrict src0, int srcw, byte * restrict dst0, int dstw, int w0, int h) +static void +text_w4i1o4(byte * restrict argb, byte * restrict src0, int srcw, byte * restrict dst0, int dstw, int w0, int h) { unsigned char alpha = argb[0]; unsigned char r = argb[1]; @@ -325,7 +237,7 @@ static void text_w4i1o4(byte * restrict argb, byte * restrict src0, int srcw, by { byte ca = fz_mul255(src[0], alpha); byte cca = 255 - ca; - dst[0] = ca + fz_mul255(dst[0], 255 - ca); + dst[0] = ca + fz_mul255(dst[0], cca); dst[1] = fz_mul255(r, ca) + fz_mul255(dst[1], cca); dst[2] = fz_mul255(g, ca) + fz_mul255(dst[2], cca); dst[3] = fz_mul255(b, ca) + fz_mul255(dst[3], cca); @@ -342,20 +254,15 @@ static void text_w4i1o4(byte * restrict argb, byte * restrict src0, int srcw, by */ void (*fz_duff_non)(byte*,int,int,byte*,int,int,int) = duff_non; -void (*fz_duff_nimcn)(byte*,int,int,byte*,int,int,byte*,int,int,int) = duff_nimcn; void (*fz_duff_nimon)(byte*,int,int,byte*,int,int,byte*,int,int,int) = duff_nimon; void (*fz_duff_1o1)(byte*,int,byte*,int,int,int) = duff_1o1; void (*fz_duff_4o4)(byte*,int,byte*,int,int,int) = duff_4o4; -void (*fz_duff_1i1c1)(byte*,int,byte*,int,byte*,int,int,int) = duff_1i1c1; -void (*fz_duff_4i1c4)(byte*,int,byte*,int,byte*,int,int,int) = duff_4i1c4; void (*fz_duff_1i1o1)(byte*,int,byte*,int,byte*,int,int,int) = duff_1i1o1; void (*fz_duff_4i1o4)(byte*,int,byte*,int,byte*,int,int,int) = duff_4i1o4; -void (*fz_path_1c1)(byte*,byte,int,byte*) = path_1c1; void (*fz_path_1o1)(byte*,byte,int,byte*) = path_1o1; void (*fz_path_w4i1o4)(byte*,byte*,byte,int,byte*) = path_w4i1o4; -void (*fz_text_1c1)(byte*,int,byte*,int,int,int) = text_1c1; void (*fz_text_1o1)(byte*,int,byte*,int,int,int) = text_1o1; void (*fz_text_w4i1o4)(byte*,byte*,int,byte*,int,int,int) = text_w4i1o4; diff --git a/fitz/dev_draw.c b/fitz/dev_draw.c index cc7bdc0c..1b2b4ded 100644 --- a/fitz/dev_draw.c +++ b/fitz/dev_draw.c @@ -133,11 +133,11 @@ fz_drawfillpath(void *user, fz_path *path, int evenodd, fz_matrix ctm, argb[1] = rgb[0] * 255; argb[2] = rgb[1] * 255; argb[3] = rgb[2] * 255; - fz_scanconvert(dev->gel, dev->ael, evenodd, bbox, dev->dest, argb, 1); + fz_scanconvert(dev->gel, dev->ael, evenodd, bbox, dev->dest, argb, nil, nil); } else { - fz_scanconvert(dev->gel, dev->ael, evenodd, bbox, dev->dest, nil, 1); + fz_scanconvert(dev->gel, dev->ael, evenodd, bbox, dev->dest, nil, nil, nil); } } @@ -176,11 +176,11 @@ fz_drawstrokepath(void *user, fz_path *path, fz_strokestate *stroke, fz_matrix c argb[1] = rgb[0] * 255; argb[2] = rgb[1] * 255; argb[3] = rgb[2] * 255; - fz_scanconvert(dev->gel, dev->ael, 0, bbox, dev->dest, argb, 1); + fz_scanconvert(dev->gel, dev->ael, 0, bbox, dev->dest, argb, nil, nil); } else { - fz_scanconvert(dev->gel, dev->ael, 0, bbox, dev->dest, nil, 1); + fz_scanconvert(dev->gel, dev->ael, 0, bbox, dev->dest, nil, nil, nil); } } @@ -222,7 +222,7 @@ fz_drawclippath(void *user, fz_path *path, int evenodd, fz_matrix ctm) memset(mask->samples, 0, mask->w * mask->h * mask->n); memset(dest->samples, 0, dest->w * dest->h * dest->n); - fz_scanconvert(dev->gel, dev->ael, evenodd, bbox, mask, nil, 1); + fz_scanconvert(dev->gel, dev->ael, evenodd, bbox, mask, nil, nil, nil); dev->clipstack[dev->cliptop].scissor = dev->scissor; dev->clipstack[dev->cliptop].mask = mask; @@ -268,7 +268,7 @@ fz_drawclipstrokepath(void *user, fz_path *path, fz_strokestate *stroke, fz_matr memset(dest->samples, 0, dest->w * dest->h * dest->n); if (!fz_isemptyrect(bbox)) - fz_scanconvert(dev->gel, dev->ael, 0, bbox, mask, nil, 1); + fz_scanconvert(dev->gel, dev->ael, 0, bbox, mask, nil, nil, nil); dev->clipstack[dev->cliptop].scissor = dev->scissor; dev->clipstack[dev->cliptop].mask = mask; @@ -515,49 +515,66 @@ fz_drawfillshade(void *user, fz_shade *shade, fz_matrix ctm) } static inline void -calcimagescale(fz_matrix ctm, int w, int h, int *odx, int *ody) +calcimagestate(fz_drawdevice *dev, fz_pixmap *image, fz_matrix ctm, + fz_bbox *bbox, fz_matrix *invmat, int *dx, int *dy) { - float sx = w / sqrt(ctm.a * ctm.a + ctm.b * ctm.b); - float sy = h / sqrt(ctm.c * ctm.c + ctm.d * ctm.d); + float sx, sy; + fz_path *path; + fz_matrix mat; + int w, h; + + sx = image->w / sqrt(ctm.a * ctm.a + ctm.b * ctm.b); + sy = image->h / sqrt(ctm.c * ctm.c + ctm.d * ctm.d); if (sx < 1.0) - *odx = 1; + *dx = 1; else - *odx = sx; + *dx = sx; if (sy < 1.0) - *ody = 1; + *dy = 1; else - *ody = sy; -} + *dy = sy; + + w = image->w / *dx; + h = image->h / *dy; + + path = fz_newpath(); + fz_moveto(path, 0.0, 0.0); + fz_lineto(path, 1.0, 0.0); + fz_lineto(path, 1.0, 1.0); + fz_lineto(path, 0.0, 1.0); + fz_closepath(path); -#define PDST(p) p->samples + ((y0-p->y) * p->w + (x0-p->x)) * p->n, p->w * p->n + fz_resetgel(dev->gel, dev->scissor); + fz_fillpath(dev->gel, path, ctm, 1.0); + fz_sortgel(dev->gel); + + fz_freepath(path); + + *bbox = fz_boundgel(dev->gel); + *bbox = fz_intersectbbox(*bbox, dev->scissor); + + mat.a = 1.0 / w; + mat.b = 0.0; + mat.c = 0.0; + mat.d = -1.0 / h; + mat.e = 0.0; + mat.f = 1.0; + *invmat = fz_invertmatrix(fz_concat(mat, ctm)); + invmat->e -= 0.5; + invmat->f -= 0.5; +} static void fz_drawfillimage(void *user, fz_pixmap *image, fz_matrix ctm) { fz_drawdevice *dev = user; - fz_rect bounds; fz_bbox bbox; int dx, dy; fz_pixmap *scaled = nil; fz_pixmap *converted = nil; - fz_matrix imgmat; fz_matrix invmat; - int fa, fb, fc, fd; - int u0, v0; - int x0, y0; - int w, h; - - bounds = fz_transformrect(ctm, fz_unitrect); - bbox = fz_roundrect(bounds); - bbox = fz_intersectbbox(bbox, dev->scissor); - - if (fz_isemptyrect(bbox)) - return; - - if (image->w == 0 || image->h == 0) - return; if (!dev->model) { @@ -565,7 +582,10 @@ fz_drawfillimage(void *user, fz_pixmap *image, fz_matrix ctm) return; } - calcimagescale(ctm, image->w, image->h, &dx, &dy); + calcimagestate(dev, image, ctm, &bbox, &invmat, &dx, &dy); + + if (fz_isemptyrect(bbox) || image->w == 0 || image->h == 0) + return; if (dx != 1 || dy != 1) { @@ -580,34 +600,7 @@ fz_drawfillimage(void *user, fz_pixmap *image, fz_matrix ctm) image = converted; } - imgmat.a = 1.0 / image->w; - imgmat.b = 0.0; - imgmat.c = 0.0; - imgmat.d = -1.0 / image->h; - imgmat.e = 0.0; - imgmat.f = 1.0; - invmat = fz_invertmatrix(fz_concat(imgmat, ctm)); - - invmat.e -= 0.5; - invmat.f -= 0.5; - - w = bbox.x1 - bbox.x0; - h = bbox.y1 - bbox.y0; - x0 = bbox.x0; - y0 = bbox.y0; - u0 = (invmat.a * (x0+0.5) + invmat.c * (y0+0.5) + invmat.e) * 65536; - v0 = (invmat.b * (x0+0.5) + invmat.d * (y0+0.5) + invmat.f) * 65536; - fa = invmat.a * 65536; - fb = invmat.b * 65536; - fc = invmat.c * 65536; - fd = invmat.d * 65536; - - if (dev->dest->colorspace) - fz_img_4o4(image->samples, image->w, image->h, PDST(dev->dest), - u0, v0, fa, fb, fc, fd, w, h); - else - fz_img_1o1(image->samples, image->w, image->h, PDST(dev->dest), - u0, v0, fa, fb, fc, fd, w, h); + fz_scanconvert(dev->gel, dev->ael, 0, bbox, dev->dest, nil, image, &invmat); if (scaled) fz_droppixmap(scaled); @@ -620,57 +613,22 @@ fz_drawfillimagemask(void *user, fz_pixmap *image, fz_matrix ctm, fz_colorspace *colorspace, float *color, float alpha) { fz_drawdevice *dev = user; - fz_rect bounds; fz_bbox bbox; int dx, dy; fz_pixmap *scaled = nil; - fz_matrix imgmat; fz_matrix invmat; - int fa, fb, fc, fd; - int u0, v0; - int x0, y0; - int w, h; - bounds = fz_transformrect(ctm, fz_unitrect); - bbox = fz_roundrect(bounds); - bbox = fz_intersectbbox(bbox, dev->scissor); + calcimagestate(dev, image, ctm, &bbox, &invmat, &dx, &dy); - if (fz_isemptyrect(bbox)) + if (fz_isemptyrect(bbox) || image->w == 0 || image->h == 0) return; - if (image->w == 0 || image->h == 0) - return; - - calcimagescale(ctm, image->w, image->h, &dx, &dy); - if (dx != 1 || dy != 1) { scaled = fz_scalepixmap(image, dx, dy); image = scaled; } - imgmat.a = 1.0 / image->w; - imgmat.b = 0.0; - imgmat.c = 0.0; - imgmat.d = -1.0 / image->h; - imgmat.e = 0.0; - imgmat.f = 1.0; - invmat = fz_invertmatrix(fz_concat(imgmat, ctm)); - - invmat.e -= 0.5; - invmat.f -= 0.5; - - w = bbox.x1 - bbox.x0; - h = bbox.y1 - bbox.y0; - x0 = bbox.x0; - y0 = bbox.y0; - u0 = (invmat.a * (x0+0.5) + invmat.c * (y0+0.5) + invmat.e) * 65536; - v0 = (invmat.b * (x0+0.5) + invmat.d * (y0+0.5) + invmat.f) * 65536; - fa = invmat.a * 65536; - fb = invmat.b * 65536; - fc = invmat.c * 65536; - fd = invmat.d * 65536; - if (dev->dest->colorspace) { unsigned char argb[4]; @@ -680,13 +638,11 @@ fz_drawfillimagemask(void *user, fz_pixmap *image, fz_matrix ctm, argb[1] = rgb[0] * 255; argb[2] = rgb[1] * 255; argb[3] = rgb[2] * 255; - fz_img_w4i1o4(argb, image->samples, image->w, image->h, PDST(dev->dest), - u0, v0, fa, fb, fc, fd, w, h); + fz_scanconvert(dev->gel, dev->ael, 0, bbox, dev->dest, argb, image, &invmat); } else { - fz_img_1o1(image->samples, image->w, image->h, PDST(dev->dest), - u0, v0, fa, fb, fc, fd, w, h); + fz_scanconvert(dev->gel, dev->ael, 0, bbox, dev->dest, nil, image, &invmat); } if (scaled) @@ -697,17 +653,11 @@ static void fz_drawclipimagemask(void *user, fz_pixmap *image, fz_matrix ctm) { fz_drawdevice *dev = user; - fz_rect bounds; fz_bbox bbox; fz_pixmap *mask, *dest; int dx, dy; fz_pixmap *scaled = nil; - fz_matrix imgmat; fz_matrix invmat; - int fa, fb, fc, fd; - int u0, v0; - int x0, y0; - int w, h; if (dev->cliptop == MAXCLIP) { @@ -715,11 +665,9 @@ fz_drawclipimagemask(void *user, fz_pixmap *image, fz_matrix ctm) return; } - bounds = fz_transformrect(ctm, fz_unitrect); - bbox = fz_roundrect(bounds); - bbox = fz_intersectbbox(bbox, dev->scissor); + calcimagestate(dev, image, ctm, &bbox, &invmat, &dx, &dy); - if (fz_isemptyrect(bbox) || (image->w == 0 || image->h == 0)) + if (fz_isemptyrect(bbox) || image->w == 0 || image->h == 0) { dev->clipstack[dev->cliptop].scissor = dev->scissor; dev->clipstack[dev->cliptop].mask = nil; @@ -729,44 +677,19 @@ fz_drawclipimagemask(void *user, fz_pixmap *image, fz_matrix ctm) return; } - calcimagescale(ctm, image->w, image->h, &dx, &dy); - if (dx != 1 || dy != 1) { scaled = fz_scalepixmap(image, dx, dy); image = scaled; } - imgmat.a = 1.0 / image->w; - imgmat.b = 0.0; - imgmat.c = 0.0; - imgmat.d = -1.0 / image->h; - imgmat.e = 0.0; - imgmat.f = 1.0; - invmat = fz_invertmatrix(fz_concat(imgmat, ctm)); - - invmat.e -= 0.5; - invmat.f -= 0.5; - - w = bbox.x1 - bbox.x0; - h = bbox.y1 - bbox.y0; - x0 = bbox.x0; - y0 = bbox.y0; - u0 = (invmat.a * (x0+0.5) + invmat.c * (y0+0.5) + invmat.e) * 65536; - v0 = (invmat.b * (x0+0.5) + invmat.d * (y0+0.5) + invmat.f) * 65536; - fa = invmat.a * 65536; - fb = invmat.b * 65536; - fc = invmat.c * 65536; - fd = invmat.d * 65536; - mask = fz_newpixmapwithrect(nil, bbox); dest = fz_newpixmapwithrect(dev->model, bbox); memset(mask->samples, 0, mask->w * mask->h * mask->n); memset(dest->samples, 0, dest->w * dest->h * dest->n); - fz_img_1o1(image->samples, image->w, image->h, PDST(mask), - u0, v0, fa, fb, fc, fd, w, h); + fz_scanconvert(dev->gel, dev->ael, 0, bbox, mask, nil, image, &invmat); dev->clipstack[dev->cliptop].scissor = dev->scissor; dev->clipstack[dev->cliptop].mask = mask; diff --git a/fitz/fitz_draw.h b/fitz/fitz_draw.h index e26a4386..a4aa8677 100644 --- a/fitz/fitz_draw.h +++ b/fitz/fitz_draw.h @@ -57,7 +57,7 @@ fz_ael * fz_newael(void); void fz_freeael(fz_ael *ael); fz_error fz_scanconvert(fz_gel *gel, fz_ael *ael, int eofill, - fz_bbox clip, fz_pixmap *pix, unsigned char *argb, int over); + fz_bbox clip, fz_pixmap *pix, unsigned char *argb, fz_pixmap *image, fz_matrix *invmat); void fz_fillpath(fz_gel *gel, fz_path *path, fz_matrix ctm, float flatness); void fz_strokepath(fz_gel *gel, fz_path *path, fz_strokestate *stroke, fz_matrix ctm, float flatness, float linewidth); @@ -67,39 +67,25 @@ void fz_dashpath(fz_gel *gel, fz_path *path, fz_strokestate *stroke, fz_matrix c * Function pointers -- they can be replaced by cpu-optimized versions */ -#define FZ_PSRC \ - unsigned char *src, int srcw, int srch -#define FZ_PDST \ - unsigned char *dst0, int dstw -#define FZ_PCTM \ - int u0, int v0, int fa, int fb, int fc, int fd, int w0, int h - extern void fz_accelerate(void); extern void (*fz_duff_non)(unsigned char*,int,int,unsigned char*,int,int,int); -extern void (*fz_duff_nimcn)(unsigned char*,int,int,unsigned char*,int,int,unsigned char*,int,int,int); extern void (*fz_duff_nimon)(unsigned char*,int,int,unsigned char*,int,int,unsigned char*,int,int,int); extern void (*fz_duff_1o1)(unsigned char*,int,unsigned char*,int,int,int); extern void (*fz_duff_4o4)(unsigned char*,int,unsigned char*,int,int,int); -extern void (*fz_duff_1i1c1)(unsigned char*,int,unsigned char*,int,unsigned char*,int,int,int); -extern void (*fz_duff_4i1c4)(unsigned char*,int,unsigned char*,int,unsigned char*,int,int,int); extern void (*fz_duff_1i1o1)(unsigned char*,int,unsigned char*,int,unsigned char*,int,int,int); extern void (*fz_duff_4i1o4)(unsigned char*,int,unsigned char*,int,unsigned char*,int,int,int); -extern void (*fz_path_1c1)(unsigned char*,unsigned char,int,unsigned char*); extern void (*fz_path_1o1)(unsigned char*,unsigned char,int,unsigned char*); extern void (*fz_path_w4i1o4)(unsigned char*,unsigned char*,unsigned char,int,unsigned char*); -extern void (*fz_text_1c1)(unsigned char*,int,unsigned char*,int,int,int); extern void (*fz_text_1o1)(unsigned char*,int,unsigned char*,int,int,int); extern void (*fz_text_w4i1o4)(unsigned char*,unsigned char*,int,unsigned char*,int,int,int); -extern void (*fz_img_ncn)(FZ_PSRC, int sn, FZ_PDST, FZ_PCTM); -extern void (*fz_img_1c1)(FZ_PSRC, FZ_PDST, FZ_PCTM); -extern void (*fz_img_4c4)(FZ_PSRC, FZ_PDST, FZ_PCTM); -extern void (*fz_img_1o1)(FZ_PSRC, FZ_PDST, FZ_PCTM); -extern void (*fz_img_4o4)(FZ_PSRC, FZ_PDST, FZ_PCTM); -extern void (*fz_img_w4i1o4)(unsigned char*,FZ_PSRC,FZ_PDST,FZ_PCTM); +extern void (*fz_img_non)(unsigned char*,unsigned char,int,unsigned char*,fz_pixmap*,fz_matrix*); +extern void (*fz_img_1o1)(unsigned char*,unsigned char,int,unsigned char*,fz_pixmap*,int u, int v, int fa, int fb); +extern void (*fz_img_4o4)(unsigned char*,unsigned char,int,unsigned char*,fz_pixmap*,int u, int v, int fa, int fb); +extern void (*fz_img_w4i1o4)(unsigned char*,unsigned char*,unsigned char,int,unsigned char*,fz_pixmap*,int u, int v, int fa, int fb); extern void (*fz_decodetile)(fz_pixmap *pix, int skip, float *decode); extern void (*fz_loadtile1)(unsigned char*, int sw, unsigned char*, int dw, int w, int h, int pad); diff --git a/mupdf/pdf_build.c b/mupdf/pdf_build.c index 9129d660..996e1212 100644 --- a/mupdf/pdf_build.c +++ b/mupdf/pdf_build.c @@ -261,7 +261,6 @@ pdf_showshade(pdf_csi *csi, fz_shade *shd) void pdf_showimage(pdf_csi *csi, pdf_image *image) { - fz_path *path = nil; pdf_gstate *gstate = csi->gstate + csi->gtop; fz_pixmap *tile = fz_newpixmap(image->cs, 0, 0, image->w, image->h); fz_error error = pdf_loadtile(image, tile); @@ -272,15 +271,6 @@ pdf_showimage(pdf_csi *csi, pdf_image *image) return; } - /* TODO: clip against a unit rectangle in the image blit instead */ - path = fz_newpath(); - fz_moveto(path, 0.0, 0.0); - fz_lineto(path, 1.0, 0.0); - fz_lineto(path, 1.0, 1.0); - fz_lineto(path, 0.0, 1.0); - fz_closepath(path); - csi->dev->clippath(csi->dev->user, path, 0, gstate->ctm); - if (image->mask) { fz_pixmap *mask = fz_newpixmap(NULL, 0, 0, image->mask->w, image->mask->h); @@ -330,9 +320,6 @@ pdf_showimage(pdf_csi *csi, pdf_image *image) if (image->mask) csi->dev->popclip(csi->dev->user); - fz_freepath(path); - csi->dev->popclip(csi->dev->user); - fz_droppixmap(tile); } |