[dia] svg: activate viewBox interpretation again on import
- From: Hans Breuer <hans src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [dia] svg: activate viewBox interpretation again on import
- Date: Sun, 1 Sep 2013 13:12:30 +0000 (UTC)
commit 4e9c7a06758a361df2353630cd41d160563c0f39
Author: Hans Breuer <hans breuer org>
Date: Sun Aug 25 18:48:02 2013 +0200
svg: activate viewBox interpretation again on import
Now it is also applied on non-root svg elements defining a local
viewport. It is only used if we are _not_ importing shapes,
restricting otherwise was a mistake when shape import was added.
With the current shape set it was triggered very seldom , because
there are only 14 out of >700 shapes defining width, height and
viewBox.
plug-ins/svg/svg-import.c | 130 ++++++++++++++++++++++++++++++++------------
1 files changed, 94 insertions(+), 36 deletions(-)
---
diff --git a/plug-ins/svg/svg-import.c b/plug-ins/svg/svg-import.c
index 836b460..961aa69 100644
--- a/plug-ins/svg/svg-import.c
+++ b/plug-ins/svg/svg-import.c
@@ -1155,6 +1155,64 @@ add_def (gpointer data,
}
/*!
+ * \brief Parse and set global user scale
+ *
+ * This function is modifying the global user scale. If it's effect
+ * should be temporary user_scale needs to be saved before.
+ *
+ * @param node element containing the viewBox attribute
+ * @param mat out parameter for optional matrix transform
+ */
+static void
+_node_read_viewbox (xmlNodePtr root, DiaMatrix **mat)
+{
+ xmlChar *swidth = xmlGetProp(root, (const xmlChar *)"width");
+ xmlChar *sheight = xmlGetProp(root, (const xmlChar *)"height");
+ xmlChar *sviewbox = xmlGetProp(root, (const xmlChar *)"viewBox");
+
+ if (swidth && sheight && sviewbox) {
+ real width = get_value_as_cm ((const char *)swidth, NULL);
+ real height = get_value_as_cm ((const char *)sheight, NULL);
+ gint x1 = 0, y1 = 0, x2 = 0, y2 = 0;
+
+ if (4 == sscanf ((const char *)sviewbox, "%d %d %d %d", &x1, &y1, &x2, &y2)) {
+ real xs, ys;
+ g_debug ("viewBox(%d %d %d %d) = (%f,%f)\n", x1, y1, x2, y2, width, height);
+ /* some basic sanity check */
+ if (x2 > x1 && y2 > y1 && width > 0 && height > 0) {
+ xs = ((real)x2 - x1) / width;
+ ys = ((real)y2 - y1) / height;
+ /* plausibility check, strictly speaking these are not required to be the same
+ * /or/ are they and Dia is writting a bogus viewBox?
+ */
+ if (fabs((fabs (xs/ys) - 1.0) < 0.1) && fabs((fabs (ys/xs) - 1.0) < 0.1)) {
+ user_scale = xs;
+ g_debug ("viewBox(%d %d %d %d) scaling (%f,%f) -> %f\n", x1, y1, x2, y2, xs, ys, user_scale);
+ } else {
+ /* the bigger the scale the smaller the objects */
+ user_scale = MAX(xs, ys);
+#if 0 /* need to think about - might fly with preserveAspectRatio handling */
+ if (mat) {
+ DiaMatrix *m = g_new0 (DiaMatrix, 1);
+ m->xx = xs > ys ? xs/ys : 1.0;
+ m->yy = ys > xs ? ys/xs : 1.0;
+ *mat = m;
+ }
+#endif
+ }
+ }
+ }
+ }
+
+ if (swidth)
+ xmlFree (swidth);
+ if (sheight)
+ xmlFree (sheight);
+ if (sviewbox)
+ xmlFree (sviewbox);
+}
+
+/*!
* Fill a GList* with objects which is to be put in a
* diagram or a group by the caller.
* Can be called recusively to allow groups in groups.
@@ -1358,6 +1416,40 @@ read_items (xmlNodePtr startnode,
} else if(!xmlStrcmp(node->name, (const xmlChar *)"pattern")) {
/* Patterns could be considered as groups, too But Dia does not
* have the facility to apply them (yet?). */
+ } else if(!xmlStrcmp(node->name, (const xmlChar *)"svg")) {
+ /* A subsequent svg node is truned into a group to simplify offseting
+ * it and maybe later honor additional attributes like viewBox, width,
+ * height and preserveAspectRatio with clipping and scaling
+ */
+ GList *moreitems;
+ Point pos;
+ /* put the global user scale on the stack */
+ real user_scale_prev = user_scale;
+ DiaMatrix *matrix = NULL;
+
+ _node_read_viewbox (node, &matrix);
+
+ pos.x = _node_get_real (node, "x", 0.0);
+ pos.y = _node_get_real (node, "y", 0.0);
+ moreitems = read_items (node->xmlChildrenNode, parent_gs, defs_ht, style_ht, filename_svg, ctx);
+ if (moreitems) {
+ DiaObject *group;
+
+ if (matrix) /* eats list and matrix */
+ group = group_create_with_matrix (moreitems, matrix);
+ else
+ group = group_create (moreitems);
+ /* remember for meta */
+ obj = group;
+ if (pos.x != 0.0 || pos.y != 0.0) {
+ pos.x += obj->position.x;
+ pos.y += obj->position.y;
+ obj->ops->move (obj, &pos);
+ }
+ items = g_list_append (items, group);
+ }
+ /* restore scale */
+ user_scale = user_scale_prev;
} else {
/* everything else is treated like a group _without grouping_, i.e. we dive
* into unknown stuff. This allows to import stuff generated by 'dot' with
@@ -1570,42 +1662,8 @@ import_svg (xmlDocPtr doc, DiagramData *dia,
user_scale = DEFAULT_SVG_SCALE;
/* if the svg root element contains width, height and viewBox calculate our user scale from it */
- if (shape_root)
- {
- xmlChar *swidth = xmlGetProp(root, (const xmlChar *)"width");
- xmlChar *sheight = xmlGetProp(root, (const xmlChar *)"height");
- xmlChar *sviewbox = xmlGetProp(root, (const xmlChar *)"viewBox");
-
- if (swidth && sheight && sviewbox) {
- real width = get_value_as_cm ((const char *)swidth, NULL);
- real height = get_value_as_cm ((const char *)sheight, NULL);
- gint x1 = 0, y1 = 0, x2 = 0, y2 = 0;
-
- if (4 == sscanf ((const char *)sviewbox, "%d %d %d %d", &x1, &y1, &x2, &y2)) {
- real xs, ys;
- g_debug ("viewBox(%d %d %d %d) = (%f,%f)\n", x1, y1, x2, y2, width, height);
- /* some basic sanity check */
- if (x2 > x1 && y2 > y1 && width > 0 && height > 0) {
- xs = ((real)x2 - x1) / width;
- ys = ((real)y2 - y1) / height;
- /* plausibility check, strictly speaking these are not required to be the same
- * /or/ are they and Dia is writting a bogus viewBox?
- */
- if (fabs((fabs (xs/ys) - 1.0) < 0.1)) {
- user_scale = xs;
- g_debug ("viewBox(%d %d %d %d) scaling (%f,%f) -> %f\n", x1, y1, x2, y2, xs, ys, user_scale);
- }
- }
- }
- }
-
- if (swidth)
- xmlFree (swidth);
- if (sheight)
- xmlFree (sheight);
- if (sviewbox)
- xmlFree (sviewbox);
- }
+ if (!shape_root)
+ _node_read_viewbox (root, NULL);
{
GHashTable *defs_ht = g_hash_table_new (g_str_hash, g_str_equal);
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]