summaryrefslogtreecommitdiff
path: root/src/cairo-svg-surface.c
diff options
context:
space:
mode:
authorAnton Danilkin <afdw@yandex.ru>2021-04-09 15:34:45 +0200
committerAnton Danilkin <afdw@yandex.ru>2021-04-11 23:59:47 +0200
commite728eb43de3476234382cd770157927658daddb6 (patch)
treea07c6d675bbc19b55d9f88a836206458ca34c36d /src/cairo-svg-surface.c
parent961db5b846a551a040895ca521732b396f747765 (diff)
downloadcairo-e728eb43de3476234382cd770157927658daddb6.tar.gz
Implement the in operator
Diffstat (limited to 'src/cairo-svg-surface.c')
-rw-r--r--src/cairo-svg-surface.c162
1 files changed, 155 insertions, 7 deletions
diff --git a/src/cairo-svg-surface.c b/src/cairo-svg-surface.c
index 9cf1f5b7f..47a1463ae 100644
--- a/src/cairo-svg-surface.c
+++ b/src/cairo-svg-surface.c
@@ -134,6 +134,7 @@ enum cairo_svg_filter {
CAIRO_SVG_FILTER_COLOR_TO_ALPHA,
CAIRO_SVG_FILTER_LAST_STATIC_FILTER,
CAIRO_SVG_FILTER_ADD,
+ CAIRO_SVG_FILTER_IN,
};
struct cairo_svg_page {
@@ -1234,6 +1235,20 @@ _cairo_svg_surface_emit_parametric_filter (cairo_svg_document_t *document,
source_composing_group_id,
destination_composing_group_id);
break;
+ case CAIRO_SVG_FILTER_IN:
+ _cairo_output_stream_printf (document->xml_node_filters,
+ "<filter id=\"filter-%d\" filterUnits=\"userSpaceOnUse\" "
+ "x=\"0%%\" y=\"0%%\" width=\"100%%\" height=\"100%%\">\n"
+ "<feImage xlink:href=\"#composing-group-%d\" result=\"source\"/>\n"
+ "<feImage xlink:href=\"#composing-group-%d\" result=\"destination\"/>\n"
+ "<feComposite in=\"source\" in2=\"destination\" "
+ "operator=\"in\" "
+ "color-interpolation-filters=\"sRGB\"/>\n"
+ "</filter>\n",
+ filter_id,
+ source_composing_group_id,
+ destination_composing_group_id);
+ break;
default:
ASSERT_NOT_REACHED;
}
@@ -2402,8 +2417,8 @@ _cairo_svg_surface_emit_paint (cairo_output_stream_t *output,
mask_source ? &mask_source->matrix : NULL);
_cairo_output_stream_printf (output,
- "<rect x=\"-1000000%%\" y=\"-1000000%%\" "
- "width=\"2000000%%\" height=\"2000000%%\" "
+ "<rect x=\"-1000%%\" y=\"-1000%%\" "
+ "width=\"2000%%\" height=\"2000%%\" "
"style=\"");
status = _cairo_svg_surface_emit_pattern (surface, source, output, FALSE, NULL);
if (unlikely (status))
@@ -2446,10 +2461,10 @@ _cairo_svg_surface_do_operator (cairo_output_stream_t *output,
}
if (op == CAIRO_OPERATOR_SOURCE) {
- unsigned int composing_group_id = document->composing_group_id++;
+ unsigned int lerp_composing_group_id = document->composing_group_id++;
_cairo_output_stream_printf (document->xml_node_defs,
"<g id=\"composing-group-%d\">\n",
- composing_group_id);
+ lerp_composing_group_id);
status = _cairo_svg_surface_set_clip (surface, document->xml_node_defs, clip);
if (unlikely (status)) {
cairo_status_t ignore1 = _cairo_output_stream_destroy (destination_stream);
@@ -2478,7 +2493,7 @@ _cairo_svg_surface_do_operator (cairo_output_stream_t *output,
source_mask_id);
_cairo_output_stream_printf (document->xml_node_defs,
"<use xlink:href=\"#composing-group-%d\"/>\n",
- composing_group_id);
+ lerp_composing_group_id);
_cairo_output_stream_printf (document->xml_node_defs, "</mask>\n");
unsigned int source_composing_group_id = document->composing_group_id++;
@@ -2501,7 +2516,7 @@ _cairo_svg_surface_do_operator (cairo_output_stream_t *output,
destination_mask_id);
_cairo_output_stream_printf (document->xml_node_defs,
"<use xlink:href=\"#composing-group-%d\" filter=\"url(#filter-%s)\"/>\n",
- composing_group_id,
+ lerp_composing_group_id,
_cairo_svg_surface_emit_static_filter (document,
CAIRO_SVG_FILTER_REMOVE_COLOR_AND_INVERT_ALPHA));
_cairo_output_stream_printf (document->xml_node_defs, "</mask>\n");
@@ -2529,7 +2544,140 @@ _cairo_svg_surface_do_operator (cairo_output_stream_t *output,
return status;
}
_cairo_output_stream_printf (surface->xml_node, "</g>\n");
+
+ return CAIRO_STATUS_SUCCESS;
+ }
+
+ unsigned int lerp_composing_group_id = document->composing_group_id++;
+ _cairo_output_stream_printf (document->xml_node_defs,
+ "<g id=\"composing-group-%d\">\n",
+ lerp_composing_group_id);
+ status = _cairo_svg_surface_set_clip (surface, document->xml_node_defs, clip);
+ if (unlikely (status)) {
+ cairo_status_t ignore1 = _cairo_output_stream_destroy (destination_stream);
+ cairo_status_t ignore2 = _cairo_output_stream_destroy (source_stream);
+ cairo_status_t ignore3 = _cairo_output_stream_destroy (mask_stream);
+ return status;
+ (void) ignore1;
+ (void) ignore2;
+ (void) ignore3;
+ }
+ cairo_pattern_t *white_pattern = cairo_pattern_create_rgb (1.0, 1.0, 1.0);
+ status = _cairo_svg_surface_emit_paint (document->xml_node_defs, surface, white_pattern, NULL);
+ cairo_pattern_destroy(white_pattern);
+ if (unlikely (status)) {
+ cairo_status_t ignore1 = _cairo_output_stream_destroy (destination_stream);
+ cairo_status_t ignore2 = _cairo_output_stream_destroy (source_stream);
+ cairo_status_t ignore3 = _cairo_output_stream_destroy (mask_stream);
+ return status;
+ (void) ignore1;
+ (void) ignore2;
+ (void) ignore3;
+ }
+ _cairo_svg_surface_reset_clip (surface);
+ _cairo_output_stream_printf (document->xml_node_defs, "</g>\n");
+
+ unsigned int mask_mask_id = document->mask_id++;
+ _cairo_output_stream_printf (document->xml_node_defs,
+ "<mask id=\"mask-%d\">\n",
+ mask_mask_id);
+ _cairo_memory_stream_copy (mask_stream, document->xml_node_defs);
+ status = _cairo_output_stream_destroy (mask_stream);
+ if (unlikely (status)) {
+ cairo_status_t ignore1 = _cairo_output_stream_destroy (source_stream);
+ cairo_status_t ignore2 = _cairo_output_stream_destroy (destination_stream);
+ return status;
+ (void) ignore1;
+ (void) ignore2;
+ }
+ _cairo_output_stream_printf (document->xml_node_defs, "</mask>\n");
+
+ unsigned int source_mask_id = document->mask_id++;
+ _cairo_output_stream_printf (document->xml_node_defs,
+ "<mask id=\"mask-%d\">\n",
+ source_mask_id);
+ _cairo_output_stream_printf (document->xml_node_defs,
+ "<use xlink:href=\"#composing-group-%d\"/>\n",
+ lerp_composing_group_id);
+ _cairo_output_stream_printf (document->xml_node_defs, "</mask>\n");
+
+ unsigned int source_composing_group_id = document->composing_group_id++;
+ _cairo_output_stream_printf (document->xml_node_defs,
+ "<g id=\"composing-group-%d\" mask=\"url(#mask-%d)\">\n",
+ source_composing_group_id,
+ source_mask_id);
+ _cairo_output_stream_printf (document->xml_node_defs,
+ "<g mask=\"url(#mask-%d)\">\n",
+ mask_mask_id);
+ _cairo_memory_stream_copy (source_stream, document->xml_node_defs);
+ status = _cairo_output_stream_destroy (source_stream);
+ if (unlikely (status)) {
+ cairo_status_t ignore = _cairo_output_stream_destroy (destination_stream);
+ return status;
+ (void) ignore;
+ }
+ _cairo_output_stream_printf (document->xml_node_defs, "</g>\n");
+ _cairo_output_stream_printf (document->xml_node_defs, "</g>\n");
+
+ unsigned int destination_mask_id = document->mask_id++;
+ _cairo_output_stream_printf (document->xml_node_defs,
+ "<mask id=\"mask-%d\">\n",
+ destination_mask_id);
+ _cairo_output_stream_printf (document->xml_node_defs,
+ "<use xlink:href=\"#composing-group-%d\" filter=\"url(#filter-%s)\"/>\n",
+ lerp_composing_group_id,
+ _cairo_svg_surface_emit_static_filter (document,
+ CAIRO_SVG_FILTER_REMOVE_COLOR_AND_INVERT_ALPHA));
+ _cairo_output_stream_printf (document->xml_node_defs, "</mask>\n");
+
+ unsigned int raw_destination_composing_group_id = document->composing_group_id++;
+ _cairo_output_stream_printf (document->xml_node_defs,
+ "<g id=\"composing-group-%d\">\n",
+ raw_destination_composing_group_id);
+ _cairo_memory_stream_copy (destination_stream, document->xml_node_defs);
+ status = _cairo_output_stream_destroy (destination_stream);
+ if (unlikely (status)) {
+ return status;
+ }
+ _cairo_output_stream_printf (document->xml_node_defs, "</g>\n");
+
+ unsigned int destination_composing_group_id = document->composing_group_id++;
+ _cairo_output_stream_printf (document->xml_node_defs,
+ "<g id=\"composing-group-%d\" mask=\"url(#mask-%d)\">\n",
+ destination_composing_group_id,
+ destination_mask_id);
+ _cairo_output_stream_printf (document->xml_node_defs,
+ "<use xlink:href=\"#composing-group-%d\"/>\n",
+ raw_destination_composing_group_id);
+ _cairo_output_stream_printf (document->xml_node_defs, "</g>\n");
+
+ unsigned int operation_composing_group_id = document->composing_group_id++;
+ _cairo_output_stream_printf (document->xml_node_defs,
+ "<g id=\"composing-group-%d\" filter=\"url(#filter-%d)\">\n",
+ operation_composing_group_id,
+ _cairo_svg_surface_emit_parametric_filter (document,
+ CAIRO_SVG_FILTER_IN,
+ source_composing_group_id,
+ raw_destination_composing_group_id));
+ cairo_pattern_t *black_pattern = cairo_pattern_create_rgb (0.0, 0.0, 0.0);
+ status = _cairo_svg_surface_emit_paint (document->xml_node_defs, surface, black_pattern, NULL);
+ cairo_pattern_destroy(black_pattern);
+ if (unlikely (status)) {
+ return status;
+ }
+ _cairo_output_stream_printf (document->xml_node_defs, "</g>\n");
+
+ _cairo_output_stream_printf (surface->xml_node,
+ "<g filter=\"url(#filter-%d)\">\n",
+ _cairo_svg_surface_emit_parametric_filter (document,
+ CAIRO_SVG_FILTER_ADD,
+ operation_composing_group_id,
+ destination_composing_group_id));
+ status = _cairo_svg_surface_emit_paint_black (surface);
+ if (unlikely (status)) {
+ return status;
}
+ _cairo_output_stream_printf (surface->xml_node, "</g>\n");
return CAIRO_STATUS_SUCCESS;
}
@@ -3011,7 +3159,7 @@ _cairo_svg_surface_show_glyphs_impl (cairo_output_stream_t *output,
NULL,
0,
&subset_glyph);
- if (status == CAIRO_INT_STATUS_UNSUPPORTED) {
+ if ((cairo_int_status_t) status == CAIRO_INT_STATUS_UNSUPPORTED) {
_cairo_output_stream_printf (output, "</g>\n");
glyphs += i;