[lasem] svg_view: reimplement group opacity optimisation.
- From: Emmanuel Pacaud <emmanuel src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [lasem] svg_view: reimplement group opacity optimisation.
- Date: Sat, 20 Oct 2012 20:05:51 +0000 (UTC)
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]