[lasem] svg_view: reimplement group opacity optimisation.



commit 113ff266b3e4ed9c3688341de45d339cb9cb35d2
Author: Emmanuel Pacaud <emmanuel gnome org>
Date:   Sat Oct 20 22:03:40 2012 +0200

    svg_view: reimplement group opacity optimisation.
    
    If group opacity of an object is lower than 1, and this object
    has only a stroke or a fill color, handle group opacity with
    solid color value, instead of using cairo push/pop group.

 src/lsmsvgcircleelement.c   |    2 ++
 src/lsmsvgclippathelement.c |    1 +
 src/lsmsvgelement.c         |    1 +
 src/lsmsvgelement.h         |    2 ++
 src/lsmsvgellipseelement.c  |    2 ++
 src/lsmsvglineelement.c     |    2 ++
 src/lsmsvgmarkerelement.c   |    1 +
 src/lsmsvgmaskelement.c     |    1 +
 src/lsmsvgpathelement.c     |    2 ++
 src/lsmsvgpatternelement.c  |    1 +
 src/lsmsvgpolygonelement.c  |    2 ++
 src/lsmsvgpolylineelement.c |    2 ++
 src/lsmsvgrectelement.c     |    2 ++
 src/lsmsvgstyle.h           |    1 +
 src/lsmsvgtextelement.c     |    2 ++
 src/lsmsvgview.c            |   25 +++++++++++++------------
 16 files changed, 37 insertions(+), 12 deletions(-)
---
diff --git a/src/lsmsvgcircleelement.c b/src/lsmsvgcircleelement.c
index c8aedd4..0c34e4a 100644
--- a/src/lsmsvgcircleelement.c
+++ b/src/lsmsvgcircleelement.c
@@ -139,6 +139,8 @@ lsm_svg_circle_element_class_init (LsmSvgCircleElementClass *s_rect_class)
 	s_element_class->get_extents = lsm_svg_circle_element_get_extents;
 	s_element_class->attribute_manager = lsm_attribute_manager_duplicate (s_element_class->attribute_manager);
 
+	s_element_class->is_shape_element = TRUE;
+
 	lsm_attribute_manager_add_attributes (s_element_class->attribute_manager,
 					      G_N_ELEMENTS (lsm_svg_circle_element_attribute_infos),
 					      lsm_svg_circle_element_attribute_infos);
diff --git a/src/lsmsvgclippathelement.c b/src/lsmsvgclippathelement.c
index c53bbe6..92c1764 100644
--- a/src/lsmsvgclippathelement.c
+++ b/src/lsmsvgclippathelement.c
@@ -53,6 +53,7 @@ lsm_svg_clip_path_element_render (LsmSvgElement *self, LsmSvgView *view)
 	}
 
 	style = lsm_svg_style_new_inherited (NULL, &self->property_bag);
+	style->ignore_group_opacity = TRUE;
 	lsm_svg_view_push_composition (view, style);
 
 	is_object_bounding_box = (clip->units.value == LSM_SVG_PATTERN_UNITS_OBJECT_BOUNDING_BOX);
diff --git a/src/lsmsvgelement.c b/src/lsmsvgelement.c
index 91e575b..9beccf9 100644
--- a/src/lsmsvgelement.c
+++ b/src/lsmsvgelement.c
@@ -160,6 +160,7 @@ _transformed_render (LsmSvgElement *element, LsmSvgView *view)
 
 	parent_style = lsm_svg_view_get_current_style (view);
 	style = lsm_svg_style_new_inherited (parent_style, &element->property_bag);
