diff options
author | Tor Andersson <tor.andersson@artifex.com> | 2011-04-04 17:44:27 +0200 |
---|---|---|
committer | Tor Andersson <tor.andersson@artifex.com> | 2011-04-04 17:44:27 +0200 |
commit | 6a87014ff020538841d7f5a0dd1adef8a6ce9e79 (patch) | |
tree | a98e917471df377a3e2ef852652ebb1535bec0be /fitz/dev_list.c | |
parent | e77893b29cf53a9d6933cab0f9ae9e78b30a6592 (diff) | |
download | mupdf-6a87014ff020538841d7f5a0dd1adef8a6ce9e79.tar.xz |
Add device interface functions to draw tiled patterns.
Diffstat (limited to 'fitz/dev_list.c')
-rw-r--r-- | fitz/dev_list.c | 55 |
1 files changed, 53 insertions, 2 deletions
diff --git a/fitz/dev_list.c b/fitz/dev_list.c index bfa4ddf1..2bba6ed3 100644 --- a/fitz/dev_list.c +++ b/fitz/dev_list.c @@ -90,6 +90,8 @@ fz_freedisplaynode(fz_displaynode *node) case FZ_CMDENDMASK: case FZ_CMDBEGINGROUP: case FZ_CMDENDGROUP: + case FZ_CMDBEGINTILE: + case FZ_CMDENDTILE: break; } if (node->stroke) @@ -291,6 +293,29 @@ fz_listendgroup(void *user) fz_appenddisplaynode(user, node); } +static void +fz_listbegintile(void *user, fz_rect area, fz_rect view, float xstep, float ystep, fz_matrix ctm) +{ + fz_displaynode *node; + node = fz_newdisplaynode(FZ_CMDBEGINTILE, ctm, nil, nil, 0); + node->rect = area; + node->color[0] = xstep; + node->color[1] = ystep; + node->color[2] = view.x0; + node->color[3] = view.y0; + node->color[4] = view.x1; + node->color[5] = view.y1; + fz_appenddisplaynode(user, node); +} + +static void +fz_listendtile(void *user) +{ + fz_displaynode *node; + node = fz_newdisplaynode(FZ_CMDENDTILE, fz_identity, nil, nil, 0); + fz_appenddisplaynode(user, node); +} + fz_device * fz_newlistdevice(fz_displaylist *list) { @@ -319,6 +344,9 @@ fz_newlistdevice(fz_displaylist *list) dev->begingroup = fz_listbegingroup; dev->endgroup = fz_listendgroup; + dev->begintile = fz_listbegintile; + dev->endtile = fz_listendtile; + return dev; } @@ -350,6 +378,7 @@ fz_executedisplaylist(fz_displaylist *list, fz_device *dev, fz_matrix topctm, fz fz_displaynode *node; fz_rect bbox; int clipped = 0; + int tiled = 0; if (!fz_isinfinitebbox(bounds)) { @@ -364,11 +393,21 @@ fz_executedisplaylist(fz_displaylist *list, fz_device *dev, fz_matrix topctm, fz fz_matrix ctm = fz_concat(node->ctm, topctm); fz_rect rect = fz_transformrect(topctm, node->rect); + /* never skip tiles */ + if (tiled) + goto visible; + /* cull objects to draw using a quick visibility test */ if (clipped || fz_isemptybbox(fz_intersectbbox(fz_roundrect(rect), bounds))) { switch (node->cmd) { + case FZ_CMDBEGINTILE: + tiled++; + goto visible; + case FZ_CMDENDTILE: + tiled--; + goto visible; case FZ_CMDCLIPPATH: case FZ_CMDCLIPSTROKEPATH: case FZ_CMDCLIPTEXT: @@ -381,18 +420,19 @@ fz_executedisplaylist(fz_displaylist *list, fz_device *dev, fz_matrix topctm, fz case FZ_CMDPOPCLIP: case FZ_CMDENDGROUP: if (!clipped) - break; + goto visible; clipped--; continue; case FZ_CMDENDMASK: if (!clipped) - break; + goto visible; continue; default: continue; } } +visible: switch (node->cmd) { case FZ_CMDFILLPATH: @@ -458,6 +498,17 @@ fz_executedisplaylist(fz_displaylist *list, fz_device *dev, fz_matrix topctm, fz case FZ_CMDENDGROUP: dev->endgroup(dev->user); break; + case FZ_CMDBEGINTILE: + bbox.x0 = node->color[2]; + bbox.y0 = node->color[3]; + bbox.x1 = node->color[4]; + bbox.y1 = node->color[5]; + dev->begintile(dev->user, node->rect, bbox, + node->color[0], node->color[1], ctm); + break; + case FZ_CMDENDTILE: + dev->endtile(dev->user); + break; } } } |