summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTor Andersson <tor@ghostscript.com>2004-12-01 03:40:40 +0100
committerTor Andersson <tor@ghostscript.com>2004-12-01 03:40:40 +0100
commit4e4e30e57fb4170f3a9dd0a9c23da78c2b46a69f (patch)
tree49f9976770425b5b2d5443ae0da7de2d44c2e007
parentc06c383d89e4ebbd092039a4a4ee0a6532e59869 (diff)
downloadmupdf-4e4e30e57fb4170f3a9dd0a9c23da78c2b46a69f.tar.xz
clean path scanconversion api
-rw-r--r--include/fitz/pathscan.h4
-rw-r--r--include/fitz/render.h6
-rw-r--r--render/optduff.c89
-rw-r--r--render/pathscan.c53
-rw-r--r--render/render.c61
5 files changed, 117 insertions, 96 deletions
diff --git a/include/fitz/pathscan.h b/include/fitz/pathscan.h
index 109d16b6..0be71e9e 100644
--- a/include/fitz/pathscan.h
+++ b/include/fitz/pathscan.h
@@ -37,8 +37,8 @@ void fz_dropgel(fz_gel *gel);
fz_error *fz_newael(fz_ael **aelp);
void fz_dropael(fz_ael *ael);
-fz_error *fz_scanconvert(fz_gel *gel, fz_ael *ael, int eofill, int y0, int y1,
- void (*blitfunc)(int,int,int,unsigned char*,void*), void *blitdata);
+fz_error *fz_scanconvert(fz_gel *gel, fz_ael *ael, int eofill,
+ fz_irect clip, fz_pixmap *pix, unsigned char *rgb, int over);
fz_error *fz_fillpath(fz_gel *gel, fz_pathnode *path, fz_matrix ctm, float flatness);
fz_error *fz_strokepath(fz_gel *gel, fz_pathnode *path, fz_matrix ctm, float flatness);
diff --git a/include/fitz/render.h b/include/fitz/render.h
index 5c2c7a67..357c3697 100644
--- a/include/fitz/render.h
+++ b/include/fitz/render.h
@@ -23,9 +23,9 @@ extern void (*fz_duff_4i1c4)(FZ_BYTE*,int,FZ_BYTE*,int,FZ_BYTE*,int,int,int);
extern void (*fz_duff_1i1o1)(FZ_BYTE*,int,FZ_BYTE*,int,FZ_BYTE*,int,int,int);
extern void (*fz_duff_4i1o4)(FZ_BYTE*,int,FZ_BYTE*,int,FZ_BYTE*,int,int,int);
-extern void (*fz_path_1c1)(FZ_BYTE*,FZ_BYTE*,int);
-extern void (*fz_path_1o1)(FZ_BYTE*,FZ_BYTE*,int);
-extern void (*fz_path_w3i1o4)(FZ_BYTE*,FZ_BYTE*,FZ_BYTE*,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_text_1c1)(FZ_BYTE*,int,FZ_BYTE*,int,int,int);
extern void (*fz_text_1o1)(FZ_BYTE*,int,FZ_BYTE*,int,int,int);
diff --git a/render/optduff.c b/render/optduff.c
index 75d305ba..9cd99dbb 100644
--- a/render/optduff.c
+++ b/render/optduff.c
@@ -236,67 +236,100 @@ static void duff_4i1o4(byte *sp0, int sw, byte *mp0, int mw, byte *dp0, int dw,
* Path and text masks
*/
-static void path_1c1(byte *src, byte *dst, int w)
+static void path_1c1(byte *src, int cov, int len, byte *dst)
{
- memcpy(dst, src, w);
+ while (len--)
+ {
+ cov += *src; *src = 0; src++;
+ *dst++ = cov;
+ }
}
-static void path_1o1(byte *src, byte *dst, int w)
+static void path_1o1(byte *src, int cov, int len, byte *dst)
{
- while (w--)
+ while (len--)
{
- dst[0] = src[0] + fz_mul255(dst[0], 255 - src[0]);
- src++;
+ cov += *src; *src = 0; src++;
+ dst[0] = cov + fz_mul255(dst[0], 255 - cov);
dst++;
}
}
-static void path_w3i1o4(byte *rgb, byte *src, byte *dst, int n)
+static void path_w3i1o4(byte *rgb, byte *src, int cov, int len, byte *dst)
{
byte rgb0 = rgb[0];
byte rgb1 = rgb[1];
byte rgb2 = rgb[2];
- byte sa, ssa;
- while (n--)
+ byte ssa;
+ while (len--)
{
- sa = src[0];
- ssa = 255 - sa;
- dst[0] = sa + fz_mul255(dst[0], ssa);
+ cov += *src; *src = 0; src++;
+ ssa = 255 - cov;
+ dst[0] = cov + 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);
- src ++;
dst += 4;
}
}
-static void text_1c1(byte *src, int srcw, byte *dst, int dstw, int w0, int h)
+static void text_1c1(byte *src0, int srcw, byte *dst0, int dstw, int w0, int h)
{
while (h--)
{
- path_1c1(src, dst, w0);
- src += srcw;
- dst += dstw;
+ byte *src = src0;
+ byte *dst = dst0;
+ int w = w0;
+ while (w--)
+ {
+ *dst++ = *src++;
+ }
+ src0 += srcw;
+ dst0 += dstw;
}
}
-static void text_1o1(byte *src, int srcw, byte *dst, int dstw, int w0, int h)
+static void text_1o1(byte *src0, int srcw, byte *dst0, int dstw, int w0, int h)
{
while (h--)
{
- path_1o1(src, dst, w0);
- src += srcw;
- dst += dstw;
+ byte *src = src0;
+ byte *dst = dst0;
+ int w = w0;
+ while (w--)
+ {
+ dst[0] = src[0] + fz_mul255(dst[0], 255 - src[0]);
+ src++;
+ dst++;
+ }
+ src0 += srcw;
+ dst0 += dstw;
}
}
-static void text_w3i1o4(byte *rgb, byte *src, int srcw, byte *dst, int dstw, int w0, int h)
+static void text_w3i1o4(byte *rgb, byte *src0, int srcw, byte *dst0, int dstw, int w0, int h)
{
+ unsigned char rgb0 = rgb[0];
+ unsigned char rgb1 = rgb[1];
+ unsigned char rgb2 = rgb[2];
while (h--)
{
- path_w3i1o4(rgb, src, dst, w0);
- src += srcw;
- dst += dstw;
+ byte *src = src0;
+ byte *dst = dst0;
+ int w = w0;
+ while (w--)
+ {
+ byte sa = src[0];
+ 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);
+ src ++;
+ dst += 4;
+ }
+ src0 += srcw;
+ dst0 += dstw;
}
}
@@ -314,9 +347,9 @@ 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) = path_1c1;
-void (*fz_path_1o1)(byte*,byte*,int) = path_1o1;
-void (*fz_path_w3i1o4)(byte*,byte*,byte*,int) = path_w3i1o4;
+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_text_1c1)(byte*,int,byte*,int,int,int) = text_1c1;
void (*fz_text_1o1)(byte*,int,byte*,int,int,int) = text_1o1;
diff --git a/render/pathscan.c b/render/pathscan.c
index 7dd6397d..472b7de1 100644
--- a/render/pathscan.c
+++ b/render/pathscan.c
@@ -367,7 +367,7 @@ evenodd(fz_ael *ael, unsigned char *list, int xofs, int hs)
}
}
-static void toalpha(unsigned char *list, int n)
+static inline void toalpha(unsigned char *list, int n)
{
int d = 0;
while (n--)
@@ -377,9 +377,34 @@ static 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 *rgb, int over)
+{
+ unsigned char *dst;
+ int cov;
+
+ dst = pix->samples + ( (y - pix->y) * pix->w + (x - pix->x) ) * pix->n;
+ cov = 0;
+
+ while (skipx--)
+ {
+ cov += *list;
+ *list = 0;
+ ++list;
+ }
+
+ if (rgb)
+ fz_path_w3i1o4(rgb, list, cov, len, dst);
+ else if (over)
+ fz_path_1o1(list, cov, len, dst);
+ else
+ fz_path_1c1(list, cov, len, dst);
+}
+
fz_error *
-fz_scanconvert(fz_gel *gel, fz_ael *ael, int eofill, int y0, int y1,
- void (*blitfunc)(int,int,int,unsigned char*,void*), void *blitdata)
+fz_scanconvert(fz_gel *gel, fz_ael *ael, int eofill, fz_irect clip,
+ fz_pixmap *pix, unsigned char *rgb, int over)
{
fz_error *error;
unsigned char *deltas;
@@ -393,6 +418,12 @@ fz_scanconvert(fz_gel *gel, fz_ael *ael, int eofill, int y0, int y1,
int hs = gel->hs;
int vs = gel->vs;
+ int skipx = clip.min.x - xmin;
+ int clipn = clip.max.x - clip.min.x;
+
+ assert(clip.min.x >= xmin);
+ assert(clip.max.x <= xmax);
+
if (gel->len == 0)
return nil;
@@ -410,12 +441,11 @@ fz_scanconvert(fz_gel *gel, fz_ael *ael, int eofill, int y0, int y1,
while (ael->len > 0 || e < gel->len)
{
yc = fz_idiv(y, vs);
- if (yc != yd) {
- if (yd >= y0 && yd < y1)
+ if (yc != yd)
+ {
+ if (yd >= clip.min.y && yd < clip.max.y)
{
- toalpha(deltas, xmax - xmin);
- blitfunc(yd, xmin, xmax - xmin, deltas, blitdata);
- memset(deltas, 0, xmax - xmin + 1);
+ blit(pix, xmin + skipx, yd, deltas, skipx, clipn, rgb, over);
}
}
yd = yc;
@@ -426,7 +456,7 @@ fz_scanconvert(fz_gel *gel, fz_ael *ael, int eofill, int y0, int y1,
return error;
}
- if (yd >= y0 && yd < y1)
+ if (yd >= clip.min.y && yd < clip.max.y)
{
if (eofill)
evenodd(ael, deltas, xofs, hs);
@@ -442,10 +472,9 @@ fz_scanconvert(fz_gel *gel, fz_ael *ael, int eofill, int y0, int y1,
y = gel->edges[e].y;
}
- if (yd >= y0 && yd < y1)
+ if (yd >= clip.min.y && yd < clip.max.y)
{
- toalpha(deltas, xmax - xmin);
- blitfunc(yd, xmin, xmax - xmin, deltas, blitdata);
+ blit(pix, xmin + skipx, yd, deltas, skipx, clipn, rgb, over);
}
fz_free(deltas);
diff --git a/render/render.c b/render/render.c
index 70ff5c75..3d745165 100644
--- a/render/render.c
+++ b/render/render.c
@@ -146,45 +146,9 @@ DEBUG("color %s [%d %d %d];\n", color->cs->name, gc->rgb[0], gc->rgb[1], gc->rgb
enum { HS = 17, VS = 15, SF = 1 };
-struct spandata
-{
- int x, n;
- fz_pixmap *dst;
- unsigned char *rgb;
- int flag;
-};
-
-static void spanfunc(int y, int x, int n, unsigned char *path, void *userdata)
-{
- struct spandata *user = userdata;
- fz_pixmap *dst = user->dst;
- unsigned char *dstp;
-
- path += user->x;
- x += user->x;
-
- dstp = dst->samples + ( (y - dst->y) * dst->w + (x - dst->x) ) * dst->n;
-
- switch (user->flag)
- {
- case FNONE:
- assert(dst->n == 1);
- fz_path_1c1(path, dstp, user->n); break;
- case FOVER:
- assert(dst->n == 1);
- fz_path_1o1(path, dstp, user->n); break;
- case FOVER | FRGB:
- assert(dst->n == 4);
- fz_path_w3i1o4(user->rgb, path, dstp, user->n); break;
- default:
- assert(!"impossible flag in path span function");
- }
-}
-
static fz_error *
renderpath(fz_renderer *gc, fz_pathnode *path, fz_matrix ctm)
{
- struct spandata user;
fz_error *error;
float flatness;
fz_irect gbox;
@@ -218,14 +182,15 @@ renderpath(fz_renderer *gc, fz_pathnode *path, fz_matrix ctm)
DEBUG("path %s;\n", path->paint == FZ_STROKE ? "stroke" : "fill");
- user.x = clip.min.x - gbox.min.x;
- user.n = clip.max.x - clip.min.x;
- user.flag = gc->flag;
- user.rgb = gc->rgb;
-
- if (gc->flag & FOVER)
+ if (gc->flag & FRGB)
{
- user.dst = gc->over;
+ return fz_scanconvert(gc->gel, gc->ael, path->paint == FZ_EOFILL,
+ clip, gc->over, gc->rgb, 1);
+ }
+ else if (gc->flag & FOVER)
+ {
+ return fz_scanconvert(gc->gel, gc->ael, path->paint == FZ_EOFILL,
+ clip, gc->over, nil, 1);
}
else
{
@@ -233,15 +198,9 @@ DEBUG("path %s;\n", path->paint == FZ_STROKE ? "stroke" : "fill");
if (error)
return error;
fz_clearpixmap(gc->dest);
- user.dst = gc->dest;
+ return fz_scanconvert(gc->gel, gc->ael, path->paint == FZ_EOFILL,
+ clip, gc->dest, nil, 0);
}
-
- error = fz_scanconvert(gc->gel, gc->ael, path->paint == FZ_EOFILL,
- clip.min.y, clip.max.y, spanfunc, &user);
- if (error)
- return error;
-
- return nil;
}
/*