+	style->ignore_group_opacity = element_class->is_shape_element;
 
 	if (style->visibility->value == LSM_SVG_VISIBILITY_VISIBLE &&
 	    style->display->value != LSM_SVG_DISPLAY_NONE) {
diff --git a/src/lsmsvgelement.h b/src/lsmsvgelement.h
index 6adf00a..536b873 100644
--- a/src/lsmsvgelement.h
+++ b/src/lsmsvgelement.h
@@ -62,6 +62,8 @@ struct _LsmSvgElementClass {
 	void 		(*get_extents)			(LsmSvgElement *element, LsmSvgView *view, LsmExtents *extents);
 	void 		(*transformed_render)		(LsmSvgElement *element, LsmSvgView *view);
 	void 		(*transformed_get_extents)	(LsmSvgElement *element, LsmSvgView *view, LsmExtents *extents);
+
+	gboolean is_shape_element;
 };
 
 GType lsm_svg_element_get_type (void);
diff --git a/src/lsmsvgellipseelement.c b/src/lsmsvgellipseelement.c
index 77280fe..6c99d61 100644
--- a/src/lsmsvgellipseelement.c
+++ b/src/lsmsvgellipseelement.c
@@ -127,6 +127,8 @@ lsm_svg_ellipse_element_class_init (LsmSvgEllipseElementClass *s_rect_class)
 	s_element_class->render = lsm_svg_ellipse_element_render;
 	s_element_class->attribute_manager = lsm_attribute_manager_duplicate (s_element_class->attribute_manager);
 
+	s_element_class->is_shape_element = TRUE;
+
 	lsm_attribute_manager_add_attributes (s_element_class->attribute_manager,
 					      G_N_ELEMENTS (lsm_svg_ellipse_element_attribute_infos),
 					      lsm_svg_ellipse_element_attribute_infos);
diff --git a/src/lsmsvglineelement.c b/src/lsmsvglineelement.c
index 2d2e98a..b467708 100644
--- a/src/lsmsvglineelement.c
+++ b/src/lsmsvglineelement.c
@@ -121,6 +121,8 @@ lsm_svg_line_element_class_init (LsmSvgLineElementClass *s_rect_class)
 	s_element_class->render = lsm_svg_line_element_render;
 	s_element_class->attribute_manager = lsm_attribute_manager_duplicate (s_element_class->attribute_manager);
 
+	s_element_class->is_shape_element = TRUE;
+
 	lsm_attribute_manager_add_attributes (s_element_class->attribute_manager,
 					      G_N_ELEMENTS (lsm_svg_line_element_attribute_infos),
 					      lsm_svg_line_element_attribute_infos);
diff --git a/src/lsmsvgmarkerelement.c b/src/lsmsvgmarkerelement.c
index ea85bd3..46deb3b 100644
--- a/src/lsmsvgmarkerelement.c
+++ b/src/lsmsvgmarkerelement.c
@@ -67,6 +67,7 @@ _marker_element_render (LsmSvgElement *self, LsmSvgView *view)
 	}
 
 	style = lsm_svg_style_new_inherited (marker->style, &self->property_bag);
+	style->ignore_group_opacity = FALSE;
 	lsm_svg_view_push_composition (view, style);
 
 	if (marker->stroke_width > 0.0 || marker->units.value != LSM_SVG_MARKER_UNITS_STROKE_WIDTH) {
diff --git a/src/lsmsvgmaskelement.c b/src/lsmsvgmaskelement.c
index bfad28c..0f710e1 100644
--- a/src/lsmsvgmaskelement.c
+++ b/src/lsmsvgmaskelement.c
@@ -56,6 +56,7 @@ lsm_svg_mask_element_render (LsmSvgElement *self, LsmSvgView *view)
 	}
 
 	style = lsm_svg_style_new_inherited (NULL, &self->property_bag);
+	style->ignore_group_opacity = FALSE;
 	lsm_svg_view_push_composition (view, style);
 
 	mask_extents = lsm_svg_view_get_pattern_extents (view);
diff --git a/src/lsmsvgpathelement.c b/src/lsmsvgpathelement.c
index 3715319..4643507 100644
--- a/src/lsmsvgpathelement.c
+++ b/src/lsmsvgpathelement.c
@@ -107,6 +107,8 @@ lsm_svg_path_element_class_init (LsmSvgPathElementClass *s_rect_class)
 	s_element_class->get_extents = lsm_svg_path_element_get_extents;
 	s_element_class->attribute_manager = lsm_attribute_manager_duplicate (s_element_class->attribute_manager);
 
