[lasem] svg: add enable-background support.



commit 9480608f41b7c1be1078622295c8565be2cc2b2f
Author: Emmanuel Pacaud <emmanuel gnome org>
Date:   Wed Oct 24 12:35:23 2012 +0200

    svg: add enable-background support.
    
    It's still broken if a cairop_push_group happens between filter and
    enable-background.

 src/lsmsvgenums.c  |   21 +++++++++++++++++++++
 src/lsmsvgenums.h  |    9 +++++++++
 src/lsmsvgstyle.c  |    2 +-
 src/lsmsvgstyle.h  |    7 ++++++-
 src/lsmsvgtraits.c |   24 ++++++++++++++++++++++++
 src/lsmsvgtraits.h |    1 +
 src/lsmsvgview.c   |   39 +++++++++++++++++++++++++++++++++++----
 src/lsmsvgview.h   |    1 +
 8 files changed, 98 insertions(+), 6 deletions(-)
---
diff --git a/src/lsmsvgenums.c b/src/lsmsvgenums.c
index 721c031..6144c0c 100644
--- a/src/lsmsvgenums.c
+++ b/src/lsmsvgenums.c
@@ -54,6 +54,27 @@ lsm_svg_blending_mode_from_string (const char *string)
 					   G_N_ELEMENTS (lsm_svg_blending_mode_strings));
 }
 
