summaryrefslogtreecommitdiff
path: root/fitz/dev_draw.c
diff options
context:
space:
mode:
authorTor Andersson <tor@ghostscript.com>2010-07-14 02:51:01 +0200
committerTor Andersson <tor@ghostscript.com>2010-07-14 02:51:01 +0200
commitb8fa3eabea0fc29a1937d661565cda0caf79ce50 (patch)
tree2a6d14905ea660155a8d0d5b5de294375f0f006f /fitz/dev_draw.c
parent48f6f0e2cd05182613b78322c2b924635caf3f55 (diff)
downloadmupdf-b8fa3eabea0fc29a1937d661565cda0caf79ce50.tar.xz
Add transparency group/mask device calls and implement basic blend modes when drawing primitive objects.
Diffstat (limited to 'fitz/dev_draw.c')
-rw-r--r--fitz/dev_draw.c87
1 files changed, 77 insertions, 10 deletions
diff --git a/fitz/dev_draw.c b/fitz/dev_draw.c
index 369cdf06..86ef1846 100644
--- a/fitz/dev_draw.c
+++ b/fitz/dev_draw.c
@@ -15,6 +15,7 @@ struct fz_drawdevice_s
fz_gel *gel;
fz_ael *ael;
fz_pixmap *dest;
+
fz_bbox scissor;
struct {
fz_pixmap *dest;
@@ -22,6 +23,10 @@ struct fz_drawdevice_s
fz_bbox scissor;
} clipstack[MAXCLIP];
int cliptop;
+
+ fz_blendmode blendmode;
+ fz_pixmap *groupstack[MAXCLIP];
+ int grouptop;
};
static void
@@ -185,8 +190,8 @@ fz_drawclippath(void *user, fz_path *path, int evenodd, fz_matrix ctm)
mask = fz_newpixmapwithrect(nil, bbox);
dest = fz_newpixmapwithrect(dev->model, bbox);
- memset(mask->samples, 0, mask->w * mask->h * mask->n);
- memset(dest->samples, 0, dest->w * dest->h * dest->n);
+ fz_clearpixmap(mask, 0);
+ fz_clearpixmap(dest, 0);
fz_scanconvert(dev->gel, dev->ael, evenodd, bbox, mask, nil, nil, nil);
@@ -230,8 +235,8 @@ fz_drawclipstrokepath(void *user, fz_path *path, fz_strokestate *stroke, fz_matr
mask = fz_newpixmapwithrect(nil, bbox);
dest = fz_newpixmapwithrect(dev->model, bbox);
- memset(mask->samples, 0, mask->w * mask->h * mask->n);
- memset(dest->samples, 0, dest->w * dest->h * dest->n);
+ fz_clearpixmap(mask, 0);
+ fz_clearpixmap(dest, 0);
if (!fz_isemptyrect(bbox))
fz_scanconvert(dev->gel, dev->ael, 0, bbox, mask, nil, nil, nil);
@@ -429,8 +434,8 @@ fz_drawcliptext(void *user, fz_text *text, fz_matrix ctm, int accumulate)
mask = fz_newpixmapwithrect(nil, bbox);
dest = fz_newpixmapwithrect(dev->model, bbox);
- memset(mask->samples, 0, mask->w * mask->h * mask->n);
- memset(dest->samples, 0, dest->w * dest->h * dest->n);
+ fz_clearpixmap(mask, 0);
+ fz_clearpixmap(dest, 0);
dev->clipstack[dev->cliptop].scissor = dev->scissor;
dev->clipstack[dev->cliptop].mask = mask;
@@ -495,8 +500,8 @@ fz_drawclipstroketext(void *user, fz_text *text, fz_strokestate *stroke, fz_matr
mask = fz_newpixmapwithrect(nil, bbox);
dest = fz_newpixmapwithrect(dev->model, bbox);
- memset(mask->samples, 0, mask->w * mask->h * mask->n);
- memset(dest->samples, 0, dest->w * dest->h * dest->n);
+ fz_clearpixmap(mask, 0);
+ fz_clearpixmap(dest, 0);
dev->clipstack[dev->cliptop].scissor = dev->scissor;
dev->clipstack[dev->cliptop].mask = mask;
@@ -763,8 +768,8 @@ fz_drawclipimagemask(void *user, fz_pixmap *image, fz_matrix ctm)
mask = fz_newpixmapwithrect(nil, bbox);
dest = fz_newpixmapwithrect(dev->model, bbox);
- memset(mask->samples, 0, mask->w * mask->h * mask->n);
- memset(dest->samples, 0, dest->w * dest->h * dest->n);
+ fz_clearpixmap(mask, 0);
+ fz_clearpixmap(dest, 0);
fz_scanconvert(dev->gel, dev->ael, 0, bbox, mask, nil, image, &invmat);
@@ -802,6 +807,62 @@ fz_drawpopclip(void *user)
}
static void
+fz_drawbeginmask(void *user, fz_rect rect, int luminosity, fz_colorspace *colorspace, float *colorfv)
+{
+ fz_warn("fz_drawbeginmask");
+}
+
+static void
+fz_drawendmask(void *user)
+{
+ fz_warn("fz_drawendmask");
+}
+
+static void
+fz_drawbegingroup(void *user, fz_rect rect, fz_colorspace *colorspace, int isolated, int knockout, fz_blendmode blendmode)
+{
+ fz_drawdevice *dev = user;
+ fz_bbox bbox;
+ fz_pixmap *dest;
+
+ fz_warn("fz_drawbegingroup");
+
+ if (dev->cliptop == MAXCLIP)
+ {
+ fz_warn("assert: too many clip masks on stack");
+ return;
+ }
+
+ bbox = fz_roundrect(rect);
+ bbox = fz_intersectbbox(bbox, dev->scissor);
+ dest = fz_newpixmapwithrect(dev->model, bbox);
+
+ fz_clearpixmap(dest, 0);
+
+ dev->blendmode = blendmode;
+ dev->groupstack[dev->grouptop++] = dev->dest;
+ dev->dest = dest;
+}
+
+static void
+fz_drawendgroup(void *user)
+{
+ fz_drawdevice *dev = user;
+ fz_pixmap *group = dev->dest;
+
+ fz_warn("fz_drawendgroup");
+
+ if (dev->grouptop > 0)
+ {
+ dev->grouptop--;
+ dev->dest = dev->groupstack[dev->grouptop];
+ fz_blendpixmaps(group, dev->dest, dev->blendmode);
+ }
+
+ fz_droppixmap(group);
+}
+
+static void
fz_drawfreeuser(void *user)
{
fz_drawdevice *dev = user;
@@ -826,6 +887,7 @@ fz_newdrawdevice(fz_glyphcache *cache, fz_pixmap *dest)
ddev->ael = fz_newael();
ddev->dest = dest;
ddev->cliptop = 0;
+ ddev->grouptop = 0;
ddev->scissor.x0 = dest->x;
ddev->scissor.y0 = dest->y;
@@ -853,5 +915,10 @@ fz_newdrawdevice(fz_glyphcache *cache, fz_pixmap *dest)
dev->popclip = fz_drawpopclip;
+ dev->beginmask = fz_drawbeginmask;
+ dev->endmask = fz_drawendmask;
+ dev->begingroup = fz_drawbegingroup;
+ dev->endgroup = fz_drawendgroup;
+
return dev;
}