summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTor Andersson <tor@ghostscript.com>2010-04-08 19:54:33 +0200
committerTor Andersson <tor@ghostscript.com>2010-04-08 19:54:33 +0200
commit28bb08951bea16b4baf3b05365d606fde0a099b6 (patch)
tree1b33a686f5e6d099d58fad96da808ebc2541bc58
parente32122e047e5882f3ca64d86cc0562473360b329 (diff)
downloadmupdf-28bb08951bea16b4baf3b05365d606fde0a099b6.tar.xz
Add display list device.
-rw-r--r--Makefile9
-rw-r--r--apps/pdfapp.c39
-rw-r--r--apps/pdfapp.h2
-rw-r--r--apps/pdfdraw.c14
-rw-r--r--draw/meshdraw.c4
-rw-r--r--draw/pixmap.c21
-rw-r--r--fitz/dev_draw.c110
-rw-r--r--fitz/dev_list.c285
-rw-r--r--fitz/dev_null.c43
-rw-r--r--fitz/dev_text.c61
-rw-r--r--fitz/dev_trace.c60
-rw-r--r--fitz/fitz_base.h35
-rw-r--r--fitz/fitz_res.h214
-rw-r--r--fitz/res_font.c4
-rw-r--r--fitz/res_path.c32
-rw-r--r--fitz/res_text.c17
-rw-r--r--mupdf/pdf_build.c39
-rw-r--r--mupdf/pdf_image.c2
18 files changed, 698 insertions, 293 deletions
diff --git a/Makefile b/Makefile
index 37afa85f..32d5e853 100644
--- a/Makefile
+++ b/Makefile
@@ -96,8 +96,7 @@ FITZ_SRC=$(addprefix fitz/, \
crypt_aes.c crypt_arc4.c crypt_crc32.c crypt_md5.c \
filt_aesd.c filt_arc4.c filt_basic.c filt_dctd.c filt_faxd.c filt_faxdtab.c filt_flate.c \
filt_jbig2d.c filt_jpxd.c filt_lzwd.c filt_pipeline.c filt_predict.c \
- node_path.c node_text.c \
- dev_null.c dev_text.c dev_draw.c dev_trace.c \
+ dev_null.c dev_text.c dev_draw.c dev_list.c dev_trace.c \
obj_array.c obj_dict.c obj_parse.c obj_print.c obj_simple.c \
res_colorspace.c res_font.c res_shade.c res_path.c res_text.c \
stm_buffer.c stm_filter.c stm_misc.c stm_open.c stm_read.c \
@@ -254,6 +253,7 @@ CMAP_SRC=\
CMAP_OBJ=$(CMAP_SRC:$(GENDIR)/%.c=$(OBJDIR)/%.o)
CMAP_LIB=$(OBJDIR)/libcmaps.a
+$(CMAP_OBJ): $(MUPDF_HDR)
$(CMAP_LIB): $(CMAP_OBJ)
$(AR_CMD)
@@ -270,6 +270,7 @@ PDFSHOW_SRC=apps/pdfshow.c apps/pdftool.c
PDFSHOW_OBJ=$(PDFSHOW_SRC:apps/%.c=$(OBJDIR)/%.o)
PDFSHOW_EXE=$(OBJDIR)/pdfshow
+$(PDFSHOW_OBJ): $(MUPDF_HDR)
$(PDFSHOW_EXE): $(PDFSHOW_OBJ) $(MUPDF_LIB) $(FITZ_LIB)
$(LD_CMD)
@@ -277,6 +278,7 @@ PDFCLEAN_SRC=apps/pdfclean.c apps/pdftool.c
PDFCLEAN_OBJ=$(PDFCLEAN_SRC:apps/%.c=$(OBJDIR)/%.o)
PDFCLEAN_EXE=$(OBJDIR)/pdfclean
+$(PDFCLEAN_OBJ): $(MUPDF_HDR)
$(PDFCLEAN_EXE): $(PDFCLEAN_OBJ) $(MUPDF_LIB) $(FITZ_LIB)
$(LD_CMD)
@@ -284,6 +286,7 @@ PDFDRAW_SRC=apps/pdfdraw.c apps/pdftool.c
PDFDRAW_OBJ=$(PDFDRAW_SRC:apps/%.c=$(OBJDIR)/%.o)
PDFDRAW_EXE=$(OBJDIR)/pdfdraw
+$(PDFDRAW_OBJ): $(MUPDF_HDR)
$(PDFDRAW_EXE): $(PDFDRAW_OBJ) $(MUPDF_LIB) $(FONT_LIB) $(CMAP_LIB) $(FITZ_LIB) $(DRAW_LIB)
$(LD_CMD)
@@ -291,6 +294,7 @@ X11VIEW_SRC=apps/x11_main.c apps/x11_image.c apps/pdfapp.c
X11VIEW_OBJ=$(X11VIEW_SRC:apps/%.c=$(OBJDIR)/%.o)
X11VIEW_EXE=$(OBJDIR)/mupdf
+$(X11VIEW_OBJ): $(MUPDF_HDR)
$(X11VIEW_EXE): $(X11VIEW_OBJ) $(MUPDF_LIB) $(FONT_LIB) $(CMAP_LIB) $(FITZ_LIB) $(DRAW_LIB)
$(LD_CMD) $(X11LIBS)
@@ -302,6 +306,7 @@ WINVIEW_EXE=$(OBJDIR)/mupdf.exe
$(OBJDIR)/%.o: apps/%.rc
windres -i $< -o $@ --include-dir=apps
+$(WINVIEW_OBJ): $(MUPDF_HDR)
$(WINVIEW_EXE): $(WINVIEW_OBJ) $(MUPDF_LIB) $(FONT_LIB) $(CMAP_LIB) $(FITZ_LIB) $(DRAW_LIB)
$(LD_CMD) $(W32LIBS)
diff --git a/apps/pdfapp.c b/apps/pdfapp.c
index 0b39f134..1f78c4e1 100644
--- a/apps/pdfapp.c
+++ b/apps/pdfapp.c
@@ -164,11 +164,11 @@ void pdfapp_close(pdfapp_t *app)
app->page = nil;
if (app->image)
- fz_freepixmap(app->image);
+ fz_droppixmap(app->image);
app->image = nil;
if (app->text)
- fz_freetextline(app->text);
+ fz_freetextspan(app->text);
app->text = nil;
if (app->outline)
@@ -222,6 +222,7 @@ static void pdfapp_showpage(pdfapp_t *app, int loadpage, int drawpage)
char buf[256];
fz_error error;
fz_device *idev, *tdev, *mdev;
+ fz_displaylist *list;
fz_matrix ctm;
fz_irect bbox;
fz_obj *obj;
@@ -253,29 +254,31 @@ static void pdfapp_showpage(pdfapp_t *app, int loadpage, int drawpage)
ctm = pdfapp_viewctm(app);
bbox = fz_roundrect(fz_transformaabb(ctm, app->page->mediabox));
+ list = fz_newdisplaylist();
+
+ mdev = fz_newlistdevice(list);
+ app->page->contents->rp = app->page->contents->bp;
+ error = pdf_runcontentstream(mdev, fz_identity(), app->xref, app->page->resources, app->page->contents);
+ if (error)
+ pdfapp_error(app, error);
+ fz_freedevice(mdev);
+
if (app->image)
- fz_freepixmap(app->image);
+ fz_droppixmap(app->image);
app->image = fz_newpixmapwithrect(pdf_devicergb, bbox);
fz_clearpixmap(app->image, 0xFF);
idev = fz_newdrawdevice(app->image);
+ fz_executedisplaylist(list, idev, ctm);
+ fz_freedevice(idev);
if (app->text)
- fz_freetextline(app->text);
- app->text = fz_newtextline();
+ fz_freetextspan(app->text);
+ app->text = fz_newtextspan();
tdev = fz_newtextdevice(app->text);
+ fz_executedisplaylist(list, tdev, ctm);
+ fz_freedevice(tdev);
- app->page->contents->rp = app->page->contents->bp;
- error = pdf_runcontentstream(idev, ctm, app->xref, app->page->resources, app->page->contents);
- if (error)
- pdfapp_error(app, error);
-
- app->page->contents->rp = app->page->contents->bp;
- error = pdf_runcontentstream(tdev, ctm, app->xref, app->page->resources, app->page->contents);
- if (error)
- pdfapp_error(app, error);
-
- fz_freedrawdevice(idev);
- fz_freetextdevice(tdev);
+ fz_freedisplaylist(list);
winconvert(app, app->image);
}
@@ -641,7 +644,7 @@ void pdfapp_oncopy(pdfapp_t *app, unsigned short *ucsbuf, int ucslen)
{
ucsbuf[0] = 0;
fz_error error;
- fz_textline *ln;
+ fz_textspan *ln;
int x, y, c;
int i, p;
diff --git a/apps/pdfapp.h b/apps/pdfapp.h
index ce43d5b4..9df3c46b 100644
--- a/apps/pdfapp.h
+++ b/apps/pdfapp.h
@@ -32,7 +32,7 @@ struct pdfapp_s
float zoom;
int rotate;
fz_pixmap *image;
- fz_textline *text;
+ fz_textspan *text;
/* current page params */
int pageno;
diff --git a/apps/pdfdraw.c b/apps/pdfdraw.c
index 2e8c8472..203919cf 100644
--- a/apps/pdfdraw.c
+++ b/apps/pdfdraw.c
@@ -236,7 +236,7 @@ static void drawpnm(int pagenum, struct benchmark *loadtimes, struct benchmark *
error = pdf_runcontentstream(dev, ctm, xref, drawpage->resources, drawpage->contents);
if (error)
die(error);
- fz_freedrawdevice(dev);
+ fz_freedevice(dev);
if (drawpattern)
{
@@ -264,7 +264,7 @@ static void drawpnm(int pagenum, struct benchmark *loadtimes, struct benchmark *
pix->h = bbox.y1 - pix->y;
}
- fz_freepixmap(pix);
+ fz_droppixmap(pix);
if (!drawpattern) {
unsigned char buf[16];
@@ -308,7 +308,7 @@ static void drawtxt(int pagenum)
fz_error error;
fz_matrix ctm;
fz_obj *pageobj;
- fz_textline *text;
+ fz_textspan *text;
fz_device *dev;
pageobj = pdf_getpageobject(xref, pagenum);
@@ -318,7 +318,7 @@ static void drawtxt(int pagenum)
ctm = fz_identity();
- text = fz_newtextline();
+ text = fz_newtextspan();
dev = fz_newtextdevice(text);
drawpage->contents->rp = drawpage->contents->bp;
@@ -327,11 +327,11 @@ static void drawtxt(int pagenum)
die(error);
printf("[Page %d]\n", pagenum);
- fz_debugtextline(text);
+ fz_debugtextspan(text);
printf("\n");
- fz_freetextdevice(dev);
- fz_freetextline(text);
+ fz_freedevice(dev);
+ fz_freetextspan(text);
}
static void drawpages(char *pagelist)
diff --git a/draw/meshdraw.c b/draw/meshdraw.c
index d756db12..fd7f2565 100644
--- a/draw/meshdraw.c
+++ b/draw/meshdraw.c
@@ -386,13 +386,13 @@ baddata:
d += 4;
}
- fz_freepixmap(temp);
+ fz_droppixmap(temp);
}
else if (shade->cs != destcs)
{
fz_convertpixmap(shade->cs, temp, destcs, dest);
- fz_freepixmap(temp);
+ fz_droppixmap(temp);
}
}
diff --git a/draw/pixmap.c b/draw/pixmap.c
index 539234f6..dd42fb31 100644
--- a/draw/pixmap.c
+++ b/draw/pixmap.c
@@ -6,6 +6,7 @@ fz_newpixmap(fz_colorspace *colorspace, int x, int y, int w, int h)
fz_pixmap *pix;
pix = fz_malloc(sizeof(fz_pixmap));
+ pix->refs = 1;
pix->x = x;
pix->y = y;
pix->w = w;
@@ -30,13 +31,23 @@ fz_newpixmapwithrect(fz_colorspace *colorspace, fz_irect r)
return fz_newpixmap(colorspace, r.x0, r.y0, r.x1 - r.x0, r.y1 - r.y0);
}
+fz_pixmap *
+fz_keeppixmap(fz_pixmap *pix)
+{
+ pix->refs++;
+ return pix;
+}
+
void
-fz_freepixmap(fz_pixmap *pix)
+fz_droppixmap(fz_pixmap *pix)
{
- if (pix->colorspace)
- fz_dropcolorspace(pix->colorspace);
- fz_free(pix->samples);
- fz_free(pix);
+ if (pix && --pix->refs == 0)
+ {
+ if (pix->colorspace)
+ fz_dropcolorspace(pix->colorspace);
+ fz_free(pix->samples);
+ fz_free(pix);
+ }
}
void
diff --git a/fitz/dev_draw.c b/fitz/dev_draw.c
index b8223ce4..f4889aeb 100644
--- a/fitz/dev_draw.c
+++ b/fitz/dev_draw.c
@@ -97,15 +97,19 @@ blendmaskover(fz_pixmap *src, fz_pixmap *msk, fz_pixmap *dst)
else if (src->n == 4 && msk->n == 1 && dst->n == 4)
fz_duff_4i1o4(sp, src->w * 4, mp, msk->w, dp, dst->w * 4, w, h);
else if (src->n == dst->n)
- fz_duff_nimon(sp, src->w * src->n, src->n, mp, msk->w * msk->n, msk->n, dp, dst->w * dst->n, w, h);
+ fz_duff_nimon(sp, src->w * src->n, src->n,
+ mp, msk->w * msk->n, msk->n,
+ dp, dst->w * dst->n, w, h);
else
assert(!"blendmaskover src and msk and dst mismatch");
}
-void fz_drawfillpath(void *user, fz_path *path, fz_colorspace *colorspace, float *color, float alpha)
+static void
+fz_drawfillpath(void *user, fz_path *path, fz_matrix ctm,
+ fz_colorspace *colorspace, float *color, float alpha)
{
fz_drawdevice *dev = user;
- float expansion = fz_matrixexpansion(path->ctm);
+ float expansion = fz_matrixexpansion(ctm);
float flatness = 0.3 / expansion;
fz_irect bbox;
fz_irect clip;
@@ -116,7 +120,7 @@ void fz_drawfillpath(void *user, fz_path *path, fz_colorspace *colorspace, float
clip.y1 = dev->dest->y + dev->dest->h;
fz_resetgel(dev->gel, clip);
- fz_fillpath(dev->gel, path, path->ctm, flatness);
+ fz_fillpath(dev->gel, path, ctm, flatness);
fz_sortgel(dev->gel);
bbox = fz_boundgel(dev->gel);
@@ -136,18 +140,20 @@ void fz_drawfillpath(void *user, fz_path *path, fz_colorspace *colorspace, float
argb[4] = rgb[0] * 255;
argb[5] = rgb[1] * 255;
argb[6] = rgb[2] * 255;
- fz_scanconvert(dev->gel, dev->ael, path->winding == FZ_EVENODD, bbox, dev->dest, argb, 1);
+ fz_scanconvert(dev->gel, dev->ael, path->evenodd, bbox, dev->dest, argb, 1);
}
else
{
- fz_scanconvert(dev->gel, dev->ael, path->winding == FZ_EVENODD, bbox, dev->dest, nil, 1);
+ fz_scanconvert(dev->gel, dev->ael, path->evenodd, bbox, dev->dest, nil, 1);
}
}
-void fz_drawstrokepath(void *user, fz_path *path, fz_colorspace *colorspace, float *color, float alpha)
+static void
+fz_drawstrokepath(void *user, fz_path *path, fz_matrix ctm,
+ fz_colorspace *colorspace, float *color, float alpha)
{
fz_drawdevice *dev = user;
- float expansion = fz_matrixexpansion(path->ctm);
+ float expansion = fz_matrixexpansion(ctm);
float flatness = 0.3 / expansion;
float linewidth = path->linewidth;
fz_irect bbox;
@@ -163,9 +169,9 @@ void fz_drawstrokepath(void *user, fz_path *path, fz_colorspace *colorspace, flo
fz_resetgel(dev->gel, clip);
if (path->dashlen > 0)
- fz_dashpath(dev->gel, path, path->ctm, flatness, linewidth);
+ fz_dashpath(dev->gel, path, ctm, flatness, linewidth);
else
- fz_strokepath(dev->gel, path, path->ctm, flatness, linewidth);
+ fz_strokepath(dev->gel, path, ctm, flatness, linewidth);
fz_sortgel(dev->gel);
bbox = fz_boundgel(dev->gel);
@@ -193,10 +199,11 @@ void fz_drawstrokepath(void *user, fz_path *path, fz_colorspace *colorspace, flo
}
}
-void fz_drawclippath(void *user, fz_path *path)
+static void
+fz_drawclippath(void *user, fz_path *path, fz_matrix ctm)
{
fz_drawdevice *dev = user;
- float expansion = fz_matrixexpansion(path->ctm);
+ float expansion = fz_matrixexpansion(ctm);
float flatness = 0.3 / expansion;
fz_irect clip, bbox;
fz_pixmap *mask, *dest;
@@ -213,7 +220,7 @@ void fz_drawclippath(void *user, fz_path *path)
clip.y1 = dev->dest->y + dev->dest->h;
fz_resetgel(dev->gel, clip);
- fz_fillpath(dev->gel, path, path->ctm, flatness);
+ fz_fillpath(dev->gel, path, ctm, flatness);
fz_sortgel(dev->gel);
bbox = fz_boundgel(dev->gel);
@@ -226,7 +233,7 @@ void fz_drawclippath(void *user, fz_path *path)
memset(dest->samples, 0, dest->w * dest->h * dest->n);
if (!fz_isemptyrect(bbox))
- fz_scanconvert(dev->gel, dev->ael, path->winding == FZ_EVENODD, bbox, mask, nil, 1);
+ fz_scanconvert(dev->gel, dev->ael, path->evenodd, bbox, mask, nil, 1);
dev->clipstack[dev->cliptop].mask = mask;
dev->clipstack[dev->cliptop].dest = dev->dest;
@@ -234,7 +241,8 @@ void fz_drawclippath(void *user, fz_path *path)
dev->cliptop++;
}
-static void drawglyph(unsigned char *argb, fz_pixmap *dst, fz_glyph *src, int xorig, int yorig)
+static void
+drawglyph(unsigned char *argb, fz_pixmap *dst, fz_glyph *src, int xorig, int yorig)
{
unsigned char *dp, *sp;
int w, h;
@@ -273,7 +281,9 @@ static void drawglyph(unsigned char *argb, fz_pixmap *dst, fz_glyph *src, int xo
fz_text_1o1(sp, src->w, dp, dst->w, w, h);
}
-void fz_drawfilltext(void *user, fz_text *text, fz_colorspace *colorspace, float *color, float alpha)
+static void
+fz_drawfilltext(void *user, fz_text *text, fz_matrix ctm,
+ fz_colorspace *colorspace, float *color, float alpha)
{
fz_drawdevice *dev = user;
fz_irect clip;
@@ -313,7 +323,7 @@ void fz_drawfilltext(void *user, fz_text *text, fz_colorspace *colorspace, float
gid = text->els[i].gid;
tm.e = text->els[i].x;
tm.f = text->els[i].y;
- trm = fz_concat(tm, text->ctm);
+ trm = fz_concat(tm, ctm);
x = fz_floor(trm.e);
y = fz_floor(trm.f);
trm.e = QUANT(trm.e - fz_floor(trm.e), HSUBPIX);
@@ -324,15 +334,17 @@ void fz_drawfilltext(void *user, fz_text *text, fz_colorspace *colorspace, float
}
}
-void fz_drawstroketext(void *user, fz_text *text, fz_colorspace *colorspace, float *color, float alpha)
+static void
+fz_drawstroketext(void *user, fz_text *text, fz_matrix ctm,
+ fz_colorspace *colorspace, float *color, float alpha)
{
- fz_drawdevice *dev = user;
fz_warn("/%s setfont", text->font->name);
fz_debugtext(text, 0);
fz_warn("charpath stroke");
}
-void fz_drawcliptext(void *user, fz_text *text)
+static void
+fz_drawcliptext(void *user, fz_text *text, fz_matrix ctm)
{
fz_warn("gsave");
fz_warn("/%s setfont", text->font->name);
@@ -340,11 +352,13 @@ void fz_drawcliptext(void *user, fz_text *text)
fz_warn("charpath clip");
}
-void fz_drawignoretext(void *user, fz_text *text)
+static void
+fz_drawignoretext(void *user, fz_text *text, fz_matrix ctm)
{
}
-void fz_drawpopclip(void *user)
+static void
+fz_drawpopclip(void *user)
{
fz_drawdevice *dev = user;
if (dev->cliptop > 0)
@@ -353,14 +367,15 @@ void fz_drawpopclip(void *user)
fz_pixmap *dest = dev->clipstack[dev->cliptop-1].dest;
fz_pixmap *scratch = dev->dest;
blendmaskover(scratch, mask, dest);
- fz_freepixmap(mask);
- fz_freepixmap(scratch);
+ fz_droppixmap(mask);
+ fz_droppixmap(scratch);
dev->cliptop--;
dev->dest = dest;
}
}
-void fz_drawdrawshade(void *user, fz_shade *shade, fz_matrix ctm)
+static void
+fz_drawfillshade(void *user, fz_shade *shade, fz_matrix ctm)
{
fz_drawdevice *dev = user;
fz_rect bounds;
@@ -413,7 +428,7 @@ void fz_drawdrawshade(void *user, fz_shade *shade, fz_matrix ctm)
fz_rendershade(shade, ctm, dev->model, temp);
blendover(temp, dev->dest);
- fz_freepixmap(temp);
+ fz_droppixmap(temp);
}
static inline void
@@ -436,7 +451,8 @@ calcimagescale(fz_matrix ctm, int w, int h, int *odx, int *ody)
*ody = dy;
}
-void fz_drawdrawimage(void *user, fz_pixmap *image, fz_matrix ctm)
+static void
+fz_drawfillimage(void *user, fz_pixmap *image, fz_matrix ctm)
{
fz_drawdevice *dev = user;
fz_rect bounds;
@@ -522,7 +538,9 @@ void fz_drawdrawimage(void *user, fz_pixmap *image, fz_matrix ctm)
u0, v0, fa, fb, fc, fd, w, h);
}
-void fz_drawfillimagemask(void *user, fz_pixmap *image, fz_matrix ctm, fz_colorspace *colorspace, float *color, float alpha)
+static void
+fz_drawfillimagemask(void *user, fz_pixmap *image, fz_matrix ctm,
+ fz_colorspace *colorspace, float *color, float alpha)
{
fz_drawdevice *dev = user;
fz_rect bounds;
@@ -609,7 +627,8 @@ void fz_drawfillimagemask(void *user, fz_pixmap *image, fz_matrix ctm, fz_colors
}
}
-void fz_drawclipimagemask(void *user, fz_pixmap *image, fz_matrix ctm)
+static void
+fz_drawclipimagemask(void *user, fz_pixmap *image, fz_matrix ctm)
{
fz_drawdevice *dev = user;
fz_rect bounds;
@@ -690,7 +709,20 @@ void fz_drawclipimagemask(void *user, fz_pixmap *image, fz_matrix ctm)
dev->cliptop++;
}
-fz_device *fz_newdrawdevice(fz_pixmap *dest)
+static void
+fz_drawfreeuser(void *user)
+{
+ fz_drawdevice *dev = user;
+ if (dev->model)
+ fz_dropcolorspace(dev->model);
+ fz_freeglyphcache(dev->cache);
+ fz_freegel(dev->gel);
+ fz_freeael(dev->ael);
+ fz_free(dev);
+}
+
+fz_device *
+fz_newdrawdevice(fz_pixmap *dest)
{
fz_drawdevice *ddev = fz_malloc(sizeof(fz_drawdevice));
if (dest->colorspace)
@@ -704,6 +736,8 @@ fz_device *fz_newdrawdevice(fz_pixmap *dest)
ddev->cliptop = 0;
fz_device *dev = fz_newdevice(ddev);
+ dev->freeuser = fz_drawfreeuser;
+
dev->fillpath = fz_drawfillpath;
dev->strokepath = fz_drawstrokepath;
dev->clippath = fz_drawclippath;
@@ -715,23 +749,11 @@ fz_device *fz_newdrawdevice(fz_pixmap *dest)
dev->fillimagemask = fz_drawfillimagemask;
dev->clipimagemask = fz_drawclipimagemask;
- dev->drawimage = fz_drawdrawimage;
- dev->drawshade = fz_drawdrawshade;
+ dev->fillimage = fz_drawfillimage;
+ dev->fillshade = fz_drawfillshade;
dev->popclip = fz_drawpopclip;
return dev;
}
-void
-fz_freedrawdevice(fz_device *dev)
-{
- fz_drawdevice *ddev = dev->user;
- if (ddev->model)
- fz_dropcolorspace(ddev->model);
- fz_freeglyphcache(ddev->cache);
- fz_freegel(ddev->gel);
- fz_freeael(ddev->ael);
- fz_free(ddev);
- fz_free(dev);
-}
diff --git a/fitz/dev_list.c b/fitz/dev_list.c
new file mode 100644
index 00000000..22982508
--- /dev/null
+++ b/fitz/dev_list.c
@@ -0,0 +1,285 @@
+#include "fitz.h"
+
+static fz_displaynode *
+fz_newdisplaynode(fz_displaycommand cmd, fz_matrix ctm,
+ fz_colorspace *colorspace, float *color, float alpha)
+{
+ fz_displaynode *node;
+ int i;
+
+ node = fz_malloc(sizeof(fz_displaynode));
+ node->cmd = cmd;
+ node->next = nil;
+ node->ctm = ctm;
+ if (colorspace)
+ {
+ node->colorspace = fz_keepcolorspace(colorspace);
+ for (i = 0; i < node->colorspace->n; i++)
+ node->color[i] = color[i];
+ }
+ else
+ {
+ node->colorspace = nil;
+ }
+ node->alpha = alpha;
+
+ return node;
+}
+
+static void
+fz_appenddisplaynode(fz_displaylist *list, fz_displaynode *node)
+{
+ if (!list->first)
+ {
+ list->first = node;
+ list->last = node;
+ }
+ else
+ {
+ list->last->next = node;
+ list->last = node;
+ }
+}
+
+static void
+fz_freedisplaynode(fz_displaynode *node)
+{
+ switch (node->cmd)
+ {
+ case FZ_CMDFILLPATH:
+ case FZ_CMDSTROKEPATH:
+ case FZ_CMDCLIPPATH:
+ fz_freepath(node->item.path);
+ break;
+ case FZ_CMDFILLTEXT:
+ case FZ_CMDSTROKETEXT:
+ case FZ_CMDCLIPTEXT:
+ case FZ_CMDIGNORETEXT:
+ fz_freetext(node->item.text);
+ break;
+ case FZ_CMDFILLSHADE:
+ fz_dropshade(node->item.shade);
+ break;
+ case FZ_CMDFILLIMAGE:
+ case FZ_CMDFILLIMAGEMASK:
+ case FZ_CMDCLIPIMAGEMASK:
+ fz_droppixmap(node->item.image);
+ break;
+ case FZ_CMDPOPCLIP:
+ break;
+ }
+ if (node->colorspace)
+ fz_dropcolorspace(node->colorspace);
+ fz_free(node);
+}
+
+static void
+fz_listfillpath(void *user, fz_path *path, fz_matrix ctm,
+ fz_colorspace *colorspace, float *color, float alpha)
+{
+ fz_displaynode *node;
+ node = fz_newdisplaynode(FZ_CMDFILLPATH, ctm, colorspace, color, alpha);
+ node->item.path = fz_clonepath(path);
+ fz_appenddisplaynode(user, node);
+}
+
+static void
+fz_liststrokepath(void *user, fz_path *path, fz_matrix ctm,
+ fz_colorspace *colorspace, float *color, float alpha)
+{
+ fz_displaynode *node;
+ node = fz_newdisplaynode(FZ_CMDSTROKEPATH, ctm, colorspace, color, alpha);
+ node->item.path = fz_clonepath(path);
+ fz_appenddisplaynode(user, node);
+}
+
+static void
+fz_listclippath(void *user, fz_path *path, fz_matrix ctm)
+{
+ fz_displaynode *node;
+ node = fz_newdisplaynode(FZ_CMDCLIPPATH, ctm, nil, nil, 0.0);
+ node->item.path = fz_clonepath(path);
+ fz_appenddisplaynode(user, node);
+}
+
+static void
+fz_listfilltext(void *user, fz_text *text, fz_matrix ctm,
+ fz_colorspace *colorspace, float *color, float alpha)
+{
+ fz_displaynode *node;
+ node = fz_newdisplaynode(FZ_CMDFILLTEXT, ctm, colorspace, color, alpha);
+ node->item.text = fz_clonetext(text);
+ fz_appenddisplaynode(user, node);
+}
+
+static void
+fz_liststroketext(void *user, fz_text *text, fz_matrix ctm,
+ fz_colorspace *colorspace, float *color, float alpha)
+{
+ fz_displaynode *node;
+ node = fz_newdisplaynode(FZ_CMDSTROKETEXT, ctm, colorspace, color, alpha);
+ node->item.text = fz_clonetext(text);
+ fz_appenddisplaynode(user, node);
+}
+
+static void
+fz_listcliptext(void *user, fz_text *text, fz_matrix ctm)
+{
+ fz_displaynode *node;
+ node = fz_newdisplaynode(FZ_CMDCLIPPATH, ctm, nil, nil, 0.0);
+ node->item.text = fz_clonetext(text);
+ fz_appenddisplaynode(user, node);
+}
+
+static void
+fz_listignoretext(void *user, fz_text *text, fz_matrix ctm)
+{
+ fz_displaynode *node;
+ node = fz_newdisplaynode(FZ_CMDCLIPPATH, ctm, nil, nil, 0.0);
+ node->item.text = fz_clonetext(text);
+ fz_appenddisplaynode(user, node);
+}
+
+static void
+fz_listpopclip(void *user)
+{
+ fz_displaynode *node;
+ node = fz_newdisplaynode(FZ_CMDPOPCLIP, fz_identity(), nil, nil, 0.0);
+ fz_appenddisplaynode(user, node);
+}
+
+static void
+fz_listfillshade(void *user, fz_shade *shade, fz_matrix ctm)
+{
+ fz_displaynode *node;
+ node = fz_newdisplaynode(FZ_CMDFILLSHADE, ctm, nil, nil, 0.0);
+ node->item.shade = fz_keepshade(shade);
+ fz_appenddisplaynode(user, node);
+}
+
+static void
+fz_listfillimage(void *user, fz_pixmap *image, fz_matrix ctm)
+{
+ fz_displaynode *node;
+ node = fz_newdisplaynode(FZ_CMDFILLIMAGE, ctm, nil, nil, 0.0);
+ node->item.image = fz_keeppixmap(image);
+ fz_appenddisplaynode(user, node);
+}
+
+static void
+fz_listfillimagemask(void *user, fz_pixmap *image, fz_matrix ctm,
+ fz_colorspace *colorspace, float *color, float alpha)
+{
+ fz_displaynode *node;
+ node = fz_newdisplaynode(FZ_CMDFILLIMAGEMASK, ctm, colorspace, color, alpha);
+ node->item.image = fz_keeppixmap(image);
+ fz_appenddisplaynode(user, node);
+}
+
+static void
+fz_listclipimagemask(void *user, fz_pixmap *image, fz_matrix ctm)
+{
+ fz_displaynode *node;
+ node = fz_newdisplaynode(FZ_CMDCLIPIMAGEMASK, ctm, nil, nil, 0.0);
+ node->item.image = fz_keeppixmap(image);
+ fz_appenddisplaynode(user, node);
+}
+
+fz_device *
+fz_newlistdevice(fz_displaylist *list)
+{
+ fz_device *dev = fz_newdevice(list);
+
+ dev->fillpath = fz_listfillpath;
+ dev->strokepath = fz_liststrokepath;
+ dev->clippath = fz_listclippath;
+
+ dev->filltext = fz_listfilltext;
+ dev->stroketext = fz_liststroketext;
+ dev->cliptext = fz_listcliptext;
+ dev->ignoretext = fz_listignoretext;
+
+ dev->fillshade = fz_listfillshade;
+ dev->fillimage = fz_listfillimage;
+ dev->fillimagemask = fz_listfillimagemask;
+ dev->clipimagemask = fz_listclipimagemask;
+
+ dev->popclip = fz_listpopclip;
+
+ return dev;
+}
+
+fz_displaylist *
+fz_newdisplaylist(void)
+{
+ fz_displaylist *list = fz_malloc(sizeof(fz_displaylist));
+ list->first = nil;
+ list->last = nil;
+ return list;
+}
+
+void
+fz_freedisplaylist(fz_displaylist *list)
+{
+ fz_displaynode *node = list->first;
+ while (node)
+ {
+ fz_displaynode *next = node->next;
+ fz_freedisplaynode(node);
+ node = next;
+ }
+}
+
+void
+fz_executedisplaylist(fz_displaylist *list, fz_device *dev, fz_matrix topctm)
+{
+ fz_displaynode *node;
+ for (node = list->first; node; node = node->next)
+ {
+ fz_matrix ctm = fz_concat(node->ctm, topctm);
+ switch (node->cmd)
+ {
+ case FZ_CMDFILLPATH:
+ dev->fillpath(dev->user, node->item.path, ctm,
+ node->colorspace, node->color, node->alpha);
+ break;
+ case FZ_CMDSTROKEPATH:
+ dev->strokepath(dev->user, node->item.path, ctm,
+ node->colorspace, node->color, node->alpha);
+ break;
+ case FZ_CMDCLIPPATH:
+ dev->clippath(dev->user, node->item.path, ctm);
+ break;
+ case FZ_CMDFILLTEXT:
+ dev->filltext(dev->user, node->item.text, ctm,
+ node->colorspace, node->color, node->alpha);
+ break;
+ case FZ_CMDSTROKETEXT:
+ dev->stroketext(dev->user, node->item.text, ctm,
+ node->colorspace, node->color, node->alpha);
+ break;
+ case FZ_CMDCLIPTEXT:
+ dev->cliptext(dev->user, node->item.text, ctm);
+ break;
+ case FZ_CMDIGNORETEXT:
+ dev->ignoretext(dev->user, node->item.text, ctm);
+ break;
+ case FZ_CMDFILLSHADE:
+ dev->fillshade(dev->user, node->item.shade, ctm);
+ break;
+ case FZ_CMDFILLIMAGE:
+ dev->fillimage(dev->user, node->item.image, ctm);
+ break;
+ case FZ_CMDFILLIMAGEMASK:
+ dev->fillimagemask(dev->user, node->item.image, ctm,
+ node->colorspace, node->color, node->alpha);
+ case FZ_CMDCLIPIMAGEMASK:
+ dev->clipimagemask(dev->user, node->item.image, ctm);
+ break;
+ case FZ_CMDPOPCLIP:
+ dev->popclip(dev->user);
+ break;
+ }
+ }
+}
+
diff --git a/fitz/dev_null.c b/fitz/dev_null.c
index 4ad2e815..06d149ac 100644
--- a/fitz/dev_null.c
+++ b/fitz/dev_null.c
@@ -1,24 +1,27 @@
#include "fitz.h"
-void fz_nullfillpath(void *user, fz_path *path, fz_colorspace *colorspace, float *color, float alpha) {}
-void fz_nullstrokepath(void *user, fz_path *path, fz_colorspace *colorspace, float *color, float alpha) {}
-void fz_nullclippath(void *user, fz_path *path) {}
-void fz_nullfilltext(void *user, fz_text *text, fz_colorspace *colorspace, float *color, float alpha) {}
-void fz_nullstroketext(void *user, fz_text *text, fz_colorspace *colorspace, float *color, float alpha) {}
-void fz_nullcliptext(void *user, fz_text *text) {}
-void fz_nullignoretext(void *user, fz_text *text) {}
-void fz_nullpopclip(void *user) {}
-void fz_nulldrawshade(void *user, fz_shade *shade, fz_matrix ctm) {}
-void fz_nulldrawimage(void *user, fz_pixmap *image, fz_matrix ctm) {}
-void fz_nullfillimagemask(void *user, fz_pixmap *image, fz_matrix ctm, fz_colorspace *colorspace, float *color, float alpha) {}
-void fz_nullclipimagemask(void *user, fz_pixmap *image, fz_matrix ctm) {}
-
-fz_device *fz_newdevice(void *user)
+static void fz_nullfreeuser(void *user) {}
+static void fz_nullfillpath(void *user, fz_path *path, fz_matrix ctm, fz_colorspace *colorspace, float *color, float alpha) {}
+static void fz_nullstrokepath(void *user, fz_path *path, fz_matrix ctm, fz_colorspace *colorspace, float *color, float alpha) {}
+static void fz_nullclippath(void *user, fz_path *path, fz_matrix ctm) {}
+static void fz_nullfilltext(void *user, fz_text *text, fz_matrix ctm, fz_colorspace *colorspace, float *color, float alpha) {}
+static void fz_nullstroketext(void *user, fz_text *text, fz_matrix ctm, fz_colorspace *colorspace, float *color, float alpha) {}
+static void fz_nullcliptext(void *user, fz_text *text, fz_matrix ctm) {}
+static void fz_nullignoretext(void *user, fz_text *text, fz_matrix ctm) {}
+static void fz_nullpopclip(void *user) {}
+static void fz_nullfillshade(void *user, fz_shade *shade, fz_matrix ctm) {}
+static void fz_nullfillimage(void *user, fz_pixmap *image, fz_matrix ctm) {}
+static void fz_nullfillimagemask(void *user, fz_pixmap *image, fz_matrix ctm, fz_colorspace *colorspace, float *color, float alpha) {}
+static void fz_nullclipimagemask(void *user, fz_pixmap *image, fz_matrix ctm) {}
+
+fz_device *
+fz_newdevice(void *user)
{
fz_device *dev = fz_malloc(sizeof(fz_device));
memset(dev, 0, sizeof(fz_device));
dev->user = user;
+ dev->freeuser = fz_nullfreeuser;
dev->fillpath = fz_nullfillpath;
dev->strokepath = fz_nullstrokepath;
@@ -29,12 +32,20 @@ fz_device *fz_newdevice(void *user)
dev->cliptext = fz_nullcliptext;
dev->ignoretext = fz_nullignoretext;
+ dev->fillshade = fz_nullfillshade;
+ dev->fillimage = fz_nullfillimage;
dev->fillimagemask = fz_nullfillimagemask;
dev->clipimagemask = fz_nullclipimagemask;
- dev->drawimage = fz_nulldrawimage;
- dev->drawshade = fz_nulldrawshade;
dev->popclip = fz_nullpopclip;
return dev;
}
+
+void
+fz_freedevice(fz_device *dev)
+{
+ if (dev->freeuser)
+ dev->freeuser(dev->user);
+ fz_free(dev);
+} \ No newline at end of file
diff --git a/fitz/dev_text.c b/fitz/dev_text.c
index 8bcdea7f..a3b01d46 100644
--- a/fitz/dev_text.c
+++ b/fitz/dev_text.c
@@ -7,7 +7,8 @@
((FREETYPE_MAJOR == 2) && (FREETYPE_MINOR == 2)) || \
((FREETYPE_MAJOR == 2) && (FREETYPE_MINOR == 3) && (FREETYPE_PATCH < 8))
-int FT_Get_Advance(FT_Face face, int gid, int masks, FT_Fixed *out)
+int
+FT_Get_Advance(FT_Face face, int gid, int masks, FT_Fixed *out)
{
int fterr;
fterr = FT_Load_Glyph(face, gid, masks | FT_LOAD_IGNORE_TRANSFORM);
@@ -28,14 +29,14 @@ typedef struct fz_textdevice_s fz_textdevice;
struct fz_textdevice_s
{
fz_point point;
- fz_textline *line;
+ fz_textspan *line;
};
-fz_textline *
-fz_newtextline(void)
+fz_textspan *
+fz_newtextspan(void)
{
- fz_textline *line;
- line = fz_malloc(sizeof(fz_textline));
+ fz_textspan *line;
+ line = fz_malloc(sizeof(fz_textspan));
line->len = 0;
line->cap = 0;
line->text = nil;
@@ -44,16 +45,16 @@ fz_newtextline(void)
}
void
-fz_freetextline(fz_textline *line)
+fz_freetextspan(fz_textspan *line)
{
if (line->next)
- fz_freetextline(line->next);
+ fz_freetextspan(line->next);
fz_free(line->text);
fz_free(line);
}
static void
-fz_addtextchar(fz_textline *line, int x, int y, int c)
+fz_addtextchar(fz_textspan *line, int x, int y, int c)
{
if (line->len + 1 >= line->cap)
{
@@ -67,7 +68,7 @@ fz_addtextchar(fz_textline *line, int x, int y, int c)
}
void
-fz_debugtextline(fz_textline *line)
+fz_debugtextspan(fz_textspan *line)
{
char buf[10];
int c, n, k, i;
@@ -87,14 +88,13 @@ fz_debugtextline(fz_textline *line)
putchar('\n');
if (line->next)
- fz_debugtextline(line->next);
+ fz_debugtextspan(line->next);
}
static void
-fz_textextractline(fz_textline **line, fz_text *text, fz_point *oldpt)
+fz_textextractline(fz_textspan **line, fz_text *text, fz_matrix ctm, fz_point *oldpt)
{
fz_font *font = text->font;
- fz_matrix ctm = text->ctm;
fz_matrix tm = text->trm;
fz_matrix inv = fz_invertmatrix(text->trm);
fz_matrix trm;
@@ -149,8 +149,8 @@ fz_textextractline(fz_textline **line, fz_text *text, fz_point *oldpt)
if (fabs(dy) > 0.2)
{
- fz_textline *newline;
- newline = fz_newtextline();
+ fz_textspan *newline;
+ newline = fz_newtextspan();
(*line)->next = newline;
*line = newline;
}
@@ -163,19 +163,30 @@ fz_textextractline(fz_textline **line, fz_text *text, fz_point *oldpt)
}
}
-void fz_textfilltext(void *user, fz_text *text, fz_colorspace *colorspace, float *color, float alpha)
+static void
+fz_textfilltext(void *user, fz_text *text, fz_matrix ctm,
+ fz_colorspace *colorspace, float *color, float alpha)
{
fz_textdevice *tdev = user;
- fz_textextractline(&tdev->line, text, &tdev->point);
+ fz_textextractline(&tdev->line, text, ctm, &tdev->point);
}
-void fz_textignoretext(void *user, fz_text *text)
+static void
+fz_textignoretext(void *user, fz_text *text, fz_matrix ctm)
{
fz_textdevice *tdev = user;
- fz_textextractline(&tdev->line, text, &tdev->point);
+ fz_textextractline(&tdev->line, text, ctm, &tdev->point);
}
-fz_device *fz_newtextdevice(fz_textline *root)
+static void
+fz_textfreeuser(void *user)
+{
+ fz_textdevice *tdev = user;
+ fz_free(tdev);
+}
+
+fz_device *
+fz_newtextdevice(fz_textspan *root)
{
fz_textdevice *tdev = fz_malloc(sizeof(fz_textdevice));
tdev->line = root;
@@ -183,16 +194,8 @@ fz_device *fz_newtextdevice(fz_textline *root)
tdev->point.y = -1;
fz_device *dev = fz_newdevice(tdev);
-
+ dev->freeuser = fz_textfreeuser;
dev->filltext = fz_textfilltext;
dev->ignoretext = fz_textignoretext;
-
return dev;
}
-
-void fz_freetextdevice(fz_device *dev)
-{
- fz_textdevice *tdev = dev->user;
- fz_free(tdev);
- fz_free(dev);
-} \ No newline at end of file
diff --git a/fitz/dev_trace.c b/fitz/dev_trace.c
index f02aa035..834aee5c 100644
--- a/fitz/dev_trace.c
+++ b/fitz/dev_trace.c
@@ -1,12 +1,14 @@
#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);
}
-static void fz_tracecolor(fz_colorspace *colorspace, float *color, float alpha)
+static void
+fz_tracecolor(fz_colorspace *colorspace, float *color, float alpha)
{
int i;
printf("/%s setcolorspace\n", colorspace->name);
@@ -16,22 +18,24 @@ static void fz_tracecolor(fz_colorspace *colorspace, float *color, float alpha)
printf("%g setalpha\n", alpha);
}
-void fz_tracefillpath(void *user, fz_path *path, fz_colorspace *colorspace, float *color, float alpha)
+static void
+fz_tracefillpath(void *user, fz_path *path, fz_matrix ctm,
+ fz_colorspace *colorspace, float *color, float alpha)
{
- fz_tracematrix(path->ctm);
fz_printpath(path, 0);
- if (path->winding == FZ_EVENODD)
+ if (path->evenodd)
printf("eofill\n");
else
printf("fill\n");
}
-void fz_tracestrokepath(void *user, fz_path *path, fz_colorspace *colorspace, float *color, float alpha)
+static void
+fz_tracestrokepath(void *user, fz_path *path, fz_matrix ctm,
+ fz_colorspace *colorspace, float *color, float alpha)
{
int i;
fz_tracecolor(colorspace, color, alpha);
- fz_tracematrix(path->ctm);
printf("%g setlinewidth\n", path->linewidth);
printf("%g setmiterlimit\n", path->miterlimit);
@@ -51,18 +55,20 @@ void fz_tracestrokepath(void *user, fz_path *path, fz_colorspace *colorspace, fl
printf("stroke\n");
}
-void fz_traceclippath(void *user, fz_path *path)
+static void
+fz_traceclippath(void *user, fz_path *path, fz_matrix ctm)
{
printf("gsave\n");
- fz_tracematrix(path->ctm);
fz_printpath(path, 0);
- if (path->winding == FZ_EVENODD)
+ if (path->evenodd)
printf("eoclip\n");
else
printf("clip\n");
}
-void fz_tracefilltext(void *user, fz_text *text, fz_colorspace *colorspace, float *color, float alpha)
+static void
+fz_tracefilltext(void *user, fz_text *text, fz_matrix ctm,
+ fz_colorspace *colorspace, float *color, float alpha)
{
printf("/%s setfont\n", text->font->name);
fz_tracematrix(text->trm);
@@ -70,7 +76,9 @@ void fz_tracefilltext(void *user, fz_text *text, fz_colorspace *colorspace, floa
printf("show\n");
}
-void fz_tracestroketext(void *user, fz_text *text, fz_colorspace *colorspace, float *color, float alpha)
+static void
+fz_tracestroketext(void *user, fz_text *text, fz_matrix ctm,
+ fz_colorspace *colorspace, float *color, float alpha)
{
printf("/%s setfont\n", text->font->name);
fz_tracematrix(text->trm);
@@ -78,7 +86,8 @@ void fz_tracestroketext(void *user, fz_text *text, fz_colorspace *colorspace, fl
printf("charpath stroke\n");
}
-void fz_tracecliptext(void *user, fz_text *text)
+static void
+fz_tracecliptext(void *user, fz_text *text, fz_matrix ctm)
{
printf("gsave\n");
printf("/%s setfont\n", text->font->name);
@@ -87,7 +96,8 @@ void fz_tracecliptext(void *user, fz_text *text)
printf("charpath clip\n");
}
-void fz_traceignoretext(void *user, fz_text *text)
+static void
+fz_traceignoretext(void *user, fz_text *text, fz_matrix ctm)
{
printf("/%s setfont\n", text->font->name);
fz_tracematrix(text->trm);
@@ -95,29 +105,29 @@ void fz_traceignoretext(void *user, fz_text *text)
printf("invisibletext\n");
}
-void fz_tracedrawimage(void *user, fz_pixmap *image, fz_matrix ctm)
+static void
+fz_tracefillimage(void *user, fz_pixmap *image, fz_matrix ctm)
{
fz_tracematrix(ctm);
- printf("drawimage\n");
+ printf("fillimage\n");
}
-void fz_tracedrawshade(void *user, fz_shade *shade, fz_matrix ctm)
+static void
+fz_tracefillshade(void *user, fz_shade *shade, fz_matrix ctm)
{
fz_tracematrix(ctm);
- printf("drawshade\n");
+ printf("fillshade\n");
}
-void fz_tracepopclip(void *user)
+static void
+fz_tracepopclip(void *user)
{
printf("grestore\n");
}
fz_device *fz_newtracedevice(void)
{
- fz_device *dev = fz_malloc(sizeof(fz_device));
- memset(dev, 0, sizeof(dev));
-
- dev->user = nil;
+ fz_device *dev = fz_newdevice(nil);
dev->fillpath = fz_tracefillpath;
dev->strokepath = fz_tracestrokepath;
@@ -128,8 +138,8 @@ fz_device *fz_newtracedevice(void)
dev->cliptext = fz_tracecliptext;
dev->ignoretext = fz_traceignoretext;
- dev->drawimage = fz_tracedrawimage;
- dev->drawshade = fz_tracedrawshade;
+ dev->fillshade = fz_tracefillshade;
+ dev->fillimage = fz_tracefillimage;
dev->popclip = fz_tracepopclip;
diff --git a/fitz/fitz_base.h b/fitz/fitz_base.h
index edecefd1..52a93f0c 100644
--- a/fitz/fitz_base.h
+++ b/fitz/fitz_base.h
@@ -288,40 +288,5 @@ fz_irect fz_mergeirects(fz_irect a, fz_irect b);
fz_point fz_transformpoint(fz_matrix m, fz_point p);
fz_rect fz_transformaabb(fz_matrix m, fz_rect r);
-/*
- *TODO: move this into draw module
- */
-
-/*
-pixmaps have n components per pixel. the first is always alpha.
-premultiplied alpha when rendering, but non-premultiplied for colorspace
-conversions and rescaling.
-*/
-
-typedef struct fz_pixmap_s fz_pixmap;
-typedef struct fz_colorspace_s fz_colorspace;
-
-extern fz_colorspace *pdf_devicegray;
-extern fz_colorspace *pdf_devicergb;
-extern fz_colorspace *pdf_devicecmyk;
-extern fz_colorspace *pdf_devicelab;
-extern fz_colorspace *pdf_devicepattern;
-
-struct fz_pixmap_s
-{
- int x, y, w, h, n;
- fz_colorspace *colorspace;
- unsigned char *samples;
-};
-
-fz_pixmap * fz_newpixmapwithrect(fz_colorspace *, fz_irect bbox);
-fz_pixmap * fz_newpixmap(fz_colorspace *, int x, int y, int w, int h);
-
-void fz_debugpixmap(fz_pixmap *map, char *prefix);
-void fz_clearpixmap(fz_pixmap *map, unsigned char value);
-void fz_freepixmap(fz_pixmap *map);
-
-fz_pixmap * fz_scalepixmap(fz_pixmap *src, int xdenom, int ydenom);
-
#endif
diff --git a/fitz/fitz_res.h b/fitz/fitz_res.h
index 35416fda..2faf883a 100644
--- a/fitz/fitz_res.h
+++ b/fitz/fitz_res.h
@@ -1,121 +1,188 @@
/*
- *
+ * Resources and other graphics related objects.
*/
+typedef struct fz_pixmap_s fz_pixmap;
+typedef struct fz_colorspace_s fz_colorspace;
typedef struct fz_path_s fz_path;
typedef struct fz_text_s fz_text;
typedef struct fz_font_s fz_font;
typedef struct fz_shade_s fz_shade;
+enum { FZ_MAXCOLORS = 32 };
+
+typedef enum fz_blendkind_e
+{
+ /* PDF 1.4 -- standard separable */
+ FZ_BNORMAL,
+ FZ_BMULTIPLY,
+ FZ_BSCREEN,
+ FZ_BOVERLAY,
+ FZ_BDARKEN,
+ FZ_BLIGHTEN,
+ FZ_BCOLORDODGE,
+ FZ_BCOLORBURN,
+ FZ_BHARDLIGHT,
+ FZ_BSOFTLIGHT,
+ FZ_BDIFFERENCE,
+ FZ_BEXCLUSION,
+
+ /* PDF 1.4 -- standard non-separable */
+ FZ_BHUE,
+ FZ_BSATURATION,
+ FZ_BCOLOR,
+ FZ_BLUMINOSITY
+} fz_blendkind;
+
+/*
+pixmaps have n components per pixel. the first is always alpha.
+premultiplied alpha when rendering, but non-premultiplied for colorspace
+conversions and rescaling.
+*/
+
+extern fz_colorspace *pdf_devicegray;
+extern fz_colorspace *pdf_devicergb;
+extern fz_colorspace *pdf_devicecmyk;
+extern fz_colorspace *pdf_devicelab;
+extern fz_colorspace *pdf_devicepattern;
+
+struct fz_pixmap_s
+{
+ int refs;
+ int x, y, w, h, n;
+ fz_colorspace *colorspace;
+ unsigned char *samples;
+};
+
+fz_pixmap * fz_newpixmapwithrect(fz_colorspace *, fz_irect bbox);
+fz_pixmap * fz_newpixmap(fz_colorspace *, int x, int y, int w, int h);
+fz_pixmap *fz_keeppixmap(fz_pixmap *map);
+void fz_droppixmap(fz_pixmap *map);
+
+void fz_debugpixmap(fz_pixmap *map, char *prefix);
+void fz_clearpixmap(fz_pixmap *map, unsigned char value);
+
+fz_pixmap * fz_scalepixmap(fz_pixmap *src, int xdenom, int ydenom);
+
+/*
+ * The device interface.
+ */
+
typedef struct fz_device_s fz_device;
struct fz_device_s
{
void *user;
+ void (*freeuser)(void *);
- void (*fillpath)(void *, fz_path *, fz_colorspace *, float *color, float alpha);
- void (*strokepath)(void *, fz_path *, fz_colorspace *, float *color, float alpha);
- void (*clippath)(void *, fz_path *);
+ void (*fillpath)(void *, fz_path *, fz_matrix, fz_colorspace *, float *color, float alpha);
+ void (*strokepath)(void *, fz_path *, fz_matrix, fz_colorspace *, float *color, float alpha);
+ void (*clippath)(void *, fz_path *, fz_matrix);
- void (*filltext)(void *, fz_text *, fz_colorspace *, float *color, float alpha);
- void (*stroketext)(void *, fz_text *, fz_colorspace *, float *color, float alpha);
- void (*cliptext)(void *, fz_text *);
- void (*ignoretext)(void *, fz_text *);
+ void (*filltext)(void *, fz_text *, fz_matrix, fz_colorspace *, float *color, float alpha);
+ void (*stroketext)(void *, fz_text *, fz_matrix, fz_colorspace *, float *color, float alpha);
+ void (*cliptext)(void *, fz_text *, fz_matrix);
+ void (*ignoretext)(void *, fz_text *, fz_matrix);
+ void (*fillshade)(void *, fz_shade *shd, fz_matrix ctm);
+ void (*fillimage)(void *, fz_pixmap *img, fz_matrix ctm);
void (*fillimagemask)(void *, fz_pixmap *img, fz_matrix ctm, fz_colorspace *, float *color, float alpha);
void (*clipimagemask)(void *, fz_pixmap *img, fz_matrix ctm);
- void (*drawimage)(void *, fz_pixmap *img, fz_matrix ctm);
- void (*drawshade)(void *, fz_shade *shd, fz_matrix ctm);
void (*popclip)(void *);
};
-/* no-op device functions */
fz_device *fz_newdevice(void *user);
-void fz_initnulldevice(fz_device *dev);
-void fz_nullfillpath(void *user, fz_path *path, fz_colorspace *colorspace, float *color, float alpha);
-void fz_nullstrokepath(void *user, fz_path *path, fz_colorspace *colorspace, float *color, float alpha);
-void fz_nullclippath(void *user, fz_path *path);
-void fz_nullfilltext(void *user, fz_text *text, fz_colorspace *colorspace, float *color, float alpha);
-void fz_nullstroketext(void *user, fz_text *text, fz_colorspace *colorspace, float *color, float alpha);
-void fz_nullcliptext(void *user, fz_text *text);
-void fz_nullignoretext(void *user, fz_text *text);
-void fz_nullpopclip(void *user);
-void fz_nulldrawshade(void *user, fz_shade *shade, fz_matrix ctm);
-void fz_nulldrawimage(void *user, fz_pixmap *image, fz_matrix ctm);
-void fz_nullfillimagemask(void *user, fz_pixmap *image, fz_matrix ctm, fz_colorspace *colorspace, float *color, float alpha);
-void fz_nullclipimagemask(void *user, fz_pixmap *image, fz_matrix ctm);
+void fz_freedevice(fz_device *dev);
fz_device *fz_newtracedevice(void);
fz_device *fz_newdrawdevice(fz_pixmap *dest);
-void fz_freedrawdevice(fz_device *dev);
-typedef struct fz_textline_s fz_textline;
+/* Text extraction device */
+
+typedef struct fz_textspan_s fz_textspan;
typedef struct fz_textchar_s fz_textchar;
struct fz_textchar_s
{
- int x, y;
- int c;
+ int c, x, y, w;
};
-struct fz_textline_s
+struct fz_textspan_s
{
+ int ascender, descender;
int len, cap;
fz_textchar *text;
- fz_textline *next;
+ fz_textspan *next;
};
-fz_textline * fz_newtextline(void);
-void fz_freetextline(fz_textline *line);
-void fz_debugtextline(fz_textline *line);
+fz_textspan * fz_newtextspan(void);
+void fz_freetextspan(fz_textspan *line);
+void fz_debugtextspan(fz_textspan *line);
-fz_device *fz_newtextdevice(fz_textline *text);
-void fz_freetextdevice(fz_device *dev);
+fz_device *fz_newtextdevice(fz_textspan *text);
-typedef enum fz_blendkind_e
+/* Display list device -- record and play back device commands. */
+
+typedef struct fz_displaylist_s fz_displaylist;
+typedef struct fz_displaynode_s fz_displaynode;
+
+typedef enum fz_displaycommand_e
{
- /* PDF 1.4 -- standard separable */
- FZ_BNORMAL,
- FZ_BMULTIPLY,
- FZ_BSCREEN,
- FZ_BOVERLAY,
- FZ_BDARKEN,
- FZ_BLIGHTEN,
- FZ_BCOLORDODGE,
- FZ_BCOLORBURN,
- FZ_BHARDLIGHT,
- FZ_BSOFTLIGHT,
- FZ_BDIFFERENCE,
- FZ_BEXCLUSION,
+ FZ_CMDFILLPATH,
+ FZ_CMDSTROKEPATH,
+ FZ_CMDCLIPPATH,
+ FZ_CMDFILLTEXT,
+ FZ_CMDSTROKETEXT,
+ FZ_CMDCLIPTEXT,
+ FZ_CMDIGNORETEXT,
+ FZ_CMDFILLSHADE,
+ FZ_CMDFILLIMAGE,
+ FZ_CMDFILLIMAGEMASK,
+ FZ_CMDCLIPIMAGEMASK,
+ FZ_CMDPOPCLIP,
+} fz_displaycommand;
+
+struct fz_displaylist_s
+{
+ fz_displaynode *first;
+ fz_displaynode *last;
+};
- /* PDF 1.4 -- standard non-separable */
- FZ_BHUE,
- FZ_BSATURATION,
- FZ_BCOLOR,
- FZ_BLUMINOSITY
-} fz_blendkind;
+struct fz_displaynode_s
+{
+ fz_displaycommand cmd;
+ fz_displaynode *next;
+ union {
+ fz_path *path;
+ fz_text *text;
+ fz_shade *shade;
+ fz_pixmap *image;
+ } item;
+ fz_matrix ctm;
+ fz_colorspace *colorspace;
+ float alpha;
+ float color[FZ_MAXCOLORS];
+};
+
+fz_displaylist *fz_newdisplaylist(void);
+void fz_freedisplaylist(fz_displaylist *list);
+fz_device *fz_newlistdevice(fz_displaylist *list);
+void fz_executedisplaylist(fz_displaylist *list, fz_device *dev, fz_matrix ctm);
/*
- * Vector paths.
- * They can be stroked and dashed, or be filled.
- * They have a fill rule (nonzero or evenodd).
+ * Vector path buffer.
+ * It can be stroked and dashed, or be filled.
+ * It has a fill rule (nonzero or evenodd).
*
* When rendering, they are flattened, stroked and dashed straight
* into the Global Edge List.
*/
typedef struct fz_stroke_s fz_stroke;
-typedef struct fz_dash_s fz_dash;
typedef union fz_pathel_s fz_pathel;
-typedef enum fz_pathwinding_e
-{
- FZ_EVENODD,
- FZ_NONZERO,
-} fz_pathwinding;
-
typedef enum fz_pathelkind_e
{
FZ_MOVETO,
@@ -132,8 +199,7 @@ union fz_pathel_s
struct fz_path_s
{
- fz_matrix ctm;
- fz_pathwinding winding;
+ int evenodd;
int linecap;
int linejoin;
float linewidth;
@@ -155,13 +221,12 @@ void fz_closepath(fz_path*);
void fz_resetpath(fz_path *path);
void fz_freepath(fz_path *path);
-fz_rect fz_boundpath(fz_path *, int dostroke);
+fz_path *fz_clonepath(fz_path *old);
+
+fz_rect fz_boundpath(fz_path *path, fz_matrix ctm, int dostroke);
void fz_debugpath(fz_path *, int indent);
void fz_printpath(fz_path *, int indent);
-fz_dash *fz_newdash(float phase, int len, float *array);
-void fz_freedash(fz_dash *dash);
-
/*
* Text buffer.
*
@@ -187,7 +252,6 @@ struct fz_text_s
{
fz_font *font;
fz_matrix trm;
- fz_matrix ctm;
int len, cap;
fz_textel *els;
};
@@ -199,14 +263,14 @@ void fz_resettext(fz_text *text);
void fz_freetext(fz_text *text);
void fz_debugtext(fz_text*, int indent);
+fz_text *fz_clonetext(fz_text *old);
+
/*
* Colorspace resources.
*
* TODO: use lcms
*/
-enum { FZ_MAXCOLORS = 32 };
-
struct fz_colorspace_s
{
int refs;
@@ -254,7 +318,7 @@ struct fz_font_s
float *t3widths; /* has 256 entries if used */
void *t3xref; /* a pdf_xref for the callback */
fz_error (*t3runcontentstream)(fz_device *dev, fz_matrix ctm,
- void *xref, fz_obj *resources, fz_buffer *contents);
+ struct pdf_xref_s *xref, fz_obj *resources, fz_buffer *contents);
fz_rect bbox;
};
diff --git a/fitz/res_font.c b/fitz/res_font.c
index 817bc3eb..ea8eec98 100644
--- a/fitz/res_font.c
+++ b/fitz/res_font.c
@@ -372,7 +372,7 @@ fz_rendert3glyph(fz_glyph *glyph, fz_font *font, int gid, fz_matrix trm)
static fz_pixmap *pixmap = nil;
if (pixmap)
{
- fz_freepixmap(pixmap);
+ fz_droppixmap(pixmap);
pixmap = nil;
}
@@ -393,7 +393,7 @@ fz_rendert3glyph(fz_glyph *glyph, fz_font *font, int gid, fz_matrix trm)
error = font->t3runcontentstream(dev, ctm, font->t3xref, font->t3resources, contents);
if (error)
fz_catch(error, "cannot draw type3 glyph");
- fz_freedrawdevice(dev);
+ fz_freedevice(dev);
glyph->x = pixmap->x;
glyph->y = pixmap->y;
diff --git a/fitz/res_path.c b/fitz/res_path.c
index f096f4ef..a7de4da9 100644
--- a/fitz/res_path.c
+++ b/fitz/res_path.c
@@ -6,10 +6,9 @@ fz_newpath(void)
fz_path *path;
path = fz_malloc(sizeof(fz_path));
- path->ctm = fz_identity();
path->dashlen = 0;
path->dashphase = 0;
- path->winding = FZ_NONZERO;
+ path->evenodd = 0;
path->linecap = 0;
path->linejoin = 0;
path->linewidth = 1.0;
@@ -21,6 +20,22 @@ fz_newpath(void)
return path;
}
+fz_path *
+fz_clonepath(fz_path *old)
+{
+ fz_path *path;
+
+ path = fz_malloc(sizeof(fz_path));
+ memcpy(path, old, sizeof(fz_path));
+
+ path->len = old->len;
+ path->cap = path->len;
+ path->els = fz_malloc(path->cap * sizeof(fz_pathel));
+ memcpy(path->els, old->els, sizeof(fz_pathel) * path->len);
+
+ return path;
+}
+
void
fz_freepath(fz_path *path)
{
@@ -31,10 +46,9 @@ fz_freepath(fz_path *path)
void
fz_resetpath(fz_path *path)
{
- path->ctm = fz_identity();
path->dashlen = 0;
path->dashphase = 0;
- path->winding = FZ_NONZERO;
+ path->evenodd = 0;
path->linecap = 0;
path->linejoin = 0;
path->linewidth = 1.0;
@@ -123,7 +137,7 @@ static inline fz_rect boundexpand(fz_rect r, fz_point p)
}
fz_rect
-fz_boundpath(fz_path *path, int dostroke)
+fz_boundpath(fz_path *path, fz_matrix ctm, int dostroke)
{
fz_point p;
fz_rect r = fz_emptyrect;
@@ -133,7 +147,7 @@ fz_boundpath(fz_path *path, int dostroke)
{
p.x = path->els[1].v;
p.y = path->els[2].v;
- p = fz_transformpoint(path->ctm, p);
+ p = fz_transformpoint(ctm, p);
r.x0 = r.x1 = p.x;
r.y0 = r.y1 = p.y;
}
@@ -145,15 +159,15 @@ fz_boundpath(fz_path *path, int dostroke)
case FZ_CURVETO:
p.x = path->els[i++].v;
p.y = path->els[i++].v;
- r = boundexpand(r, fz_transformpoint(path->ctm, p));
+ r = boundexpand(r, fz_transformpoint(ctm, p));
p.x = path->els[i++].v;
p.y = path->els[i++].v;
- r = boundexpand(r, fz_transformpoint(path->ctm, p));
+ r = boundexpand(r, fz_transformpoint(ctm, p));
case FZ_MOVETO:
case FZ_LINETO:
p.x = path->els[i++].v;
p.y = path->els[i++].v;
- r = boundexpand(r, fz_transformpoint(path->ctm, p));
+ r = boundexpand(r, fz_transformpoint(ctm, p));
break;
case FZ_CLOSEPATH:
break;
diff --git a/fitz/res_text.c b/fitz/res_text.c
index a21cb3fc..798bd8a5 100644
--- a/fitz/res_text.c
+++ b/fitz/res_text.c
@@ -8,7 +8,6 @@ fz_newtext(fz_font *font)
text = fz_malloc(sizeof(fz_text));
text->font = fz_keepfont(font);
text->trm = fz_identity();
- text->ctm = fz_identity();
text->len = 0;
text->cap = 0;
text->els = nil;
@@ -24,6 +23,22 @@ fz_freetext(fz_text *text)
fz_free(text);
}
+fz_text *
+fz_clonetext(fz_text *old)
+{
+ fz_text *text;
+
+ text = fz_malloc(sizeof(fz_text));
+ text->font = fz_keepfont(old->font);
+ text->trm = old->trm;
+ text->len = old->len;
+ text->cap = text->len;
+ text->els = fz_malloc(text->len * sizeof(fz_textel));
+ memcpy(text->els, old->els, text->len * sizeof(fz_textel));
+
+ return text;
+}
+
fz_rect
fz_boundtext(fz_text *text, fz_matrix ctm)
{
diff --git a/mupdf/pdf_build.c b/mupdf/pdf_build.c
index 445541dd..c3013855 100644
--- a/mupdf/pdf_build.c
+++ b/mupdf/pdf_build.c
@@ -250,7 +250,7 @@ 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->fillshade(csi->dev->user, shd, gstate->ctm);
}
void
@@ -261,7 +261,7 @@ pdf_showimage(pdf_csi *csi, pdf_xref *xref, pdf_image *image)
fz_error error = pdf_loadtile(image, tile);
if (error)
{
- fz_freepixmap(tile);
+ fz_droppixmap(tile);
fz_catch(error, "cannot load image data");
return;
}
@@ -273,7 +273,7 @@ pdf_showimage(pdf_csi *csi, pdf_xref *xref, pdf_image *image)
if (error)
fz_catch(error, "cannot load image mask data");
csi->dev->clipimagemask(csi->dev->user, mask, gstate->ctm);
- fz_freepixmap(mask);
+ fz_droppixmap(mask);
}
if (image->n == 0 && image->a == 1)
@@ -302,20 +302,20 @@ pdf_showimage(pdf_csi *csi, pdf_xref *xref, pdf_image *image)
break;
case PDF_MSHADE:
csi->dev->clipimagemask(csi->dev->user, tile, gstate->ctm);
- csi->dev->drawshade(csi->dev->user, gstate->fill.shade, gstate->ctm);
+ csi->dev->fillshade(csi->dev->user, gstate->fill.shade, gstate->ctm);
csi->dev->popclip(csi->dev->user);
break;
}
}
else
{
- csi->dev->drawimage(csi->dev->user, tile, gstate->ctm);
+ csi->dev->fillimage(csi->dev->user, tile, gstate->ctm);
}
if (image->mask)
csi->dev->popclip(csi->dev->user);
- fz_freepixmap(tile);
+ fz_droppixmap(tile);
}
void
@@ -328,8 +328,7 @@ pdf_showpath(pdf_csi *csi, pdf_xref *xref, int doclose, int dofill, int dostroke
if (doclose)
fz_closepath(csi->path);
- csi->path->ctm = gstate->ctm;
- csi->path->winding = evenodd ? FZ_EVENODD : FZ_NONZERO;
+ csi->path->evenodd = evenodd;
csi->path->linewidth = gstate->linewidth;
csi->path->linecap = gstate->linecap;
csi->path->linejoin = gstate->linejoin;
@@ -342,7 +341,7 @@ pdf_showpath(pdf_csi *csi, pdf_xref *xref, int doclose, int dofill, int dostroke
if (csi->clip)
{
gstate->clipdepth++;
- csi->dev->clippath(csi->dev->user, csi->path);
+ csi->dev->clippath(csi->dev->user, csi->path, gstate->ctm);
csi->clip = 0;
}
@@ -355,18 +354,18 @@ pdf_showpath(pdf_csi *csi, pdf_xref *xref, int doclose, int dofill, int dostroke
case PDF_MCOLOR:
case PDF_MINDEXED:
case PDF_MLAB:
- csi->dev->fillpath(csi->dev->user, csi->path,
+ csi->dev->fillpath(csi->dev->user, csi->path, gstate->ctm,
gstate->fill.cs, gstate->fill.v, gstate->fill.alpha);
break;
case PDF_MPATTERN:
- bbox = fz_boundpath(csi->path, 0);
- csi->dev->clippath(csi->dev->user, csi->path);
+ bbox = fz_boundpath(csi->path, gstate->ctm, 0);
+ csi->dev->clippath(csi->dev->user, csi->path, gstate->ctm);
pdf_showpattern(csi, gstate->fill.pattern, xref, bbox, PDF_MFILL);
csi->dev->popclip(csi->dev->user);
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->clippath(csi->dev->user, csi->path, gstate->ctm);
+ csi->dev->fillshade(csi->dev->user, gstate->fill.shade, gstate->ctm);
csi->dev->popclip(csi->dev->user);
break;
}
@@ -381,7 +380,7 @@ pdf_showpath(pdf_csi *csi, pdf_xref *xref, int doclose, int dofill, int dostroke
case PDF_MCOLOR:
case PDF_MINDEXED:
case PDF_MLAB:
- csi->dev->strokepath(csi->dev->user, csi->path,
+ csi->dev->strokepath(csi->dev->user, csi->path, gstate->ctm,
gstate->stroke.cs, gstate->stroke.v, gstate->stroke.alpha);
break;
case PDF_MPATTERN:
@@ -412,8 +411,6 @@ pdf_flushtext(pdf_csi *csi)
if (!csi->text)
return;
- csi->text->ctm = gstate->ctm;
-
switch (csi->textmode)
{
case 0:
@@ -448,12 +445,12 @@ pdf_flushtext(pdf_csi *csi)
}
if (doinvisible)
- csi->dev->ignoretext(csi->dev->user, csi->text);
+ csi->dev->ignoretext(csi->dev->user, csi->text, gstate->ctm);
if (doclip)
{
gstate->clipdepth++;
- csi->dev->cliptext(csi->dev->user, csi->text);
+ csi->dev->cliptext(csi->dev->user, csi->text, gstate->ctm);
}
if (dofill)
@@ -465,7 +462,7 @@ pdf_flushtext(pdf_csi *csi)
case PDF_MCOLOR:
case PDF_MINDEXED:
case PDF_MLAB:
- csi->dev->filltext(csi->dev->user, csi->text,
+ csi->dev->filltext(csi->dev->user, csi->text, gstate->ctm,
gstate->fill.cs, gstate->fill.v, gstate->fill.alpha);
break;
case PDF_MPATTERN:
@@ -486,7 +483,7 @@ pdf_flushtext(pdf_csi *csi)
case PDF_MCOLOR:
case PDF_MINDEXED:
case PDF_MLAB:
- csi->dev->stroketext(csi->dev->user, csi->text,
+ csi->dev->stroketext(csi->dev->user, csi->text, gstate->ctm,
gstate->stroke.cs, gstate->stroke.v, gstate->stroke.alpha);
break;
case PDF_MPATTERN:
diff --git a/mupdf/pdf_image.c b/mupdf/pdf_image.c
index 00a9ee30..0b1dca7e 100644
--- a/mupdf/pdf_image.c
+++ b/mupdf/pdf_image.c
@@ -553,7 +553,7 @@ pdf_loadtile(pdf_image *src, fz_pixmap *tile)
if (src->usecolorkey)
maskcolorkeyindexed(tmp, tile, src->colorkey);
- fz_freepixmap(tmp);
+ fz_droppixmap(tmp);
}
else