static fz_error * rendershade(fz_renderer *gc, fz_shadenode *node, fz_matrix ctm) { fz_error *error; fz_irect bbox; assert(!gc->maskonly); DEBUG("shade;\n"); bbox = fz_roundrect(fz_boundnode((fz_node*)node, ctm)); bbox = fz_intersectirects(gc->clip, bbox); error = fz_newpixmapwithrect(&gc->dest, bbox, gc->model->n + 1); if (error) return error; return fz_rendershade(node->shade, ctm, gc->model, gc->dest); }
static void fz_drawfillshade(void *user, fz_shade *shade, fz_matrix ctm, float alpha) { fz_drawdevice *dev = user; fz_colorspace *model = dev->dest->colorspace; fz_pixmap *dest = dev->dest; fz_rect bounds; fz_bbox bbox; float colorfv[FZ_MAXCOLORS]; unsigned char colorbv[FZ_MAXCOLORS + 1]; bounds = fz_boundshade(shade, ctm); bbox = fz_intersectbbox(fz_roundrect(bounds), dev->scissor); // TODO: proper clip by shade->bbox if (!fz_isemptyrect(shade->bbox)) { bounds = fz_transformrect(fz_concat(shade->matrix, ctm), shade->bbox); bbox = fz_intersectbbox(fz_roundrect(bounds), bbox); } if (fz_isemptyrect(bbox)) return; if (!model) { fz_warn("cannot render shading directly to an alpha mask"); return; } if (alpha < 1) { dest = fz_newpixmapwithrect(dev->dest->colorspace, bbox); fz_clearpixmap(dest, 0); } if (shade->usebackground) { unsigned char *s; int x, y, n, i; fz_convertcolor(shade->cs, shade->background, model, colorfv); for (i = 0; i < model->n; i++) colorbv[i] = colorfv[i] * 255; colorbv[i] = 255; n = dest->n; for (y = bbox.y0; y < bbox.y1; y++) { s = dest->samples + ((bbox.x0 - dest->x) + (y - dest->y) * dest->w) * dest->n; for (x = bbox.x0; x < bbox.x1; x++) { for (i = 0; i < n; i++) *s++ = colorbv[i]; } } } fz_rendershade(shade, ctm, dest, bbox); if (alpha < 1) { fz_paintpixmap(dev->dest, dest, alpha * 255); fz_droppixmap(dest); } }