summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGlenn Kennard <glenn.kennard@gmail.com>2008-03-21 23:48:10 +0100
committerGlenn Kennard <glenn.kennard@gmail.com>2008-03-21 23:48:10 +0100
commit15d836f1e88c9aa2b993f95f95b3bed2a0548ba1 (patch)
tree03dab413d621af264a742eccab8736aaa878eaea
parent3e9200955bf75860835f1499fa699d2c0460cbcb (diff)
downloadmupdf-15d836f1e88c9aa2b993f95f95b3bed2a0548ba1.tar.xz
Fix fast path compositing. Constant color is NOT premultiplied.
-rw-r--r--include/fitz/draw_misc.h8
-rw-r--r--raster/imagedraw.c28
-rw-r--r--raster/pathscan.c2
-rw-r--r--raster/porterduff.c50
-rw-r--r--raster/render.c13
5 files changed, 54 insertions, 47 deletions
diff --git a/include/fitz/draw_misc.h b/include/fitz/draw_misc.h
index 8cf01d49..fe25b956 100644
--- a/include/fitz/draw_misc.h
+++ b/include/fitz/draw_misc.h
@@ -25,18 +25,18 @@ extern void (*fz_duff_4i1o4)(FZ_BYTE*,int,FZ_BYTE*,int,FZ_BYTE*,int,int,int);
extern void (*fz_path_1c1)(FZ_BYTE*,int,int,FZ_BYTE*);
extern void (*fz_path_1o1)(FZ_BYTE*,int,int,FZ_BYTE*);
-extern void (*fz_path_w3i1o4)(FZ_BYTE*,FZ_BYTE*,int,int,FZ_BYTE*);
+extern void (*fz_path_w4i1o4)(FZ_BYTE*,FZ_BYTE*,int,int,FZ_BYTE*);
extern void (*fz_text_1c1)(FZ_BYTE*,int,FZ_BYTE*,int,int,int);
extern void (*fz_text_1o1)(FZ_BYTE*,int,FZ_BYTE*,int,int,int);
-extern void (*fz_text_w3i1o4)(FZ_BYTE*,FZ_BYTE*,int,FZ_BYTE*,int,int,int);
+extern void (*fz_text_w4i1o4)(FZ_BYTE*,FZ_BYTE*,int,FZ_BYTE*,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_w3i1o4)(FZ_BYTE*,FZ_PSRC,FZ_PDST,FZ_PCTM);
+extern void (*fz_img_w4i1o4)(FZ_BYTE*,FZ_PSRC,FZ_PDST,FZ_PCTM);
extern void (*fz_decodetile)(fz_pixmap *pix, int skip, float *decode);
extern void (*fz_loadtile1)(FZ_BYTE*, int sw, FZ_BYTE*, int dw, int w, int h, int pad);
@@ -69,7 +69,7 @@ struct fz_renderer_s
fz_irect clip;
fz_pixmap *dest;
fz_pixmap *over;
- unsigned char argb[4];
+ unsigned char argb[7]; /* alpha, a*r, a*g, a*b, r, g, b */
int flag;
};
diff --git a/raster/imagedraw.c b/raster/imagedraw.c
index d7eb5dc7..1ad74bf7 100644
--- a/raster/imagedraw.c
+++ b/raster/imagedraw.c
@@ -201,13 +201,14 @@ static void img_4o4(FZ_PSRC, FZ_PDST, FZ_PCTM)
}
}
-static void img_w3i1o4(byte *argb, FZ_PSRC, FZ_PDST, FZ_PCTM)
+static void img_w4i1o4(byte *argb, FZ_PSRC, FZ_PDST, FZ_PCTM)
{
- byte ca = argb[0];
- byte rgb0 = argb[1];
- byte rgb1 = argb[2];
- byte rgb2 = argb[3];
- byte sa, ssa;
+ byte alpha = argb[0];
+ byte r = argb[4];
+ byte g = argb[5];
+ byte b = argb[6];
+ byte cov;
+ byte ca;
while (h--)
{
byte *dstp = dst0;
@@ -216,13 +217,12 @@ static void img_w3i1o4(byte *argb, FZ_PSRC, FZ_PDST, FZ_PCTM)
int w = w0;
while (w--)
{
- sa = samplemask(src, srcw, srch, u, v);
- sa = fz_mul255(sa, ca);
- ssa = 255 - sa;
- dstp[0] = sa + fz_mul255(dstp[0], ssa);
- dstp[1] = rgb0 + fz_mul255((short)dstp[1] - rgb0, ssa);
- dstp[2] = rgb1 + fz_mul255((short)dstp[2] - rgb1, ssa);
- dstp[3] = rgb2 + fz_mul255((short)dstp[3] - rgb2, ssa);
+ 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;
@@ -238,5 +238,5 @@ 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_w3i1o4)(byte*,FZ_PSRC,FZ_PDST,FZ_PCTM) = img_w3i1o4;
+void (*fz_img_w4i1o4)(byte*,FZ_PSRC,FZ_PDST,FZ_PCTM) = img_w4i1o4;
diff --git a/raster/pathscan.c b/raster/pathscan.c
index 126da926..62f60fa1 100644
--- a/raster/pathscan.c
+++ b/raster/pathscan.c
@@ -445,7 +445,7 @@ static inline void blit(fz_pixmap *pix, int x, int y,
}
if (argb)
- fz_path_w3i1o4(argb, list, cov, len, dst);
+ fz_path_w4i1o4(argb, list, cov, len, dst);
else if (over)
fz_path_1o1(list, cov, len, dst);
else
diff --git a/raster/porterduff.c b/raster/porterduff.c
index 0521362e..62e2512e 100644
--- a/raster/porterduff.c
+++ b/raster/porterduff.c
@@ -257,23 +257,22 @@ static void path_1o1(byte * restrict src, int cov, int len, byte * restrict dst)
}
}
-static void path_w3i1o4(byte * restrict argb, byte * restrict src, int cov, int len, byte * restrict dst)
+// With 4 In 1 Over 4
+static void path_w4i1o4(byte * restrict argb, byte * restrict src, int cov, int len, byte * restrict dst)
{
- byte ca = argb[0];
- byte rgb0 = argb[1];
- byte rgb1 = argb[2];
- byte rgb2 = argb[3];
- byte ssa;
+ byte alpha = argb[0];
+ byte r = argb[4];
+ byte g = argb[5];
+ byte b = argb[6];
while (len--)
{
- byte a;
+ byte ca;
cov += *src; *src = 0; src++;
- a = fz_mul255(cov, ca);
- ssa = 255 - a;
- dst[0] = a + fz_mul255(dst[0], ssa);
- dst[1] = rgb0 + fz_mul255((short)dst[1] - rgb0, ssa);
- dst[2] = rgb1 + fz_mul255((short)dst[2] - rgb1, ssa);
- dst[3] = rgb2 + fz_mul255((short)dst[3] - rgb2, ssa);
+ ca = fz_mul255(cov, alpha);
+ dst[0] = ca + fz_mul255(dst[0], 255 - ca);
+ dst[1] = fz_mul255((short)r - dst[1], ca) + dst[1];
+ dst[2] = fz_mul255((short)g - dst[2], ca) + dst[2];
+ dst[3] = fz_mul255((short)b - dst[3], ca) + dst[3];
dst += 4;
}
}
@@ -312,12 +311,12 @@ static void text_1o1(byte * restrict src0, int srcw, byte * restrict dst0, int d
}
}
-static void text_w3i1o4(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 ca = argb[0];
- unsigned char rgb0 = argb[1];
- unsigned char rgb1 = argb[2];
- unsigned char rgb2 = argb[3];
+ unsigned char alpha = argb[0];
+ unsigned char r = argb[4];
+ unsigned char g = argb[5];
+ unsigned char b = argb[6];
while (h--)
{
byte *src = src0;
@@ -325,12 +324,11 @@ static void text_w3i1o4(byte * restrict argb, byte * restrict src0, int srcw, by
int w = w0;
while (w--)
{
- byte sa = fz_mul255(src[0], ca);
- byte ssa = 255 - sa;
- dst[0] = sa + fz_mul255(dst[0], ssa);
- dst[1] = rgb0 + fz_mul255((short)dst[1] - rgb0, ssa);
- dst[2] = rgb1 + fz_mul255((short)dst[2] - rgb1, ssa);
- dst[3] = rgb2 + fz_mul255((short)dst[3] - rgb2, ssa);
+ byte ca = fz_mul255(src[0], alpha);
+ dst[0] = ca + fz_mul255(dst[0], 255 - ca);
+ dst[1] = fz_mul255((short)r - dst[1], ca);
+ dst[2] = fz_mul255((short)g - dst[2], ca);
+ dst[3] = fz_mul255((short)b - dst[3], ca);
src ++;
dst += 4;
}
@@ -355,9 +353,9 @@ void (*fz_duff_4i1o4)(byte*,int,byte*,int,byte*,int,int,int) = duff_4i1o4;
void (*fz_path_1c1)(byte*,int,int,byte*) = path_1c1;
void (*fz_path_1o1)(byte*,int,int,byte*) = path_1o1;
-void (*fz_path_w3i1o4)(byte*,byte*,int,int,byte*) = path_w3i1o4;
+void (*fz_path_w4i1o4)(byte*,byte*,int,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_w3i1o4)(byte*,byte*,int,byte*,int,int,int) = text_w3i1o4;
+void (*fz_text_w4i1o4)(byte*,byte*,int,byte*,int,int,int) = text_w4i1o4;
diff --git a/raster/render.c b/raster/render.c
index 9f39056a..d19e7a3c 100644
--- a/raster/render.c
+++ b/raster/render.c
@@ -51,6 +51,9 @@ fz_newrenderer(fz_renderer **gcp, fz_colorspace *pcm, int maskonly, int gcmem)
gc->argb[1] = 0;
gc->argb[2] = 0;
gc->argb[3] = 0;
+ gc->argb[4] = 0;
+ gc->argb[5] = 0;
+ gc->argb[6] = 0;
gc->flag = 0;
*gcp = gc;
@@ -120,6 +123,9 @@ rendersolid(fz_renderer *gc, fz_solidnode *solid, fz_matrix ctm)
gc->argb[1] = rgb[0] * solid->a * 255;
gc->argb[2] = rgb[1] * solid->a * 255;
gc->argb[3] = rgb[2] * solid->a * 255;
+ gc->argb[4] = rgb[0] * 255;
+ gc->argb[5] = rgb[1] * 255;
+ gc->argb[6] = rgb[2] * 255;
DEBUG("solid %s [%d %d %d %d];\n", solid->cs->name, gc->argb[0], gc->argb[1], gc->argb[2], gc->argb[3]);
@@ -278,7 +284,7 @@ static void drawglyph(fz_renderer *gc, fz_pixmap *dst, fz_glyph *src, int xorig,
case FOVER | FRGB:
assert(dst->n == 4);
- fz_text_w3i1o4(gc->argb, sp, src->w, dp, dst->w * 4, w, h);
+ fz_text_w4i1o4(gc->argb, sp, src->w, dp, dst->w * 4, w, h);
break;
default:
@@ -516,7 +522,7 @@ DEBUG(" fover %d x %d\n", w, h);
case FOVER | FRGB:
DEBUG(" fover+rgb %d x %d\n", w, h);
- fz_img_w3i1o4(gc->argb, PSRC, PDST(gc->over), PCTM);
+ fz_img_w4i1o4(gc->argb, PSRC, PDST(gc->over), PCTM);
break;
default:
@@ -731,6 +737,9 @@ rendermask(fz_renderer *gc, fz_masknode *mask, fz_matrix ctm)
gc->argb[1] = rgb[0] * solid->a * 255;
gc->argb[2] = rgb[1] * solid->a * 255;
gc->argb[3] = rgb[2] * solid->a * 255;
+ gc->argb[4] = rgb[0] * 255;
+ gc->argb[5] = rgb[1] * 255;
+ gc->argb[6] = rgb[2] * 255;
gc->flag |= FRGB;
/* we know these can handle the FRGB shortcut */