[dia] Bug 611299 - prefer relative image path for svg/shape export
- From: Hans Breuer <hans src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [dia] Bug 611299 - prefer relative image path for svg/shape export
- Date: Mon, 2 Aug 2010 18:16:14 +0000 (UTC)
commit d461bd21220f0ae2ec5350685ef40fe2c7b87b52
Author: Hans Breuer <hans breuer org>
Date: Sun Aug 1 20:43:06 2010 +0200
Bug 611299 - prefer relative image path for svg/shape export
lib/dia_dirs.[hc] : dia_relativize_filename() to be reused elsewhere
lib/libdia.def : export it
lib/diasvgrenderer.c : if an included image is in the same directory as the main file use a relative path
plug-ins/svg/svg-import.c : support relative image path, too.
lib/dia_dirs.c | 31 +++++++++++++++++++++++++++++++
lib/dia_dirs.h | 1 +
lib/diasvgrenderer.c | 12 ++++++++----
lib/libdia.def | 1 +
plug-ins/svg/svg-import.c | 22 ++++++++++++++++------
5 files changed, 57 insertions(+), 10 deletions(-)
---
diff --git a/lib/dia_dirs.c b/lib/dia_dirs.c
index 4111b14..7fe4cb0 100644
--- a/lib/dia_dirs.c
+++ b/lib/dia_dirs.c
@@ -263,3 +263,34 @@ dia_get_absolute_filename (const gchar *filename)
g_free(fullname);
return canonical;
}
+
+/** Calculate a filename relative to the basepath of a master file
+ * @param master The main filename
+ * @param slave A filename to become relative to the master
+ * @return Relative filename or NULL if there is no common base path
+ */
+gchar *
+dia_relativize_filename (const gchar *master, const gchar *slave)
+{
+ gchar *bp1;
+ gchar *bp2;
+ gchar * rel = NULL;
+
+ if (!g_path_is_absolute (master) || !g_path_is_absolute (slave))
+ return NULL;
+
+ bp1 = g_path_get_dirname (master);
+ bp2 = g_path_get_dirname (slave);
+
+ if (g_str_has_prefix (bp1, bp2)) {
+ gchar *p;
+ rel = g_strdup (slave + strlen (bp1) + 1);
+ /* flip backslashes */
+ for (p = rel; *p != '\0'; p++)
+ if (*p == '\\') *p = '/';
+ }
+ g_free (bp1);
+ g_free (bp2);
+
+ return rel;
+}
\ No newline at end of file
diff --git a/lib/dia_dirs.h b/lib/dia_dirs.h
index 355a535..2ca8154 100644
--- a/lib/dia_dirs.h
+++ b/lib/dia_dirs.h
@@ -32,6 +32,7 @@ gchar *dia_get_lib_directory (const gchar* subdir);
gchar *dia_config_filename (const gchar* file);
gboolean dia_config_ensure_dir (const gchar* filename);
gchar *dia_get_absolute_filename (const gchar *filename);
+gchar *dia_relativize_filename (const gchar *master, const gchar *slave);
gchar *dia_get_canonical_path (const gchar *path);
const gchar *dia_message_filename (const gchar *filename);
diff --git a/lib/diasvgrenderer.c b/lib/diasvgrenderer.c
index 94fd431..068a6ad 100644
--- a/lib/diasvgrenderer.c
+++ b/lib/diasvgrenderer.c
@@ -44,6 +44,7 @@
#include "message.h"
#include "dia_xml_libxml.h"
#include "dia_image.h"
+#include "dia_dirs.h"
#include "diasvgrenderer.h"
#include "textline.h"
@@ -730,7 +731,7 @@ draw_image(DiaRenderer *self,
DiaSvgRenderer *renderer = DIA_SVG_RENDERER (self);
xmlNodePtr node;
gchar d_buf[DTOSTR_BUF_SIZE];
- gchar *uri;
+ gchar *uri = NULL;
node = xmlNewChild(renderer->root, NULL, (const xmlChar *)"image", NULL);
@@ -742,9 +743,12 @@ draw_image(DiaRenderer *self,
xmlSetProp(node, (const xmlChar *)"width", (xmlChar *) d_buf);
dia_svg_dtostr(d_buf, height);
xmlSetProp(node, (const xmlChar *)"height", (xmlChar *) d_buf);
-
- uri = g_filename_to_uri(dia_image_filename(image), NULL, NULL);
- if (uri)
+
+ /* if the image file location is relative to the SVG file's store
+ * a relative path */
+ if ((uri = dia_relativize_filename (renderer->filename, dia_image_filename(image))) != NULL)
+ xmlSetProp(node, (const xmlChar *)"xlink:href", (xmlChar *) uri);
+ else if ((uri = g_filename_to_uri(dia_image_filename(image), NULL, NULL)) != NULL)
xmlSetProp(node, (const xmlChar *)"xlink:href", (xmlChar *) uri);
else /* not sure if this fallbach is better than nothing */
xmlSetProp(node, (const xmlChar *)"xlink:href", (xmlChar *) dia_image_filename(image));
diff --git a/lib/libdia.def b/lib/libdia.def
index 43fbfd3..5c77427 100644
--- a/lib/libdia.def
+++ b/lib/libdia.def
@@ -251,6 +251,7 @@ EXPORTS
dia_get_data_directory
dia_get_lib_directory
dia_get_absolute_filename
+ dia_relativize_filename
dia_get_canonical_path
dia_image_add_ref
diff --git a/plug-ins/svg/svg-import.c b/plug-ins/svg/svg-import.c
index b4d5397..eb1c032 100644
--- a/plug-ins/svg/svg-import.c
+++ b/plug-ins/svg/svg-import.c
@@ -668,7 +668,7 @@ read_rect_svg(xmlNodePtr node, DiaSvgStyle *parent_style, GList *list)
}
static GList *
-read_image_svg(xmlNodePtr node, DiaSvgStyle *parent_style, GList *list)
+read_image_svg(xmlNodePtr node, DiaSvgStyle *parent_style, GList *list, const gchar *filename_svg)
{
xmlChar *str;
real x = 0, y = 0, width = 0, height = 0;
@@ -702,6 +702,16 @@ read_image_svg(xmlNodePtr node, DiaSvgStyle *parent_style, GList *list)
str = xmlGetProp(node, (const xmlChar *)"href");
if (str) {
filename = g_filename_from_uri((gchar *) str, NULL, NULL);
+ if (!filename || !g_path_is_absolute (filename)) {
+ /* if image file path is relative use the main path */
+ gchar *dir = g_path_get_dirname (filename_svg);
+ gchar *absfn = g_build_path (G_DIR_SEPARATOR_S,
+ dir, filename ? filename : (gchar *)str, NULL);
+
+ g_free (filename);
+ g_free (dir);
+ filename = absfn;
+ }
xmlFree(str);
}
new_obj = create_standard_image(x, y, width, height, filename ? filename : "<broken>");
@@ -717,7 +727,7 @@ read_image_svg(xmlNodePtr node, DiaSvgStyle *parent_style, GList *list)
* Can be called recusively to allow groups in groups.
*/
static GList*
-read_items (xmlNodePtr startnode, DiaSvgStyle *parent_gs)
+read_items (xmlNodePtr startnode, DiaSvgStyle *parent_gs, const gchar *filename_svg)
{
xmlNodePtr node;
GList *items = NULL;
@@ -735,7 +745,7 @@ read_items (xmlNodePtr startnode, DiaSvgStyle *parent_gs)
dia_svg_style_init (group_gs, parent_gs);
dia_svg_parse_style (node, group_gs, user_scale);
- moreitems = read_items (node->xmlChildrenNode, group_gs);
+ moreitems = read_items (node->xmlChildrenNode, group_gs, filename_svg);
if (moreitems) {
DiaObject *group = group_create (moreitems);
@@ -762,13 +772,13 @@ read_items (xmlNodePtr startnode, DiaSvgStyle *parent_gs)
} else if(!xmlStrcmp(node->name, (const xmlChar *)"path")) {
items = read_path_svg(node, parent_gs, items);
} else if(!xmlStrcmp(node->name, (const xmlChar *)"image")) {
- items = read_image_svg(node, parent_gs, items);
+ items = read_image_svg(node, parent_gs, items, filename_svg);
} 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 links for the nodes */
GList *moreitems;
- moreitems = read_items (node->xmlChildrenNode, parent_gs);
+ moreitems = read_items (node->xmlChildrenNode, parent_gs, filename_svg);
if (moreitems) {
items = g_list_concat (items, moreitems);
}
@@ -867,7 +877,7 @@ import_svg(const gchar *filename, DiagramData *dia, void* user_data)
xmlFree (sviewbox);
}
- items = read_items (root->xmlChildrenNode, NULL);
+ items = read_items (root->xmlChildrenNode, NULL, filename);
for (item = items; item != NULL; item = g_list_next (item)) {
DiaObject *obj = (DiaObject *)item->data;
layer_add_object(dia->active_layer, obj);
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]