[dia] svg: split style string parsing to it's own function
- From: Hans Breuer <hans src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [dia] svg: split style string parsing to it's own function
- Date: Sun, 4 Aug 2013 12:44:11 +0000 (UTC)
commit 7e766114e149c1a8c36ba5edf17b05ba409d824e
Author: Hans Breuer <hans breuer org>
Date: Sat Aug 3 12:01:23 2013 +0200
svg: split style string parsing to it's own function
Introduce dia_svg_parse_style_string() - cut and paste from
the implmentation withing dia_svg_parse_style()
lib/dia_svg.c | 438 +++++++++++++++++++++++++++++--------------------------
lib/dia_svg.h | 1 +
lib/libdia.def | 1 +
3 files changed, 233 insertions(+), 207 deletions(-)
---
diff --git a/lib/dia_svg.c b/lib/dia_svg.c
index 62b933d..f99f42e 100644
--- a/lib/dia_svg.c
+++ b/lib/dia_svg.c
@@ -304,212 +304,257 @@ _parse_dasharray (DiaSvgStyle *s, real user_scale, gchar *str, gchar **end)
}
/*
- * \brief Parse SVG style properties
- * This function not only parses the style attribute of the given node
- * it also extracts some of the style properties directly.
- * @param node An XML node to parse a style from.
- * @param s The SVG style object to fill out. This should previously be
- * initialized to some default values.
- * @param user_scale, if >0 scalable values (font-size, stroke-width, ...) are divided by this, otherwise
ignored
+ * \brief Parse SVG/CSS style string
+ *
+ * Parse as much information from the given style string as Dia can handle.
+ * There are still known limitations:
+ * - does not follow references to somewhere inside or outside the string
+ * (e.g. url(...), color and currentColor)
+ * - font parsing should be extended to support lists of fonts somehow
+ *
* \ingroup DiaSvg
*/
void
-dia_svg_parse_style(xmlNodePtr node, DiaSvgStyle *s, real user_scale)
+dia_svg_parse_style_string (DiaSvgStyle *s, real user_scale, const gchar *str)
{
- xmlChar *str;
gchar temp[FONT_NAME_LENGTH_MAX+1]; /* font-family names will be limited to 40 characters */
int i = 0;
gboolean over = FALSE;
+ gchar *ptr = (gchar *)str;
char *family = NULL, *style = NULL, *weight = NULL;
- str = xmlGetProp(node, (const xmlChar *)"style");
+ while (ptr[0] != '\0') {
+ /* skip white space at start */
+ while (ptr[0] != '\0' && g_ascii_isspace(ptr[0])) ptr++;
+ if (ptr[0] == '\0') break;
+
+ if (!strncmp("font-family:", ptr, 12)) {
+ ptr += 12;
+ while ((ptr[0] != '\0') && g_ascii_isspace(ptr[0])) ptr++;
+ i = 0; over = FALSE;
+ while (ptr[0] != '\0' && ptr[0] != ';' && !over) {
+ if (i < FONT_NAME_LENGTH_MAX) {
+ temp[i] = ptr[0];
+ } else over = TRUE;
+ i++;
+ ptr++;
+ }
+ temp[i] = '\0';
- if (str) {
- gchar *ptr = (gchar *)str;
- while (ptr[0] != '\0') {
- /* skip white space at start */
+ if (!over) {
+ if (strcmp (temp, "sanserif") == 0 || strcmp (temp, "sans-serif") == 0)
+ family = g_strdup ("sans"); /* special name adaption */
+ else
+ family = g_strdup(temp);
+ }
+ } else if (!strncmp("font-weight:", ptr, 12)) {
+ ptr += 12;
+ while ((ptr[0] != '\0') && g_ascii_isspace(ptr[0])) ptr++;
+ i = 0; over = FALSE;
+ while (ptr[0] != '\0' && ptr[0] != ';' && !over) {
+ if (i < FONT_NAME_LENGTH_MAX) {
+ temp[i] = ptr[0];
+ } else over = TRUE;
+ i++;
+ ptr++;
+ }
+ temp[i] = '\0';
+
+ if (!over) weight = g_strdup(temp);
+ } else if (!strncmp("font-style:", ptr, 11)) {
+ ptr += 11;
+ while ((ptr[0] != '\0') && g_ascii_isspace(ptr[0])) ptr++;
+ i = 0; over = FALSE;
+ while (ptr[0] != '\0' && ptr[0] != ';' && !over) {
+ if (i < FONT_NAME_LENGTH_MAX) {
+ temp[i] = ptr[0];
+ } else over = TRUE;
+ i++;
+ ptr++;
+ }
+ temp[i] = '\0';
+
+ if (!over) style = g_strdup(temp);
+ } else if (!strncmp("font-size:", ptr, 10)) {
+ ptr += 10;
+ while ((ptr[0] != '\0') && g_ascii_isspace(ptr[0])) ptr++;
+ i = 0; over = FALSE;
+ while (ptr[0] != '\0' && ptr[0] != ';' && !over) {
+ if (i < FONT_NAME_LENGTH_MAX) {
+ temp[i] = ptr[0];
+ } else over = TRUE;
+ i++;
+ ptr++;
+ }
+ temp[i] = '\0';
+
+ if (!over) {
+ s->font_height = g_ascii_strtod(temp, NULL);
+ if (user_scale > 0)
+ s->font_height /= user_scale;
+ }
+ } else if (!strncmp("text-anchor:", ptr, 12)) {
+ ptr += 12;
+ while ((ptr[0] != '\0') && g_ascii_isspace(ptr[0])) ptr++;
+ if (!strncmp(ptr, "start", 5))
+ s->alignment = ALIGN_LEFT;
+ else if (!strncmp(ptr, "end", 3))
+ s->alignment = ALIGN_RIGHT;
+ else if (!strncmp(ptr, "middle", 6))
+ s->alignment = ALIGN_CENTER;
+
+ } else if (!strncmp("stroke-width:", ptr, 13)) {
+ ptr += 13;
+ s->line_width = g_ascii_strtod(ptr, &ptr);
+ if (user_scale > 0)
+ s->line_width /= user_scale;
+ } else if (!strncmp("stroke:", ptr, 7)) {
+ ptr += 7;
+ while ((ptr[0] != '\0') && g_ascii_isspace(ptr[0])) ptr++;
+ if (ptr[0] == '\0') break;
+
+ if (!_parse_color (&s->stroke, ptr))
+ s->stroke = DIA_SVG_COLOUR_NONE;
+ } else if (!strncmp("stroke-opacity:", ptr, 15)) {
+ ptr += 15;
+ s->stroke_opacity = g_ascii_strtod(ptr, &ptr);
+ } else if (!strncmp("fill:", ptr, 5)) {
+ ptr += 5;
while (ptr[0] != '\0' && g_ascii_isspace(ptr[0])) ptr++;
if (ptr[0] == '\0') break;
- if (!strncmp("font-family:", ptr, 12)) {
- ptr += 12;
- while ((ptr[0] != '\0') && g_ascii_isspace(ptr[0])) ptr++;
- i = 0; over = FALSE;
- while (ptr[0] != '\0' && ptr[0] != ';' && !over) {
- if (i < FONT_NAME_LENGTH_MAX) {
- temp[i] = ptr[0];
- } else over = TRUE;
- i++;
- ptr++;
- }
- temp[i] = '\0';
+ if (!_parse_color (&s->fill, ptr))
+ s->fill = DIA_SVG_COLOUR_NONE;
+ } else if (!strncmp("fill-opacity:", ptr, 13)) {
+ ptr += 13;
+ s->fill_opacity = g_ascii_strtod(ptr, &ptr);
+ } else if (!strncmp("opacity", ptr, 7)) {
+ real opacity;
+ ptr += 7;
+ opacity = g_ascii_strtod(ptr, &ptr);
+ /* multiplicative effect of opacity */
+ s->stroke_opacity *= opacity;
+ s->fill_opacity *= opacity;
+ } else if (!strncmp("stroke-linecap:", ptr, 15)) {
+ ptr += 15;
+ while (ptr[0] != '\0' && g_ascii_isspace(ptr[0])) ptr++;
+ if (ptr[0] == '\0') break;
- if (!over) {
- if (strcmp (temp, "sanserif") == 0 || strcmp (temp, "sans-serif") == 0)
- family = g_strdup ("sans"); /* special name adaption */
- else
- family = g_strdup(temp);
- }
- } else if (!strncmp("font-weight:", ptr, 12)) {
- ptr += 12;
- while ((ptr[0] != '\0') && g_ascii_isspace(ptr[0])) ptr++;
- i = 0; over = FALSE;
- while (ptr[0] != '\0' && ptr[0] != ';' && !over) {
- if (i < FONT_NAME_LENGTH_MAX) {
- temp[i] = ptr[0];
- } else over = TRUE;
- i++;
- ptr++;
- }
- temp[i] = '\0';
-
- if (!over) weight = g_strdup(temp);
- } else if (!strncmp("font-style:", ptr, 11)) {
- ptr += 11;
- while ((ptr[0] != '\0') && g_ascii_isspace(ptr[0])) ptr++;
- i = 0; over = FALSE;
- while (ptr[0] != '\0' && ptr[0] != ';' && !over) {
- if (i < FONT_NAME_LENGTH_MAX) {
- temp[i] = ptr[0];
- } else over = TRUE;
- i++;
- ptr++;
- }
- temp[i] = '\0';
-
- if (!over) style = g_strdup(temp);
- } else if (!strncmp("font-size:", ptr, 10)) {
- ptr += 10;
- while ((ptr[0] != '\0') && g_ascii_isspace(ptr[0])) ptr++;
- i = 0; over = FALSE;
- while (ptr[0] != '\0' && ptr[0] != ';' && !over) {
- if (i < FONT_NAME_LENGTH_MAX) {
- temp[i] = ptr[0];
- } else over = TRUE;
- i++;
- ptr++;
- }
- temp[i] = '\0';
+ if (!strncmp(ptr, "butt", 4))
+ s->linecap = LINECAPS_BUTT;
+ else if (!strncmp(ptr, "round", 5))
+ s->linecap = LINECAPS_ROUND;
+ else if (!strncmp(ptr, "square", 6) || !strncmp(ptr, "projecting", 10))
+ s->linecap = LINECAPS_PROJECTING;
+ else if (!strncmp(ptr, "default", 7))
+ s->linecap = DIA_SVG_LINECAPS_DEFAULT;
+ } else if (!strncmp("stroke-linejoin:", ptr, 16)) {
+ ptr += 16;
+ while (ptr[0] != '\0' && g_ascii_isspace(ptr[0])) ptr++;
+ if (ptr[0] == '\0') break;
- if (!over) {
- s->font_height = g_ascii_strtod(temp, NULL);
- if (user_scale > 0)
- s->font_height /= user_scale;
- }
- } else if (!strncmp("text-anchor:", ptr, 12)) {
- ptr += 12;
- while ((ptr[0] != '\0') && g_ascii_isspace(ptr[0])) ptr++;
- if (!strncmp(ptr, "start", 5))
- s->alignment = ALIGN_LEFT;
- else if (!strncmp(ptr, "end", 3))
- s->alignment = ALIGN_RIGHT;
- else if (!strncmp(ptr, "middle", 6))
- s->alignment = ALIGN_CENTER;
-
- } else if (!strncmp("stroke-width:", ptr, 13)) {
- ptr += 13;
- s->line_width = g_ascii_strtod(ptr, &ptr);
- if (user_scale > 0)
- s->line_width /= user_scale;
- } else if (!strncmp("stroke:", ptr, 7)) {
- ptr += 7;
- while ((ptr[0] != '\0') && g_ascii_isspace(ptr[0])) ptr++;
- if (ptr[0] == '\0') break;
-
- if (!_parse_color (&s->stroke, ptr))
- s->stroke = DIA_SVG_COLOUR_NONE;
- } else if (!strncmp("stroke-opacity:", ptr, 15)) {
- ptr += 15;
- s->stroke_opacity = g_ascii_strtod(ptr, &ptr);
- } else if (!strncmp("fill:", ptr, 5)) {
- ptr += 5;
- while (ptr[0] != '\0' && g_ascii_isspace(ptr[0])) ptr++;
- if (ptr[0] == '\0') break;
-
- if (!_parse_color (&s->fill, ptr))
- s->fill = DIA_SVG_COLOUR_NONE;
- } else if (!strncmp("fill-opacity:", ptr, 13)) {
- ptr += 13;
- s->fill_opacity = g_ascii_strtod(ptr, &ptr);
- } else if (!strncmp("opacity", ptr, 7)) {
- real opacity;
- ptr += 7;
- opacity = g_ascii_strtod(ptr, &ptr);
- /* multiplicative effect of opacity */
- s->stroke_opacity *= opacity;
- s->fill_opacity *= opacity;
- } else if (!strncmp("stroke-linecap:", ptr, 15)) {
- ptr += 15;
- while (ptr[0] != '\0' && g_ascii_isspace(ptr[0])) ptr++;
- if (ptr[0] == '\0') break;
-
- if (!strncmp(ptr, "butt", 4))
- s->linecap = LINECAPS_BUTT;
- else if (!strncmp(ptr, "round", 5))
- s->linecap = LINECAPS_ROUND;
- else if (!strncmp(ptr, "square", 6) || !strncmp(ptr, "projecting", 10))
- s->linecap = LINECAPS_PROJECTING;
- else if (!strncmp(ptr, "default", 7))
- s->linecap = DIA_SVG_LINECAPS_DEFAULT;
- } else if (!strncmp("stroke-linejoin:", ptr, 16)) {
- ptr += 16;
- while (ptr[0] != '\0' && g_ascii_isspace(ptr[0])) ptr++;
- if (ptr[0] == '\0') break;
-
- if (!strncmp(ptr, "miter", 5))
- s->linejoin = LINEJOIN_MITER;
- else if (!strncmp(ptr, "round", 5))
- s->linejoin = LINEJOIN_ROUND;
- else if (!strncmp(ptr, "bevel", 5))
- s->linejoin = LINEJOIN_BEVEL;
- else if (!strncmp(ptr, "default", 7))
- s->linejoin = DIA_SVG_LINEJOIN_DEFAULT;
- } else if (!strncmp("stroke-pattern:", ptr, 15)) {
- ptr += 15;
- while (ptr[0] != '\0' && g_ascii_isspace(ptr[0])) ptr++;
- if (ptr[0] == '\0') break;
-
- if (!strncmp(ptr, "solid", 5))
- s->linestyle = LINESTYLE_SOLID;
- else if (!strncmp(ptr, "dashed", 6))
- s->linestyle = LINESTYLE_DASHED;
- else if (!strncmp(ptr, "dash-dot", 8))
- s->linestyle = LINESTYLE_DASH_DOT;
- else if (!strncmp(ptr, "dash-dot-dot", 12))
- s->linestyle = LINESTYLE_DASH_DOT_DOT;
- else if (!strncmp(ptr, "dotted", 6))
- s->linestyle = LINESTYLE_DOTTED;
- else if (!strncmp(ptr, "default", 7))
- s->linestyle = DIA_SVG_LINESTYLE_DEFAULT;
- /* XXX: deal with a real pattern */
- } else if (!strncmp("stroke-dashlength:", ptr, 18)) {
- ptr += 18;
- while (ptr[0] != '\0' && g_ascii_isspace(ptr[0])) ptr++;
- if (ptr[0] == '\0') break;
-
- if (!strncmp(ptr, "default", 7))
- s->dashlength = 1.0;
- else {
- s->dashlength = g_ascii_strtod(ptr, &ptr);
- if (user_scale > 0)
- s->dashlength /= user_scale;
- }
- } else if (!strncmp("stroke-dasharray:", ptr, 17)) {
+ if (!strncmp(ptr, "miter", 5))
+ s->linejoin = LINEJOIN_MITER;
+ else if (!strncmp(ptr, "round", 5))
+ s->linejoin = LINEJOIN_ROUND;
+ else if (!strncmp(ptr, "bevel", 5))
+ s->linejoin = LINEJOIN_BEVEL;
+ else if (!strncmp(ptr, "default", 7))
+ s->linejoin = DIA_SVG_LINEJOIN_DEFAULT;
+ } else if (!strncmp("stroke-pattern:", ptr, 15)) {
+ ptr += 15;
+ while (ptr[0] != '\0' && g_ascii_isspace(ptr[0])) ptr++;
+ if (ptr[0] == '\0') break;
+
+ if (!strncmp(ptr, "solid", 5))
+ s->linestyle = LINESTYLE_SOLID;
+ else if (!strncmp(ptr, "dashed", 6))
s->linestyle = LINESTYLE_DASHED;
- ptr += 17;
- while (ptr[0] != '\0' && g_ascii_isspace(ptr[0])) ptr++;
- if (ptr[0] == '\0') break;
+ else if (!strncmp(ptr, "dash-dot", 8))
+ s->linestyle = LINESTYLE_DASH_DOT;
+ else if (!strncmp(ptr, "dash-dot-dot", 12))
+ s->linestyle = LINESTYLE_DASH_DOT_DOT;
+ else if (!strncmp(ptr, "dotted", 6))
+ s->linestyle = LINESTYLE_DOTTED;
+ else if (!strncmp(ptr, "default", 7))
+ s->linestyle = DIA_SVG_LINESTYLE_DEFAULT;
+ /* XXX: deal with a real pattern */
+ } else if (!strncmp("stroke-dashlength:", ptr, 18)) {
+ ptr += 18;
+ while (ptr[0] != '\0' && g_ascii_isspace(ptr[0])) ptr++;
+ if (ptr[0] == '\0') break;
- if (!strncmp(ptr, "default", 7))
- s->dashlength = 1.0;
- else
- _parse_dasharray (s, user_scale, ptr, &ptr);
+ if (!strncmp(ptr, "default", 7))
+ s->dashlength = 1.0;
+ else {
+ s->dashlength = g_ascii_strtod(ptr, &ptr);
+ if (user_scale > 0)
+ s->dashlength /= user_scale;
}
+ } else if (!strncmp("stroke-dasharray:", ptr, 17)) {
+ s->linestyle = LINESTYLE_DASHED;
+ ptr += 17;
+ while (ptr[0] != '\0' && g_ascii_isspace(ptr[0])) ptr++;
+ if (ptr[0] == '\0') break;
+
+ if (!strncmp(ptr, "default", 7))
+ s->dashlength = 1.0;
+ else
+ _parse_dasharray (s, user_scale, ptr, &ptr);
+ }
+
+ /* skip up to the next attribute */
+ while (ptr[0] != '\0' && ptr[0] != ';' && ptr[0] != '\n') ptr++;
+ if (ptr[0] != '\0') ptr++;
+ }
- /* skip up to the next attribute */
- while (ptr[0] != '\0' && ptr[0] != ';' && ptr[0] != '\n') ptr++;
- if (ptr[0] != '\0') ptr++;
+ if (family || style || weight) {
+ if (s->font)
+ dia_font_unref (s->font);
+ /* given font_height is bogus, especially if not given at all
+ * or without unit ... see bug 665648 about invalid CSS
+ */
+ s->font = dia_font_new_from_style(DIA_FONT_SANS, s->font_height > 0 ? s->font_height : 1.0);
+ if (family) {
+ dia_font_set_any_family(s->font,family);
+ g_free(family);
+ }
+ if (style) {
+ dia_font_set_slant_from_string(s->font,style);
+ g_free(style);
}
+ if (weight) {
+ dia_font_set_weight_from_string(s->font,weight);
+ g_free(weight);
+ }
+ }
+}
+
+
+/*
+ * \brief Parse SVG style properties
+ * This function not only parses the style attribute of the given node
+ * it also extracts some of the style properties directly.
+ * @param node An XML node to parse a style from.
+ * @param s The SVG style object to fill out. This should previously be
+ * initialized to some default values.
+ * @param user_scale, if >0 scalable values (font-size, stroke-width, ...)
+ * are divided by this, otherwise ignored
+ * \ingroup DiaSvg
+ */
+void
+dia_svg_parse_style(xmlNodePtr node, DiaSvgStyle *s, real user_scale)
+{
+ xmlChar *str;
+ gchar temp[FONT_NAME_LENGTH_MAX+1]; /* font-family names will be limited to 40 characters */
+ int i = 0;
+ gboolean over = FALSE;
+ char *family = NULL, *style = NULL, *weight = NULL;
+
+ str = xmlGetProp(node, (const xmlChar *)"style");
+
+ if (str) {
+ dia_svg_parse_style_string (s, user_scale, (gchar *)str);
xmlFree(str);
}
@@ -567,27 +612,6 @@ dia_svg_parse_style(xmlNodePtr node, DiaSvgStyle *s, real user_scale)
xmlFree(str);
}
-
- if (family || style || weight) {
- if (s->font)
- dia_font_unref (s->font);
- /* given font_height is bogus, especially if not given at all
- * or without unit ... see bug 665648 about invalid CSS
- */
- s->font = dia_font_new_from_style(DIA_FONT_SANS, s->font_height > 0 ? s->font_height : 1.0);
- if (family) {
- dia_font_set_any_family(s->font,family);
- g_free(family);
- }
- if (style) {
- dia_font_set_slant_from_string(s->font,style);
- g_free(style);
- }
- if (weight) {
- dia_font_set_weight_from_string(s->font,weight);
- g_free(weight);
- }
- }
}
/*!
diff --git a/lib/dia_svg.h b/lib/dia_svg.h
index fa89d6e..05a9a47 100644
--- a/lib/dia_svg.h
+++ b/lib/dia_svg.h
@@ -62,6 +62,7 @@ void dia_svg_style_init (DiaSvgStyle *gs, DiaSvgStyle *parent_style);
void dia_svg_style_copy (DiaSvgStyle *dest, DiaSvgStyle *src);
gboolean dia_svg_parse_color(const gchar *str, Color *color);
void dia_svg_parse_style(xmlNodePtr node, DiaSvgStyle *s, real user_scale);
+void dia_svg_parse_style_string (DiaSvgStyle *s, real user_scale, const gchar *str);
/* parse the svg sub format for pathes int an array of BezPoint */
gboolean dia_svg_parse_path(GArray *points, const gchar *path_str, gchar **unparsed,
gboolean *closed, Point *current_point);
diff --git a/lib/libdia.def b/lib/libdia.def
index e5e862d..1d2f9fc 100644
--- a/lib/libdia.def
+++ b/lib/libdia.def
@@ -367,6 +367,7 @@ EXPORTS
dia_svg_style_copy
dia_svg_parse_color
dia_svg_parse_style
+ dia_svg_parse_style_string
dia_svg_parse_path
dia_svg_parse_transform
dia_svg_from_matrix
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]