From d5d8d07709f6ad7d76ee1c466faf4d28549299a9 Mon Sep 17 00:00:00 2001 From: Tor Andersson Date: Wed, 21 Jul 2010 22:42:11 +0000 Subject: Replace path blending with general blending functions. Rewrite image rendering loops so they don't depend on the scan converter. --- fitz/dev_draw.c | 136 ++++++++++++++++++-------------------------------------- fitz/fitz.h | 14 ++---- 2 files changed, 46 insertions(+), 104 deletions(-) (limited to 'fitz') diff --git a/fitz/dev_draw.c b/fitz/dev_draw.c index 36423051..f707b968 100644 --- a/fitz/dev_draw.c +++ b/fitz/dev_draw.c @@ -57,11 +57,11 @@ fz_drawfillpath(void *user, fz_path *path, int evenodd, fz_matrix ctm, for (i = 0; i < model->n; i++) colorbv[i] = colorfv[i] * 255; colorbv[i] = alpha * 255; - fz_scanconvert(dev->gel, dev->ael, evenodd, bbox, dev->dest, colorbv, nil, nil); + fz_scanconvert(dev->gel, dev->ael, evenodd, bbox, dev->dest, colorbv); } else { - fz_scanconvert(dev->gel, dev->ael, evenodd, bbox, dev->dest, nil, nil, nil); + fz_scanconvert(dev->gel, dev->ael, evenodd, bbox, dev->dest, nil); } } @@ -101,11 +101,11 @@ fz_drawstrokepath(void *user, fz_path *path, fz_strokestate *stroke, fz_matrix c for (i = 0; i < model->n; i++) colorbv[i] = colorfv[i] * 255; colorbv[i] = alpha * 255; - fz_scanconvert(dev->gel, dev->ael, 0, bbox, dev->dest, colorbv, nil, nil); + fz_scanconvert(dev->gel, dev->ael, 0, bbox, dev->dest, colorbv); } else { - fz_scanconvert(dev->gel, dev->ael, 0, bbox, dev->dest, nil, nil, nil); + fz_scanconvert(dev->gel, dev->ael, 0, bbox, dev->dest, nil); } } @@ -148,7 +148,7 @@ fz_drawclippath(void *user, fz_path *path, int evenodd, fz_matrix ctm) fz_clearpixmap(mask, 0); fz_clearpixmap(dest, 0); - fz_scanconvert(dev->gel, dev->ael, evenodd, bbox, mask, nil, nil, nil); + fz_scanconvert(dev->gel, dev->ael, evenodd, bbox, mask, nil); dev->stack[dev->top].scissor = dev->scissor; dev->stack[dev->top].mask = mask; @@ -195,7 +195,7 @@ fz_drawclipstrokepath(void *user, fz_path *path, fz_strokestate *stroke, fz_matr fz_clearpixmap(dest, 0); if (!fz_isemptyrect(bbox)) - fz_scanconvert(dev->gel, dev->ael, 0, bbox, mask, nil, nil, nil); + fz_scanconvert(dev->gel, dev->ael, 0, bbox, mask, nil); dev->stack[dev->top].scissor = dev->scissor; dev->stack[dev->top].mask = mask; @@ -539,56 +539,14 @@ fz_drawfillshade(void *user, fz_shade *shade, fz_matrix ctm) fz_rendershade(shade, ctm, dev->dest, bbox); } -static inline void -calcimagestate(fz_drawdevice *dev, fz_pixmap *image, fz_matrix ctm, - fz_bbox *bbox, fz_matrix *invmat, int *dx, int *dy) +static int +fz_calcimagescale(fz_pixmap *image, fz_matrix ctm, int *dx, int *dy) { - float sx, sy; - fz_path *path; - fz_matrix mat; - int w, h; - - sx = image->w / sqrtf(ctm.a * ctm.a + ctm.b * ctm.b); - sy = image->h / sqrtf(ctm.c * ctm.c + ctm.d * ctm.d); - - if (sx < 1) - *dx = 1; - else - *dx = sx; - - if (sy < 1) - *dy = 1; - else - *dy = sy; - - w = (image->w + *dx - 1) / *dx; - h = (image->h + *dy - 1) / *dy; - - path = fz_newpath(); - fz_moveto(path, 0, 0); - fz_lineto(path, 1, 0); - fz_lineto(path, 1, 1); - fz_lineto(path, 0, 1); - fz_closepath(path); - - fz_resetgel(dev->gel, dev->scissor); - fz_fillpath(dev->gel, path, ctm, 1); - fz_sortgel(dev->gel); - - fz_freepath(path); - - *bbox = fz_boundgel(dev->gel); - *bbox = fz_intersectbbox(*bbox, dev->scissor); - - mat.a = 1.0f / w; - mat.b = 0; - mat.c = 0; - mat.d = -1.0f / h; - mat.e = 0; - mat.f = 1; - *invmat = fz_invertmatrix(fz_concat(mat, ctm)); - invmat->e -= 0.5f; - invmat->f -= 0.5f; + float sx = image->w / sqrtf(ctm.a * ctm.a + ctm.b * ctm.b); + float sy = image->h / sqrtf(ctm.c * ctm.c + ctm.d * ctm.d); + *dx = sx > 1 ? sx : 1; + *dy = sy > 1 ? sy : 1; + return *dx > 1 || *dy > 1; } static void @@ -596,11 +554,9 @@ fz_drawfillimage(void *user, fz_pixmap *image, fz_matrix ctm) { fz_drawdevice *dev = user; fz_colorspace *model = dev->dest->colorspace; - fz_bbox bbox; - int dx, dy; - fz_pixmap *scaled = nil; fz_pixmap *converted = nil; - fz_matrix invmat; + fz_pixmap *scaled = nil; + int dx, dy; if (!model) { @@ -608,17 +564,9 @@ fz_drawfillimage(void *user, fz_pixmap *image, fz_matrix ctm) return; } - calcimagestate(dev, image, ctm, &bbox, &invmat, &dx, &dy); - - if (fz_isemptyrect(bbox) || image->w == 0 || image->h == 0) + if (image->w == 0 || image->h == 0) return; - if (dx != 1 || dy != 1) - { - scaled = fz_scalepixmap(image, dx, dy); - image = scaled; - } - if (image->colorspace != model) { converted = fz_newpixmap(model, image->x, image->y, image->w, image->h); @@ -626,7 +574,13 @@ fz_drawfillimage(void *user, fz_pixmap *image, fz_matrix ctm) image = converted; } - fz_scanconvert(dev->gel, dev->ael, 0, bbox, dev->dest, nil, image, &invmat); + if (fz_calcimagescale(image, ctm, &dx, &dy)) + { + scaled = fz_scalepixmap(image, dx, dy); + image = scaled; + } + + fz_blendimage(dev->dest, dev->scissor, image, ctm); if (scaled) fz_droppixmap(scaled); @@ -642,18 +596,14 @@ fz_drawfillimagemask(void *user, fz_pixmap *image, fz_matrix ctm, fz_colorspace *model = dev->dest->colorspace; unsigned char colorbv[FZ_MAXCOLORS + 1]; float colorfv[FZ_MAXCOLORS]; - fz_bbox bbox; - int dx, dy; fz_pixmap *scaled = nil; - fz_matrix invmat; + int dx, dy; int i; - calcimagestate(dev, image, ctm, &bbox, &invmat, &dx, &dy); - - if (fz_isemptyrect(bbox) || image->w == 0 || image->h == 0) + if (image->w == 0 || image->h == 0) return; - if (dx != 1 || dy != 1) + if (fz_calcimagescale(image, ctm, &dx, &dy)) { scaled = fz_scalepixmap(image, dx, dy); image = scaled; @@ -665,11 +615,11 @@ fz_drawfillimagemask(void *user, fz_pixmap *image, fz_matrix ctm, for (i = 0; i < model->n; i++) colorbv[i] = colorfv[i] * 255; colorbv[i] = alpha * 255; - fz_scanconvert(dev->gel, dev->ael, 0, bbox, dev->dest, colorbv, image, &invmat); + fz_blendimagewithcolor(dev->dest, dev->scissor, image, ctm, colorbv); } else { - fz_scanconvert(dev->gel, dev->ael, 0, bbox, dev->dest, nil, image, &invmat); + fz_blendimage(dev->dest, dev->scissor, image, ctm); } if (scaled) @@ -683,9 +633,8 @@ fz_drawclipimagemask(void *user, fz_pixmap *image, fz_matrix ctm) fz_colorspace *model = dev->dest->colorspace; fz_bbox bbox; fz_pixmap *mask, *dest; - int dx, dy; fz_pixmap *scaled = nil; - fz_matrix invmat; + int dx, dy; if (dev->top == STACKSIZE) { @@ -693,23 +642,18 @@ fz_drawclipimagemask(void *user, fz_pixmap *image, fz_matrix ctm) return; } - calcimagestate(dev, image, ctm, &bbox, &invmat, &dx, &dy); - - if (fz_isemptyrect(bbox) || image->w == 0 || image->h == 0) + if (image->w == 0 || image->h == 0) { dev->stack[dev->top].scissor = dev->scissor; dev->stack[dev->top].mask = nil; dev->stack[dev->top].dest = nil; - dev->scissor = bbox; + dev->scissor = fz_emptybbox; dev->top++; return; } - if (dx != 1 || dy != 1) - { - scaled = fz_scalepixmap(image, dx, dy); - image = scaled; - } + bbox = fz_roundrect(fz_transformrect(ctm, fz_unitrect)); + bbox = fz_intersectbbox(bbox, dev->scissor); mask = fz_newpixmapwithrect(nil, bbox); dest = fz_newpixmapwithrect(model, bbox); @@ -717,7 +661,16 @@ fz_drawclipimagemask(void *user, fz_pixmap *image, fz_matrix ctm) fz_clearpixmap(mask, 0); fz_clearpixmap(dest, 0); - fz_scanconvert(dev->gel, dev->ael, 0, bbox, mask, nil, image, &invmat); + if (fz_calcimagescale(image, ctm, &dx, &dy)) + { + scaled = fz_scalepixmap(image, dx, dy); + image = scaled; + } + + fz_blendimage(mask, bbox, image, ctm); + + if (scaled) + fz_droppixmap(scaled); dev->stack[dev->top].scissor = dev->scissor; dev->stack[dev->top].mask = mask; @@ -725,9 +678,6 @@ fz_drawclipimagemask(void *user, fz_pixmap *image, fz_matrix ctm) dev->scissor = bbox; dev->dest = dest; dev->top++; - - if (scaled) - fz_droppixmap(scaled); } static void diff --git a/fitz/fitz.h b/fitz/fitz.h index 1465e8b9..12a273a5 100644 --- a/fitz/fitz.h +++ b/fitz/fitz.h @@ -977,7 +977,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 *colorbv, fz_pixmap *image, fz_matrix *invmat); + fz_bbox clip, fz_pixmap *pix, unsigned char *colorbv); 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); @@ -1147,16 +1147,8 @@ void fz_blendwithcolormask(unsigned char * restrict dp, unsigned char * restrict void fz_blendnormal(unsigned char * restrict dp, unsigned char * restrict sp, int n, int w); void fz_blendwithmask(unsigned char * restrict dp, unsigned char * restrict sp, unsigned char * restrict mp, int n, int w); -extern void (*fz_path_1o1)(unsigned char*restrict,unsigned char,int,unsigned char*restrict); -extern void (*fz_path_w2i1o2)(unsigned char*,unsigned char*restrict,unsigned char,int,unsigned char*restrict); -extern void (*fz_path_w4i1o4)(unsigned char*,unsigned char*restrict,unsigned char,int,unsigned char*restrict); - -extern void (*fz_img_non)(unsigned char*restrict,unsigned char,int,unsigned char*restrict,fz_pixmap*,fz_matrix*); -extern void (*fz_img_1o1)(unsigned char*restrict,unsigned char,int,unsigned char*restrict,fz_pixmap*,int u, int v, int fa, int fb); -extern void (*fz_img_4o4)(unsigned char*restrict,unsigned char,int,unsigned char*restrict,fz_pixmap*,int u, int v, int fa, int fb); -extern void (*fz_img_2o2)(unsigned char*restrict,unsigned char,int,unsigned char*restrict,fz_pixmap*,int u, int v, int fa, int fb); -extern void (*fz_img_w2i1o2)(unsigned char*,unsigned char*restrict,unsigned char,int,unsigned char*restrict,fz_pixmap*,int u, int v, int fa, int fb); -extern void (*fz_img_w4i1o4)(unsigned char*,unsigned char*restrict,unsigned char,int,unsigned char*restrict,fz_pixmap*,int u, int v, int fa, int fb); +void fz_blendimage(fz_pixmap *dst, fz_bbox scissor, fz_pixmap *img, fz_matrix ctm); +void fz_blendimagewithcolor(fz_pixmap *dst, fz_bbox scissor, fz_pixmap *img, fz_matrix ctm, unsigned char *colorbv); extern void (*fz_srown)(unsigned char *restrict, unsigned char *restrict, int w, int denom, int n); extern void (*fz_srow1)(unsigned char *restrict, unsigned char *restrict, int w, int denom); -- cgit v1.2.3