summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCaleb Michael Moore <cmoore@src.gnome.org>2004-11-17 05:30:14 +0000
committerCaleb Michael Moore <cmoore@src.gnome.org>2004-11-17 05:30:14 +0000
commitfbb6780313c44fd84bea4db3fdced77ce1a4bd1b (patch)
treeafa509ce0232929fb6bfb1075e9393e6b16367b5
parent03d4b91975aa49e75ecd2f419d9e04170a31a446 (diff)
downloadlibrsvg-fbb6780313c44fd84bea4db3fdced77ce1a4bd1b.tar.gz
interfile linking, w00t
-rw-r--r--ChangeLog4
-rw-r--r--rsvg-defs.c96
-rw-r--r--rsvg-defs.h3
-rw-r--r--rsvg-filter.c26
-rw-r--r--rsvg-mask.c52
-rw-r--r--rsvg-paint-server.c3
-rw-r--r--rsvg-shapes.c4
-rw-r--r--rsvg-shapes.h3
-rw-r--r--rsvg-text.c8
-rw-r--r--rsvg.c1
10 files changed, 148 insertions, 52 deletions
diff --git a/ChangeLog b/ChangeLog
index b4c9d71d..47a1cbd1 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,9 @@
2004-11-17 Caleb Moore <c.moore@student.unsw.edu.au>
+ * rsvg-defs.c: Interfile linking now implemented. Can't yet use gnome-vfs
+
+2004-11-17 Caleb Moore <c.moore@student.unsw.edu.au>
+
* everywhere: split RsvgHandle into two parts.
* rsvg.c: made the image be rendered when get_pixbuf is actually called.
* rsvg-text.c: Large number of text improvements: formatting, alignment, whitespace handling and styling.
diff --git a/rsvg-defs.c b/rsvg-defs.c
index 021ea8f6..dc1886f2 100644
--- a/rsvg-defs.c
+++ b/rsvg-defs.c
@@ -25,6 +25,9 @@
#include "config.h"
#include "rsvg-private.h"
#include "rsvg-defs.h"
+#include "rsvg-gz.h"
+#include "rsvg-styles.h"
+#include "rsvg-shapes.h"
#include <glib/ghash.h>
#include <glib/gmem.h>
@@ -34,6 +37,8 @@
struct _RsvgDefs {
GHashTable *hash;
GPtrArray *unnamed;
+ GHashTable *externs;
+ gchar * base_uri;
};
RsvgDefs *
@@ -42,15 +47,102 @@ rsvg_defs_new (void)
RsvgDefs *result = g_new (RsvgDefs, 1);
result->hash = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, NULL);
+ result->externs = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, NULL);
result->unnamed = g_ptr_array_new ();
-
+ result->base_uri = NULL;
+
return result;
}
+void
+rsvg_defs_set_base_uri (RsvgDefs * self, gchar * base_uri)
+{
+ self->base_uri = base_uri;
+}
+
+
+#define SVG_BUFFER_SIZE (1024 * 8)
+
+static int
+rsvg_defs_load_extern(const RsvgDefs *defs, const char *name)
+{
+ RsvgHandle * handle;
+ guchar chars[SVG_BUFFER_SIZE];
+ int result;
+ gchar * filename;
+ if (defs->base_uri)
+ filename = rsvg_get_file_path(name,defs->base_uri);
+ else
+ filename = g_strdup(name);
+
+ FILE *f = fopen (filename, "rb");
+ if (!f)
+ {
+ printf("file: %s not found\n", filename );
+ g_free(filename);
+ return 1;
+ }
+ result = fread (chars, 1, SVG_BUFFER_SIZE, f);
+
+ /* test for GZ marker */
+ if ((result >= 2) && (chars[0] == (guchar)0x1f) && (chars[1] == (guchar)0x8b))
+ handle = rsvg_handle_new_gz ();
+ else
+ handle = rsvg_handle_new ();
+
+ if (!handle)
+ {
+ g_free(filename);
+ return 1;
+ }
+
+ rsvg_handle_set_base_uri (handle, name);
+
+ rsvg_handle_write (handle, chars, result, NULL);
+
+ while (!feof(f) && ((result = fread (chars, 1, SVG_BUFFER_SIZE, f)) > 0))
+ rsvg_handle_write (handle, chars, result, NULL);
+
+ rsvg_handle_close (handle, NULL);
+
+ g_hash_table_insert (defs->externs, g_strdup (name), handle);
+
+ g_free(filename);
+ return 0;
+}
+
+static RsvgDefVal *
+rsvg_defs_extern_lookup (const RsvgDefs *defs, const char *filename, const char *name)
+{
+ RsvgHandle * file;
+ file = (RsvgHandle *)g_hash_table_lookup (defs->externs, filename);
+ if (file == NULL)
+ {
+ if (rsvg_defs_load_extern(defs, filename))
+ return NULL;
+ file = (RsvgHandle *)g_hash_table_lookup (defs->externs, filename);
+ }
+ return (RsvgDefVal *)g_hash_table_lookup (file->defs->hash, name);
+}
+
RsvgDefVal *
rsvg_defs_lookup (const RsvgDefs *defs, const char *name)
{
- return (RsvgDefVal *)g_hash_table_lookup (defs->hash, name);
+ char * hashpos;
+ hashpos = g_strrstr (name, "#");
+ if (!hashpos)
+ return NULL;
+ if (hashpos == name)
+ return (RsvgDefVal *)g_hash_table_lookup (defs->hash, name+1);
+ else
+ {
+ gchar ** splitbits;
+ RsvgDefVal * toreturn;
+ splitbits = g_strsplit (name, "#", 2);
+ toreturn = rsvg_defs_extern_lookup(defs, splitbits[0], splitbits[1]);
+ g_strfreev(splitbits);
+ return toreturn;
+ }
}
void
diff --git a/rsvg-defs.h b/rsvg-defs.h
index 0a709df5..352a8205 100644
--- a/rsvg-defs.h
+++ b/rsvg-defs.h
@@ -65,6 +65,9 @@ rsvg_defs_set (RsvgDefs *defs, const char *name, RsvgDefVal *val);
void
rsvg_defs_free (RsvgDefs *defs);
+void
+rsvg_defs_set_base_uri (RsvgDefs * self, gchar * base_uri);
+
G_END_DECLS
#endif
diff --git a/rsvg-filter.c b/rsvg-filter.c
index 3953128c..a635e9e3 100644
--- a/rsvg-filter.c
+++ b/rsvg-filter.c
@@ -613,22 +613,18 @@ rsvg_filter_parse (const RsvgDefs * defs, const char *str)
while (g_ascii_isspace (*p))
p++;
- if (*p == '#')
+ for (ix = 0; p[ix]; ix++)
+ if (p[ix] == ')')
+ break;
+
+ if (p[ix] == ')')
{
- p++;
- for (ix = 0; p[ix]; ix++)
- if (p[ix] == ')')
- break;
-
- if (p[ix] == ')')
- {
- name = g_strndup (p, ix);
- val = rsvg_defs_lookup (defs, name);
- g_free (name);
-
- if (val && val->type == RSVG_DEF_FILTER)
- return (RsvgFilter *) val;
- }
+ name = g_strndup (p, ix);
+ val = rsvg_defs_lookup (defs, name);
+ g_free (name);
+
+ if (val && val->type == RSVG_DEF_FILTER)
+ return (RsvgFilter *) val;
}
}
diff --git a/rsvg-mask.c b/rsvg-mask.c
index b64bf011..918b5b24 100644
--- a/rsvg-mask.c
+++ b/rsvg-mask.c
@@ -259,22 +259,18 @@ rsvg_mask_parse (const RsvgDefs * defs, const char *str)
while (g_ascii_isspace (*p))
p++;
- if (*p == '#')
+ for (ix = 0; p[ix]; ix++)
+ if (p[ix] == ')')
+ break;
+
+ if (p[ix] == ')')
{
- p++;
- for (ix = 0; p[ix]; ix++)
- if (p[ix] == ')')
- break;
-
- if (p[ix] == ')')
- {
- name = g_strndup (p, ix);
- val = rsvg_defs_lookup (defs, name);
- g_free (name);
-
- if (val && val->type == RSVG_DEF_MASK)
- return (RsvgDefsDrawable *) val;
- }
+ name = g_strndup (p, ix);
+ val = rsvg_defs_lookup (defs, name);
+ g_free (name);
+
+ if (val && val->type == RSVG_DEF_MASK)
+ return (RsvgDefsDrawable *) val;
}
}
return NULL;
@@ -408,22 +404,18 @@ rsvg_clip_path_parse (const RsvgDefs * defs, const char *str)
while (g_ascii_isspace (*p))
p++;
- if (*p == '#')
+ for (ix = 0; p[ix]; ix++)
+ if (p[ix] == ')')
+ break;
+
+ if (p[ix] == ')')
{
- p++;
- for (ix = 0; p[ix]; ix++)
- if (p[ix] == ')')
- break;
-
- if (p[ix] == ')')
- {
- name = g_strndup (p, ix);
- val = rsvg_defs_lookup (defs, name);
- g_free (name);
-
- if (val && val->type == RSVG_DEF_CLIP_PATH)
- return (RsvgDefsDrawable *) val;
- }
+ name = g_strndup (p, ix);
+ val = rsvg_defs_lookup (defs, name);
+ g_free (name);
+
+ if (val && val->type == RSVG_DEF_CLIP_PATH)
+ return (RsvgDefsDrawable *) val;
}
}
return NULL;
diff --git a/rsvg-paint-server.c b/rsvg-paint-server.c
index 1b56c034..1ce1adbf 100644
--- a/rsvg-paint-server.c
+++ b/rsvg-paint-server.c
@@ -669,9 +669,6 @@ rsvg_paint_server_parse (gboolean * inherit, const RsvgDefs *defs, const char *s
RsvgDefVal *val;
while (g_ascii_isspace (*p)) p++;
- if (*p != '#')
- return NULL;
- p++;
for (ix = 0; p[ix]; ix++)
if (p[ix] == ')') break;
if (p[ix] != ')')
diff --git a/rsvg-shapes.c b/rsvg-shapes.c
index e03f1197..f3c9f85b 100644
--- a/rsvg-shapes.c
+++ b/rsvg-shapes.c
@@ -1514,7 +1514,7 @@ rsvg_pixbuf_new_from_data_at_size (const char *data,
return pixbuf;
}
-static gchar *
+gchar *
rsvg_get_file_path (const gchar * filename, const gchar *basedir)
{
gchar *absolute_filename;
@@ -2115,7 +2115,7 @@ rsvg_start_use (RsvgHandle *ctx, RsvgPropertyBag *atts)
if (xlink_href != NULL)
{
- RsvgDefVal * parent = rsvg_defs_lookup (ctx->defs, xlink_href+1);
+ RsvgDefVal * parent = rsvg_defs_lookup (ctx->defs, xlink_href);
if (parent != NULL)
switch(parent->type)
{
diff --git a/rsvg-shapes.h b/rsvg-shapes.h
index 73b76f4e..19a354b5 100644
--- a/rsvg-shapes.h
+++ b/rsvg-shapes.h
@@ -146,6 +146,9 @@ rsvg_affine_image(GdkPixbuf *img, GdkPixbuf *intermediate,
void rsvg_defs_drawable_group_pack (RsvgDefsDrawableGroup *self, RsvgDefsDrawable *child);
+gchar *
+rsvg_get_file_path (const gchar * filename, const gchar *basedir);
+
G_END_DECLS
#endif /* RSVG_SHAPES_H */
diff --git a/rsvg-text.c b/rsvg-text.c
index fb37a9ea..629a048e 100644
--- a/rsvg-text.c
+++ b/rsvg-text.c
@@ -191,6 +191,10 @@ rsvg_tchunk_remove_leading(RsvgTChunk * self);
static void
rsvg_tspan_remove_leading(RsvgTspan * self)
{
+ if (!self)
+ return;
+ if (!self->contents->len == 0)
+ return
rsvg_tchunk_remove_leading(g_ptr_array_index(self->contents, 0));
}
@@ -210,6 +214,10 @@ rsvg_tchunk_remove_trailing(RsvgTChunk * self);
static void
rsvg_tspan_remove_trailing(RsvgTspan * self)
{
+ if (!self)
+ return;
+ if (!self->contents->len == 0)
+ return
rsvg_tchunk_remove_trailing(g_ptr_array_index(self->contents,
self->contents->len - 1));
}
diff --git a/rsvg.c b/rsvg.c
index 27ea9bb5..6155e687 100644
--- a/rsvg.c
+++ b/rsvg.c
@@ -1443,6 +1443,7 @@ void rsvg_handle_set_base_uri (RsvgHandle *handle,
if (handle->base_uri)
g_free (handle->base_uri);
handle->base_uri = g_strdup (base_uri);
+ rsvg_defs_set_base_uri(handle->defs, handle->base_uri);
}
}