summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTor Andersson <tor.andersson@artifex.com>2011-04-04 01:29:38 +0200
committerTor Andersson <tor.andersson@artifex.com>2011-04-04 01:29:38 +0200
commitfda7116fc12ea7e125ff8fc9851e3ca9280459b9 (patch)
tree940d4e7734bb297dbbf7454602615ac278e2be77
parent4d125739c1ac42d629360a7e2700410e788028c7 (diff)
downloadmupdf-fda7116fc12ea7e125ff8fc9851e3ca9280459b9.tar.xz
draw: Speed up display list execution by using a visibility test.
-rw-r--r--apps/pdfapp.c4
-rw-r--r--apps/pdfdraw.c6
-rw-r--r--apps/xpsdraw.c6
-rw-r--r--fitz/dev_draw.c1
-rw-r--r--fitz/dev_list.c45
-rw-r--r--fitz/fitz.h2
6 files changed, 53 insertions, 11 deletions
diff --git a/apps/pdfapp.c b/apps/pdfapp.c
index a9cb698a..8f5b3912 100644
--- a/apps/pdfapp.c
+++ b/apps/pdfapp.c
@@ -365,7 +365,7 @@ static void pdfapp_showpage(pdfapp_t *app, int loadpage, int drawpage, int repai
/* Extract text */
app->page_text = fz_newtextspan();
tdev = fz_newtextdevice(app->page_text);
- fz_executedisplaylist(app->page_list, tdev, fz_identity);
+ fz_executedisplaylist(app->page_list, tdev, fz_identity, fz_infinitebbox);
fz_freedevice(tdev);
}
@@ -392,7 +392,7 @@ static void pdfapp_showpage(pdfapp_t *app, int loadpage, int drawpage, int repai
app->image = fz_newpixmapwithrect(colorspace, bbox);
fz_clearpixmapwithcolor(app->image, 255);
idev = fz_newdrawdevice(app->cache, app->image);
- fz_executedisplaylist(app->page_list, idev, ctm);
+ fz_executedisplaylist(app->page_list, idev, ctm, bbox);
fz_freedevice(idev);
}
diff --git a/apps/pdfdraw.c b/apps/pdfdraw.c
index 9c46a3a9..3de0a80c 100644
--- a/apps/pdfdraw.c
+++ b/apps/pdfdraw.c
@@ -120,7 +120,7 @@ static void drawpage(pdf_xref *xref, int pagenum)
dev = fz_newtracedevice();
printf("<page number=\"%d\">\n", pagenum);
if (list)
- fz_executedisplaylist(list, dev, fz_identity);
+ fz_executedisplaylist(list, dev, fz_identity, fz_infinitebbox);
else
pdf_runpage(xref, page, dev, fz_identity);
printf("</page>\n");
@@ -132,7 +132,7 @@ static void drawpage(pdf_xref *xref, int pagenum)
fz_textspan *text = fz_newtextspan();
dev = fz_newtextdevice(text);
if (list)
- fz_executedisplaylist(list, dev, fz_identity);
+ fz_executedisplaylist(list, dev, fz_identity, fz_infinitebbox);
else
pdf_runpage(xref, page, dev, fz_identity);
fz_freedevice(dev);
@@ -173,7 +173,7 @@ static void drawpage(pdf_xref *xref, int pagenum)
dev = fz_newdrawdevice(glyphcache, pix);
if (list)
- fz_executedisplaylist(list, dev, ctm);
+ fz_executedisplaylist(list, dev, ctm, bbox);
else
pdf_runpage(xref, page, dev, ctm);
fz_freedevice(dev);
diff --git a/apps/xpsdraw.c b/apps/xpsdraw.c
index a9050a1c..2e30de9a 100644
--- a/apps/xpsdraw.c
+++ b/apps/xpsdraw.c
@@ -115,7 +115,7 @@ static void drawpage(xps_context *ctx, int pagenum)
dev = fz_newtracedevice();
printf("<page number=\"%d\">\n", pagenum);
if (list)
- fz_executedisplaylist(list, dev, fz_identity);
+ fz_executedisplaylist(list, dev, fz_identity, fz_infinitebbox);
else
xps_run_page(ctx, page, dev, fz_identity);
printf("</page>\n");
@@ -127,7 +127,7 @@ static void drawpage(xps_context *ctx, int pagenum)
fz_textspan *text = fz_newtextspan();
dev = fz_newtextdevice(text);
if (list)
- fz_executedisplaylist(list, dev, fz_identity);
+ fz_executedisplaylist(list, dev, fz_identity, fz_infinitebbox);
else
xps_run_page(ctx, page, dev, fz_identity);
fz_freedevice(dev);
@@ -171,7 +171,7 @@ static void drawpage(xps_context *ctx, int pagenum)
dev = fz_newdrawdevice(glyphcache, pix);
if (list)
- fz_executedisplaylist(list, dev, ctm);
+ fz_executedisplaylist(list, dev, ctm, bbox);
else
xps_run_page(ctx, page, dev, ctm);
fz_freedevice(dev);
diff --git a/fitz/dev_draw.c b/fitz/dev_draw.c
index e9cb74fc..e0a12492 100644
--- a/fitz/dev_draw.c
+++ b/fitz/dev_draw.c
@@ -632,7 +632,6 @@ fz_drawfillimage(void *user, fz_pixmap *image, fz_matrix ctm, float alpha)
}
#endif
-
if (image->colorspace != model && after)
{
converted = fz_newpixmap(model, image->x, image->y, image->w, image->h);
diff --git a/fitz/dev_list.c b/fitz/dev_list.c
index 4dcd1470..d90f64c2 100644
--- a/fitz/dev_list.c
+++ b/fitz/dev_list.c
@@ -176,6 +176,9 @@ fz_listcliptext(void *user, fz_text *text, fz_matrix ctm, int accumulate)
node->rect = fz_boundtext(text, ctm);
node->item.text = fz_clonetext(text);
node->flag = accumulate;
+ /* when accumulating, be conservative about culling */
+ if (accumulate)
+ node->rect = fz_infiniterect;
fz_appenddisplaynode(user, node);
}
@@ -342,13 +345,53 @@ fz_freedisplaylist(fz_displaylist *list)
}
void
-fz_executedisplaylist(fz_displaylist *list, fz_device *dev, fz_matrix topctm)
+fz_executedisplaylist(fz_displaylist *list, fz_device *dev, fz_matrix topctm, fz_bbox bounds)
{
fz_displaynode *node;
fz_rect bbox;
+ int clipped = 0;
+
+ if (!fz_isinfinitebbox(bounds))
+ {
+ /* add some fuzz at the edges, as especially glyph rects
+ * are sometimes not actually completely bounding the glyph */
+ bounds.x0 -= 20; bounds.y0 -= 20;
+ bounds.x1 += 20; bounds.y1 += 20;
+ }
+
for (node = list->first; node; node = node->next)
{
fz_matrix ctm = fz_concat(node->ctm, topctm);
+
+ /* cull objects to draw using a quick visibility test */
+ if (clipped || fz_isemptybbox(fz_intersectbbox(fz_roundrect(node->rect), bounds)))
+ {
+ switch (node->cmd)
+ {
+ case FZ_CMDCLIPPATH:
+ case FZ_CMDCLIPSTROKEPATH:
+ case FZ_CMDCLIPTEXT:
+ case FZ_CMDCLIPSTROKETEXT:
+ case FZ_CMDCLIPIMAGEMASK:
+ case FZ_CMDBEGINMASK:
+ case FZ_CMDBEGINGROUP:
+ clipped++;
+ continue;
+ case FZ_CMDPOPCLIP:
+ case FZ_CMDENDGROUP:
+ if (!clipped)
+ break;
+ clipped--;
+ continue;
+ case FZ_CMDENDMASK:
+ if (!clipped)
+ break;
+ continue;
+ default:
+ continue;
+ }
+ }
+
switch (node->cmd)
{
case FZ_CMDFILLPATH:
diff --git a/fitz/fitz.h b/fitz/fitz.h
index 216c7264..4a91c90d 100644
--- a/fitz/fitz.h
+++ b/fitz/fitz.h
@@ -1126,7 +1126,7 @@ struct fz_displaylist_s
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);
+void fz_executedisplaylist(fz_displaylist *list, fz_device *dev, fz_matrix ctm, fz_bbox area);
/*
* Function pointers for plotting functions.