diff options
author | Tor Andersson <tor@ghostscript.com> | 2004-12-01 03:40:40 +0100 |
---|---|---|
committer | Tor Andersson <tor@ghostscript.com> | 2004-12-01 03:40:40 +0100 |
commit | 4e4e30e57fb4170f3a9dd0a9c23da78c2b46a69f (patch) | |
tree | 49f9976770425b5b2d5443ae0da7de2d44c2e007 | |
parent | c06c383d89e4ebbd092039a4a4ee0a6532e59869 (diff) | |
download | mupdf-4e4e30e57fb4170f3a9dd0a9c23da78c2b46a69f.tar.xz |
clean path scanconversion api
-rw-r--r-- | include/fitz/pathscan.h | 4 | ||||
-rw-r--r-- | include/fitz/render.h | 6 | ||||
-rw-r--r-- | render/optduff.c | 89 | ||||
-rw-r--r-- | render/pathscan.c | 53 | ||||
-rw-r--r-- | render/render.c | 61 |
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; } /* |