+	s_element_class->is_shape_element = TRUE;
+
 	lsm_attribute_manager_add_attributes (s_element_class->attribute_manager,
 					      G_N_ELEMENTS (lsm_svg_path_element_attribute_infos),
 					      lsm_svg_path_element_attribute_infos);
diff --git a/src/lsmsvgpatternelement.c b/src/lsmsvgpatternelement.c
index e26be50..cf7981d 100644
--- a/src/lsmsvgpatternelement.c
+++ b/src/lsmsvgpatternelement.c
@@ -187,6 +187,7 @@ lsm_svg_pattern_element_render (LsmSvgElement *self, LsmSvgView *view)
 		return;
 
 	style = lsm_svg_style_new_inherited (NULL, &self->property_bag);
+	style->ignore_group_opacity = FALSE;
 	lsm_svg_view_push_composition (view, style);
 
 	pattern_extents = lsm_svg_view_get_pattern_extents (view);
diff --git a/src/lsmsvgpolygonelement.c b/src/lsmsvgpolygonelement.c
index 9e17733..dae4936 100644
--- a/src/lsmsvgpolygonelement.c
+++ b/src/lsmsvgpolygonelement.c
@@ -87,6 +87,8 @@ lsm_svg_polygon_element_class_init (LsmSvgPolygonElementClass *s_rect_class)
 	s_element_class->render = lsm_svg_polygon_element_render;
 	s_element_class->attribute_manager = lsm_attribute_manager_duplicate (s_element_class->attribute_manager);
 
+	s_element_class->is_shape_element = TRUE;
+
 	lsm_attribute_manager_add_attributes (s_element_class->attribute_manager,
 					      G_N_ELEMENTS (lsm_svg_polygon_element_attribute_infos),
 					      lsm_svg_polygon_element_attribute_infos);
diff --git a/src/lsmsvgpolylineelement.c b/src/lsmsvgpolylineelement.c
index 49bae43..60d83b3 100644
--- a/src/lsmsvgpolylineelement.c
+++ b/src/lsmsvgpolylineelement.c
@@ -87,6 +87,8 @@ lsm_svg_polyline_element_class_init (LsmSvgPolylineElementClass *s_rect_class)
 	s_element_class->render = lsm_svg_polyline_element_render;
 	s_element_class->attribute_manager = lsm_attribute_manager_duplicate (s_element_class->attribute_manager);
 
+	s_element_class->is_shape_element = TRUE;
+
 	lsm_attribute_manager_add_attributes (s_element_class->attribute_manager,
 					      G_N_ELEMENTS (lsm_svg_polyline_element_attribute_infos),
 					      lsm_svg_polyline_element_attribute_infos);
diff --git a/src/lsmsvgrectelement.c b/src/lsmsvgrectelement.c
index 36be4bf..e5446f6 100644
--- a/src/lsmsvgrectelement.c
+++ b/src/lsmsvgrectelement.c
@@ -174,6 +174,8 @@ lsm_svg_rect_element_class_init (LsmSvgRectElementClass *s_rect_class)
 	s_element_class->get_extents = lsm_svg_rect_element_get_extents;
 	s_element_class->attribute_manager = lsm_attribute_manager_duplicate (s_element_class->attribute_manager);
 
+	s_element_class->is_shape_element = TRUE;
+
 	lsm_attribute_manager_add_attributes (s_element_class->attribute_manager,
 					      G_N_ELEMENTS (lsm_svg_rect_element_attribute_infos),
 					      lsm_svg_rect_element_attribute_infos);
