summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--apps/pdfdraw.c11
-rw-r--r--fitz/dev_draw.c173
-rw-r--r--fitz/dev_trace.c22
-rw-r--r--fitz/fitz_base.h13
-rw-r--r--fitz/fitz_res.h6
-rw-r--r--fitzdraw/Jamfile1
-rw-r--r--fitzdraw/glyphcache.c1
-rw-r--r--fitzdraw/imagescale.c29
-rw-r--r--fitzdraw/meshdraw.c19
-rw-r--r--fitzdraw/pixmap.c38
-rw-r--r--mupdf/mupdf.h1
-rw-r--r--mupdf/pdf_build.c33
-rw-r--r--mupdf/pdf_image.c7
-rw-r--r--mupdf/pdf_interpret.c8
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