Lumiera 0.pre.04
»edit your freedom«
Loading...
Searching...
No Matches
rsvg-convert.c
Go to the documentation of this file.
1/*
2 rsvg-convert.c - Command line utility for exercising rsvg with cairo.
3
4 Copyright (C) Red Hat, Inc.
5 2005, Carl Worth <cworth@cworth.org>
6 Caleb Moore <c.moore@student.unsw.edu.au>
7 Dom Lachowicz <cinamod@hotmail.com>
8 2008, Joel Holdsworth <joel@airwebreathe.org.uk>
9
10  **Lumiera** is free software; you can redistribute it and/or modify it
11  under the terms of the GNU General Public License as published by the
12  Free Software Foundation; either version 2 of the License, or (at your
13  option) any later version. See the file COPYING for further details.
14
15* *****************************************************************/
16
17
26#ifndef N_
27#define N_(X) X
28#endif
29
30#include <stdio.h>
31#include <stdlib.h>
32#include <string.h>
33#include <locale.h>
34
35#include <librsvg/rsvg.h>
36#include <librsvg/rsvg-cairo.h>
37
38
39#ifdef CAIRO_HAS_PS_SURFACE
40 #include <cairo-ps.h>
41#endif
42
43#ifdef CAIRO_HAS_PDF_SURFACE
44 #include <cairo-pdf.h>
45#endif
46
47#ifdef CAIRO_HAS_SVG_SURFACE
48 #include <cairo-svg.h>
49#endif
50
51#ifndef _
52 #define _(X) X
53#endif
54
55
57 {
58 gint width;
59 gint height;
60 };
61
63 {
64 double left;
65 double top;
66 double width;
67 double height;
68 };
69
70
71static void
73{
74 if (err)
75 {
76 g_print ("%s\n", err->message);
77 g_error_free (err);
78 }
79}
80
81
82static void
83rsvg_cairo_size_callback (int *width, int *height, gpointer data)
84{
85 RsvgDimensionData *dimensions = data;
86 *width = dimensions->width;
87 *height = dimensions->height;
88}
89
90
91static cairo_status_t
92rsvg_cairo_write_func (void *closure, const unsigned char *data, unsigned int length)
93{
94 if (fwrite (data, 1, length, (FILE *) closure) == length)
95 return CAIRO_STATUS_SUCCESS;
96 return CAIRO_STATUS_WRITE_ERROR;
97}
98
99
100int
101main (int argc, char **argv)
102{
103 GOptionContext *g_option_context;
104 int width = -1;
105 int height = -1;
106 char *source_rect_string = NULL;
107 char *output = NULL;
108 GError *error = NULL;
109 char *filename = NULL;
110
111 char **args = NULL;
112 RsvgHandle *rsvg;
113 cairo_surface_t *surface = NULL;
114 cairo_t *cr = NULL;
115 RsvgDimensionData dimensions;
116 FILE *output_file = stdout;
117
118 struct RsvgSourceRectangle source_rect = {0, 0, 0, 0};
119
120 GOptionEntry options_table[] = {
121 {"width", 'w', 0, G_OPTION_ARG_INT, &width,
122 N_("width [optional; defaults to the SVG's width]"), N_("<int>")},
123 {"height", 'h', 0, G_OPTION_ARG_INT, &height,
124 N_("height [optional; defaults to the SVG's height]"), N_("<int>")},
125 {"source-rect", 'r', 0, G_OPTION_ARG_STRING, &source_rect_string,
126 N_("source rectangle [optional; defaults to rectangle of the SVG document]"), N_("left:top:width:height")},
127 {"output", 'o', 0, G_OPTION_ARG_STRING, &output,
128 N_("output filename"), NULL},
129 {G_OPTION_REMAINING, 0, 0, G_OPTION_ARG_FILENAME_ARRAY, &args, NULL, N_("FILE")},
130 {NULL}
131 };
132
133 /* Set the locale so that UTF-8 filenames work */
134 setlocale (LC_ALL, "");
135
136 g_option_context = g_option_context_new (_("- SVG Converter"));
137 g_option_context_add_main_entries (g_option_context, options_table, NULL);
138 g_option_context_set_help_enabled (g_option_context, TRUE);
139 if (!g_option_context_parse (g_option_context, &argc, &argv, &error))
140 {
142 exit (1);
143 }
144
145 g_option_context_free (g_option_context);
146
147 if (output != NULL)
148 {
149 output_file = fopen (output, "wb");
150 if (!output_file)
151 {
152 fprintf (stderr, _("Error saving to file: %s\n"), output);
153 exit (1);
154 }
155 }
156
157 if (args[0] != NULL)
158 filename = args[0];
159
160 /* Parse the source rect */
161 if(source_rect_string != NULL)
162 {
163 const int n = sscanf(source_rect_string, "%lg:%lg:%lg:%lg",
164 &source_rect.left, &source_rect.top,
165 &source_rect.width, &source_rect.height);
166 if (n != 4 || source_rect.width <= 0.0 || source_rect.height < 0.0)
167 {
168 fprintf (stderr, _("Invalid source rect: %s\n"), source_rect_string);
169 exit(1);
170 }
171 }
172
173 rsvg_init ();
174
175 rsvg = rsvg_handle_new_from_file (filename, &error);
176
177 if (!rsvg)
178 {
179 fprintf (stderr, _("Error reading SVG:"));
181 fprintf (stderr, "\n");
182 exit (1);
183 }
184
185 /* if the user did not specify a source rectangle, get the page size from the SVG */
186 if(source_rect_string == NULL)
187 {
188 rsvg_handle_set_size_callback (rsvg, rsvg_cairo_size_callback, &dimensions, NULL);
189 source_rect.left = 0;
190 source_rect.top = 0;
191 source_rect.width = dimensions.width;
192 source_rect.height = dimensions.height;
193 }
194
195 rsvg_handle_get_dimensions (rsvg, &dimensions);
196
197 if (width != -1 && height != -1)
198 {
199 dimensions.width = width;
200 dimensions.height = height;
201 }
202 else if(source_rect_string != NULL)
203 {
204 dimensions.width = source_rect.width;
205 dimensions.height = source_rect.height;
206 }
207
208 surface = cairo_image_surface_create (CAIRO_FORMAT_ARGB32,
209 dimensions.width,
210 dimensions.height);
211
212 cr = cairo_create (surface);
213
214 cairo_translate (cr, -source_rect.left, -source_rect.top);
215
216 if (width != -1 && height != -1 && source_rect_string != NULL)
217 {
218 cairo_scale (cr,
219 (double)dimensions.width / (double)source_rect.width,
220 (double)dimensions.height / (double)source_rect.height);
221 }
222
223 rsvg_handle_render_cairo (rsvg, cr);
224
225 cairo_surface_write_to_png_stream (surface, rsvg_cairo_write_func, output_file);
226
227 g_object_unref (G_OBJECT (rsvg));
228
229 cairo_destroy (cr);
230 cairo_surface_destroy (surface);
231
232 fclose (output_file);
233
234 rsvg_term ();
235
236 return 0;
237}
return NULL
Definition llist.h:586
int main()
Definition main.c:37
#define _(X)
#define N_(X)
static cairo_status_t rsvg_cairo_write_func(void *closure, const unsigned char *data, unsigned int length)
static void rsvg_cairo_size_callback(int *width, int *height, gpointer data)
static void display_error(GError *err)