[lasem] svg_marker: implement overflow.



commit 03911d5d57e469dc2122989edfc027fe837546be
Author: Emmanuel Pacaud <emmanuel gnome org>
Date:   Sat Sep 29 23:12:43 2012 +0200

    svg_marker: implement overflow.

 src/lsmdebug.c                                     |    6 +++
 src/lsmdebug.h                                     |    1 +
 src/lsmproperties.c                                |   12 ++++---
 src/lsmsvgenums.c                                  |   29 ++++++++++++++-
 src/lsmsvgenums.h                                  |   15 +++++++-
 src/lsmsvgmarkerelement.c                          |   19 ++++++----
 src/lsmsvgstyle.c                                  |   11 +++---
 src/lsmsvgstyle.h                                  |    7 +++-
 src/lsmsvgtraits.c                                 |   24 ++++++++++++
 src/lsmsvgtraits.h                                 |    1 +
 src/lsmsvgview.c                                   |   13 ++++---
 .../librsvg-bug403357-marker-overflow-visible.png  |  Bin 1493 -> 1382 bytes
 .../librsvg-bug403357-marker-overflow-visible.svg  |   39 ++++++++++----------
 13 files changed, 129 insertions(+), 48 deletions(-)
---
diff --git a/src/lsmdebug.c b/src/lsmdebug.c
index 3d00d8d..982cb74 100644
--- a/src/lsmdebug.c
+++ b/src/lsmdebug.c
@@ -49,6 +49,12 @@ LsmDebugCategory lsm_debug_category_render =
 	.level = -1
 };
 
+LsmDebugCategory lsm_debug_category_viewport =
+{
+	.name = "viewport",
+	.level = -1
+};
+
 static GHashTable *lsm_debug_categories = NULL;
 
 static void
diff --git a/src/lsmdebug.h b/src/lsmdebug.h
index f6bb454..a9c4b1d 100644
--- a/src/lsmdebug.h
+++ b/src/lsmdebug.h
@@ -45,6 +45,7 @@ extern LsmDebugCategory lsm_debug_category_dom;
 extern LsmDebugCategory lsm_debug_category_measure;
 extern LsmDebugCategory lsm_debug_category_update;
 extern LsmDebugCategory lsm_debug_category_render;
+extern LsmDebugCategory lsm_debug_category_viewport;
 
 #define lsm_debug_dom(...) 		lsm_debug (&lsm_debug_category_dom, __VA_ARGS__)
 #define lsm_log_dom(...)		lsm_log (&lsm_debug_category_dom, __VA_ARGS__)
diff --git a/src/lsmproperties.c b/src/lsmproperties.c
index 45616e9..b8d824b 100644
--- a/src/lsmproperties.c
+++ b/src/lsmproperties.c
@@ -343,11 +343,13 @@ lsm_property_manager_apply_property_bag (LsmPropertyManager *manager,
 				if (g_strcmp0 (property->value, "inherit") != 0)
 					*((LsmProperty **) ((void*) style
 							    + LSM_PROPERTY_ID_TO_OFFSET (property->id))) = property;
-				else
-					*((LsmProperty **) ((void*) style
-							    + LSM_PROPERTY_ID_TO_OFFSET (property->id))) =
-						*((LsmProperty **) ((void*) parent_style
-								    + LSM_PROPERTY_ID_TO_OFFSET (property->id)));
+				else {
+					if (parent_style != NULL)
+						*((LsmProperty **) ((void*) style
+								    + LSM_PROPERTY_ID_TO_OFFSET (property->id))) =
+							*((LsmProperty **) ((void*) parent_style
+									    + LSM_PROPERTY_ID_TO_OFFSET (property->id)));
+				}
 
 				manager->property_check[property->id] = manager->property_check_count;
 				previous_iter = iter;
diff --git a/src/lsmsvgenums.c b/src/lsmsvgenums.c
index bedd9dc..8a31c3d 100644
--- a/src/lsmsvgenums.c
+++ b/src/lsmsvgenums.c
@@ -119,6 +119,31 @@ lsm_svg_line_cap_from_string (const char *string)
 					   G_N_ELEMENTS (lsm_svg_line_cap_strings));
 }
 
