diff options
author | Tor Andersson <tor@ghostscript.com> | 2010-01-07 14:25:59 +0100 |
---|---|---|
committer | Tor Andersson <tor@ghostscript.com> | 2010-01-07 14:25:59 +0100 |
commit | ce5bbd9d57287b041e249a21bc88ad87a4c4f9ff (patch) | |
tree | 0e3c31f0da3515349a53fccf931db0139eb89c2b | |
parent | 3417c5d2f429b5166a630fc9eb20c9854283ffcc (diff) | |
download | mupdf-ce5bbd9d57287b041e249a21bc88ad87a4c4f9ff.tar.xz |
Draw images and shadings.
-rw-r--r-- | apps/pdfdraw.c | 11 | ||||
-rw-r--r-- | fitz/dev_draw.c | 173 | ||||
-rw-r--r-- | fitz/dev_trace.c | 22 | ||||
-rw-r--r-- | fitz/fitz_base.h | 13 | ||||
-rw-r--r-- | fitz/fitz_res.h | 6 | ||||
-rw-r--r-- | fitzdraw/Jamfile | 1 | ||||
-rw-r--r-- | fitzdraw/glyphcache.c | 1 | ||||
-rw-r--r-- | fitzdraw/imagescale.c | 29 | ||||
-rw-r--r-- | fitzdraw/meshdraw.c | 19 | ||||
-rw-r--r-- | fitzdraw/pixmap.c | 38 | ||||
-rw-r--r-- | mupdf/mupdf.h | 1 | ||||
-rw-r--r-- | mupdf/pdf_build.c | 33 | ||||
-rw-r--r-- | mupdf/pdf_image.c | 7 | ||||
-rw-r--r-- | mupdf/pdf_interpret.c | 8 |
14 files changed, 257 insertions, 105 deletions
diff --git a/apps/pdfdraw.c b/apps/pdfdraw.c index 6c66b9d1..00dc8848 100644 --- a/apps/pdfdraw.c +++ b/apps/pdfdraw.c @@ -206,9 +206,7 @@ static void drawpnm(int pagenum, struct benchmark *loadtimes, struct benchmark * write(fd, pnmhdr, strlen(pnmhdr)); } - error = fz_newpixmap(&pix, bbox.x0, bbox.y0, w, bh, 4); - if (error) - die(error); + pix = fz_newpixmap(bbox.x0, bbox.y0, w, bh, 4); memset(pix->samples, 0xff, pix->h * pix->w * pix->n); @@ -261,7 +259,7 @@ static void drawpnm(int pagenum, struct benchmark *loadtimes, struct benchmark * pix->h = bbox.y1 - pix->y; } - fz_droppixmap(pix); + fz_freepixmap(pix); if (!drawpattern) { unsigned char buf[16]; @@ -378,7 +376,6 @@ static void drawpages(char *pagelist) int main(int argc, char **argv) { - fz_error error; char *password = ""; int c; enum { NO_FILE_OPENED, NO_PAGES_DRAWN, DREW_PAGES } state; @@ -415,9 +412,7 @@ int main(int argc, char **argv) closexref(); -//XXX error = fz_newrenderer(&drawgc, pdf_devicergb, 0, 1024 * 512); -// if (error) -// die(error); +//XXX fz_newrenderer(&drawgc, pdf_devicergb, 0, 1024 * 512); openxref(argv[fz_optind], password, 0); state = NO_PAGES_DRAWN; diff --git a/fitz/dev_draw.c b/fitz/dev_draw.c index 92663a5c..1285ae51 100644 --- a/fitz/dev_draw.c +++ b/fitz/dev_draw.c @@ -16,6 +16,42 @@ struct fz_drawdevice_s fz_pixmap *dest; }; +static void +blendover(fz_pixmap *src, fz_pixmap *dst) +{ + unsigned char *sp, *dp; + fz_irect sr, dr; + int x, y, w, h; + + sr.x0 = src->x; + sr.y0 = src->y; + sr.x1 = src->x + src->w; + sr.y1 = src->y + src->h; + + dr.x0 = dst->x; + dr.y0 = dst->y; + dr.x1 = dst->x + dst->w; + dr.y1 = dst->y + dst->h; + + dr = fz_intersectirects(sr, dr); + x = dr.x0; + y = dr.y0; + w = dr.x1 - dr.x0; + h = dr.y1 - dr.y0; + + sp = src->samples + ((y - src->y) * src->w + (x - src->x)) * src->n; + dp = dst->samples + ((y - dst->y) * dst->w + (x - dst->x)) * dst->n; + + if (src->n == 1 && dst->n == 1) + fz_duff_1o1(sp, src->w, dp, dst->w, w, h); + else if (src->n == 4 && dst->n == 4) + fz_duff_4o4(sp, src->w * 4, dp, dst->w * 4, w, h); + else if (src->n == dst->n) + fz_duff_non(sp, src->w * src->n, src->n, dp, dst->w * dst->n, w, h); + else + assert(!"blendover src and dst mismatch"); +} + void fz_drawfillpath(void *user, fz_path *path, fz_colorspace *colorspace, float *color, float alpha) { fz_drawdevice *dev = user; @@ -207,19 +243,146 @@ void fz_drawignoretext(void *user, fz_text *text) printf("invisibletext\n"); } -void fz_drawdrawimage(void *user, fz_image *image, fz_matrix *ctm) +static inline void +calcimagescale(fz_matrix ctm, int w, int h, int *odx, int *ody) { - printf("drawimage\n"); + float sx, sy; + int dx, dy; + + sx = sqrt(ctm.a * ctm.a + ctm.b * ctm.b); + dx = 1; + while (((w+dx-1)/dx)/sx > 2.0 && (w+dx-1)/dx > 1) + dx++; + + sy = sqrt(ctm.c * ctm.c + ctm.d * ctm.d); + dy = 1; + while (((h+dy-1)/dy)/sy > 2.0 && (h+dy-1)/dy > 1) + dy++; + + *odx = dx; + *ody = dy; +} + +void fz_drawdrawshade(void *user, fz_shade *shade, fz_matrix ctm) +{ + fz_drawdevice *dev = user; + fz_rect bounds; + fz_irect bbox; + fz_irect clip; + fz_pixmap *tmp; + + bounds = fz_transformaabb(fz_concat(shade->matrix, ctm), shade->bbox); + bbox = fz_roundrect(bounds); + + clip.x0 = dev->dest->x; + clip.y0 = dev->dest->y; + clip.x1 = dev->dest->x + dev->dest->w; + clip.y1 = dev->dest->y + dev->dest->h; + clip = fz_intersectirects(clip, bbox); + + tmp = fz_newpixmapwithrect(clip, dev->model->n + 1); + fz_rendershade(shade, ctm, dev->model, tmp); + blendover(tmp, dev->dest); + fz_freepixmap(tmp); } -void fz_drawdrawshade(void *user, fz_shade *shade, fz_matrix *ctm) +void fz_drawdrawimage(void *user, fz_image *image, fz_matrix ctm) { - printf("drawshade\n"); + fz_drawdevice *dev = user; + fz_error error; + fz_rect bounds; + fz_irect bbox; + fz_irect clip; + int dx, dy; + fz_pixmap *tile; + fz_pixmap *temp; + fz_matrix imgmat; + fz_matrix invmat; + int fa, fb, fc, fd; + int u0, v0; + int x0, y0; + int w, h; + + printf("drawimage\n"); + + bounds.x0 = 0; + bounds.y0 = 0; + bounds.x1 = 1; + bounds.y1 = 1; + bounds = fz_transformaabb(ctm, bounds); + bbox = fz_roundrect(bounds); + + clip.x0 = dev->dest->x; + clip.y0 = dev->dest->y; + clip.x1 = dev->dest->x + dev->dest->w; + clip.y1 = dev->dest->y + dev->dest->h; + clip = fz_intersectirects(clip, bbox); + + if (fz_isemptyrect(clip)) + return; + if (image->w == 0 || image->h == 0) + return; + + calcimagescale(ctm, image->w, image->h, &dx, &dy); + + tile = fz_newpixmap(0, 0, image->w, image->h, image->n + 1); + + error = image->loadtile(image, tile); + if (error) + { + fz_catch(error, "cannot load image data"); + return; + } + + if (dx != 1 || dy != 1) + { + temp = fz_scalepixmap(tile, dx, dy); + fz_freepixmap(tile); + tile = temp; + } + + if (image->cs && image->cs != dev->model) + { + temp = fz_newpixmap(tile->x, tile->y, tile->w, tile->h, dev->model->n + 1); + fz_convertpixmap(image->cs, tile, dev->model, temp); + fz_freepixmap(tile); + tile = temp; + } + + imgmat.a = 1.0 / tile->w; + imgmat.b = 0.0; + imgmat.c = 0.0; + imgmat.d = -1.0 / tile->h; + imgmat.e = 0.0; + imgmat.f = 1.0; + invmat = fz_invertmatrix(fz_concat(imgmat, ctm)); + + invmat.e -= 0.5; + invmat.f -= 0.5; + + w = clip.x1 - clip.x0; + h = clip.y1 - clip.y0; + x0 = clip.x0; + y0 = clip.y0; + u0 = (invmat.a * (x0+0.5) + invmat.c * (y0+0.5) + invmat.e) * 65536; + v0 = (invmat.b * (x0+0.5) + invmat.d * (y0+0.5) + invmat.f) * 65536; + fa = invmat.a * 65536; + fb = invmat.b * 65536; + fc = invmat.c * 65536; + fd = invmat.d * 65536; + +#define PDST(p) p->samples + ((y0-p->y) * p->w + (x0-p->x)) * p->n, p->w * p->n + + if (image->cs) + fz_img_4o4(tile->samples, tile->w, tile->h, PDST(dev->dest), + u0, v0, fa, fb, fc, fd, w, h); + + fz_freepixmap(tile); } void fz_drawpopclip(void *user) { - printf("grestore\n"); + printf("popclip\n"); } fz_device *fz_newdrawdevice(fz_colorspace *colorspace, fz_pixmap *dest) diff --git a/fitz/dev_trace.c b/fitz/dev_trace.c index 85118e1b..4816bf10 100644 --- a/fitz/dev_trace.c +++ b/fitz/dev_trace.c @@ -1,9 +1,9 @@ #include "fitz.h" -static void fz_tracematrix(fz_matrix *ctm) +static void fz_tracematrix(fz_matrix ctm) { printf("%g %g %g %g %g %g setmatrix\n", - ctm->a, ctm->b, ctm->c, ctm->d, ctm->e, ctm->f); + ctm.a, ctm.b, ctm.c, ctm.d, ctm.e, ctm.f); } static void fz_tracecolor(fz_colorspace *colorspace, float *color, float alpha) @@ -14,7 +14,7 @@ static void fz_tracecolor(fz_colorspace *colorspace, float *color, float alpha) void fz_tracefillpath(void *user, fz_path *path, fz_colorspace *colorspace, float *color, float alpha) { - fz_tracematrix(&path->ctm); + fz_tracematrix(path->ctm); fz_printpath(path, 0); if (path->winding == FZ_EVENODD) printf("eofill\n"); @@ -27,7 +27,7 @@ void fz_tracestrokepath(void *user, fz_path *path, fz_colorspace *colorspace, fl int i; fz_tracecolor(colorspace, color, alpha); - fz_tracematrix(&path->ctm); + fz_tracematrix(path->ctm); printf("%g setlinewidth\n", path->linewidth); printf("%g setmiterlimit\n", path->miterlimit); @@ -50,7 +50,7 @@ void fz_tracestrokepath(void *user, fz_path *path, fz_colorspace *colorspace, fl void fz_traceclippath(void *user, fz_path *path) { printf("gsave\n"); - fz_tracematrix(&path->ctm); + fz_tracematrix(path->ctm); fz_printpath(path, 0); if (path->winding == FZ_EVENODD) printf("eoclip\n"); @@ -61,7 +61,7 @@ void fz_traceclippath(void *user, fz_path *path) void fz_tracefilltext(void *user, fz_text *text, fz_colorspace *colorspace, float *color, float alpha) { printf("/%s setfont\n", text->font->name); - fz_tracematrix(&text->trm); + fz_tracematrix(text->trm); fz_debugtext(text, 0); printf("show\n"); } @@ -69,7 +69,7 @@ void fz_tracefilltext(void *user, fz_text *text, fz_colorspace *colorspace, floa void fz_tracestroketext(void *user, fz_text *text, fz_colorspace *colorspace, float *color, float alpha) { printf("/%s setfont\n", text->font->name); - fz_tracematrix(&text->trm); + fz_tracematrix(text->trm); fz_debugtext(text, 0); printf("charpath stroke\n"); } @@ -78,7 +78,7 @@ void fz_tracecliptext(void *user, fz_text *text) { printf("gsave\n"); printf("/%s setfont\n", text->font->name); - fz_tracematrix(&text->trm); + fz_tracematrix(text->trm); fz_debugtext(text, 0); printf("charpath clip\n"); } @@ -86,18 +86,18 @@ void fz_tracecliptext(void *user, fz_text *text) void fz_traceignoretext(void *user, fz_text *text) { printf("/%s setfont\n", text->font->name); - fz_tracematrix(&text->trm); + fz_tracematrix(text->trm); fz_debugtext(text, 0); printf("invisibletext\n"); } -void fz_tracedrawimage(void *user, fz_image *image, fz_matrix *ctm) +void fz_tracedrawimage(void *user, fz_image *image, fz_matrix ctm) { fz_tracematrix(ctm); printf("drawimage\n"); } -void fz_tracedrawshade(void *user, fz_shade *shade, fz_matrix *ctm) +void fz_tracedrawshade(void *user, fz_shade *shade, fz_matrix ctm) { fz_tracematrix(ctm); printf("drawshade\n"); diff --git a/fitz/fitz_base.h b/fitz/fitz_base.h index 46556a01..10ec702e 100644 --- a/fitz/fitz_base.h +++ b/fitz/fitz_base.h @@ -307,21 +307,18 @@ struct fz_pixmap_s fz_sample *samples; }; -fz_error fz_newpixmapwithrect(fz_pixmap **mapp, fz_irect bbox, int n); -fz_error fz_newpixmap(fz_pixmap **mapp, int x, int y, int w, int h, int n); -fz_error fz_newpixmapcopy(fz_pixmap **pixp, fz_pixmap *old); +fz_pixmap * fz_newpixmapwithrect(fz_irect bbox, int n); +fz_pixmap * fz_newpixmap(int x, int y, int w, int h, int n); +fz_pixmap * fz_newpixmapcopy(fz_pixmap *old); void fz_debugpixmap(fz_pixmap *map, char *prefix); void fz_clearpixmap(fz_pixmap *map); -void fz_droppixmap(fz_pixmap *map); +void fz_freepixmap(fz_pixmap *map); -fz_error fz_scalepixmap(fz_pixmap **dstp, fz_pixmap *src, int xdenom, int ydenom); +fz_pixmap * fz_scalepixmap(fz_pixmap *src, int xdenom, int ydenom); /* needed for tiled rendering */ fz_error fz_newscaledpixmap(fz_pixmap **dstp, int w, int h, int n, int xdenom, int ydenom); fz_error fz_scalepixmaptile(fz_pixmap *dstp, int xoffs, int yoffs, fz_pixmap *tile, int xdenom, int ydenom); -#endif - - diff --git a/fitz/fitz_res.h b/fitz/fitz_res.h index 5d789cd8..64e796b7 100644 --- a/fitz/fitz_res.h +++ b/fitz/fitz_res.h @@ -24,8 +24,8 @@ struct fz_device_s void (*cliptext)(void *, fz_text *); void (*ignoretext)(void *, fz_text *); - void (*drawimage)(void *, fz_image *img, fz_matrix *ctm); - void (*drawshade)(void *, fz_shade *shd, fz_matrix *ctm); + void (*drawimage)(void *, fz_image *img, fz_matrix ctm); + void (*drawshade)(void *, fz_shade *shd, fz_matrix ctm); void (*popclip)(void *); }; @@ -284,5 +284,5 @@ fz_shade *fz_keepshade(fz_shade *shade); void fz_dropshade(fz_shade *shade); fz_rect fz_boundshade(fz_shade *shade, fz_matrix ctm); -fz_error fz_rendershade(fz_shade *shade, fz_matrix ctm, fz_colorspace *dsts, fz_pixmap *dstp); +void fz_rendershade(fz_shade *shade, fz_matrix ctm, fz_colorspace *dsts, fz_pixmap *dstp); diff --git a/fitzdraw/Jamfile b/fitzdraw/Jamfile index 613e2d7a..b1489b93 100644 --- a/fitzdraw/Jamfile +++ b/fitzdraw/Jamfile @@ -11,7 +11,6 @@ Library libfitzdraw : pathscan.c pathfill.c pathstroke.c -# render.c blendmodes.c ; diff --git a/fitzdraw/glyphcache.c b/fitzdraw/glyphcache.c index dd06d2d3..e9443934 100644 --- a/fitzdraw/glyphcache.c +++ b/fitzdraw/glyphcache.c @@ -297,7 +297,6 @@ evictall(fz_glyphcache *arena) void fz_renderglyph(fz_glyphcache *arena, fz_glyph *glyph, fz_font *font, int cid, fz_matrix ctm) { - fz_error error; fz_key key; fz_val *val; int size; diff --git a/fitzdraw/imagescale.c b/fitzdraw/imagescale.c index 19c8abd7..970b3468 100644 --- a/fitzdraw/imagescale.c +++ b/fitzdraw/imagescale.c @@ -177,16 +177,16 @@ void (*fz_scol2)(byte *src, byte *dst, int w, int denom) = scol2; void (*fz_scol4)(byte *src, byte *dst, int w, int denom) = scol4; void (*fz_scol5)(byte *src, byte *dst, int w, int denom) = scol5; -fz_error -fz_newscaledpixmap(fz_pixmap **dstp, int w, int h, int n, int xdenom, int ydenom) +fz_pixmap * +fz_newscaledpixmap(int w, int h, int n, int xdenom, int ydenom) { int ow = (w + xdenom - 1) / xdenom; int oh = (h + ydenom - 1) / ydenom; - return fz_newpixmap(dstp, 0, 0, ow, oh, n); + return fz_newpixmap(0, 0, ow, oh, n); } /* TODO: refactor */ -fz_error +void fz_scalepixmaptile(fz_pixmap *dst, int xoffs, int yoffs, fz_pixmap *src, int xdenom, int ydenom) { unsigned char *buf; @@ -209,8 +209,6 @@ fz_scalepixmaptile(fz_pixmap *dst, int xoffs, int yoffs, fz_pixmap *src, int xde assert(dst->w >= xoffs + ow && dst->h >= yoffs + oh); buf = fz_malloc(ow * n * ydenom); - if (!buf) - return fz_rethrow(-1, "out of memory"); switch (n) { @@ -274,13 +272,11 @@ fz_scalepixmaptile(fz_pixmap *dst, int xoffs, int yoffs, fz_pixmap *src, int xde } fz_free(buf); - return fz_okay; } -fz_error -fz_scalepixmap(fz_pixmap **dstp, fz_pixmap *src, int xdenom, int ydenom) +fz_pixmap * +fz_scalepixmap(fz_pixmap *src, int xdenom, int ydenom) { - fz_error error; fz_pixmap *dst; unsigned char *buf; int y, iy, oy; @@ -295,15 +291,8 @@ fz_scalepixmap(fz_pixmap **dstp, fz_pixmap *src, int xdenom, int ydenom) n = src->n; buf = fz_malloc(ow * n * ydenom); - if (!buf) - return fz_rethrow(-1, "out of memory"); - error = fz_newpixmap(&dst, 0, 0, ow, oh, src->n); - if (error) - { - fz_free(buf); - return error; - } + dst = fz_newpixmap(0, 0, ow, oh, src->n); switch (n) { @@ -366,7 +355,5 @@ fz_scalepixmap(fz_pixmap **dstp, fz_pixmap *src, int xdenom, int ydenom) } fz_free(buf); - *dstp = dst; - return fz_okay; + return dst; } - diff --git a/fitzdraw/meshdraw.c b/fitzdraw/meshdraw.c index 2078371f..9722e9ec 100644 --- a/fitzdraw/meshdraw.c +++ b/fitzdraw/meshdraw.c @@ -310,7 +310,7 @@ fz_drawtriangle(fz_pixmap *pix, float *av, float *bv, float *cv, int n) * mesh drawing */ -fz_error +void fz_rendershade(fz_shade *shade, fz_matrix ctm, fz_colorspace *destcs, fz_pixmap *dest) { unsigned char clut[256][3]; @@ -329,17 +329,12 @@ fz_rendershade(fz_shade *shade, fz_matrix ctm, fz_colorspace *destcs, fz_pixmap if (shade->usefunction) { n = 3; - error = fz_newpixmap(&temp, dest->x, dest->y, dest->w, dest->h, 2); - if (error) - return error; + temp = fz_newpixmap(dest->x, dest->y, dest->w, dest->h, 2); } else if (shade->cs != destcs) { n = 2 + shade->cs->n; - error = fz_newpixmap(&temp, dest->x, dest->y, dest->w, dest->h, - shade->cs->n + 1); - if (error) - return error; + temp = fz_newpixmap(dest->x, dest->y, dest->w, dest->h, shade->cs->n + 1); } else { @@ -357,7 +352,7 @@ fz_rendershade(fz_shade *shade, fz_matrix ctm, fz_colorspace *destcs, fz_pixmap p.y = shade->mesh[(i * 3 + k) * n + 1]; p = fz_transformpoint(ctm, p); if (isnan(p.y) || isnan(p.x)) // How is this happening? - goto baddata; + goto baddata; tri[k][0] = p.x; tri[k][1] = p.y; for (j = 2; j < n; j++) @@ -392,15 +387,13 @@ baddata: d += 4; } - fz_droppixmap(temp); + fz_freepixmap(temp); } else if (shade->cs != destcs) { fz_convertpixmap(shade->cs, temp, destcs, dest); - fz_droppixmap(temp); + fz_freepixmap(temp); } - - return fz_okay; } diff --git a/fitzdraw/pixmap.c b/fitzdraw/pixmap.c index 96e08b84..d5aed102 100644 --- a/fitzdraw/pixmap.c +++ b/fitzdraw/pixmap.c @@ -1,14 +1,11 @@ #include "fitz.h" -fz_error -fz_newpixmap(fz_pixmap **pixp, int x, int y, int w, int h, int n) +fz_pixmap * +fz_newpixmap(int x, int y, int w, int h, int n) { fz_pixmap *pix; - pix = *pixp = fz_malloc(sizeof(fz_pixmap)); - if (!pix) - return fz_rethrow(-1, "out of memory"); - + pix = fz_malloc(sizeof(fz_pixmap)); pix->x = x; pix->y = y; pix->w = w; @@ -16,33 +13,26 @@ fz_newpixmap(fz_pixmap **pixp, int x, int y, int w, int h, int n) pix->n = n; pix->samples = fz_malloc(pix->w * pix->h * pix->n * sizeof(fz_sample)); - if (!pix->samples) { - fz_free(pix); - return fz_rethrow(-1, "out of memory"); - } - - return fz_okay; + + return pix; } -fz_error -fz_newpixmapwithrect(fz_pixmap **pixp, fz_irect r, int n) +fz_pixmap * +fz_newpixmapwithrect(fz_irect r, int n) { - return fz_newpixmap(pixp, r.x0, r.y0, r.x1 - r.x0, r.y1 - r.y0, n); + return fz_newpixmap(r.x0, r.y0, r.x1 - r.x0, r.y1 - r.y0, n); } -fz_error -fz_newpixmapcopy(fz_pixmap **pixp, fz_pixmap *old) +fz_pixmap * +fz_newpixmapcopy(fz_pixmap *old) { - fz_error error; - error = fz_newpixmap(pixp, old->x, old->y, old->w, old->h, old->n); - if (error) - return error; - memcpy((*pixp)->samples, old->samples, old->w * old->h * old->n); - return fz_okay; + fz_pixmap *pix = fz_newpixmap(old->x, old->y, old->w, old->h, old->n); + memcpy(pix->samples, old->samples, old->w * old->h * old->n); + return pix; } void -fz_droppixmap(fz_pixmap *pix) +fz_freepixmap(fz_pixmap *pix) { fz_free(pix->samples); fz_free(pix); diff --git a/mupdf/mupdf.h b/mupdf/mupdf.h index 080dbe22..2ef8402c 100644 --- a/mupdf/mupdf.h +++ b/mupdf/mupdf.h @@ -649,6 +649,7 @@ struct pdf_material_s struct pdf_gstate_s { fz_matrix ctm; + int clipdepth; /* path stroking */ float linewidth; diff --git a/mupdf/pdf_build.c b/mupdf/pdf_build.c index cdf133de..b834556b 100644 --- a/mupdf/pdf_build.c +++ b/mupdf/pdf_build.c @@ -5,6 +5,7 @@ void pdf_initgstate(pdf_gstate *gs, fz_matrix ctm) { gs->ctm = ctm; + gs->clipdepth = 0; gs->linewidth = 1.0; gs->linecap = 0; @@ -207,14 +208,14 @@ void pdf_showshade(pdf_csi *csi, fz_shade *shd) { pdf_gstate *gstate = csi->gstate + csi->gtop; - csi->dev->drawshade(csi->dev->user, shd, &gstate->ctm); + csi->dev->drawshade(csi->dev->user, shd, gstate->ctm); } void pdf_showimage(pdf_csi *csi, pdf_image *img) { pdf_gstate *gstate = csi->gstate + csi->gtop; - csi->dev->drawimage(csi->dev->user, (fz_image*)img, &gstate->ctm); + csi->dev->drawimage(csi->dev->user, (fz_image*)img, gstate->ctm); } void @@ -239,15 +240,34 @@ pdf_showpath(pdf_csi *csi, int doclose, int dofill, int dostroke, int evenodd) if (csi->clip) { + gstate->clipdepth++; csi->dev->clippath(csi->dev->user, csi->path); csi->clip = 0; } + if (dofill) { - // TODO: indexed, pattern, shade materials - csi->dev->fillpath(csi->dev->user, csi->path, - gstate->fill.cs, gstate->fill.v, gstate->fill.alpha); + switch (gstate->fill.kind) + { + case PDF_MNONE: + break; + case PDF_MCOLOR: + case PDF_MINDEXED: + case PDF_MLAB: + csi->dev->fillpath(csi->dev->user, csi->path, + gstate->fill.cs, gstate->fill.v, gstate->fill.alpha); + break; + case PDF_MPATTERN: + printf("pattern fills not supported yet\n"); + break; + case PDF_MSHADE: + csi->dev->clippath(csi->dev->user, csi->path); + csi->dev->drawshade(csi->dev->user, gstate->fill.shade, gstate->ctm); + csi->dev->popclip(csi->dev->user); + break; + } } + if (dostroke) { // TODO: indexed, pattern, shade materials @@ -313,7 +333,10 @@ pdf_flushtext(pdf_csi *csi) csi->dev->ignoretext(csi->dev->user, csi->text); if (doclip) + { + gstate->clipdepth++; csi->dev->cliptext(csi->dev->user, csi->text); + } if (dofill) { diff --git a/mupdf/pdf_image.c b/mupdf/pdf_image.c index fe6aab7a..cbe9589a 100644 --- a/mupdf/pdf_image.c +++ b/mupdf/pdf_image.c @@ -483,7 +483,6 @@ pdf_loadtile(fz_image *img, fz_pixmap *tile) { pdf_image *src = (pdf_image*)img; void (*tilefunc)(unsigned char*,int,unsigned char*, int, int, int, int); - fz_error error; assert(tile->x == 0); /* can't handle general tile yet, only y-banding */ @@ -510,9 +509,7 @@ pdf_loadtile(fz_image *img, fz_pixmap *tile) int x, y, k, i; int bpcfact = 1; - error = fz_newpixmap(&tmp, tile->x, tile->y, tile->w, tile->h, 1); - if (error) - return error; + tmp = fz_newpixmap(tile->x, tile->y, tile->w, tile->h, 1); switch (src->bpc) { @@ -549,7 +546,7 @@ pdf_loadtile(fz_image *img, fz_pixmap *tile) if (src->usecolorkey) maskcolorkeyindexed(tmp, tile, src->colorkey); - fz_droppixmap(tmp); + fz_freepixmap(tmp); } else diff --git a/mupdf/pdf_interpret.c b/mupdf/pdf_interpret.c index b9700e35..5678caf9 100644 --- a/mupdf/pdf_interpret.c +++ b/mupdf/pdf_interpret.c @@ -101,6 +101,7 @@ static void grestore(pdf_csi *csi) { pdf_gstate *gs = csi->gstate + csi->gtop; + int clipdepth = gs->clipdepth; if (csi->gtop == 0) { @@ -114,6 +115,13 @@ grestore(pdf_csi *csi) pdf_dropfont(gs->font); csi->gtop --; + + gs = csi->gstate + csi->gtop; + while (clipdepth > gs->clipdepth) + { + csi->dev->popclip(csi->dev->user); + clipdepth--; + } } static void |