+static const char *lsm_svg_enable_background_strings[] = {
+	"accumulate",
+	"new"
+};
+
+const char *
+lsm_svg_enable_background_to_string (LsmSvgEnableBackground enable_background)
+{
+	if (enable_background < 0 || enable_background > LSM_SVG_ENABLE_BACKGROUND_NEW)
+		return NULL;
+
+	return lsm_svg_enable_background_strings[enable_background];
+}
+
+LsmSvgEnableBackground
+lsm_svg_enable_background_from_string (const char *string)
+{
+	return lsm_enum_value_from_string (string, lsm_svg_enable_background_strings,
+					   G_N_ELEMENTS (lsm_svg_enable_background_strings));
+}
+
 static const char *lsm_svg_length_type_strings[] = {
 	"",
 	"%",
diff --git a/src/lsmsvgenums.h b/src/lsmsvgenums.h
index 0a94487..867eb06 100644
--- a/src/lsmsvgenums.h
+++ b/src/lsmsvgenums.h
@@ -53,6 +53,15 @@ const char * 		lsm_svg_blending_mode_to_string 	(LsmSvgBlendingMode blending_mod
 LsmSvgBlendingMode	lsm_svg_blending_mode_from_string 	(const char *string);
 
 typedef enum {
+	LSM_SVG_ENABLE_BACKGROUND_ERROR = -1,
+	LSM_SVG_ENABLE_BACKGROUND_ACCUMULATE,
+	LSM_SVG_ENABLE_BACKGROUND_NEW
+} LsmSvgEnableBackground;
+
+const char * 		lsm_svg_enable_background_to_string 	(LsmSvgEnableBackground enable_background);
+LsmSvgEnableBackground	lsm_svg_enable_background_from_string 	(const char *string);
+
+typedef enum {
 	LSM_SVG_PAINT_TYPE_ERROR = -1,
 	LSM_SVG_PAINT_TYPE_UNKNOWN = 0,
 	LSM_SVG_PAINT_TYPE_RGB_COLOR,
diff --git a/src/lsmsvgstyle.c b/src/lsmsvgstyle.c
index 85b8b1f..1fb7ce1 100644
--- a/src/lsmsvgstyle.c
+++ b/src/lsmsvgstyle.c
@@ -62,7 +62,7 @@ static const LsmPropertyInfos lsm_svg_property_infos[] = {
 	{
 		.name = "enable-background",
 		.id = LSM_PROPERTY_OFFSET_TO_ID (LsmSvgStyle, enable_background),
-		.trait_class = &lsm_null_trait_class,
+		.trait_class = &lsm_svg_enable_background_trait_class,
 		.trait_default = "accumulate"
 	},
 	{
diff --git a/src/lsmsvgstyle.h b/src/lsmsvgstyle.h
index 1f1884c..f29a079 100644
--- a/src/lsmsvgstyle.h
+++ b/src/lsmsvgstyle.h
@@ -36,6 +36,11 @@ typedef struct {
 
 typedef struct {
 	LsmProperty base;
+	LsmSvgEnableBackground value;
+} LsmSvgEnableBackgroundProperty;
+
+typedef struct {
+	LsmProperty base;
 	LsmSvgLength length;
 } LsmSvgLengthProperty;
 
@@ -122,7 +127,7 @@ struct _LsmSvgStyle {
 	LsmProperty *	 		clip;
 	LsmProperty *	 		clip_path;
 	LsmProperty *	 		dominant_baseline;
-	LsmProperty *	 		enable_background;
+	LsmSvgEnableBackgroundProperty *enable_background;
 	LsmProperty *	 		filter;
 	LsmSvgColorProperty *		flood_color;
 	LsmSvgDoubleProperty *		flood_opacity;
diff --git a/src/lsmsvgtraits.c b/src/lsmsvgtraits.c
index d79a57c..59fd632 100644
--- a/src/lsmsvgtraits.c
+++ b/src/lsmsvgtraits.c
@@ -56,6 +56,30 @@ const LsmTraitClass lsm_svg_blending_mode_trait_class = {
 };
 
 static gboolean
+lsm_svg_enable_background_trait_from_string (LsmTrait *abstract_trait, char *string)
+{
+	LsmSvgEnableBackground *trait = (LsmSvgEnableBackground *) abstract_trait;
+
+	*trait = lsm_svg_enable_background_from_string (string);
+
+	return *trait >= 0;
+}
+
+char *
+lsm_svg_enable_background_trait_to_string (LsmTrait *abstract_trait)
+{
+	LsmSvgEnableBackground *trait = (LsmSvgEnableBackground *) abstract_trait;
+
+	return g_strdup (lsm_svg_enable_background_to_string (*trait));
+}
+
+const LsmTraitClass lsm_svg_enable_background_trait_class = {
+	.size = sizeof (LsmSvgEnableBackground),
+	.from_string = lsm_svg_enable_background_trait_from_string,
+	.to_string = lsm_svg_enable_background_trait_to_string
+};
+
+static gboolean
 lsm_svg_length_trait_from_string (LsmTrait *abstract_trait, char *string)
 {
 	LsmSvgLength *svg_length = (LsmSvgLength *) abstract_trait;
diff --git a/src/lsmsvgtraits.h b/src/lsmsvgtraits.h
index 8cd0a91..c51f9f2 100644
--- a/src/lsmsvgtraits.h
+++ b/src/lsmsvgtraits.h
@@ -74,6 +74,7 @@ typedef struct {
 
 extern const LsmTraitClass lsm_svg_angle_trait_class;
 extern const LsmTraitClass lsm_svg_blending_mode_trait_class;
+extern const LsmTraitClass lsm_svg_enable_background_trait_class;
 extern const LsmTraitClass lsm_svg_color_trait_class;
 extern const LsmTraitClass lsm_svg_dash_array_trait_class;
 extern const LsmTraitClass lsm_svg_display_trait_class;
diff --git a/src/lsmsvgview.c b/src/lsmsvgview.c
index a1f978c..4a54f68 100644
--- a/src/lsmsvgview.c
+++ b/src/lsmsvgview.c
@@ -1696,17 +1696,21 @@ _get_filter_surface (LsmSvgView *view, const char *input)
 		cairo_matrix_t pattern_matrix;
 		cairo_t *cairo;
 
+		if (view->background_stack == NULL)
+			return NULL;
+
 		surface = lsm_svg_filter_surface_new_similar ("BackgroundImage", source_surface, NULL);
 		view->filter_surfaces = g_slist_prepend (view->filter_surfaces, surface);	
 
-		background_surface = cairo_get_target (view->pattern_data->old_cairo);
+		background_surface = view->background_stack->data;
+
 		cairo_get_matrix (view->pattern_data->old_cairo, &matrix);
 		cairo_pattern_get_matrix (view->pattern_data->pattern, &pattern_matrix);
 		
 		cairo_matrix_invert (&matrix);
 		cairo_matrix_multiply (&matrix, &matrix, &pattern_matrix);
 
-		lsm_debug_render ("[LsmSvgView::_get_filter_surface] Background image matrix %g, %g, %g, %g, %g, %g\n",
+		lsm_debug_render ("[LsmSvgView::_get_filter_surface] Background image matrix %g, %g, %g, %g, %g, %g",
 				  matrix.xx, matrix.xy, matrix.yx, matrix.yy,
 				  matrix.x0, matrix.y0);
 
@@ -1721,6 +1725,9 @@ _get_filter_surface (LsmSvgView *view, const char *input)
 		LsmSvgFilterSurface *surface;
 		LsmSvgFilterSurface *background_surface;
 
+		if (view->background_stack == NULL)
+			return NULL;
+
 		background_surface = _get_filter_surface (view, "BackgroundImage");
 
 		surface = lsm_svg_filter_surface_new_similar ("BackgroundAlpha", background_surface, NULL);
@@ -2014,8 +2021,17 @@ lsm_svg_view_push_composition (LsmSvgView *view, LsmSvgStyle *style)
 	do_mask = (g_strcmp0 (style->mask->value, "none") != 0);
 	do_filter = (g_strcmp0 (style->filter->value, "none") != 0);
 
-	if (view->style->opacity->value < 1.0 && !do_filter && !view->is_clipping && !view->style->ignore_group_opacity) {
+	if ((view->style->opacity->value < 1.0 ||
+	     view->style->enable_background->value == LSM_SVG_ENABLE_BACKGROUND_NEW) &&
+	    !do_filter &&
+	    !view->is_clipping &&
+	    !view->style->ignore_group_opacity) {
+		lsm_debug_render ("[LsmSvgView::push_composition] Push group");
 		cairo_push_group (view->dom_view.cairo);
+		if (view->style->enable_background->value == LSM_SVG_ENABLE_BACKGROUND_NEW) {
+			lsm_debug_render ("[LsmSvgView::push_composition] Push background");
+			view->background_stack = g_slist_prepend (view->background_stack, cairo_get_group_target (view->dom_view.cairo));
+		}
 	}
 
 	if (do_clip) {
@@ -2075,9 +2091,18 @@ void lsm_svg_view_pop_composition (LsmSvgView *view)
 	if (do_clip)
 		lsm_svg_view_pop_clip (view);
 
-	if (view->style->opacity->value < 1.0 && !do_filter && !view->is_clipping && !view->style->ignore_group_opacity) {
+	if ((view->style->opacity->value < 1.0 ||
+	     view->style->enable_background->value == LSM_SVG_ENABLE_BACKGROUND_NEW) &&
+	    !do_filter &&
+	    !view->is_clipping &&
+	    !view->style->ignore_group_opacity) {
+		if (view->style->enable_background->value == LSM_SVG_ENABLE_BACKGROUND_NEW) {
+			lsm_debug_render ("[LsmSvgView::pop_composition] Pop background");
+			view->background_stack = g_slist_delete_link (view->background_stack, view->background_stack);
+		}
 		cairo_pop_group_to_source (view->dom_view.cairo);
 		cairo_paint_with_alpha (view->dom_view.cairo, view->style->opacity->value);
+		lsm_debug_render ("[LsmSvgView::pop_composition] Pop group");
 	}
 
 	lsm_svg_view_pop_style (view);
@@ -2155,6 +2180,7 @@ lsm_svg_view_render (LsmDomView *view)
 	svg_view->viewbox_stack = NULL;
 	svg_view->matrix_stack = NULL;
 	svg_view->pango_layout_stack = NULL;
+	svg_view->background_stack = NULL;
 
 	svg_view->is_clipping = FALSE;
 	svg_view->is_pango_layout_in_use = FALSE;
@@ -2196,6 +2222,11 @@ lsm_svg_view_render (LsmDomView *view)
 		g_slist_free (svg_view->style_stack);
 		svg_view->style_stack = NULL;
 	}
+	if (svg_view->background_stack != NULL) {
+		g_warning ("[LsmSvgView::render] Dangling background in stack");
+		g_slist_free (svg_view->background_stack);
+		svg_view->background_stack = NULL;
+	}
 }
 
 static void
diff --git a/src/lsmsvgview.h b/src/lsmsvgview.h
index a0c3e33..b38828e 100644
--- a/src/lsmsvgview.h
+++ b/src/lsmsvgview.h
@@ -60,6 +60,7 @@ struct _LsmSvgView {
 	GSList *viewbox_stack;
 	GSList *matrix_stack;
 	GSList *pango_layout_stack;
+	GSList *background_stack;
 
 	gboolean is_pango_layout_in_use;
 



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]