CAIRO_CAN_TEST_SVG_SURFACE depends on librsvg.

cairo_svg_surface_t owns a xml node, for support of svg_surface_composite. (_cairo_svg_surface_create_for_document): init xml_node. All surfaces except first one are stored in defs node. (emit_composite_image_pattern): returns pattern size, and don't call emit_transform if is_pattern == TRUE. (emit_composite_svg_pattern): do something. (emit_composite_pattern): returns pattern size. (_cairo_svg_surface_composite): xml_node is stored in cairo_svg_surface_t now. (emit_surface_pattern): emit surface pattern width here. Fix property names. (_cairo_svg_path_close_path): don't close path if no current point. (_cairo_svg_surface_fill_rectangles): new. (_cairo_svg_surface_fill): emit fill rule. xml_node is in surface now. (_cairo_svg_surface_composite_trapezoids): xml_node is in surface now. (_cairo_svg_surface_stroke): ditto. (_cairo_svg_surface_intersect_clip_path): ditto. Emit fill rule.
ignore svg2png.
build svg2png utility.
test SVG backend if CAIRO_HAS_SVG_SURFACE && CAIRO_CAN_TEST_SVG_SURFACE.
new.
This commit is contained in:
Emmanuel Pacaud 2005-12-19 13:59:34 +00:00
parent 70c45dd502
commit ec574cd6f0
7 changed files with 329 additions and 29 deletions

View file

@ -1,3 +1,33 @@
2005-12-19 Emmanuel Pacaud <emmanuel.pacaud@free.fr>
* configure.in: CAIRO_CAN_TEST_SVG_SURFACE depends on librsvg.
* src/cairo-svg-surface.c: cairo_svg_surface_t owns a xml node, for
support of svg_surface_composite.
(_cairo_svg_surface_create_for_document): init xml_node. All surfaces
except first one are stored in defs node.
(emit_composite_image_pattern): returns pattern size, and don't call
emit_transform if is_pattern == TRUE.
(emit_composite_svg_pattern): do something.
(emit_composite_pattern): returns pattern size.
(_cairo_svg_surface_composite): xml_node is stored in
cairo_svg_surface_t now.
(emit_surface_pattern): emit surface pattern width here.
Fix property names.
(_cairo_svg_path_close_path): don't close path if no current point.
(_cairo_svg_surface_fill_rectangles): new.
(_cairo_svg_surface_fill): emit fill rule. xml_node is in surface now.
(_cairo_svg_surface_composite_trapezoids): xml_node is in surface now.
(_cairo_svg_surface_stroke): ditto.
(_cairo_svg_surface_intersect_clip_path): ditto. Emit fill rule.
* test/.cvsignore: ignore svg2png.
* test/Makefile.am: build svg2png utility.
* test/cairo-test.c (create_svg_surface): new.
(svg_surface_write_to_png): new.
(cleanup_svg): new.
(cairo_test_expecting): test SVG backend if CAIRO_HAS_SVG_SURFACE &&
CAIRO_CAN_TEST_SVG_SURFACE.
* test/svg2png.c: new.
2005-12-19 Christian Biesinger <cbiesinger@web.de>
* configure.in:

View file

@ -524,9 +524,19 @@ fi
AM_CONDITIONAL(CAIRO_HAS_SVG_SURFACE, test "x$use_svg" = "xyes")
if test "x$use_svg" = "xyes"; then
SVG_SURFACE_FEATURE="#define CAIRO_HAS_SVG_SURFACE 1"
PKG_CHECK_MODULES(LIBRSVG, librsvg-2.0 gdk-2.0, [test_svg=yes], [test_svg=no])
if test "x$test_svg" = "xyes"; then
AC_DEFINE([CAIRO_CAN_TEST_SVG_SURFACE], 1, [Define to 1 if the SVG backend can be tested (need librsvg)])
else
AC_MSG_WARN([SVG backend will not be tested since a librsvg is not available])
fi
fi
AC_SUBST(SVG_SURFACE_FEATURE)
AM_CONDITIONAL(CAIRO_CAN_TEST_SVG_SURFACE, test "x$test_svg" = "xyes")
AC_SUBST(LIBRSVG_CFLAGS)
AC_SUBST(LIBRSVG_LIBS)
CAIRO_CFLAGS="$CAIRO_CFLAGS $XML_CFLAGS"
CAIRO_LIBS="$CAIRO_LIBS $XML_LIBS"

