summaryrefslogtreecommitdiff
path: root/fitz/dev_draw.c
diff options
context:
space:
mode:
authorTor Andersson <tor.andersson@artifex.com>2011-04-04 17:44:27 +0200
committerTor Andersson <tor.andersson@artifex.com>2011-04-04 17:44:27 +0200
commit6a87014ff020538841d7f5a0dd1adef8a6ce9e79 (patch)
treea98e917471df377a3e2ef852652ebb1535bec0be /fitz/dev_draw.c
parente77893b29cf53a9d6933cab0f9ae9e78b30a6592 (diff)
downloadmupdf-6a87014ff020538841d7f5a0dd1adef8a6ce9e79.tar.xz
Add device interface functions to draw tiled patterns.
Diffstat (limited to 'fitz/dev_draw.c')
-rw-r--r--fitz/dev_draw.c82
1 files changed, 82 insertions, 0 deletions
diff --git a/fitz/dev_draw.c b/fitz/dev_draw.c
index e0a12492..fb8c4c72 100644
--- a/fitz/dev_draw.c
+++ b/fitz/dev_draw.c
@@ -27,6 +27,9 @@ struct fz_drawdevice_s
fz_blendmode blendmode;
int luminosity;
float alpha;
+ fz_matrix ctm;
+ float xstep, ystep;
+ fz_rect area;
} stack[STACKSIZE];
};
@@ -928,6 +931,82 @@ fz_drawendgroup(void *user)
}
static void
+fz_drawbegintile(void *user, fz_rect area, fz_rect view, float xstep, float ystep, fz_matrix ctm)
+{
+ fz_drawdevice *dev = user;
+ fz_colorspace *model = dev->dest->colorspace;
+ fz_pixmap *dest;
+ fz_bbox bbox;
+
+ /* area, view, xstep, ystep are in pattern space */
+ /* ctm maps from pattern space to device space */
+
+ if (dev->top == STACKSIZE)
+ {
+ fz_warn("assert: too many buffers on stack");
+ return;
+ }
+
+ bbox = fz_roundrect(fz_transformrect(ctm, view));
+ dest = fz_newpixmapwithrect(model, bbox);
+ fz_clearpixmap(dest);
+
+ dev->stack[dev->top].scissor = dev->scissor;
+ dev->stack[dev->top].dest = dev->dest;
+ dev->stack[dev->top].xstep = xstep;
+ dev->stack[dev->top].ystep = ystep;
+ dev->stack[dev->top].area = area;
+ dev->stack[dev->top].ctm = ctm;
+ dev->top++;
+
+ dev->scissor = bbox;
+ dev->dest = dest;
+}
+
+static void
+fz_drawendtile(void *user)
+{
+ fz_drawdevice *dev = user;
+ fz_pixmap *tile = dev->dest;
+ float xstep, ystep;
+ fz_matrix ctm, ttm;
+ fz_rect area;
+ int x0, y0, x1, y1, x, y;
+
+ if (dev->top > 0)
+ {
+ dev->top--;
+ xstep = dev->stack[dev->top].xstep;
+ ystep = dev->stack[dev->top].ystep;
+ area = dev->stack[dev->top].area;
+ ctm = dev->stack[dev->top].ctm;
+ dev->scissor = dev->stack[dev->top].scissor;
+ dev->dest = dev->stack[dev->top].dest;
+
+ x0 = floorf(area.x0 / xstep);
+ y0 = floorf(area.y0 / ystep);
+ x1 = ceilf(area.x1 / xstep);
+ y1 = ceilf(area.y1 / ystep);
+
+ ctm.e = tile->x;
+ ctm.f = tile->y;
+
+ for (y = y0; y < y1; y++)
+ {
+ for (x = x0; x < x1; x++)
+ {
+ ttm = fz_concat(fz_translate(x * xstep, y * ystep), ctm);
+ tile->x = roundf(ttm.e);
+ tile->y = roundf(ttm.f);
+ fz_paintpixmapbbox(dev->dest, tile, 255, dev->scissor);
+ }
+ }
+
+ fz_droppixmap(tile);
+ }
+}
+
+static void
fz_drawfreeuser(void *user)
{
fz_drawdevice *dev = user;
@@ -979,5 +1058,8 @@ fz_newdrawdevice(fz_glyphcache *cache, fz_pixmap *dest)
dev->begingroup = fz_drawbegingroup;
dev->endgroup = fz_drawendgroup;
+ dev->begintile = fz_drawbegintile;
+ dev->endtile = fz_drawendtile;
+
return dev;
}