+static const char *lsm_svg_overflow_strings[] = {
+	"visible",
+	"hidden",
+	"scroll",
+	"auto"
+};
+
+const char *
+lsm_svg_overflow_to_string (LsmSvgOverflow overflow)
+{
+	if (overflow < 0 || overflow > LSM_SVG_OVERFLOW_AUTO)
+		return NULL;
+
+	return lsm_svg_overflow_strings[overflow];
+}
+
+LsmSvgOverflow
+lsm_svg_overflow_from_string (const char *string)
+{
+	LsmSvgOverflow overflow = lsm_enum_value_from_string (string, lsm_svg_overflow_strings,
+							      G_N_ELEMENTS (lsm_svg_overflow_strings));
+
+	return overflow;
+}
+
 static const char *lsm_svg_pattern_units_strings[] = {
 	"userSpaceOnUse",
 	"objectBoundingBox"
@@ -141,8 +166,8 @@ lsm_svg_pattern_units_from_string (const char *string)
 }
 
 static const char *lsm_svg_marker_units_strings[] = {
-	"userSpaceOnUse",
-	"strokeWidth"
+	"strokeWidth",
+	"userSpaceOnUse"
 };
 
 const char *
diff --git a/src/lsmsvgenums.h b/src/lsmsvgenums.h
index c176b4c..942cbed 100644
--- a/src/lsmsvgenums.h
+++ b/src/lsmsvgenums.h
@@ -112,6 +112,17 @@ typedef enum {
 } LsmSvgTransformType;
 
 typedef enum {
+	LSM_SVG_OVERFLOW_ERROR = -1,
+	LSM_SVG_OVERFLOW_VISIBLE,
+	LSM_SVG_OVERFLOW_HIDDEN,
+	LSM_SVG_OVERFLOW_SCROLL,
+	LSM_SVG_OVERFLOW_AUTO
+} LsmSvgOverflow;
+
+const char * 		lsm_svg_overflow_to_string 		(LsmSvgOverflow overflow);
+LsmSvgOverflow		lsm_svg_overflow_from_string		(const char *string);
+
+typedef enum {
 	LSM_SVG_PATTERN_UNITS_ERROR = -1,
 	LSM_SVG_PATTERN_UNITS_USER_SPACE_ON_USE,
 	LSM_SVG_PATTERN_UNITS_OBJECT_BOUNDING_BOX
@@ -122,8 +133,8 @@ LsmSvgPatternUnits	lsm_svg_pattern_units_from_string		(const char *string);
 
 typedef enum {
 	LSM_SVG_MARKER_UNITS_ERROR = -1,
-	LSM_SVG_MARKER_UNITS_USER_SPACE_ON_USE,
-	LSM_SVG_MARKER_UNITS_STROKE_WIDTH
+	LSM_SVG_MARKER_UNITS_STROKE_WIDTH,
+	LSM_SVG_MARKER_UNITS_USER_SPACE_ON_USE
 } LsmSvgMarkerUnits;
 
 const char * 		lsm_svg_marker_units_to_string 			(LsmSvgMarkerUnits units);
diff --git a/src/lsmsvgmarkerelement.c b/src/lsmsvgmarkerelement.c
index b99aaaf..1b8cd73 100644
--- a/src/lsmsvgmarkerelement.c
+++ b/src/lsmsvgmarkerelement.c
@@ -26,6 +26,7 @@
 #include <lsmdebug.h>
 #include <lsmdomdocument.h>
 #include <stdio.h>
+#include <math.h>
 
 static GObjectClass *parent_class;
 
@@ -48,6 +49,7 @@ _marker_element_render (LsmSvgElement *self, LsmSvgView *view)
 	LsmSvgStyle *style;
 	LsmSvgMatrix matrix;
 	LsmBox viewport;
+	LsmBox viewbox;
 	double ref_x, ref_y;
 
 	if (!marker->enable_rendering) {
@@ -76,20 +78,24 @@ _marker_element_render (LsmSvgElement *self, LsmSvgView *view)
 	viewport.height = lsm_svg_view_normalize_length (view, &marker->height.length,
 							 LSM_SVG_LENGTH_DIRECTION_HORIZONTAL);
 
+	if (lsm_attribute_is_defined (&marker->viewbox.base))
+		viewbox = marker->viewbox.value;
+	else
+		viewbox = viewport;
 
 	if (marker->units.value == LSM_SVG_MARKER_UNITS_STROKE_WIDTH) {
 		viewport.width *= marker->stroke_width;
 		viewport.height *= marker->stroke_width;
+
+		lsm_debug_render ("[LsmSvgMarkerElement::render] stroke_width scale = %g",
+				  marker->stroke_width);
 	}
 
-	lsm_svg_view_viewbox_to_viewport (view, &viewport, &marker->viewbox.value,
+	lsm_svg_view_viewbox_to_viewport (view, &viewport, &viewbox,
 					  &marker->preserve_aspect_ratio.value, &ref_x, &ref_y);
 
-	lsm_debug_render ("[LsmSvgMarkerElement::render] stroke_width scale = %g",
-		   marker->stroke_width);
-
 	if (marker->orientation.value.type == LSM_SVG_ANGLE_TYPE_FIXED) {
-		lsm_svg_matrix_init_rotate (&matrix, marker->orientation.value.angle);
+		lsm_svg_matrix_init_rotate (&matrix, marker->orientation.value.angle * M_PI / 18.0);
 		lsm_debug_render ("[LsmSvgMarkerElement::render] fixed angle = %g", marker->orientation.value.angle);
 	} else {
 		lsm_svg_matrix_init_rotate (&matrix, marker->vertex_angle);
@@ -99,7 +105,7 @@ _marker_element_render (LsmSvgElement *self, LsmSvgView *view)
 
 	if (lsm_svg_view_push_matrix (view, &matrix)) {
 
-		lsm_svg_view_push_viewport (view, &viewport, &marker->viewbox.value,
+		lsm_svg_view_push_viewport (view, &viewport, &viewbox,
 					    &marker->preserve_aspect_ratio.value);
 
 		LSM_SVG_ELEMENT_CLASS (parent_class)->render (self, view);
@@ -109,7 +115,6 @@ _marker_element_render (LsmSvgElement *self, LsmSvgView *view)
 
 	lsm_svg_view_pop_matrix (view);
 
-
 	lsm_svg_view_pop_style (view);
 	lsm_svg_style_unref (style);
 }
diff --git a/src/lsmsvgstyle.c b/src/lsmsvgstyle.c
index 19d515d..9970ce3 100644
--- a/src/lsmsvgstyle.c
+++ b/src/lsmsvgstyle.c
@@ -104,8 +104,8 @@ static const LsmPropertyInfos lsm_svg_property_infos[] = {
 	{
 		.name = "overflow",
 		.id = LSM_PROPERTY_OFFSET_TO_ID (LsmSvgStyle, overflow),
-		.trait_class = &lsm_null_trait_class,
-		.trait_default = ""
+		.trait_class = &lsm_svg_overflow_trait_class,
+		.trait_default = "visible"
 	},
 	{
 		.name = "stop-color",
@@ -502,6 +502,7 @@ lsm_svg_style_unref (LsmSvgStyle *style)
 LsmSvgStyle *
 lsm_svg_style_new_inherited (const LsmSvgStyle *parent_style, LsmPropertyBag *property_bag)
 {
+	LsmPropertyManager *property_manager = lsm_svg_get_property_manager ();
 	LsmSvgRealStyle *real_style;
 	LsmSvgStyle *style;
 	const LsmSvgStyle *default_style;
@@ -514,17 +515,15 @@ lsm_svg_style_new_inherited (const LsmSvgStyle *parent_style, LsmPropertyBag *pr
 	style = &real_style->base;
 
 	if (parent_style != NULL) {
-		LsmPropertyManager *property_manager = lsm_svg_get_property_manager ();
-
 		memcpy (style, default_style, offsetof (LsmSvgStyle, clip_rule));
 		memcpy (&style->clip_rule, &parent_style->clip_rule,
 			sizeof (LsmSvgStyle) - offsetof (LsmSvgStyle, clip_rule));
-
-		lsm_property_manager_apply_property_bag (property_manager, property_bag, style, parent_style);
 	} else {
 		memcpy (style, default_style, sizeof (LsmSvgStyle));
 	}
 
+	lsm_property_manager_apply_property_bag (property_manager, property_bag, style, parent_style);
+
 	return style;
 }
 
diff --git a/src/lsmsvgstyle.h b/src/lsmsvgstyle.h
index 9932211..56a8ebe 100644
--- a/src/lsmsvgstyle.h
+++ b/src/lsmsvgstyle.h
@@ -41,6 +41,11 @@ typedef struct {
 
 typedef struct {
 	LsmProperty base;
+	LsmSvgOverflow value;
+} LsmSvgOverflowProperty;
+
+typedef struct {
+	LsmProperty base;
 	LsmSvgPaint paint;
 } LsmSvgPaintProperty;
 
@@ -124,7 +129,7 @@ struct _LsmSvgStyle {
 	LsmProperty *			lighting_color;
 	LsmProperty *			mask;
 	LsmSvgDoubleProperty *		opacity;
-	LsmProperty *			overflow;
+	LsmSvgOverflowProperty *	overflow;
 	LsmSvgColorProperty *		stop_color;
 	LsmSvgDoubleProperty *		stop_opacity;
 	LsmProperty *			text_decoration;
diff --git a/src/lsmsvgtraits.c b/src/lsmsvgtraits.c
index 3357f4d..29139cb 100644
--- a/src/lsmsvgtraits.c
+++ b/src/lsmsvgtraits.c
@@ -966,6 +966,30 @@ const LsmTraitClass lsm_svg_one_or_two_double_trait_class = {
 };
 
 static gboolean
+lsm_svg_overflow_trait_from_string (LsmTrait *abstract_trait, char *string)
+{
+	LsmSvgOverflow *trait = (LsmSvgOverflow *) abstract_trait;
+
+	*trait = lsm_svg_overflow_from_string (string);
+
+	return *trait >= 0;
+}
+
+char *
+lsm_svg_overflow_trait_to_string (LsmTrait *abstract_trait)
+{
+	LsmSvgOverflow *trait = (LsmSvgOverflow *) abstract_trait;
+
+	return g_strdup (lsm_svg_overflow_to_string (*trait));
+}
+
+const LsmTraitClass lsm_svg_overflow_trait_class = {
+	.size = sizeof (LsmSvgOverflow),
+	.from_string = lsm_svg_overflow_trait_from_string,
+	.to_string = lsm_svg_overflow_trait_to_string
+};
+
+static gboolean
 lsm_svg_writing_mode_trait_from_string (LsmTrait *abstract_trait, char *string)
 {
 	LsmSvgDisplay *trait = (LsmSvgDisplay *) abstract_trait;
diff --git a/src/lsmsvgtraits.h b/src/lsmsvgtraits.h
index 95f362c..716da41 100644
--- a/src/lsmsvgtraits.h
+++ b/src/lsmsvgtraits.h
@@ -86,6 +86,7 @@ extern const LsmTraitClass lsm_svg_line_cap_trait_class;
 extern const LsmTraitClass lsm_svg_marker_units_trait_class;
 extern const LsmTraitClass lsm_svg_matrix_trait_class;
 extern const LsmTraitClass lsm_svg_one_or_two_double_trait_class;
+extern const LsmTraitClass lsm_svg_overflow_trait_class;
 extern const LsmTraitClass lsm_svg_paint_trait_class;
 extern const LsmTraitClass lsm_svg_pattern_units_trait_class;
 extern const LsmTraitClass lsm_svg_preserve_aspect_ratio_trait_class;
diff --git a/src/lsmsvgview.c b/src/lsmsvgview.c
index aaa4d32..f276366 100644
--- a/src/lsmsvgview.c
+++ b/src/lsmsvgview.c
@@ -1628,8 +1628,8 @@ lsm_svg_view_push_viewport (LsmSvgView *view, const LsmBox *viewport, const LsmB
 	cairo = view->dom_view.cairo;
 
 	cairo_save (cairo);
-#if 0
-	if (view->dom_view.debug) {
+
+	if (lsm_debug_check (&lsm_debug_category_viewport, LSM_DEBUG_LEVEL_LOG)) {
 		cairo_save (cairo);
 		cairo_set_line_width (cairo, 1.0);
 		cairo_set_source_rgb (cairo, 0.0, 0.0, 0.0);
@@ -1637,9 +1637,12 @@ lsm_svg_view_push_viewport (LsmSvgView *view, const LsmBox *viewport, const LsmB
 		cairo_stroke (cairo);
 		cairo_restore (cairo);
 	}
-#endif
-	cairo_rectangle (cairo, viewport->x, viewport->y, viewport->width, viewport->height);
-	cairo_clip (cairo);
+
+	if (view->style != NULL && view->style->overflow->value == LSM_SVG_OVERFLOW_HIDDEN) {
+		cairo_rectangle (cairo, viewport->x, viewport->y, viewport->width, viewport->height);
+		cairo_clip (cairo);
+	}
+
 	cairo_translate (cairo, viewport->x + x_offset, viewport->y + y_offset);
 	cairo_scale (cairo, x_scale, y_scale);
 }
diff --git a/tests/data/svg/librsvg/librsvg-bug403357-marker-overflow-visible.png b/tests/data/svg/librsvg/librsvg-bug403357-marker-overflow-visible.png
index 024577f..520cdc2 100644
Binary files a/tests/data/svg/librsvg/librsvg-bug403357-marker-overflow-visible.png and b/tests/data/svg/librsvg/librsvg-bug403357-marker-overflow-visible.png differ
diff --git a/tests/data/svg/librsvg/librsvg-bug403357-marker-overflow-visible.svg b/tests/data/svg/librsvg/librsvg-bug403357-marker-overflow-visible.svg
index 39f3adc..3f31aee 100644
--- a/tests/data/svg/librsvg/librsvg-bug403357-marker-overflow-visible.svg
+++ b/tests/data/svg/librsvg/librsvg-bug403357-marker-overflow-visible.svg
@@ -1,47 +1,46 @@
-<?xml version="1.0" encoding="UTF-8" standalone="no"?>
-<svg xmlns:svg="http://www.w3.org/2000/svg"; version="1.1" width="200" height="160">
+<svg xmlns="http://www.w3.org/2000/svg"; version="1.1" width="200" height="160">
   <defs>
     <marker orient="0" markerHeight="10" markerWidth="10" viewBox="0 0 1 1" refY="0.5" refX="0.5" id="marker0" overflow="hidden">
-	    <path d="M 0 0.5 L 0.5 1 L 1 0.5 L 0.5 0 Z" />
+	    <path d="M 0 0.5 L 0.5 1 L 1 0.5 L 0.5 0 Z"/>
     </marker>
     <marker orient="0" markerHeight="5" markerWidth="5" viewBox="0 0 .5 .5" refY="0.5" refX="0.5" id="marker1" overflow="hidden">
-	    <path d="M 0 0.5 L 0.5 1 L 1 0.5 L 0.5 0 Z" />
+	    <path d="M 0 0.5 L 0.5 1 L 1 0.5 L 0.5 0 Z"/>
     </marker>
     <marker orient="0" markerHeight="5" markerWidth="5" viewBox="0 0 .5 .5" refY="0.5" refX="0.5" id="marker2" overflow="visible">
-	    <path d="M 0 0.5 L 0.5 1 L 1 0.5 L 0.5 0 Z" />
+	    <path d="M 0 0.5 L 0.5 1 L 1 0.5 L 0.5 0 Z"/>
     </marker>
     <marker orient="30" markerHeight="10" markerWidth="10" viewBox="0 0 1 1" refY="0.5" refX="0.5" id="marker3" overflow="hidden">
-	    <path d="M 0 0.5 L 0.5 1 L 1 0.5 L 0.5 0 Z" />
+	    <path d="M 0 0.5 L 0.5 1 L 1 0.5 L 0.5 0 Z"/>
     </marker>
     <marker orient="30" markerHeight="5" markerWidth="5" viewBox="0 0 .5 .5" refY="0.5" refX="0.5" id="marker4" overflow="hidden">
-	    <path d="M 0 0.5 L 0.5 1 L 1 0.5 L 0.5 0 Z" />
+	    <path d="M 0 0.5 L 0.5 1 L 1 0.5 L 0.5 0 Z"/>
     </marker>
     <marker orient="30" markerHeight="5" markerWidth="5" viewBox="0 0 .5 .5" refY="0.5" refX="0.5" id="marker5" overflow="visible">
-	    <path d="M 0 0.5 L 0.5 1 L 1 0.5 L 0.5 0 Z" />
+	    <path d="M 0 0.5 L 0.5 1 L 1 0.5 L 0.5 0 Z"/>
     </marker>
     <marker orient="0" markerHeight="10" markerWidth="10" refY="5" refX="5" id="marker10" overflow="hidden">
-	    <path d="M 0 5 L 5 10 L 10 5 L 5 0 Z" />
+	    <path d="M 0 5 L 5 10 L 10 5 L 5 0 Z"/>
     </marker>
     <marker orient="0" markerHeight="5" markerWidth="5" refY="5" refX="5" id="marker11" overflow="hidden">
-	    <path d="M 0 5 L 5 10 L 10 5 L 5 0 Z" />
+	    <path d="M 0 5 L 5 10 L 10 5 L 5 0 Z"/>
     </marker>
     <marker orient="0" markerHeight="5" markerWidth="5" refY="5" refX="5" id="marker12" overflow="visible">
-	    <path d="M 0 5 L 5 10 L 10 5 L 5 0 Z" />
+	    <path d="M 0 5 L 5 10 L 10 5 L 5 0 Z"/>
     </marker>
     <marker orient="30" markerHeight="10" markerWidth="10" refY="5" refX="5" id="marker13" overflow="hidden">
-	    <path d="M 0 5 L 5 10 L 10 5 L 5 0 Z" />
+	    <path d="M 0 5 L 5 10 L 10 5 L 5 0 Z"/>
     </marker>
     <marker orient="30" markerHeight="5" markerWidth="5" refY="5" refX="5" id="marker14" overflow="hidden">
-	    <path d="M 0 5 L 5 10 L 10 5 L 5 0 Z" />
+	    <path d="M 0 5 L 5 10 L 10 5 L 5 0 Z"/>
     </marker>
     <marker orient="30" markerHeight="5" markerWidth="5" refY="5" refX="5" id="marker15" overflow="visible">
-	    <path d="M 0 5 L 5 10 L 10 5 L 5 0 Z" />
+	    <path d="M 0 5 L 5 10 L 10 5 L 5 0 Z"/>
     </marker>
   </defs>
-  <path stroke="black" stroke-width="2" marker-start="url(#marker0)" marker-end="url(#marker10)" d="M 20 40 L 80 40" />
-  <path stroke="black" stroke-width="2" marker-start="url(#marker1)" marker-end="url(#marker11)" d="M 20 80 L 80 80" />
-  <path stroke="black" stroke-width="2" marker-start="url(#marker2)" marker-end="url(#marker12)" d="M 20 120 L 80 120" />
-  <path stroke="black" stroke-width="2" marker-start="url(#marker3)" marker-end="url(#marker13)" d="M 120 40 L 180 40" />
-  <path stroke="black" stroke-width="2" marker-start="url(#marker4)" marker-end="url(#marker14)" d="M 120 80 L 180 80" />
-  <path stroke="black" stroke-width="2" marker-start="url(#marker5)" marker-end="url(#marker15)" d="M 120 120 L 180 120" />
+  <path stroke="black" stroke-width="2" marker-start="url(#marker0)" marker-end="url(#marker10)" d="M 20 40 L 80 40"/>
+  <path stroke="black" stroke-width="2" marker-start="url(#marker1)" marker-end="url(#marker11)" d="M 20 80 L 80 80"/>
+  <path stroke="black" stroke-width="2" marker-start="url(#marker2)" marker-end="url(#marker12)" d="M 20 120 L 80 120"/>
+  <path stroke="black" stroke-width="2" marker-start="url(#marker3)" marker-end="url(#marker13)" d="M 120 40 L 180 40"/>
+  <path stroke="black" stroke-width="2" marker-start="url(#marker4)" marker-end="url(#marker14)" d="M 120 80 L 180 80"/>
+  <path stroke="black" stroke-width="2" marker-start="url(#marker5)" marker-end="url(#marker15)" d="M 120 120 L 180 120"/>
 </svg>



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