diff --git a/src/lsmsvgstyle.h b/src/lsmsvgstyle.h
index fca298d..1f1884c 100644
--- a/src/lsmsvgstyle.h
+++ b/src/lsmsvgstyle.h
@@ -183,6 +183,7 @@ struct _LsmSvgStyle {
 	LsmSvgWritingModeProperty *	writing_mode;
 
 	double font_size_px;
+	gboolean ignore_group_opacity;
 };
 
 void 		lsm_svg_property_bag_set_property 	(LsmPropertyBag *property_bag,
diff --git a/src/lsmsvgtextelement.c b/src/lsmsvgtextelement.c
index cf9bf4e..9897bf4 100644
--- a/src/lsmsvgtextelement.c
+++ b/src/lsmsvgtextelement.c
@@ -137,6 +137,8 @@ lsm_svg_text_element_class_init (LsmSvgTextElementClass *s_text_class)
 	s_element_class->render = lsm_svg_text_element_render;
 	s_element_class->attribute_manager = lsm_attribute_manager_duplicate (s_element_class->attribute_manager);
 
+	s_element_class->is_shape_element = TRUE;
+
 	lsm_attribute_manager_add_attributes (s_element_class->attribute_manager,
 					      G_N_ELEMENTS (lsm_svg_text_element_attribute_infos),
 					      lsm_svg_text_element_attribute_infos);
diff --git a/src/lsmsvgview.c b/src/lsmsvgview.c
index 8043736..28cbaa6 100644
--- a/src/lsmsvgview.c
+++ b/src/lsmsvgview.c
@@ -1074,23 +1074,22 @@ paint (LsmSvgView *view, LsmSvgViewPathInfos *path_infos)
 	cairo = view->dom_view.cairo;
 	style = view->style;
 
-#if 0
-	/* This is disabled for now, as care should be taken in push_composition to
-	 * defer group opacity for simple shape to this function. */
-	if (style->opacity != NULL) {
+	if (style->opacity != NULL &&
+	    style->ignore_group_opacity &&
+	    g_strcmp0 (style->filter->value, "none") == 0) {
 		group_opacity = style->opacity->value;
 
-		use_group = style->fill->paint.type != LSM_SVG_PAINT_TYPE_NONE &&
-			style->stroke->paint.type != LSM_SVG_PAINT_TYPE_NONE &&
+		use_group = ((style->fill->paint.type != LSM_SVG_PAINT_TYPE_NONE &&
+			      style->stroke->paint.type != LSM_SVG_PAINT_TYPE_NONE) ||
+			     style->stroke->paint.type == LSM_SVG_PAINT_TYPE_URI ||
+			     style->stroke->paint.type == LSM_SVG_PAINT_TYPE_URI_RGB_COLOR ||
+			     style->fill->paint.type == LSM_SVG_PAINT_TYPE_URI_RGB_COLOR ||
+			     style->fill->paint.type == LSM_SVG_PAINT_TYPE_URI) &&
 			group_opacity < 1.0;
 	} else {
 		use_group = FALSE;
 		group_opacity = 1.0;
 	}
-#else
-	use_group = FALSE;
-	group_opacity = 1.0;
-#endif
 
 	/* Instead of push_group, we should restrict to the current path bounding box */
 	if (use_group)
@@ -2354,8 +2353,10 @@ 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)
+	if (view->style->opacity->value < 1.0 && !do_filter && !view->is_clipping && !view->style->ignore_group_opacity) {
+		printf ("Push group opacity\n");
 		cairo_push_group (view->dom_view.cairo);
+	}
 
 	if (do_clip) {
 		lsm_debug_render ("[LsmSvgView::push_style] Start clip '%s'", style->clip_path->value);
@@ -2414,7 +2415,7 @@ 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) {
+	if (view->style->opacity->value < 1.0 && !do_filter && !view->is_clipping && !view->style->ignore_group_opacity) {
 		cairo_pop_group_to_source (view->dom_view.cairo);
 		cairo_paint_with_alpha (view->dom_view.cairo, view->style->opacity->value);
 	}



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