View file

@ -66,8 +66,9 @@ struct cairo_svg_document {
xmlDocPtr xml_doc;
xmlNodePtr xml_node_defs;
xmlNodePtr xml_node;
xmlNodePtr xml_node_main;
unsigned int surface_id;
unsigned int linear_pattern_id;
unsigned int radial_pattern_id;
unsigned int pattern_id;
@ -78,11 +79,15 @@ struct cairo_svg_document {
struct cairo_svg_surface {
cairo_surface_t base;
unsigned int id;
double width;
double height;
cairo_svg_document_t *document;
xmlNodePtr xml_node;
cairo_bool_t has_clip;
};
@ -173,6 +178,7 @@ _cairo_svg_surface_create_for_document (cairo_svg_document_t *document,
double height)
{
cairo_svg_surface_t *surface;
char buffer[CAIRO_SVG_DTOSTR_BUFFER_LEN];
surface = malloc (sizeof (cairo_svg_surface_t));
if (surface == NULL)
@ -188,6 +194,15 @@ _cairo_svg_surface_create_for_document (cairo_svg_document_t *document,
surface->has_clip = FALSE;
surface->id = document->surface_id++;
if (surface->id == 0)
surface->xml_node = document->xml_node_main;
else {
surface->xml_node = xmlNewChild (document->xml_node_defs, NULL, CC2XML ("g"), NULL);
snprintf (buffer, sizeof buffer, "surface%d", surface->id);
xmlSetProp (surface->xml_node, CC2XML ("id"), C2XML (buffer));
}
return &surface->base;
}
@ -364,7 +379,10 @@ _cairo_surface_base64_encode (cairo_surface_t *surface,
static cairo_int_status_t
emit_composite_image_pattern (xmlNodePtr node,
cairo_surface_pattern_t *pattern)
cairo_surface_pattern_t *pattern,
double *width,
double *height,
int is_pattern)
{
cairo_surface_t *surface = pattern->surface;
cairo_image_surface_t *image;
@ -392,10 +410,16 @@ emit_composite_image_pattern (xmlNodePtr node,
xmlBufferFree (image_buffer);
p2u = pattern->base.matrix;
cairo_matrix_invert (&p2u);
if (!is_pattern) {
p2u = pattern->base.matrix;
cairo_matrix_invert (&p2u);
emit_transform (child, "transform", &p2u);
}
emit_transform (child, "transform", &p2u);
if (width != NULL)
*width = image->width;
if (height != NULL)
*height = image->height;
_cairo_surface_release_source_image (pattern->surface, image, image_extra);
@ -404,20 +428,37 @@ emit_composite_image_pattern (xmlNodePtr node,
static cairo_int_status_t
emit_composite_svg_pattern (xmlNodePtr node,
cairo_surface_pattern_t *pattern)
cairo_surface_pattern_t *pattern,
double *width,
double *height)
{
printf ("TODO: _cairo_svg_surface_composite_svg\r\n");
cairo_svg_surface_t *surface = (cairo_svg_surface_t *) pattern->surface;
xmlNodePtr child;
char buffer[CAIRO_SVG_DTOSTR_BUFFER_LEN];
child = xmlNewChild (node, NULL, CC2XML("use"), NULL);
snprintf (buffer, sizeof buffer, "#surface%d", surface->id);
xmlSetProp (child, CC2XML ("xlink:href"), C2XML (buffer));
if (width != NULL)
*width = surface->width;
if (height != NULL)
*height = surface->height;
return CAIRO_STATUS_SUCCESS;
}
static cairo_int_status_t
emit_composite_pattern (xmlNodePtr node,
cairo_surface_pattern_t *pattern)
cairo_surface_pattern_t *pattern,
double *width,
double *height,
int is_pattern)
{
if (pattern->surface->backend == &cairo_svg_surface_backend)
return emit_composite_svg_pattern (node, pattern);
return emit_composite_svg_pattern (node, pattern, width, height);
else
return emit_composite_image_pattern (node, pattern);
return emit_composite_image_pattern (node, pattern, width, height, is_pattern);
}
static cairo_int_status_t
@ -435,7 +476,6 @@ _cairo_svg_surface_composite (cairo_operator_t op,
unsigned int height)
{
cairo_svg_surface_t *dst = abstract_dst;
cairo_svg_document_t *document = dst->document;
cairo_surface_pattern_t *src = (cairo_surface_pattern_t *) src_pattern;
if (mask_pattern)
@ -444,7 +484,7 @@ _cairo_svg_surface_composite (cairo_operator_t op,
if (src_pattern->type != CAIRO_PATTERN_SURFACE)
return CAIRO_STATUS_SUCCESS;
return emit_composite_pattern (document->xml_node, src);
return emit_composite_pattern (dst->xml_node, src, NULL, NULL, FALSE);
}
static void
@ -529,6 +569,7 @@ emit_surface_pattern (cairo_svg_surface_t *surface,
xmlNodePtr child;
xmlBufferPtr id;
cairo_matrix_t p2u;
double width, height;
char buffer[CAIRO_SVG_DTOSTR_BUFFER_LEN];
child = xmlNewChild (document->xml_node_defs, NULL, CC2XML ("pattern"), NULL);
@ -546,14 +587,19 @@ emit_surface_pattern (cairo_svg_surface_t *surface,
document->pattern_id++;
emit_composite_pattern (child, pattern);
emit_composite_pattern (child, pattern, &width, &height, TRUE);
_cairo_dtostr (buffer, sizeof buffer, width);
xmlSetProp (child, CC2XML ("width"), C2XML (buffer));
_cairo_dtostr (buffer, sizeof buffer, height);
xmlSetProp (child, CC2XML ("height"), C2XML (buffer));
p2u = pattern->base.matrix;
cairo_matrix_invert (&p2u);
emit_transform (child, "gradientTransform", &p2u);
emit_transform (child, "patternTransform", &p2u);
xmlSetProp (child, CC2XML ("gradientUnits"), CC2XML ("userSpaceOnUse"));
xmlSetProp (child, CC2XML ("patternUnits"), CC2XML ("userSpaceOnUse"));
}
static int
@ -843,13 +889,50 @@ _cairo_svg_path_close_path (void *closure)
{
svg_path_info_t *info = closure;
xmlBufferCat (info->path, CC2XML ("Z "));
if (info->has_current_point)
xmlBufferCat (info->path, CC2XML ("Z "));
info->has_current_point = FALSE;
return CAIRO_STATUS_SUCCESS;
}
static cairo_int_status_t
_cairo_svg_surface_fill_rectangles (void *abstract_surface,
cairo_operator_t op,
const cairo_color_t *color,
cairo_rectangle_t *rects,
int num_rects)
{
cairo_svg_surface_t *surface = abstract_surface;
xmlNodePtr child;
xmlBufferPtr style;
char buffer[CAIRO_SVG_DTOSTR_BUFFER_LEN];
int i;
style = xmlBufferCreate ();
emit_color (color, style, "fill", "opacity");
xmlBufferCat (style, " stroke: none;");
emit_operator (op, surface, style);
for (i = 0; i < num_rects; i++) {
child = xmlNewChild (surface->xml_node, NULL, CC2XML ("rect"), NULL);
_cairo_dtostr (buffer, sizeof buffer, rects[i].x);
xmlSetProp (child, CC2XML ("x"), C2XML (buffer));
_cairo_dtostr (buffer, sizeof buffer, rects[i].y);
xmlSetProp (child, CC2XML ("y"), C2XML (buffer));
_cairo_dtostr (buffer, sizeof buffer, rects[i].width);
xmlSetProp (child, CC2XML ("width"), C2XML (buffer));
_cairo_dtostr (buffer, sizeof buffer, rects[i].height);
xmlSetProp (child, CC2XML ("height"), C2XML (buffer));
xmlSetProp (child, CC2XML ("style"), xmlBufferContent (style));
}
xmlBufferFree (style);
return CAIRO_STATUS_SUCCESS;
}
static cairo_int_status_t
_cairo_svg_surface_fill (void *abstract_surface,
cairo_operator_t op,
@ -873,6 +956,8 @@ _cairo_svg_surface_fill (void *abstract_surface,
style = xmlBufferCreate ();
emit_pattern (surface, source, style, 0);
xmlBufferCat (style, " stroke: none;");
xmlBufferCat (style, " fill-rule: ");
xmlBufferCat (style, fill_rule == CAIRO_FILL_RULE_EVEN_ODD ? "evenodd;" : "nonzero;");
emit_operator (op, surface, style);
status = _cairo_path_fixed_interpret (path,
@ -882,8 +967,8 @@ _cairo_svg_surface_fill (void *abstract_surface,
_cairo_svg_path_curve_to,
_cairo_svg_path_close_path,
&info);
child = xmlNewChild (document->xml_node, NULL, CC2XML ("path"), NULL);
child = xmlNewChild (surface->xml_node, NULL, CC2XML ("path"), NULL);
xmlSetProp (child, CC2XML ("d"), xmlBufferContent (info.path));
xmlSetProp (child, CC2XML ("style"), xmlBufferContent (style));
@ -917,7 +1002,6 @@ _cairo_svg_surface_composite_trapezoids (cairo_operator_t op,
int num_traps)
{
cairo_svg_surface_t *surface = abstract_dst;
cairo_svg_document_t *document = surface->document;
xmlBufferPtr style, path;
xmlNodePtr child;
double left_x1, left_x2, right_x1, right_x2;
@ -968,7 +1052,7 @@ _cairo_svg_surface_composite_trapezoids (cairo_operator_t op,
xmlBufferCat (path, CC2XML (" Z"));
}
child = xmlNewChild (document->xml_node, NULL, CC2XML ("path"), NULL);
child = xmlNewChild (surface->xml_node, NULL, CC2XML ("path"), NULL);
xmlSetProp (child, CC2XML ("d"), xmlBufferContent (path));
xmlSetProp (child, CC2XML ("style"), xmlBufferContent (style));
@ -998,6 +1082,40 @@ _cairo_svg_surface_get_extents (void *abstract_surface,
return CAIRO_STATUS_SUCCESS;
}
/* First attempt of paint implementation, but obviously I didn't
* understand how it's supposed to work */
#if 0
static cairo_int_status_t
_cairo_svg_surface_paint (void *abstract_surface,
cairo_operator_t op,
cairo_pattern_t *source)
{
cairo_svg_surface_t *surface = abstract_surface;
xmlNodePtr child;
xmlBufferPtr style;
char buffer[CAIRO_SVG_DTOSTR_BUFFER_LEN];
style = xmlBufferCreate ();
emit_pattern (surface, source, style, 0);
xmlBufferCat (style, " stroke: none;");
emit_operator (op, surface, style);
child = xmlNewChild (surface->xml_node, NULL, CC2XML ("rect"), NULL);
xmlSetProp (child, CC2XML ("x"), CC2XML ("0"));
xmlSetProp (child, CC2XML ("y"), CC2XML ("0"));
_cairo_dtostr (buffer, sizeof buffer, surface->width);
xmlSetProp (child, CC2XML ("width"), C2XML (buffer));
_cairo_dtostr (buffer, sizeof buffer, surface->height);
xmlSetProp (child, CC2XML ("height"), C2XML (buffer));
xmlSetProp (child, CC2XML ("style"), xmlBufferContent (style));
xmlBufferFree (style);
return CAIRO_STATUS_SUCCESS;
}
#endif
static cairo_int_status_t
_cairo_svg_surface_stroke (void *abstract_dst,
cairo_operator_t op,
@ -1084,7 +1202,7 @@ _cairo_svg_surface_stroke (void *abstract_dst,
_cairo_svg_path_close_path,
&info);
child = xmlNewChild (document->xml_node, NULL, CC2XML ("path"), NULL);
child = xmlNewChild (surface->xml_node, NULL, CC2XML ("path"), NULL);
xmlSetProp (child, CC2XML ("d"), xmlBufferContent (info.path));
xmlSetProp (child, CC2XML ("style"), xmlBufferContent (style));
@ -1152,7 +1270,7 @@ _cairo_svg_surface_intersect_clip_path (void *dst,
if (path == NULL) {
if (surface->has_clip)
document->xml_node = document->xml_node->parent;
surface->xml_node = surface->xml_node->parent;
surface->has_clip = FALSE;
return CAIRO_STATUS_SUCCESS;
}
@ -1164,7 +1282,7 @@ _cairo_svg_surface_intersect_clip_path (void *dst,
info.has_current_point = FALSE;
info.path = xmlBufferCreate ();
group = xmlNewChild (document->xml_node, NULL, CC2XML ("g"), NULL);
group = xmlNewChild (surface->xml_node, NULL, CC2XML ("g"), NULL);
clip = xmlNewChild (document->xml_node_defs, NULL, CC2XML ("clipPath"), NULL);
clip_path = xmlNewChild (clip, NULL, CC2XML ("path"), NULL);
@ -1177,7 +1295,7 @@ _cairo_svg_surface_intersect_clip_path (void *dst,
&info);
xmlSetProp (clip_path, CC2XML ("d"), xmlBufferContent (info.path));
xmlBufferFree (info.path);
id = xmlBufferCreate ();
xmlBufferCat (id, CC2XML ("clip"));
snprintf (buffer, sizeof buffer, "%d", document->clip_id);
@ -1189,12 +1307,15 @@ _cairo_svg_surface_intersect_clip_path (void *dst,
xmlBufferCat (url, xmlBufferContent (id));
xmlBufferCat (url, CC2XML (")"));
xmlSetProp (group, CC2XML ("clip-path"), C2XML (xmlBufferContent (url)));
xmlSetProp (group, CC2XML ("clip-rule"),
fill_rule == CAIRO_FILL_RULE_EVEN_ODD ?
CC2XML ("evenodd") : CC2XML ("nonzero"));
xmlBufferFree (url);
xmlBufferFree (id);
document->clip_id++;
document->xml_node = group;
surface->xml_node = group;
}
return status;
@ -1220,7 +1341,7 @@ static const cairo_surface_backend_t cairo_svg_surface_backend = {
NULL, /* release_dest_image */
NULL, /* clone_similar */
_cairo_svg_surface_composite,
NULL, /* fill_rectangle */
_cairo_svg_surface_fill_rectangles,
_cairo_svg_surface_composite_trapezoids,
NULL, /* copy_page */
NULL, /* show_page */
@ -1233,7 +1354,7 @@ static const cairo_surface_backend_t cairo_svg_surface_backend = {
NULL, /* mark dirty rectangle */
NULL, /* scaled font fini */
NULL, /* scaled glyph fini */
NULL, /* paint */
NULL, /*_cairo_svg_surface_paint,*/
NULL, /* mask */
_cairo_svg_surface_stroke,
_cairo_svg_surface_fill,
@ -1263,6 +1384,7 @@ _cairo_svg_document_create (cairo_output_stream_t *output_stream,
document->x_dpi = CAIRO_SVG_DEFAULT_DPI;
document->y_dpi = CAIRO_SVG_DEFAULT_DPI;
document->surface_id = 0;
document->linear_pattern_id = 0;
document->radial_pattern_id = 0;
document->pattern_id = 0;
@ -1275,7 +1397,7 @@ _cairo_svg_document_create (cairo_output_stream_t *output_stream,
xmlDocSetRootElement (doc, node);
document->xml_doc = doc;
document->xml_node = node;
document->xml_node_main = node;
document->xml_node_defs = xmlNewChild (node, NULL, CC2XML ("defs"), NULL);
_cairo_dtostr (buffer, sizeof buffer, width);

View file

@ -45,6 +45,7 @@ pdf-clip
pdf-clip.pdf
pdf-surface
pdf-surface.pdf
svg2png
svg-clip
svg-clip.svg
svg-surface

View file

@ -273,7 +273,6 @@ if CAIRO_CAN_TEST_GLITZ_WGL_SURFACE
LDADDS += $(GLITZ_WGL_LIBS)
endif
if HAVE_PTHREAD
LDADDS += -lpthread
endif
@ -359,8 +358,15 @@ pdf2png_CFLAGS = $(POPPLER_CFLAGS)
pdf2png_LDADD = $(LDADDS) $(POPPLER_LIBS)
endif
if CAIRO_CAN_TEST_SVG_SURFACE
noinst_PROGRAMS += svg2png
svg2png_CFLAGS = $(LIBRSVG_CFLAGS)
svg2png_LDADD = $(LIBRSVG_LIBS)
endif
CLEANFILES = \
*.ps \
*.svg \
*-out.png \
*-diff.png \
*.log \

View file

@ -1127,6 +1127,71 @@ cleanup_pdf (void *closure)
}
#endif /* CAIRO_HAS_PDF_SURFACE && CAIRO_CAN_TEST_PDF_SURFACE */
#if CAIRO_HAS_SVG_SURFACE && CAIRO_CAN_TEST_SVG_SURFACE
#include "cairo-svg.h"
cairo_user_data_key_t svg_closure_key;
typedef struct _svg_target_closure
{
char *filename;
int width, height;
} svg_target_closure_t;
static cairo_surface_t *
create_svg_surface (cairo_test_t *test, cairo_format_t format,
void **closure)
{
int width = test->width;
int height = test->height;
svg_target_closure_t *ptc;
cairo_surface_t *surface;
/* This is the only format supported by the PS surface backend. */
assert (format == CAIRO_FORMAT_RGB24);
*closure = ptc = xmalloc (sizeof (svg_target_closure_t));
ptc->width = width;
ptc->height = height;
xasprintf (&ptc->filename, "%s-%s%s", test->name, "svg-rgb24-out", ".svg");
surface = cairo_svg_surface_create (ptc->filename, width, height);
if (cairo_surface_status (surface)) {
free (ptc->filename);
free (ptc);
return NULL;
}
cairo_surface_set_user_data (surface, &svg_closure_key, ptc, NULL);
return surface;
}
static cairo_status_t
svg_surface_write_to_png (cairo_surface_t *surface, const char *filename)
{
svg_target_closure_t *ptc = cairo_surface_get_user_data (surface, &svg_closure_key);
char command[4096];
cairo_surface_finish (surface);
sprintf (command, "./svg2png %s %s",
ptc->filename, filename);
if (system (command) != 0)
return CAIRO_STATUS_WRITE_ERROR;
return CAIRO_STATUS_WRITE_ERROR;
}
static void
cleanup_svg (void *closure)
{
svg_target_closure_t *ptc = closure;
free (ptc->filename);
free (ptc);
}
#endif /* CAIRO_HAS_SVG_SURFACE && CAIRO_CAN_TEST_SVG_SURFACE */
static cairo_test_status_t
cairo_test_for_target (cairo_test_t *test,
cairo_test_draw_function_t draw,
@ -1307,6 +1372,10 @@ cairo_test_expecting (cairo_test_t *test, cairo_test_draw_function_t draw,
{ "pdf", CAIRO_FORMAT_RGB24,
create_pdf_surface, pdf_surface_write_to_png, cleanup_pdf },
#endif
#if CAIRO_HAS_SVG_SURFACE && CAIRO_CAN_TEST_SVG_SURFACE
{ "svg", CAIRO_FORMAT_RGB24,
create_svg_surface, svg_surface_write_to_png, cleanup_svg },
#endif
#if CAIRO_HAS_BEOS_SURFACE
{ "beos", CAIRO_FORMAT_RGB24,
create_beos_surface, cairo_surface_write_to_png, cleanup_beos},

62
test/svg2png.c Normal file
View file

@ -0,0 +1,62 @@
/*
* Copyright © 2005 Red Hat, Inc.
* Copyright © 2005 Emmanuel Pacaud <emmanuel.pacaud@free.fr>
*
* Permission to use, copy, modify, distribute, and sell this software
* and its documentation for any purpose is hereby granted without
* fee, provided that the above copyright notice appear in all copies
* and that both that copyright notice and this permission notice
* appear in supporting documentation, and that the name of
* Red Hat, Inc. not be used in advertising or publicity pertaining to
* distribution of the software without specific, written prior
* permission. Red Hat, Inc. makes no representations about the
* suitability of this software for any purpose. It is provided "as
* is" without express or implied warranty.
*
* RED HAT, INC. DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
* SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
* FITNESS, IN NO EVENT SHALL RED HAT, INC. BE LIABLE FOR ANY SPECIAL,
* INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER
* RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
* OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR
* IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*
* Author: Kristian Høgsberg <krh@redhat.com>
* Emmanuel Pacaud <emmanuel.pacaud@free.fr>
*/
#include <stdlib.h>
#include <gdk/gdk.h>
#include <gdk/gdkpixbuf.h>
#include <librsvg/rsvg.h>
#define FAIL(msg) \
do { fprintf (stderr, "FAIL: %s\n", msg); exit (-1); } while (0)
#define PIXELS_PER_POINT 1
int main (int argc, char *argv[])
{
GError *error = NULL;
GdkPixbuf *pixbuf;
const char *filename = argv[1];
const char *output_filename = argv[2];
if (argc != 3)
FAIL ("usage: svg2png input_file.svg output_file.png");
g_type_init ();
error = NULL;
pixbuf = rsvg_pixbuf_from_file (filename, &error);
if (error != NULL)
FAIL (error->message);
gdk_pixbuf_save (pixbuf, output_filename, "png", &error, NULL);
if (error != NULL)
FAIL (error->message);
g_object_unref (pixbuf);
return 0;
}