[lasem] [SVG] stroke-dasharray and stroke-dashoffset support.
- From: Emmanuel Pacaud <emmanuel src gnome org>
- To: svn-commits-list gnome org
- Subject: [lasem] [SVG] stroke-dasharray and stroke-dashoffset support.
- Date: Sun, 3 May 2009 05:12:00 -0400 (EDT)
commit 7d50eabaa4385335399012befb71b821cd786bea
Author: Emmanuel Pacaud <emmanuel pacaud lapp in2p3 fr>
Date: Sun May 3 11:11:21 2009 +0200
[SVG] stroke-dasharray and stroke-dashoffset support.
---
src/lsmdomattributes.h | 30 +++++-----
src/lsmsvgattributebags.c | 12 ++++
src/lsmsvgattributebags.h | 3 +-
src/lsmsvgattributes.c | 134 +++++++++++++++++++++++++++++++++++++++++++--
src/lsmsvgattributes.h | 21 +++++++
src/lsmsvggraphic.c | 2 +
src/lsmsvgstyle.c | 3 +
src/lsmsvgstyle.h | 2 +
src/lsmsvgutils.h | 2 +-
src/lsmsvgview.c | 9 +++
10 files changed, 195 insertions(+), 23 deletions(-)
diff --git a/src/lsmdomattributes.h b/src/lsmdomattributes.h
index 7bf56b9..164079b 100644
--- a/src/lsmdomattributes.h
+++ b/src/lsmdomattributes.h
@@ -58,45 +58,45 @@ typedef struct {
typedef void (*LsmDomAttributeFinalizeFunc) (void *);
-LsmDomAttributeMap * lsm_dom_attribute_map_new (void);
+LsmDomAttributeMap * lsm_dom_attribute_map_new (void);
LsmDomAttributeMap * lsm_dom_attribute_map_duplicate (const LsmDomAttributeMap *from);
-void lsm_dom_attribute_map_free (LsmDomAttributeMap *map);
+void lsm_dom_attribute_map_free (LsmDomAttributeMap *map);
-void lsm_dom_attribute_map_add_bag_attribute (LsmDomAttributeMap *map,
+void lsm_dom_attribute_map_add_bag_attribute (LsmDomAttributeMap *map,
const char *name,
ptrdiff_t attribute_offset,
const LsmDomAttributeClass *attribute_class,
ptrdiff_t bag_offset,
const LsmDomAttributeBagClass *bag_class);
-void lsm_dom_attribute_map_add_attribute_full (LsmDomAttributeMap *map,
+void lsm_dom_attribute_map_add_attribute_full (LsmDomAttributeMap *map,
char const *name,
ptrdiff_t offset,
const LsmDomAttributeClass *attribute_class);
-void lsm_dom_attribute_map_add_attribute (LsmDomAttributeMap *map,
+void lsm_dom_attribute_map_add_attribute (LsmDomAttributeMap *map,
char const *name,
ptrdiff_t offset);
-void lsm_dom_attribute_map_free_attributes (LsmDomAttributeMap *map,
+void lsm_dom_attribute_map_free_attributes (LsmDomAttributeMap *map,
void *instance);
-gboolean lsm_dom_attribute_map_set_attribute (LsmDomAttributeMap *map,
+gboolean lsm_dom_attribute_map_set_attribute (LsmDomAttributeMap *map,
void *instance,
char const *name,
char const *value);
-char const * lsm_dom_attribute_map_get_attribute (LsmDomAttributeMap *map,
+char const * lsm_dom_attribute_map_get_attribute (LsmDomAttributeMap *map,
void *instance,
char const *name);
-gboolean lsm_dom_attribute_map_set_css_attribute (LsmDomAttributeMap *map,
+gboolean lsm_dom_attribute_map_set_css_attribute (LsmDomAttributeMap *map,
void *instance,
char const *name,
char const *value,
LsmDomCssType css_type);
-gboolean lsm_dom_attribute_map_is_attribute_defined (LsmDomAttributeMap *map,
+gboolean lsm_dom_attribute_map_is_attribute_defined (LsmDomAttributeMap *map,
void *instance,
char const *name);
-gboolean lsm_dom_attribute_is_defined (const LsmDomAttribute *attribute);
-char const * lsm_dom_attribute_get_value (const LsmDomAttribute *attribute);
+gboolean lsm_dom_attribute_is_defined (const LsmDomAttribute *attribute);
+char const * lsm_dom_attribute_get_value (const LsmDomAttribute *attribute);
typedef struct {
LsmDomAttribute attr;
@@ -138,7 +138,7 @@ typedef unsigned int (*LsmDomNamedConvert) (const char *string);
void lsm_dom_boolean_attribute_parse (LsmDomBooleanAttribute *attribute,
gboolean *default_value);
-void lsm_dom_unsigned_attribute_parse (LsmDomUnsignedAttribute *attribute,
+void lsm_dom_unsigned_attribute_parse (LsmDomUnsignedAttribute *attribute,
unsigned *default_value);
void lsm_dom_double_attribute_parse (LsmDomDoubleAttribute *attribute,
double *default_value);
@@ -151,11 +151,11 @@ void lsm_dom_enum_list_attribute_parse (LsmDomEnumListAttribute *attribute,
LsmDomEnumList *style_value,
LsmDomNamedConvert convert);
-void lsm_dom_string_attribute_finalize (void *abstract);
+void lsm_dom_string_attribute_finalize (void *abstract);
void lsm_dom_enum_list_attribute_finalize (void *abstract);
-void lsm_dom_attribute_map_add_string (LsmDomAttributeMap *map,
+void lsm_dom_attribute_map_add_string (LsmDomAttributeMap *map,
char const *name,
ptrdiff_t offset);
void lsm_dom_attribute_map_add_enum_list (LsmDomAttributeMap *map,
diff --git a/src/lsmsvgattributebags.c b/src/lsmsvgattributebags.c
index 49f9e0d..1dec313 100644
--- a/src/lsmsvgattributebags.c
+++ b/src/lsmsvgattributebags.c
@@ -84,6 +84,10 @@ static const LsmDomAttributeBagClass lsm_svg_stroke_attribute_bag_class =
.finalize = lsm_svg_stroke_attribute_bag_finalize
};
+static const LsmDomAttributeClass lsm_svg_dash_array_attribute_class = {
+ .finalize = lsm_svg_dash_array_attribute_finalize
+};
+
void
lsm_dom_attribute_map_add_stroke_attribute_bag (LsmDomAttributeMap *map, ptrdiff_t bag_offset)
{
@@ -111,6 +115,14 @@ lsm_dom_attribute_map_add_stroke_attribute_bag (LsmDomAttributeMap *map, ptrdiff
offsetof (LsmSvgStrokeAttributeBag, miter_limit),
NULL,
bag_offset, &lsm_svg_stroke_attribute_bag_class);
+ lsm_dom_attribute_map_add_bag_attribute (map, "stroke-dasharray",
+ offsetof (LsmSvgStrokeAttributeBag, dash_array),
+ &lsm_svg_dash_array_attribute_class,
+ bag_offset, &lsm_svg_stroke_attribute_bag_class);
+ lsm_dom_attribute_map_add_bag_attribute (map, "stroke-dashoffset",
+ offsetof (LsmSvgStrokeAttributeBag, dash_offset),
+ NULL,
+ bag_offset, &lsm_svg_stroke_attribute_bag_class);
}
static void *
diff --git a/src/lsmsvgattributebags.h b/src/lsmsvgattributebags.h
index f72395a..9fe4ab7 100644
--- a/src/lsmsvgattributebags.h
+++ b/src/lsmsvgattributebags.h
@@ -39,8 +39,9 @@ typedef struct {
LsmDomEnumAttribute line_join;
LsmDomEnumAttribute line_cap;
LsmSvgDoubleAttribute miter_limit;
- LsmSvgLengthAttribute dash_offset;
LsmDomDoubleAttribute opacity;
+ LsmSvgLengthAttribute dash_offset;
+ LsmSvgDashArrayAttribute dash_array;
} LsmSvgStrokeAttributeBag;
typedef struct {
diff --git a/src/lsmsvgattributes.c b/src/lsmsvgattributes.c
index f25cffc..074248a 100644
--- a/src/lsmsvgattributes.c
+++ b/src/lsmsvgattributes.c
@@ -28,6 +28,53 @@
#include <stdio.h>
#include <math.h>
+const LsmSvgDashArray lsm_svg_dash_array_null = {0, NULL};
+
+LsmSvgDashArray *
+lsm_svg_dash_array_new (unsigned int n_dashes)
+{
+ LsmSvgDashArray *array;
+
+ g_return_val_if_fail (n_dashes > 0, (LsmSvgDashArray *) &lsm_svg_dash_array_null);
+
+ array = g_new (LsmSvgDashArray, 1);
+ if (array != NULL) {
+ array->n_dashes = n_dashes;
+ array->dashes = g_new (double, n_dashes);
+ if (array->dashes != NULL)
+ return array;
+ g_free (array);
+ }
+
+ return (LsmSvgDashArray *) &lsm_svg_dash_array_null;
+}
+
+void
+lsm_svg_dash_array_free (LsmSvgDashArray *array)
+{
+ if (array == NULL || array == &lsm_svg_dash_array_null)
+ return;
+
+ g_free (array->dashes);
+ g_free (array);
+}
+
+LsmSvgDashArray *
+lsm_svg_dash_array_duplicate (const LsmSvgDashArray *origin)
+{
+ LsmSvgDashArray *duplicate;
+
+ if (origin == NULL || origin == &lsm_svg_dash_array_null)
+ return (LsmSvgDashArray *) &lsm_svg_dash_array_null;
+
+ duplicate = lsm_svg_dash_array_new (origin->n_dashes);
+
+ if (duplicate != &lsm_svg_dash_array_null)
+ memcpy (duplicate->dashes, origin->dashes, sizeof (double) * origin->n_dashes);
+
+ return duplicate;
+}
+
const LsmSvgColor lsm_svg_color_null = {0.0, 0.0, 0.0};
void
@@ -86,8 +133,8 @@ lsm_svg_length_compute (const LsmSvgLength *length, double viewbox, double font_
void
lsm_svg_length_attribute_parse (LsmSvgLengthAttribute *attribute,
- LsmSvgLength *default_value,
- double font_size)
+ LsmSvgLength *default_value,
+ double font_size)
{
const char *string;
char *length_type_str;
@@ -103,7 +150,7 @@ lsm_svg_length_attribute_parse (LsmSvgLengthAttribute *attribute,
attribute->length.value_unit = g_strtod (string, &length_type_str);
attribute->length.type = lsm_svg_length_type_from_string (length_type_str);
attribute->length.value = lsm_svg_length_compute (&attribute->length,
- default_value->value, font_size);
+ default_value->value, font_size);
*default_value = attribute->length;
}
@@ -111,8 +158,8 @@ lsm_svg_length_attribute_parse (LsmSvgLengthAttribute *attribute,
void
lsm_svg_animated_length_attribute_parse (LsmSvgAnimatedLengthAttribute *attribute,
- LsmSvgLength *default_value,
- double font_size)
+ LsmSvgLength *default_value,
+ double font_size)
{
const char *string;
char *length_type_str;
@@ -129,7 +176,7 @@ lsm_svg_animated_length_attribute_parse (LsmSvgAnimatedLengthAttribute *attribut
attribute->length.base.value_unit = g_strtod (string, &length_type_str);
attribute->length.base.type = lsm_svg_length_type_from_string (length_type_str);
attribute->length.base.value = lsm_svg_length_compute (&attribute->length.base,
- default_value->value, font_size);
+ default_value->value, font_size);
attribute->length.animated = attribute->length.base;
*default_value = attribute->length.base;
@@ -137,6 +184,81 @@ lsm_svg_animated_length_attribute_parse (LsmSvgAnimatedLengthAttribute *attribut
}
void
+lsm_svg_dash_array_attribute_finalize (void *abstract)
+{
+ LsmSvgDashArrayAttribute *attribute = abstract;
+
+ g_return_if_fail (attribute != NULL);
+
+ lsm_svg_dash_array_free (attribute->value);
+ attribute->value = NULL;
+}
+
+void
+lsm_svg_dash_array_attribute_parse (LsmSvgDashArrayAttribute *attribute,
+ LsmSvgDashArray **default_value)
+{
+ const char *string;
+
+ g_return_if_fail (attribute != NULL);
+
+ string = lsm_dom_attribute_get_value ((LsmDomAttribute *) attribute);
+ if (g_strcmp0 (string, "inherit") == 0)
+ string = NULL;
+
+ if (string == NULL) {
+ lsm_svg_dash_array_free (attribute->value);
+ attribute->value = lsm_svg_dash_array_duplicate (*default_value);
+ } else {
+ unsigned int n_dashes = 1;
+
+ lsm_svg_dash_array_free (attribute->value);
+
+ if (strcmp (string, "none") == 0) {
+ attribute->value = (LsmSvgDashArray *) &lsm_svg_dash_array_null;
+ } else {
+ char *iter = (char *) string;
+ unsigned int i;
+
+ while (*iter != '\0') {
+ if (*iter == ',')
+ n_dashes++;
+ iter++;
+ }
+
+ g_message ("n_dashes = %d", n_dashes);
+
+ attribute->value = lsm_svg_dash_array_new (n_dashes);
+ if (attribute->value != &lsm_svg_dash_array_null) {
+ LsmSvgLength length;
+
+ iter = (char *)string;
+ lsm_svg_str_skip_spaces (&iter);
+
+ for (i = 0; i < n_dashes; i++) {
+ g_message ("iter = %s", iter);
+ if (lsm_svg_str_parse_double (&iter, &length.value_unit)) {
+ g_message ("iter for length = %s", iter);
+ length.type = lsm_svg_length_type_from_string (iter);
+ attribute->value->dashes[i] = lsm_svg_length_compute (&length,
+ 0.0, 0.0);
+ g_message ("length.value = %g", length.value_unit);
+ while (*iter != '\0' && *iter != ' ' && *iter != ',')
+ iter ++;
+ } else
+ attribute->value->dashes[i] = 0.0;
+ g_message ("dashes[%d] = %g", i, attribute->value->dashes[i]);
+ lsm_svg_str_skip_comma_and_spaces (&iter);
+ }
+ }
+ }
+
+ lsm_svg_dash_array_free (*default_value);
+ *default_value = lsm_svg_dash_array_duplicate (attribute->value);
+ }
+}
+
+void
lsm_svg_fill_rule_attribute_parse (LsmDomEnumAttribute *attribute,
unsigned int *style_value)
{
diff --git a/src/lsmsvgattributes.h b/src/lsmsvgattributes.h
index f46fdab..ca66f49 100644
--- a/src/lsmsvgattributes.h
+++ b/src/lsmsvgattributes.h
@@ -44,6 +44,22 @@ typedef struct {
extern const LsmSvgColor lsm_svg_color_null;
typedef struct {
+ unsigned int n_dashes;
+ double *dashes;
+} LsmSvgDashArray;
+
+extern const LsmSvgDashArray lsm_svg_dash_array_null;
+
+LsmSvgDashArray * lsm_svg_dash_array_new (unsigned int n_dashes);
+void lsm_svg_dash_array_free (LsmSvgDashArray *array);
+LsmSvgDashArray * lsm_svg_dash_array_duplicate (const LsmSvgDashArray *origin);
+
+typedef struct {
+ LsmDomAttribute attr;
+ LsmSvgDashArray *value;
+} LsmSvgDashArrayAttribute;
+
+typedef struct {
double value;
double value_unit;
LsmSvgLengthType type;
@@ -112,6 +128,11 @@ void lsm_svg_length_attribute_parse (LsmSvgLengthAttribute *attribute,
void lsm_svg_animated_length_attribute_parse (LsmSvgAnimatedLengthAttribute *attribute,
LsmSvgLength *default_value,
double font_size);
+
+void lsm_svg_dash_array_attribute_finalize (void *abstract);
+
+void lsm_svg_dash_array_attribute_parse (LsmSvgDashArrayAttribute *attribute,
+ LsmSvgDashArray **default_value);
void lsm_svg_fill_rule_attribute_parse (LsmDomEnumAttribute *attribute,
unsigned int *style_value);
void lsm_svg_line_join_attribute_parse (LsmDomEnumAttribute *attribute,
diff --git a/src/lsmsvggraphic.c b/src/lsmsvggraphic.c
index 41f0b6d..ffd771b 100644
--- a/src/lsmsvggraphic.c
+++ b/src/lsmsvggraphic.c
@@ -114,6 +114,8 @@ lsm_svg_graphic_update (LsmSvgElement *self, LsmSvgStyle *parent_style)
lsm_svg_line_join_attribute_parse (&graphic->stroke->line_join, &parent_style->stroke.line_join);
lsm_svg_line_cap_attribute_parse (&graphic->stroke->line_cap, &parent_style->stroke.line_cap);
lsm_svg_double_attribute_parse (&graphic->stroke->miter_limit, &parent_style->stroke.miter_limit);
+ lsm_svg_dash_array_attribute_parse (&graphic->stroke->dash_array, &parent_style->stroke.dash_array);
+ lsm_svg_length_attribute_parse (&graphic->stroke->dash_offset, &parent_style->stroke.dash_offset, 0.0);
}
if (graphic->transform != NULL) {
diff --git a/src/lsmsvgstyle.c b/src/lsmsvgstyle.c
index 38acda6..8e98709 100644
--- a/src/lsmsvgstyle.c
+++ b/src/lsmsvgstyle.c
@@ -40,6 +40,8 @@ lsm_svg_style_free (LsmSvgStyle *style)
{
g_return_if_fail (style != NULL);
+ lsm_svg_dash_array_free (style->stroke.dash_array);
+
g_free (style->text.font_family);
g_free (style);
}
@@ -56,6 +58,7 @@ lsm_svg_style_duplicate (const LsmSvgStyle *from)
memcpy (style, from, sizeof (LsmSvgStyle));
+ style->stroke.dash_array = lsm_svg_dash_array_duplicate (from->stroke.dash_array);
style->text.font_family = g_strdup (from->text.font_family);
return style;
diff --git a/src/lsmsvgstyle.h b/src/lsmsvgstyle.h
index 8321e6e..ce8303d 100644
--- a/src/lsmsvgstyle.h
+++ b/src/lsmsvgstyle.h
@@ -43,6 +43,8 @@ struct _GSvgStyle {
LsmSvgLineCap line_cap;
double opacity;
double miter_limit;
+ LsmSvgDashArray *dash_array;
+ LsmSvgLength dash_offset;
} stroke;
struct {
diff --git a/src/lsmsvgutils.h b/src/lsmsvgutils.h
index 19bc589..828772d 100644
--- a/src/lsmsvgutils.h
+++ b/src/lsmsvgutils.h
@@ -27,7 +27,7 @@
G_BEGIN_DECLS
-gboolean lsm_svg_str_parse_double (char **str, double *x);
+gboolean lsm_svg_str_parse_double (char **str, double *x);
gboolean lsm_svg_str_parse_double_list (char **str, unsigned int n_values, double *values);
static inline void
diff --git a/src/lsmsvgview.c b/src/lsmsvgview.c
index dff7815..1e05a20 100644
--- a/src/lsmsvgview.c
+++ b/src/lsmsvgview.c
@@ -819,6 +819,15 @@ _paint (LsmSvgView *view)
cairo_set_miter_limit (cairo, stroke->miter_limit.value);
cairo_set_line_width (cairo, stroke->width.length.value);
+
+ if (stroke->dash_array.value != NULL)
+ cairo_set_dash (cairo,
+ stroke->dash_array.value->dashes,
+ stroke->dash_array.value->n_dashes,
+ stroke->dash_offset.length.value);
+ else
+ cairo_set_dash (cairo, NULL, 0, 0.0);
+
cairo_stroke (cairo);
}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]