diff options
Diffstat (limited to 'xps')
-rw-r--r-- | xps/muxps.h | 4 | ||||
-rw-r--r-- | xps/xpscolor.c | 2 | ||||
-rw-r--r-- | xps/xpsopacity.c | 37 | ||||
-rw-r--r-- | xps/xpspage.c | 3 |
4 files changed, 42 insertions, 4 deletions
diff --git a/xps/muxps.h b/xps/muxps.h index 8150996f..f135b875 100644 --- a/xps/muxps.h +++ b/xps/muxps.h @@ -256,6 +256,10 @@ struct xps_context_s */ int fill_rule; + /* Opacity attribute stack */ + float opacity[64]; + int opacity_top; + /* Current path being accumulated */ fz_path *path; fz_text *text; /* ... or text, for clipping brushes */ diff --git a/xps/xpscolor.c b/xps/xpscolor.c index 1858c687..37dee5fe 100644 --- a/xps/xpscolor.c +++ b/xps/xpscolor.c @@ -10,7 +10,7 @@ xps_set_color(xps_context *ctx, fz_colorspace *colorspace, float *samples) ctx->colorspace = colorspace; for (i = 0; i < colorspace->n; i++) ctx->color[i] = samples[i + 1]; - ctx->alpha = samples[0]; + ctx->alpha = samples[0] * ctx->opacity[ctx->opacity_top]; } static int unhex(int chr) diff --git a/xps/xpsopacity.c b/xps/xpsopacity.c index 047e213d..51a356e3 100644 --- a/xps/xpsopacity.c +++ b/xps/xpsopacity.c @@ -36,12 +36,36 @@ xps_begin_opacity(xps_context *ctx, fz_matrix ctm, char *base_uri, xps_resource if (opacity_att) opacity = atof(opacity_att); + if (opacity_mask_tag && !strcmp(xps_tag(opacity_mask_tag), "SolidColorBrush")) + { + char *scb_opacity_att = xps_att(opacity_mask_tag, "Opacity"); + char *scb_color_att = xps_att(opacity_mask_tag, "Color"); + if (scb_opacity_att) + opacity = opacity * atof(scb_opacity_att); + if (scb_color_att) + { + fz_colorspace *colorspace; + float samples[32]; + xps_parse_color(ctx, base_uri, scb_color_att, &colorspace, samples); + opacity = opacity * samples[0]; + } + opacity_mask_tag = NULL; + } + xps_bounds_in_user_space(ctx, &bbox); - ctx->dev->beginmask(ctx->dev->user, bbox, 0, fz_devicegray, &opacity); + if (ctx->opacity_top + 1 < nelem(ctx->opacity)) + { + ctx->opacity[ctx->opacity_top + 1] = ctx->opacity[ctx->opacity_top] * opacity; + ctx->opacity_top++; + } + if (opacity_mask_tag) + { + ctx->dev->beginmask(ctx->dev->user, bbox, 0, NULL, NULL); xps_parse_brush(ctx, ctm, base_uri, dict, opacity_mask_tag); - ctx->dev->endmask(ctx->dev->user); + ctx->dev->endmask(ctx->dev->user); + } } void @@ -51,5 +75,12 @@ xps_end_opacity(xps_context *ctx, char *base_uri, xps_resource *dict, if (!opacity_att && !opacity_mask_tag) return; - ctx->dev->popclip(ctx->dev->user); + if (ctx->opacity_top > 0) + ctx->opacity_top--; + + if (opacity_mask_tag) + { + if (strcmp(xps_tag(opacity_mask_tag), "SolidColorBrush")) + ctx->dev->popclip(ctx->dev->user); + } } diff --git a/xps/xpspage.c b/xps/xpspage.c index 32439f19..39731ef2 100644 --- a/xps/xpspage.c +++ b/xps/xpspage.c @@ -101,6 +101,9 @@ xps_parse_fixed_page(xps_context *ctx, fz_matrix ctm, xps_page *page) dict = NULL; + ctx->opacity_top = 0; + ctx->opacity[0] = 1; + for (node = xps_down(page->root); node; node = xps_next(node)) { if (!strcmp(xps_tag(node), "FixedPage.Resources") && xps_down(node)) |