[dia] svg: parse font-* and text-* also as attributes
- From: Hans Breuer <hans src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [dia] svg: parse font-* and text-* also as attributes
- Date: Sun, 4 Aug 2013 12:44:56 +0000 (UTC)
commit e785c0a1dd6684a6f9f02409fa2f4a307f32d847
Author: Hans Breuer <hans breuer org>
Date: Sun Aug 4 11:25:10 2013 +0200
svg: parse font-* and text-* also as attributes
Small code restructuring to support more attributes with
only small code duplication. Related changes to the order
of <text/> vs. <tspan/> style parsing and some more matrix
usage when interpreting <text/>.
lib/dia_svg.c | 134 +++++++++++++++++++++++++++-----------------
plug-ins/svg/svg-import.c | 19 ++++---
2 files changed, 93 insertions(+), 60 deletions(-)
---
diff --git a/lib/dia_svg.c b/lib/dia_svg.c
index 5c3df71..2cab789 100644
--- a/lib/dia_svg.c
+++ b/lib/dia_svg.c
@@ -333,7 +333,66 @@ _parse_linecap (DiaSvgStyle *s, const char *val)
s->linecap = DIA_SVG_LINECAPS_DEFAULT;
}
-/*
+/*!
+ * \brief Given any of the three parameters adjust the font
+ * @param s Dia SVG style to modify
+ * @param family comma-separated list of family names
+ * @param style font slant string
+ * @param weight font weight string
+ */
+static void
+_style_adjust_font (DiaSvgStyle *s, const char *family, const char *style, const char *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) {
+ /* SVG allows a list of families here, also there is some stange formatting
+ * seen, like 'Arial'. If the given family name can not be resolved by
+ * Pango it complaints loudly with g_warning().
+ */
+ gchar **families = g_strsplit(family, ",", -1);
+ int i = 0;
+ gboolean found = FALSE;
+ while (!found && families[i]) {
+ const gchar *chomped = g_strchomp (g_strdelimit(families[i], "'", ' '));
+ PangoFont *loaded;
+ dia_font_set_any_family(s->font, chomped);
+ loaded = pango_context_load_font(dia_font_get_context(),
+ dia_font_get_description(s->font));
+ if (loaded) {
+ g_object_unref(loaded);
+ found = TRUE;
+ }
+ ++i;
+ }
+ if (!found)
+ dia_font_set_any_family(s->font, "sans");
+ g_strfreev(families);
+ }
+ if (style) {
+ dia_font_set_slant_from_string(s->font,style);
+ }
+ if (weight) {
+ dia_font_set_weight_from_string(s->font,weight);
+ }
+}
+
+static void
+_parse_text_align(DiaSvgStyle *s, const gchar *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;
+}
+
+/*!
* \brief Parse SVG/CSS style string
*
* Parse as much information from the given style string as Dia can handle.
@@ -426,13 +485,8 @@ dia_svg_parse_style_string (DiaSvgStyle *s, real user_scale, const gchar *str)
} 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;
+ _parse_text_align(s, ptr);
} else if (!strncmp("stroke-width:", ptr, 13)) {
ptr += 13;
s->line_width = g_ascii_strtod(ptr, &ptr);
@@ -525,45 +579,11 @@ dia_svg_parse_style_string (DiaSvgStyle *s, real user_scale, const gchar *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) {
- /* SVG allows a list of families here, also there is some stange formatting
- * seen, like 'Arial'. If the given family name can not be resolved by
- * Pango it complaints loudly with g_warning().
- */
- gchar **families = g_strsplit(family, ",", -1);
- int i = 0;
- gboolean found = FALSE;
- while (!found && families[i]) {
- const gchar *chomped = g_strchomp (g_strdelimit(families[i], "'", ' '));
- PangoFont *loaded;
- dia_font_set_any_family(s->font, chomped);
- loaded = pango_context_load_font(dia_font_get_context(),
- dia_font_get_description(s->font));
- if (loaded) {
- g_object_unref(loaded);
- found = TRUE;
- }
- ++i;
- }
- if (!found)
- dia_font_set_any_family(s->font, "sans");
- g_strfreev(families);
- 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);
- }
+ _style_adjust_font (s, family, style, weight);
+
+ g_free(family);
+ g_free(style);
+ g_free(weight);
}
}
@@ -661,14 +681,24 @@ dia_svg_parse_style(xmlNodePtr node, DiaSvgStyle *s, real user_scale)
}
str = xmlGetProp(node, (const xmlChar *)"text-anchor");
if (str) {
- if (xmlStrcmp(str, (const xmlChar*)"middle") == 0)
- s->alignment = ALIGN_CENTER;
- else if (xmlStrcmp(str, (const xmlChar*)"end") == 0)
- s->alignment = ALIGN_RIGHT;
- else if (xmlStrcmp(str, (const xmlChar*)"start") == 0)
- s->alignment = ALIGN_LEFT;
+ _parse_text_align (s, (const gchar*)str);
xmlFree(str);
}
+ {
+ xmlChar *family = xmlGetProp(node, (const xmlChar *)"font-family");
+ xmlChar *slant = xmlGetProp(node, (const xmlChar *)"font-style");
+ xmlChar *weight = xmlGetProp(node, (const xmlChar *)"font-weight");
+ if (family || slant || weight) {
+ _style_adjust_font (s, (gchar *)family, (gchar *)slant, (gchar *)weight);
+
+ if (family)
+ xmlFree(family);
+ if (slant)
+ xmlFree(slant);
+ if (weight)
+ xmlFree(weight);
+ }
+ }
}
/*!
diff --git a/plug-ins/svg/svg-import.c b/plug-ins/svg/svg-import.c
index ea59d8f..a64ee2f 100644
--- a/plug-ins/svg/svg-import.c
+++ b/plug-ins/svg/svg-import.c
@@ -651,6 +651,9 @@ read_text_svg(xmlNodePtr node, DiaSvgStyle *parent_style, GHashTable *style_ht,
xmlFree(str);
}
+ /* parse from <text/> before looking at the first <tspan/> */
+ dia_svg_parse_style(node, gs, user_scale);
+
{
xmlNode *tspan = node->children;
GString *paragraph = g_string_sized_new(512);
@@ -659,8 +662,8 @@ read_text_svg(xmlNodePtr node, DiaSvgStyle *parent_style, GHashTable *style_ht,
xmlChar *line = xmlNodeGetContent(tspan);
if (any_tspan) /* every other line needs separation */
g_string_append(paragraph, "\n");
- else /* only first time */
- dia_svg_parse_style(tspan, gs, user_scale);
+ else /* only first time - with bogus, experimental division of user scale */
+ dia_svg_parse_style(tspan, gs, matrix ? user_scale / matrix->yy : user_scale);
g_string_append(paragraph, (gchar*)line);
xmlFree(line);
any_tspan = TRUE;
@@ -675,11 +678,8 @@ read_text_svg(xmlNodePtr node, DiaSvgStyle *parent_style, GHashTable *style_ht,
str = xmlNodeGetContent(node);
}
if(str || multiline) {
- if (matrix) {
- /* TODO: transform the text, too - when it is supported */
+ if (matrix)
transform_point (&point, matrix);
- g_free (matrix);
- }
new_obj = otype->ops->create(&point, otype->default_user_data,
&h1, &h2);
list = g_list_append (list, new_obj);
@@ -687,7 +687,6 @@ read_text_svg(xmlNodePtr node, DiaSvgStyle *parent_style, GHashTable *style_ht,
props = prop_list_from_descs(svg_text_prop_descs, pdtpp_true);
g_assert(props->len == 1);
- dia_svg_parse_style(node, gs, user_scale);
if(gs->font == NULL) {
gs->font = dia_font_new_from_legacy_name("Courier");
}
@@ -704,7 +703,9 @@ read_text_svg(xmlNodePtr node, DiaSvgStyle *parent_style, GHashTable *style_ht,
if (font_height > 0.0) {
/* font-size should be the line-height according to SVG spec,
* but see node_set_text_style() - round-trip first */
- real font_scale = dia_font_get_height (prop->attr.font) / dia_font_get_size (prop->attr.font);
+ real font_scale = dia_font_get_height (prop->attr.font) / dia_font_get_size (prop->attr.font);
+ if (matrix) /* ToDo: more text transform */
+ font_scale /= matrix->yy;
prop->attr.height = font_height * font_scale;
} else
prop->attr.height = gs->font_height;
@@ -729,10 +730,12 @@ read_text_svg(xmlNodePtr node, DiaSvgStyle *parent_style, GHashTable *style_ht,
}
new_obj->ops->set_props(new_obj, props);
prop_list_free(props);
+
}
if (gs->font)
dia_font_unref (gs->font);
g_free(gs);
+ g_free(matrix);
return list;
}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]