diff options
author | Tor Andersson <tor.andersson@artifex.com> | 2011-04-04 01:29:38 +0200 |
---|---|---|
committer | Tor Andersson <tor.andersson@artifex.com> | 2011-04-04 01:29:38 +0200 |
commit | fda7116fc12ea7e125ff8fc9851e3ca9280459b9 (patch) | |
tree | 940d4e7734bb297dbbf7454602615ac278e2be77 /fitz | |
parent | 4d125739c1ac42d629360a7e2700410e788028c7 (diff) | |
download | mupdf-fda7116fc12ea7e125ff8fc9851e3ca9280459b9.tar.xz |
draw: Speed up display list execution by using a visibility test.
Diffstat (limited to 'fitz')
-rw-r--r-- | fitz/dev_draw.c | 1 | ||||
-rw-r--r-- | fitz/dev_list.c | 45 | ||||
-rw-r--r-- | fitz/fitz.h | 2 |
3 files changed, 45 insertions, 3 deletions
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. |