From 71a1131902da7e7f41566eb67cae3cad60bb14f4 Mon Sep 17 00:00:00 2001 From: Tor Andersson Date: Sun, 28 Nov 2010 21:54:26 +0000 Subject: Support luminosity softmask background colors. --- apps/pdfapp.c | 2 +- apps/pdfdraw.c | 4 ++-- draw/meshdraw.c | 2 +- fitz/dev_draw.c | 36 +++++++++++++++++++++--------------- fitz/fitz.h | 3 ++- fitz/res_font.c | 2 +- fitz/res_pixmap.c | 25 +++++++++++++++++++++++-- mupdf/mupdf.h | 2 ++ mupdf/pdf_interpret.c | 19 +++++++++++++++++-- mupdf/pdf_xobject.c | 12 ++++++++++++ 10 files changed, 82 insertions(+), 25 deletions(-) diff --git a/apps/pdfapp.c b/apps/pdfapp.c index 54827b8e..63149512 100644 --- a/apps/pdfapp.c +++ b/apps/pdfapp.c @@ -305,7 +305,7 @@ static void pdfapp_showpage(pdfapp_t *app, int loadpage, int drawpage) colorspace = fz_devicergb; #endif app->image = fz_newpixmapwithrect(colorspace, bbox); - fz_clearpixmap(app->image, 0xFF); + fz_clearpixmapwithcolor(app->image, 255); idev = fz_newdrawdevice(app->cache, app->image); fz_executedisplaylist(app->page->list, idev, ctm); fz_freedevice(idev); diff --git a/apps/pdfdraw.c b/apps/pdfdraw.c index 768ad263..ac998b51 100644 --- a/apps/pdfdraw.c +++ b/apps/pdfdraw.c @@ -152,9 +152,9 @@ static void drawpage(pdf_xref *xref, int pagenum) pix = fz_newpixmapwithrect(colorspace, bbox); if (savealpha) - fz_clearpixmap(pix, 0x00); + fz_clearpixmap(pix); else - fz_clearpixmap(pix, 0xff); + fz_clearpixmapwithcolor(pix, 255); dev = fz_newdrawdevice(glyphcache, pix); fz_executedisplaylist(list, dev, ctm); diff --git a/draw/meshdraw.c b/draw/meshdraw.c index b5880ddf..74035cfd 100644 --- a/draw/meshdraw.c +++ b/draw/meshdraw.c @@ -335,7 +335,7 @@ fz_rendershade(fz_shade *shade, fz_matrix ctm, fz_pixmap *dest, fz_bbox bbox) } conv = fz_newpixmapwithrect(dest->colorspace, bbox); temp = fz_newpixmapwithrect(fz_devicegray, bbox); - fz_clearpixmap(temp, 0); + fz_clearpixmap(temp); ntris = shade->meshlen / 9; } else diff --git a/fitz/dev_draw.c b/fitz/dev_draw.c index e321eaf4..aef2ee1e 100644 --- a/fitz/dev_draw.c +++ b/fitz/dev_draw.c @@ -135,8 +135,8 @@ fz_drawclippath(void *user, fz_path *path, int evenodd, fz_matrix ctm) mask = fz_newpixmapwithrect(nil, bbox); dest = fz_newpixmapwithrect(model, bbox); - fz_clearpixmap(mask, 0); - fz_clearpixmap(dest, 0); + fz_clearpixmap(mask); + fz_clearpixmap(dest); fz_scanconvert(dev->gel, dev->ael, evenodd, bbox, mask, nil); @@ -181,8 +181,8 @@ fz_drawclipstrokepath(void *user, fz_path *path, fz_strokestate *stroke, fz_matr mask = fz_newpixmapwithrect(nil, bbox); dest = fz_newpixmapwithrect(model, bbox); - fz_clearpixmap(mask, 0); - fz_clearpixmap(dest, 0); + fz_clearpixmap(mask); + fz_clearpixmap(dest); if (!fz_isemptyrect(bbox)) fz_scanconvert(dev->gel, dev->ael, 0, bbox, mask, nil); @@ -353,8 +353,8 @@ fz_drawcliptext(void *user, fz_text *text, fz_matrix ctm, int accumulate) mask = fz_newpixmapwithrect(nil, bbox); dest = fz_newpixmapwithrect(model, bbox); - fz_clearpixmap(mask, 0); - fz_clearpixmap(dest, 0); + fz_clearpixmap(mask); + fz_clearpixmap(dest); dev->stack[dev->top].scissor = dev->scissor; dev->stack[dev->top].mask = mask; @@ -420,8 +420,8 @@ fz_drawclipstroketext(void *user, fz_text *text, fz_strokestate *stroke, fz_matr mask = fz_newpixmapwithrect(nil, bbox); dest = fz_newpixmapwithrect(model, bbox); - fz_clearpixmap(mask, 0); - fz_clearpixmap(dest, 0); + fz_clearpixmap(mask); + fz_clearpixmap(dest); dev->stack[dev->top].scissor = dev->scissor; dev->stack[dev->top].mask = mask; @@ -496,7 +496,7 @@ fz_drawfillshade(void *user, fz_shade *shade, fz_matrix ctm, float alpha) if (alpha < 1) { dest = fz_newpixmapwithrect(dev->dest->colorspace, bbox); - fz_clearpixmap(dest, 0); + fz_clearpixmap(dest); } if (shade->usebackground) @@ -718,8 +718,8 @@ fz_drawclipimagemask(void *user, fz_pixmap *image, fz_matrix ctm) mask = fz_newpixmapwithrect(nil, bbox); dest = fz_newpixmapwithrect(model, bbox); - fz_clearpixmap(mask, 0); - fz_clearpixmap(dest, 0); + fz_clearpixmap(mask); + fz_clearpixmap(dest); #ifdef SMOOTHSCALE dx = sqrtf(ctm.a * ctm.a + ctm.b * ctm.b); @@ -799,9 +799,15 @@ fz_drawbeginmask(void *user, fz_rect rect, int luminosity, fz_colorspace *colors dest = fz_newpixmapwithrect(fz_devicegray, bbox); if (luminosity) - fz_clearpixmap(dest, 255); + { + float bc; + if (!colorspace) + colorspace = fz_devicegray; + fz_convertcolor(colorspace, colorfv, fz_devicegray, &bc); + fz_clearpixmapwithcolor(dest, bc * 255); + } else - fz_clearpixmap(dest, 0); + fz_clearpixmap(dest); dev->stack[dev->top].scissor = dev->scissor; dev->stack[dev->top].dest = dev->dest; @@ -842,7 +848,7 @@ fz_drawendmask(void *user) /* create new dest scratch buffer */ bbox = fz_boundpixmap(temp); dest = fz_newpixmapwithrect(dev->dest->colorspace, bbox); - fz_clearpixmap(dest, 0); + fz_clearpixmap(dest); /* push soft mask as clip mask */ dev->stack[dev->top].scissor = dev->scissor; @@ -872,7 +878,7 @@ fz_drawbegingroup(void *user, fz_rect rect, int isolated, int knockout, fz_blend bbox = fz_intersectbbox(bbox, dev->scissor); dest = fz_newpixmapwithrect(model, bbox); - fz_clearpixmap(dest, 0); + fz_clearpixmap(dest); dev->stack[dev->top].alpha = alpha; dev->stack[dev->top].blendmode = blendmode; diff --git a/fitz/fitz.h b/fitz/fitz.h index 57161305..ac3bf00f 100644 --- a/fitz/fitz.h +++ b/fitz/fitz.h @@ -599,7 +599,8 @@ fz_pixmap * fz_newpixmapwithrect(fz_colorspace *, fz_bbox bbox); fz_pixmap * fz_newpixmap(fz_colorspace *, int x, int y, int w, int h); fz_pixmap *fz_keeppixmap(fz_pixmap *pix); void fz_droppixmap(fz_pixmap *pix); -void fz_clearpixmap(fz_pixmap *pix, int value); +void fz_clearpixmap(fz_pixmap *pix); +void fz_clearpixmapwithcolor(fz_pixmap *pix, int value); void fz_gammapixmap(fz_pixmap *pix, float gamma); fz_pixmap *fz_alphafromgray(fz_pixmap *gray, int luminosity); fz_bbox fz_boundpixmap(fz_pixmap *pix); diff --git a/fitz/res_font.c b/fitz/res_font.c index fd3bbe3f..26d7267f 100644 --- a/fitz/res_font.c +++ b/fitz/res_font.c @@ -475,7 +475,7 @@ fz_rendert3glyph(fz_font *font, int gid, fz_matrix trm) fz_freedevice(dev); glyph = fz_newpixmap(fz_devicegray, bbox.x0-1, bbox.y0-1, bbox.x1 - bbox.x0 + 1, bbox.y1 - bbox.y0 + 1); - fz_clearpixmap(glyph, 0); + fz_clearpixmap(glyph); cache = fz_newglyphcache(); dev = fz_newdrawdevice(cache, glyph); diff --git a/fitz/res_pixmap.c b/fitz/res_pixmap.c index 4826502e..7455338a 100644 --- a/fitz/res_pixmap.c +++ b/fitz/res_pixmap.c @@ -70,9 +70,30 @@ fz_droppixmap(fz_pixmap *pix) } void -fz_clearpixmap(fz_pixmap *pix, int value) +fz_clearpixmap(fz_pixmap *pix) { - memset(pix->samples, value, pix->w * pix->h * pix->n); + memset(pix->samples, 0, pix->w * pix->h * pix->n); +} + +void +fz_clearpixmapwithcolor(fz_pixmap *pix, int value) +{ + if (value == 255) + memset(pix->samples, 255, pix->w * pix->h * pix->n); + else + { + int k, x, y; + unsigned char *s = pix->samples; + for (y = 0; y < pix->h; y++) + { + for (x = 0; x < pix->w; x++) + { + for (k = 0; k < pix->n - 1; k++) + *s++ = value; + *s++ = 255; + } + } + } } fz_bbox diff --git a/mupdf/mupdf.h b/mupdf/mupdf.h index 65c03197..0fc0ec75 100644 --- a/mupdf/mupdf.h +++ b/mupdf/mupdf.h @@ -245,6 +245,7 @@ struct pdf_xobject_s int isolated; int knockout; int transparency; + fz_colorspace *colorspace; fz_obj *resources; fz_buffer *contents; }; @@ -581,6 +582,7 @@ struct pdf_gstate_s fz_blendmode blendmode; pdf_xobject *softmask; fz_matrix softmaskctm; + float softmaskbc[FZ_MAXCOLORS]; int luminosity; }; diff --git a/mupdf/pdf_interpret.c b/mupdf/pdf_interpret.c index e2e55650..6bbaff57 100644 --- a/mupdf/pdf_interpret.c +++ b/mupdf/pdf_interpret.c @@ -168,7 +168,7 @@ pdf_runxobject(pdf_csi *csi, fz_obj *resources, pdf_xobject *xobj) gstate->softmask = nil; popmask = 1; - csi->dev->beginmask(csi->dev->user, bbox, gstate->luminosity, nil, nil); + csi->dev->beginmask(csi->dev->user, bbox, gstate->luminosity, softmask->colorspace, gstate->softmaskbc); error = pdf_runxobject(csi, resources, softmask); if (error) return fz_rethrow(error, "cannot run softmask"); @@ -336,7 +336,7 @@ pdf_runextgstate(pdf_csi *csi, pdf_gstate *gstate, fz_obj *rdb, fz_obj *extgstat { fz_error error; pdf_xobject *xobj; - fz_obj *group, *luminosity; + fz_obj *group, *luminosity, *bc; if (gstate->softmask) { @@ -351,6 +351,21 @@ pdf_runextgstate(pdf_csi *csi, pdf_gstate *gstate, fz_obj *rdb, fz_obj *extgstat gstate->softmaskctm = fz_concat(xobj->matrix, gstate->ctm); gstate->softmask = xobj; + gstate->softmaskbc[0] = 0; + + bc = fz_dictgets(val, "BC"); + if (fz_isarray(bc)) + { + fz_colorspace *cs; + int i; + + cs = xobj->colorspace; + if (!cs) + cs = fz_devicegray; + + for (i = 0; i < cs->n; i++) + gstate->softmaskbc[i] = fz_toreal(fz_arrayget(bc, i)); + } luminosity = fz_dictgets(val, "S"); if (fz_isname(luminosity) && !strcmp(fz_toname(luminosity), "Luminosity")) diff --git a/mupdf/pdf_xobject.c b/mupdf/pdf_xobject.c index 8f94eccf..44389efc 100644 --- a/mupdf/pdf_xobject.c +++ b/mupdf/pdf_xobject.c @@ -18,6 +18,7 @@ pdf_loadxobject(pdf_xobject **formp, pdf_xref *xref, fz_obj *dict) form->refs = 1; form->resources = nil; form->contents = nil; + form->colorspace = nil; pdf_logrsrc("load xobject (%d %d R) ptr=%p {\n", fz_tonum(dict), fz_togen(dict), form); @@ -57,6 +58,15 @@ pdf_loadxobject(pdf_xobject **formp, pdf_xref *xref, fz_obj *dict) obj = fz_dictgets(attrs, "S"); if (fz_isname(obj) && !strcmp(fz_toname(obj), "Transparency")) form->transparency = 1; + + obj = fz_dictgets(attrs, "CS"); + if (obj) + { + error = pdf_loadcolorspace(&form->colorspace, xref, obj); + if (error) + fz_catch(error, "cannot load xobject colorspace"); + pdf_logrsrc("colorspace %s\n", form->colorspace->name); + } } pdf_logrsrc("isolated %d\n", form->isolated); @@ -94,6 +104,8 @@ pdf_dropxobject(pdf_xobject *xobj) { if (xobj && --xobj->refs == 0) { + if (xobj->colorspace) + fz_dropcolorspace(xobj->colorspace); if (xobj->resources) fz_dropobj(xobj->resources); if (xobj->contents) -- cgit v1.2.3