summaryrefslogtreecommitdiff
path: root/draw
diff options
context:
space:
mode:
authorRobin Watts <robin.watts@artifex.com>2010-06-22 20:20:12 +0200
committerRobin Watts <robin.watts@artifex.com>2010-06-22 20:20:12 +0200
commit685f0177891376b1d0e02de5c95d9ec3175228b3 (patch)
treebee588d8bbbf22c1ea631092438e8f3445442960 /draw
parent0edb7f95c50f0012ae173b3fa42cebe2905f1826 (diff)
downloadmupdf-685f0177891376b1d0e02de5c95d9ec3175228b3.tar.xz
Add support for greyscale rendering to the mupdf core and pdfdraw.
Diffstat (limited to 'draw')
-rw-r--r--draw/imagedraw.c123
-rw-r--r--draw/imageunpack.c2
-rw-r--r--draw/pathscan.c54
-rw-r--r--draw/porterduff.c53
4 files changed, 223 insertions, 9 deletions
diff --git a/draw/imagedraw.c b/draw/imagedraw.c
index 9f6d93bf..81d2bb05 100644
--- a/draw/imagedraw.c
+++ b/draw/imagedraw.c
@@ -22,6 +22,16 @@ getargb(byte *s, int w, int h, int u, int v)
return s + ((w * v + u) << 2);
}
+static inline byte *
+getag(byte *s, int w, int h, int u, int v)
+{
+ 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) << 1);
+}
+
static inline int
getcolor(byte *s, int w, int h, int n, int u, int v, int k)
{
@@ -39,6 +49,13 @@ lerp(int a, int b, int t)
}
static inline void
+lerpag(byte *dst, byte *a, byte *b, int t)
+{
+ dst[0] = lerp(a[0], b[0], t);
+ dst[1] = lerp(a[1], b[1], t);
+}
+
+static inline void
lerpargb(byte *dst, byte *a, byte *b, int t)
{
dst[0] = lerp(a[0], b[0], t);
@@ -64,6 +81,24 @@ samplemask(byte *s, int w, int h, int u, int v)
}
static inline void
+sampleag(byte *s, int w, int h, int u, int v, byte *out)
+{
+ byte ab[4];
+ byte cd[4];
+ int ui = u >> 16;
+ int vi = v >> 16;
+ int ud = u & 0xFFFF;
+ int vd = v & 0xFFFF;
+ byte *a = getag(s, w, h, ui, vi);
+ byte *b = getag(s, w, h, ui+1, vi);
+ byte *c = getag(s, w, h, ui, vi+1);
+ byte *d = getag(s, w, h, ui+1, vi+1);
+ lerpag(ab, a, b, ud);
+ lerpag(cd, c, d, ud);
+ lerpag(out, ab, cd, vd);
+}
+
+static inline void
sampleargb(byte *s, int w, int h, int u, int v, byte *out)
{
byte ab[4];
@@ -129,6 +164,35 @@ img_1o1(byte * restrict src, byte cov, int len, byte * restrict dst,
}
static void
+img_2o2(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 ag[2];
+
+ while (len--)
+ {
+ int sa;
+ cov += *src; *src = 0; src++;
+ if (cov != 0)
+ {
+ sampleag(samples, w, h, u, v, ag);
+ sa = FZ_COMBINE(FZ_EXPAND(ag[0]), FZ_EXPAND(cov));
+ if (sa != 0)
+ {
+ dst[0] = FZ_BLEND(255, dst[0], sa);
+ dst[1] = FZ_BLEND(ag[1], dst[1], sa);
+ }
+ }
+ dst += 2;
+ u += fa;
+ v += fb;
+ }
+}
+
+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)
{
@@ -160,6 +224,63 @@ img_4o4(byte * restrict src, byte cov, int len, byte * restrict dst,
}
static void
+img_w2i1o2(byte *ag, 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;
+ int alpha = FZ_EXPAND(ag[0]);
+ byte g = ag[1];
+
+ if (alpha == 0)
+ return;
+ if (alpha != 256)
+ {
+ while (len--)
+ {
+ int ca;
+ cov += *src; *src = 0; src++;
+ if (cov != 0)
+ {
+ ca = samplemask(samples, w, h, u, v);
+ ca =FZ_COMBINE(FZ_EXPAND(cov),FZ_EXPAND(ca));
+ ca = FZ_COMBINE(ca, alpha);
+ if (ca != 0)
+ {
+ dst[0] = FZ_BLEND(255, dst[0], ca);
+ dst[1] = FZ_BLEND(g, dst[1], ca);
+ }
+ }
+ dst += 2;
+ u += fa;
+ v += fb;
+ }
+ }
+ else
+ {
+ while (len--)
+ {
+ int ca;
+ cov += *src; *src = 0; src++;
+ if (cov != 0)
+ {
+ ca = samplemask(samples, w, h, u, v);
+ ca =FZ_COMBINE(FZ_EXPAND(cov),FZ_EXPAND(ca));
+ if (ca != 0)
+ {
+ dst[0] = FZ_BLEND(255, dst[0], ca);
+ dst[1] = FZ_BLEND(g, dst[1], ca);
+ }
+ }
+ dst += 2;
+ u += fa;
+ v += fb;
+ }
+ }
+}
+
+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)
{
@@ -223,5 +344,7 @@ img_w4i1o4(byte *argb, byte * restrict src, byte cov, int len, byte * restrict d
}
void (*fz_img_1o1)(byte*, byte, int, byte*, fz_pixmap *image, int u, int v, int fa, int fb) = img_1o1;
+void (*fz_img_2o2)(byte*, byte, int, byte*, fz_pixmap *image, int u, int v, int fa, int fb) = img_2o2;
void (*fz_img_4o4)(byte*, byte, int, byte*, fz_pixmap *image, int u, int v, int fa, int fb) = img_4o4;
+void (*fz_img_w2i1o2)(byte*, byte*, byte, int, byte*, fz_pixmap *image, int u, int v, int fa, int fb) = img_w2i1o2;
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/imageunpack.c b/draw/imageunpack.c
index 4c9923fd..4e876092 100644
--- a/draw/imageunpack.c
+++ b/draw/imageunpack.c
@@ -28,7 +28,7 @@ static void decodetile(fz_pixmap *pix, int skip, float *decode)
min[i] = decode[(i - skip) * 2] * 255;
max[i] = decode[(i - skip) * 2 + 1] * 255;
sub[i] = max[i] - min[i];
- needed |= (min[i] != 0) | (max[i] != 255);
+ needed |= (min[i] != 0) | (max[i] != 255);
justinvert &= min[i] == 255 && max[i] == 0 && sub[i] == -255;
}
diff --git a/draw/pathscan.c b/draw/pathscan.c
index 5a656144..319cfeb1 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, fz_pixmap *image, fz_matrix *invmat)
+ unsigned char *color, fz_pixmap *image, fz_matrix *invmat)
{
unsigned char *dst;
unsigned char cov;
@@ -443,17 +443,61 @@ static inline void blit(fz_pixmap *pix, int x, int y,
int v = (invmat->b * (x + 0.5f) + invmat->d * (y + 0.5f) + 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);
+ assert(image->n == pix->n);
+ if (color)
+ {
+ switch (pix->n)
+ {
+ case 2:
+ fz_img_w2i1o2(color, list, cov, len, dst, image, u, v, fa, fb);
+ break;
+ case 4:
+ fz_img_w4i1o4(color, list, cov, len, dst, image, u, v, fa, fb);
+ break;
+ default:
+ assert("Write fz_img_wni1on" != NULL);
+ //fz_img_wni1on(color, list, cov, len, dst, image, u, v, fa, fb);
+ break;
+ }
+ }
else if (image->colorspace)
+ {
+ assert(image->colorspace->n == image->n-1);
+ switch (pix->n)
+ {
+ case 2:
+ fz_img_2o2(list, cov, len, dst, image, u, v, fa, fb);
+ break;
+ case 4:
fz_img_4o4(list, cov, len, dst, image, u, v, fa, fb);
+ break;
+ default:
+ assert("Write fz_img_non" != NULL);
+ //fz_img_non(list, cov, len, dst, image, u, v, fa, fb);
+ break;
+ }
+ }
else
fz_img_1o1(list, cov, len, dst, image, u, v, fa, fb);
}
else
{
- if (argb)
- fz_path_w4i1o4(argb, list, cov, len, dst);
+ if (color)
+ {
+ switch (pix->n)
+ {
+ case 2:
+ fz_path_w2i1o2(color, list, cov, len, dst);
+ break;
+ case 4:
+ fz_path_w4i1o4(color, list, cov, len, dst);
+ break;
+ default:
+ assert("Write fz_path_wni1on" != NULL);
+ //fz_path_wni1on(color, list, cov, len, dst);
+ break;
+ }
+ }
else
fz_path_1o1(list, cov, len, dst);
}
diff --git a/draw/porterduff.c b/draw/porterduff.c
index 34d5cee8..4616e3fa 100644
--- a/draw/porterduff.c
+++ b/draw/porterduff.c
@@ -20,7 +20,8 @@ duff_non(byte * restrict sp, int sw, int sn, byte * restrict dp, int dw, int w0,
{
/* RJW: Alpha handling suspicious here; sp[0] counts twice */
int sa = FZ_EXPAND(sp[0]);
- for (k = 0; k < sn; k++)
+ dp[0] = FZ_BLEND(255, dp[k], sa);
+ for (k = 1; k < sn; k++)
{
dp[k] = FZ_BLEND(sp[k], dp[k], sa);
}
@@ -47,7 +48,8 @@ duff_nimon(byte * restrict sp, int sw, int sn, byte * restrict mp, int mw, int m
{
/* TODO: validate this */
int ma = FZ_COMBINE(FZ_EXPAND(mp[0]), FZ_EXPAND(sp[0]));
- for (k = 0; k < sn; k++)
+ dp[k] = FZ_BLEND(255, dp[k], ma);
+ for (k = 1; k < sn; k++)
{
dp[k] = FZ_BLEND(sp[k], dp[k], ma);
}
@@ -93,7 +95,7 @@ duff_4o4(byte *sp, int sw, byte *dp, int dw, int w0, int h)
while (w--)
{
int alpha = FZ_EXPAND(sp[0]);
- dp[0] = FZ_BLEND(sp[0], dp[0], alpha);
+ dp[0] = FZ_BLEND(255, dp[0], alpha);
dp[1] = FZ_BLEND(sp[1], dp[1], alpha);
dp[2] = FZ_BLEND(sp[2], dp[2], alpha);
dp[3] = FZ_BLEND(sp[3], dp[3], alpha);
@@ -174,12 +176,30 @@ path_1o1(byte * restrict src, byte cov, int len, byte * restrict dst)
}
static void
+path_w2i1o2(byte * restrict ag, byte * restrict src, byte cov, int len, byte * restrict dst)
+{
+ int alpha = FZ_EXPAND(ag[0]);
+ byte g = ag[1];
+
+ while (len--)
+ {
+ int ca;
+ cov += *src; *src = 0; src++;
+ ca = FZ_COMBINE(FZ_EXPAND(cov), alpha);
+ dst[0] = FZ_BLEND(255, dst[0], ca);
+ dst[1] = FZ_BLEND(g, dst[1], ca);
+ dst += 2;
+ }
+}
+
+static void
path_w4i1o4(byte * restrict argb, byte * restrict src, byte cov, int len, byte * restrict dst)
{
int alpha = FZ_EXPAND(argb[0]);
byte r = argb[1];
byte g = argb[2];
byte b = argb[3];
+
while (len--)
{
int ca;
@@ -218,12 +238,37 @@ text_1o1(byte * restrict src, int srcw, byte * restrict dst, int dstw, int w0, i
}
static void
+text_w2i1o2(byte * restrict ag, byte * restrict src, int srcw, byte * restrict dst, int dstw, int w0, int h)
+{
+ int alpha = FZ_EXPAND(ag[0]);
+ byte g = ag[1];
+
+ srcw -= w0;
+ dstw -= w0<<1;
+ while (h--)
+ {
+ int w = w0;
+ while (w--)
+ {
+ int c = FZ_COMBINE(FZ_EXPAND(src[0]), alpha);
+ dst[0] = FZ_BLEND(255, dst[0], c);
+ dst[1] = FZ_BLEND(g, dst[1], c);
+ src ++;
+ dst += 2;
+ }
+ src += srcw;
+ dst += dstw;
+ }
+}
+
+static void
text_w4i1o4(byte * restrict argb, byte * restrict src, int srcw, byte * restrict dst, int dstw, int w0, int h)
{
int alpha = FZ_EXPAND(argb[0]);
byte r = argb[1];
byte g = argb[2];
byte b = argb[3];
+
srcw -= w0;
dstw -= w0<<2;
while (h--)
@@ -256,7 +301,9 @@ 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_1o1)(byte*,byte,int,byte*) = path_1o1;
+void (*fz_path_w2i1o2)(byte*,byte*,byte,int,byte*) = path_w2i1o2;
void (*fz_path_w4i1o4)(byte*,byte*,byte,int,byte*) = path_w4i1o4;
void (*fz_text_1o1)(byte*,int,byte*,int,int,int) = text_1o1;
+void (*fz_text_w2i1o2)(byte*,byte*,int,byte*,int,int,int) = text_w2i1o2;
void (*fz_text_w4i1o4)(byte*,byte*,int,byte*,int,int,int) = text_w4i1o4;