[cairo-commit] src/cairo-svg-surface.c
Emmanuel Pacaud
emmanuel at kemper.freedesktop.org
Mon Apr 17 14:30:10 PDT 2006
src/cairo-svg-surface.c | 49 +++++++++++++++++++++++++++++++++++++++++++-----
1 files changed, 44 insertions(+), 5 deletions(-)
New commits:
diff-tree 170a028bfa00286324d8598d831e570d868a26f1 (from 9e2a2ea0da93065c46a6d6249f98a319ee6158dd)
Author: Emmanuel Pacaud <emmanuel.pacaud at free.fr>
Date: Mon Apr 17 23:26:30 2006 +0200
SVG: Fix mask and try to support CAIRO_CONTENT_ALPHA.
Cairo and SVG differ in their implementation of mask. Cairo only uses alpha channel where SVG uses all channels. So, before using a surface for masking, we use a filter that sets RGB channels to 1.0.
Support for CAIRO_CONTENT_ALPHA is similar and use the same filter when a SVG alpha surface is composited.
diff --git a/src/cairo-svg-surface.c b/src/cairo-svg-surface.c
index da38a1e..447abf8 100644
--- a/src/cairo-svg-surface.c
+++ b/src/cairo-svg-surface.c
@@ -75,6 +75,8 @@ struct cairo_svg_document {
unsigned int filter_id;
unsigned int clip_id;
unsigned int mask_id;
+
+ cairo_bool_t alpha_filter;
};
struct cairo_svg_surface {
@@ -332,6 +334,29 @@ _cairo_svg_surface_finish (void *abstrac
}
static void
+emit_alpha_filter (cairo_svg_document_t *document)
+{
+ if (!document->alpha_filter) {
+ xmlNodePtr node;
+ xmlNodePtr child;
+
+ node = xmlNewChild (document->xml_node_defs, NULL,
+ CC2XML ("filter"), NULL);
+ xmlSetProp (node, CC2XML ("id"), CC2XML ("alpha"));
+ xmlSetProp (node, CC2XML ("filterUnits"), CC2XML ("objectBoundingBox"));
+ xmlSetProp (node, CC2XML ("x"), CC2XML ("0%"));
+ xmlSetProp (node, CC2XML ("y"), CC2XML ("0%"));
+ xmlSetProp (node, CC2XML ("width"), CC2XML ("100%"));
+ xmlSetProp (node, CC2XML ("height"), CC2XML ("100%"));
+ child = xmlNewChild (node, NULL, CC2XML ("feColorMatrix"), NULL);
+ xmlSetProp (child, CC2XML("type"), CC2XML ("matrix"));
+ xmlSetProp (child, CC2XML("in"), CC2XML ("SourceGraphic"));
+ xmlSetProp (child, CC2XML("values"), CC2XML ("0 0 0 0 1 0 0 0 0 1 0 0 0 0 1 0 0 0 1 0"));
+ document->alpha_filter = TRUE;
+ }
+}
+
+static void
emit_transform (xmlNodePtr node,
char const *attribute_str,
cairo_matrix_t *matrix)
@@ -528,8 +553,13 @@ emit_composite_svg_pattern (xmlNodePtr n
xmlNodePtr child;
char buffer[CAIRO_SVG_DTOSTR_BUFFER_LEN];
- if (surface->modified)
- xmlAddChild (document->xml_node_defs, xmlCopyNode (surface->xml_root_node, 1));
+ if (surface->modified) {
+ if (surface->content == CAIRO_CONTENT_ALPHA)
+ emit_alpha_filter (document);
+ child = xmlAddChild (document->xml_node_defs, xmlCopyNode (surface->xml_root_node, 1));
+ if (surface->content == CAIRO_CONTENT_ALPHA)
+ xmlSetProp (child, CC2XML ("filter"), CC2XML("url(#alpha)"));
+ }
child = xmlNewChild (node, NULL, CC2XML("use"), NULL);
snprintf (buffer, sizeof buffer, "#surface%d",
@@ -1033,7 +1063,8 @@ emit_paint (xmlNodePtr node,
xmlBufferPtr style;
char buffer[CAIRO_SVG_DTOSTR_BUFFER_LEN];
- if (source->type == CAIRO_PATTERN_TYPE_SURFACE)
+ if (source->type == CAIRO_PATTERN_TYPE_SURFACE &&
+ source->extend == CAIRO_EXTEND_NONE)
return emit_composite_pattern (node,
(cairo_surface_pattern_t *) source,
NULL, NULL, FALSE);
@@ -1112,10 +1143,16 @@ _cairo_svg_surface_mask (void *abst
xmlNodePtr child, mask_node;
char buffer[CAIRO_SVG_DTOSTR_BUFFER_LEN];
- mask_node = xmlNewChild (document->xml_node_defs, NULL, CC2XML ("mask"), NULL);
+ emit_alpha_filter (document);
+
+ mask_node = xmlNewNode (NULL, CC2XML ("mask"));
snprintf (buffer, sizeof buffer, "mask%d", document->mask_id);
xmlSetProp (mask_node, CC2XML ("id"), C2XML (buffer));
- emit_paint (mask_node, surface, op, mask);
+ child = xmlNewChild (mask_node, NULL, CC2XML ("g"), NULL);
+ xmlSetProp (child, CC2XML ("filter"), CC2XML ("url(#alpha)"));
+ emit_paint (child, surface, op, mask);
+
+ xmlAddChild (document->xml_node_defs, mask_node);
child = emit_paint (surface->xml_node, surface, op, source);
@@ -1416,6 +1453,8 @@ _cairo_svg_document_create (cairo_output
xmlSetProp (node, CC2XML ("xmlns:xlink"), CC2XML ("http://www.w3.org/1999/xlink"));
xmlSetProp (node, CC2XML ("version"), CC2XML ("1.2"));
+ document->alpha_filter = FALSE;
+
return document;
}
More information about the cairo-commit
mailing list