Commit 3791f602 authored by Dom Lachowicz's avatar Dom Lachowicz

add support for the title and desc elements

parent 3cc918b2
2003-06-20 Dom Lachowicz <cinamod@hotmail.com>
* rsvg.c: Add support for <title> and <desc> elements
2003-04-08 Dom Lachowicz <cinamod@hotmail.com>
* configure.in: enable librsvg to be built w/o gtk+
......
......@@ -6,10 +6,6 @@ noinst_PROGRAMS = test-performance #test-display
man_MANS = rsvg.1
if PLATFORM_WIN32
no_undefined = -no-undefined
endif
if WITH_LIBGSF
GSFHEADERS = rsvg-gz.h
GSFSOURCES = rsvg-gz.c
......@@ -50,7 +46,7 @@ librsvg_2_la_SOURCES = $(GSFSOURCES) \
rsvg-text.h \
rsvg.c
librsvg_2_la_LDFLAGS = -version-info @VERSION_INFO@ $(no_undefined)
librsvg_2_la_LDFLAGS = -version-info @VERSION_INFO@ -no-undefined -export-dynamic
librsvg_2_la_LIBADD = $(LIBRSVG_LIBS)
librsvgincdir = $(includedir)/librsvg-2/librsvg
......
......@@ -33,15 +33,14 @@
typedef struct {
RsvgHandle *handle;
GdkPixbuf *pixbuf;
GdkPixbufModuleUpdatedFunc updated_func;
GdkPixbufModulePreparedFunc prepared_func;
gpointer user_data;
#if HAVE_SVGZ
GdkPixbufModuleSizeFunc size_func;
gboolean first_write;
#endif
gpointer user_data;
} SvgContext;
G_MODULE_EXPORT void fill_vtable (GdkPixbufModule *module);
......@@ -59,15 +58,8 @@ gdk_pixbuf__svg_image_begin_load (GdkPixbufModuleSizeFunc size_func,
if (error)
*error = NULL;
#if HAVE_SVGZ
/* lazy create the handle on the first write */
context->handle = NULL;
context->first_write = TRUE;
context->size_func = size_func;
#else
context->handle = rsvg_handle_new ();
rsvg_handle_set_size_callback (context->handle, size_func, user_data, NULL);
#endif
context->prepared_func = prepared_func;
context->updated_func = updated_func;
......@@ -87,19 +79,20 @@ gdk_pixbuf__svg_image_load_increment (gpointer data,
if (error)
*error = NULL;
#if HAVE_SVGZ
if (context->first_write == TRUE) {
context->first_write = FALSE;
#ifdef HAVE_SVGZ
/* lazy create a SVGZ or SVG loader */
if ((size >= 2) && (buf[0] == (guchar)0x1f) && (buf[1] == (guchar)0x8b))
context->handle = rsvg_handle_new_gz ();
else
#endif
context->handle = rsvg_handle_new ();
rsvg_handle_set_size_callback (context->handle, context->size_func, context->user_data, NULL);
}
#endif
result = rsvg_handle_write (context->handle, buf, size, error);
......
......@@ -208,7 +208,9 @@ rsvg_pixbuf_from_file_with_size_data (const gchar * file_name,
* by this call and must be freed by the caller.
*
* Return value: A newly allocated #GdkPixbuf, or %NULL
**/
*
* Since: 2.4
*/
GdkPixbuf *
rsvg_pixbuf_from_file_at_size_ex (RsvgHandle * handle,
const gchar *file_name,
......@@ -237,7 +239,9 @@ rsvg_pixbuf_from_file_at_size_ex (RsvgHandle * handle,
* freed by the caller.
*
* Return value: A newly allocated #GdkPixbuf, or %NULL
**/
*
* Since: 2.4
*/
GdkPixbuf *
rsvg_pixbuf_from_file_ex (RsvgHandle * handle,
const gchar *file_name,
......@@ -261,7 +265,9 @@ rsvg_pixbuf_from_file_ex (RsvgHandle * handle,
* call and must be freed by the caller.
*
* Return value: A newly allocated #GdkPixbuf, or %NULL
**/
*
* Since: 2.4
*/
GdkPixbuf *
rsvg_pixbuf_from_file_at_zoom_ex (RsvgHandle * handle,
const gchar *file_name,
......@@ -296,7 +302,9 @@ rsvg_pixbuf_from_file_at_zoom_ex (RsvgHandle * handle,
* must be freed by the caller.
*
* Return value: A newly allocated #GdkPixbuf, or %NULL
**/
*
* Since: 2.4
*/
GdkPixbuf *
rsvg_pixbuf_from_file_at_max_size_ex (RsvgHandle * handle,
const gchar *file_name,
......@@ -331,7 +339,9 @@ rsvg_pixbuf_from_file_at_max_size_ex (RsvgHandle * handle,
* Returned handle is closed by this call and must be freed by the caller.
*
* Return value: A newly allocated #GdkPixbuf, or %NULL
**/
*
* Since: 2.4
*/
GdkPixbuf *
rsvg_pixbuf_from_file_at_zoom_with_max_ex (RsvgHandle * handle,
const gchar *file_name,
......
......@@ -74,6 +74,9 @@ struct RsvgHandle {
int height;
double dpi;
GString * title;
GString * desc;
/* virtual fns */
gboolean (* write) (RsvgHandle *handle,
const guchar *buf,
......
......@@ -59,7 +59,7 @@ rsvg_draw_hline (RsvgHandle *ctx, double x, double w, double y)
#endif
static char *
char *
make_valid_utf8 (const char *str)
{
GString *string;
......
......@@ -32,6 +32,7 @@ G_BEGIN_DECLS
void rsvg_start_text (RsvgHandle *ctx, const xmlChar **atts);
void rsvg_start_tspan (RsvgHandle *ctx, const xmlChar **atts);
char * make_valid_utf8 (const char *str);
G_END_DECLS
......
......@@ -259,6 +259,10 @@ typedef struct _RsvgSaxHandlerGstops {
const char * parent_tag;
} RsvgSaxHandlerGstops;
/* hide this fact from the general public */
typedef RsvgSaxHandlerDefs RsvgSaxHandlerTitle;
typedef RsvgSaxHandlerDefs RsvgSaxHandlerDesc;
static void
rsvg_gradient_stop_handler_free (RsvgSaxHandler *self)
{
......@@ -278,10 +282,7 @@ rsvg_gradient_stop_handler_start (RsvgSaxHandler *self, const xmlChar *name,
int n_stop;
if (strcmp ((char *)name, "stop"))
{
g_warning ("unexpected <%s> element in gradient\n", name);
return;
}
return;
rsvg_state_init (&state);
......@@ -487,13 +488,15 @@ rsvg_start_linear_gradient (RsvgHandle *ctx, const xmlChar **atts)
rsvg_defs_set (ctx->defs, id, &grad->super);
#if 0
for (i = 0; i < 6; i++)
grad->affine[i] = state->affine[i];
#endif
if (got_transform)
art_affine_multiply (grad->affine, affine, grad->affine);
/* state inherits parent/cloned information unless it's explicity gotten */
/* gradient inherits parent/cloned information unless it's explicity gotten */
grad->obj_bbox = (cloned && !got_bbox) ? grad->obj_bbox : obj_bbox;
grad->x1 = (cloned && !got_x1) ? grad->x1 : x1;
grad->y1 = (cloned && !got_y1) ? grad->y1 : y1;
......@@ -630,14 +633,16 @@ rsvg_start_radial_gradient (RsvgHandle *ctx, const xmlChar **atts, const char *
}
rsvg_defs_set (ctx->defs, id, &grad->super);
#if 0
for (i = 0; i < 6; i++)
grad->affine[i] = state->affine[i];
#endif
if (got_transform)
art_affine_multiply (grad->affine, affine, grad->affine);
/* state inherits parent/cloned information unless it's explicity gotten */
/* gradient inherits parent/cloned information unless it's explicity gotten */
grad->obj_bbox = (cloned && !got_bbox) ? grad->obj_bbox : obj_bbox;
grad->cx = (cloned && !got_cx) ? grad->cx : cx;
grad->cy = (cloned && !got_cy) ? grad->cy : cy;
......@@ -707,7 +712,7 @@ rsvg_start_style (RsvgHandle *ctx, const xmlChar **atts)
ctx->handler = &handler->super;
}
/* */
/* start defs */
static void
rsvg_defs_handler_free (RsvgSaxHandler *self)
......@@ -805,6 +810,160 @@ rsvg_start_defs (RsvgHandle *ctx, const xmlChar **atts)
/* end defs */
/* start desc */
static void
rsvg_desc_handler_free (RsvgSaxHandler *self)
{
g_free (self);
}
static void
rsvg_desc_handler_characters (RsvgSaxHandler *self, const xmlChar *ch, int len)
{
RsvgSaxHandlerDesc *z = (RsvgSaxHandlerDesc *)self;
RsvgHandle *ctx = z->ctx;
char * string = NULL;
char * utf8 = NULL;
/* This isn't quite the correct behavior - in theory, any graphics
element may contain a title or desc element */
if (!ch || !len)
return;
string = g_strndup (ch, len);
if (!g_utf8_validate (string, -1, NULL))
{
utf8 = make_valid_utf8 (string);
g_free (string);
string = utf8;
}
g_string_append (ctx->desc, string);
g_free (string);
}
static void
rsvg_desc_handler_start (RsvgSaxHandler *self, const xmlChar *name,
const xmlChar **atts)
{
}
static void
rsvg_desc_handler_end (RsvgSaxHandler *self, const xmlChar *name)
{
RsvgSaxHandlerDesc *z = (RsvgSaxHandlerDesc *)self;
RsvgHandle *ctx = z->ctx;
if (!strcmp((char *)name, "desc"))
{
if (ctx->handler != NULL)
{
ctx->handler->free (ctx->handler);
ctx->handler = NULL;
}
}
/* pop the state stack */
ctx->n_state--;
rsvg_state_finalize (&ctx->state[ctx->n_state]);
}
static void
rsvg_start_desc (RsvgHandle *ctx, const xmlChar **atts)
{
RsvgSaxHandlerDesc *handler = g_new0 (RsvgSaxHandlerDesc, 1);
handler->super.free = rsvg_desc_handler_free;
handler->super.characters = rsvg_desc_handler_characters;
handler->super.start_element = rsvg_desc_handler_start;
handler->super.end_element = rsvg_desc_handler_end;
handler->ctx = ctx;
ctx->handler = &handler->super;
}
/* end desc */
/* start title */
static void
rsvg_title_handler_free (RsvgSaxHandler *self)
{
g_free (self);
}
static void
rsvg_title_handler_characters (RsvgSaxHandler *self, const xmlChar *ch, int len)
{
RsvgSaxHandlerDesc *z = (RsvgSaxHandlerDesc *)self;
RsvgHandle *ctx = z->ctx;
char * string = NULL;
char * utf8 = NULL;
/* This isn't quite the correct behavior - in theory, any graphics
element may contain a title or desc element */
if (!ch || !len)
return;
string = g_strndup (ch, len);
if (!g_utf8_validate (string, -1, NULL))
{
utf8 = make_valid_utf8 (string);
g_free (string);
string = utf8;
}
g_string_append (ctx->title, string);
g_free (string);
}
static void
rsvg_title_handler_start (RsvgSaxHandler *self, const xmlChar *name,
const xmlChar **atts)
{
}
static void
rsvg_title_handler_end (RsvgSaxHandler *self, const xmlChar *name)
{
RsvgSaxHandlerTitle *z = (RsvgSaxHandlerTitle *)self;
RsvgHandle *ctx = z->ctx;
if (!strcmp((char *)name, "title"))
{
if (ctx->handler != NULL)
{
ctx->handler->free (ctx->handler);
ctx->handler = NULL;
}
}
/* pop the state stack */
ctx->n_state--;
rsvg_state_finalize (&ctx->state[ctx->n_state]);
}
static void
rsvg_start_title (RsvgHandle *ctx, const xmlChar **atts)
{
RsvgSaxHandlerTitle *handler = g_new0 (RsvgSaxHandlerTitle, 1);
handler->super.free = rsvg_title_handler_free;
handler->super.characters = rsvg_title_handler_characters;
handler->super.start_element = rsvg_title_handler_start;
handler->super.end_element = rsvg_title_handler_end;
handler->ctx = ctx;
ctx->handler = &handler->super;
}
/* end title */
static void
rsvg_start_element (void *data, const xmlChar *name, const xmlChar **atts)
{
......@@ -856,6 +1015,10 @@ rsvg_start_element (void *data, const xmlChar *name, const xmlChar **atts)
rsvg_start_image (ctx, atts);
else if (!strcmp ((char *)name, "style"))
rsvg_start_style (ctx, atts);
else if (!strcmp ((char *)name, "title"))
rsvg_start_title (ctx, atts);
else if (!strcmp ((char *)name, "desc"))
rsvg_start_desc (ctx, atts);
/* see conicalGradient discussion above */
else if (!strcmp ((char *)name, "linearGradient"))
......@@ -1071,9 +1234,43 @@ rsvg_handle_free_impl (RsvgHandle *handle)
(* handle->user_data_destroy) (handle->user_data);
if (handle->pixbuf)
g_object_unref (handle->pixbuf);
g_string_free (handle->title, TRUE);
g_string_free (handle->desc, TRUE);
g_free (handle);
}
/**
* rsvg_handle_get_title:
*
* Returns the SVG's title in UTF-8 or %NULL. You must make a copy
* of this title if you wish to use it after #handle has been freed.
*
* Returns: The SVG's title
*
* Since: 2.4
*/
G_CONST_RETURN char *rsvg_handle_get_title (RsvgHandle *handle)
{
return handle->title->str;
}
/**
* rsvg_handle_get_desc:
*
* Returns the SVG's description in UTF-8 or %NULL. You must make a copy
* of this description if you wish to use it after #handle has been freed.
*
* Returns: The SVG's description
*
* Since: 2.4
*/
G_CONST_RETURN char *rsvg_handle_get_desc (RsvgHandle *handle)
{
return handle->desc->str;
}
/**
* rsvg_handle_new:
*
......@@ -1114,6 +1311,9 @@ rsvg_handle_init (RsvgHandle * handle)
g_free, g_free);
handle->ctxt = NULL;
handle->title = g_string_new (NULL);
handle->desc = g_string_new (NULL);
}
/**
......@@ -1123,6 +1323,8 @@ rsvg_handle_init (RsvgHandle * handle)
* Sets the DPI for the all future outgoing pixbufs. Common values are
* 72, 90, and 300 DPI. Passing a number <= 0 to #dpi will
* reset the DPI to whatever the default value happens to be.
*
* Since: 2.2
*/
void
rsvg_set_default_dpi (double dpi)
......@@ -1141,6 +1343,8 @@ rsvg_set_default_dpi (double dpi)
* Sets the DPI for the outgoing pixbuf. Common values are
* 72, 90, and 300 DPI. Passing a number <= 0 to #dpi will
* reset the DPI to whatever the default value happens to be.
*
* Since: 2.2
*/
void
rsvg_handle_set_dpi (RsvgHandle * handle, double dpi)
......
......@@ -71,7 +71,7 @@ gboolean rsvg_handle_close (RsvgHandle *handle,
GdkPixbuf *rsvg_handle_get_pixbuf (RsvgHandle *handle);
void rsvg_handle_free (RsvgHandle *handle);
/* convenience API */
/* Convenience API */
GdkPixbuf *rsvg_pixbuf_from_file (const gchar *file_name,
GError **error);
......@@ -94,7 +94,12 @@ GdkPixbuf *rsvg_pixbuf_from_file_at_zoom_with_max (const gchar *file_name,
gint max_height,
GError **error);
/* "New" convenience API (2.2.2+) */
/* Accessibility API */
G_CONST_RETURN char *rsvg_handle_get_title (RsvgHandle *handle);
G_CONST_RETURN char *rsvg_handle_get_desc (RsvgHandle *handle);
/* Extended Convenience API */
GdkPixbuf * rsvg_pixbuf_from_file_at_size_ex (RsvgHandle * handle,
const gchar *file_name,
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment