summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTor Andersson <tor@ghostscript.com>2010-05-20 23:49:12 +0200
committerTor Andersson <tor@ghostscript.com>2010-05-20 23:49:12 +0200
commit20191dcca2bde592da73db125193bb773c62f502 (patch)
treea11da9f79a120cbbfabe6e80605abe49a09a7b33
parent30b8e3187fed0ad8f4c879cbe08fdd75f496e693 (diff)
downloadmupdf-20191dcca2bde592da73db125193bb773c62f502.tar.xz
Draw images with anti-aliased edges.
-rw-r--r--draw/archx86.c6
-rw-r--r--draw/imagedraw.c295
-rw-r--r--draw/pathscan.c32
-rw-r--r--draw/porterduff.c137
-rw-r--r--fitz/dev_draw.c197
-rw-r--r--fitz/fitz_draw.h24
-rw-r--r--mupdf/pdf_build.c13
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);
}