10
#include <librsvg/rsvg.h>
11
#ifndef LIBRSVG_CHECK_VERSION
12
# include <librsvg/librsvg-features.h>
14
#if LIBRSVG_CHECK_VERSION(2,36,2)
16
# include <librsvg/rsvg-cairo.h>
19
#define DATA32 unsigned int
21
static RsvgHandle *rsvg = NULL;
24
static RsvgDimensionData dim;
26
static inline Eina_Bool
27
evas_image_load_file_is_svg(const char *file)
29
int i, len = strlen(file);
30
Eina_Bool is_gz = EINA_FALSE;
32
for (i = len - 1; i > 0; i--)
38
else if (strcasecmp(file + i + 1, "gz") == 0)
45
if (i < 1) return EINA_FALSE;
47
if (i >= len) return EINA_FALSE;
48
if (strncasecmp(file + i, "svg", 3) != 0) return EINA_FALSE;
52
if (file[i] == '.') return EINA_TRUE;
53
else return EINA_FALSE;
57
if (file[i] == '\0') return EINA_TRUE;
58
else if (((file[i] == 'z') || (file[i] == 'Z')) && (!file[i + 1])) return EINA_TRUE;
59
else return EINA_FALSE;
64
_svg_init(const char *file)
67
# if !defined(GLIB_VERSION_2_36)
74
if (!evas_image_load_file_is_svg(file)) return 0;
76
rsvg = rsvg_handle_new_from_file(file, NULL);
87
// we don't really need this it seems and it's deprecated in 2.46
88
// rsvg_handle_close(rsvg, NULL);
91
// Maybe it's not crashing anymore, let's try it.
98
read_svg_header(int scale_down, double dpi, int size_w, int size_h)
100
rsvg_handle_set_dpi(rsvg, 75.0);
103
double owidth, oheight;
105
rsvg_handle_get_intrinsic_size_in_pixels(rsvg, &owidth, &oheight);
106
width = ceil(owidth);
107
height = ceil(oheight);
108
if ((width == 0) || (height == 0))
111
gboolean has_l1, has_l2, has_vb;
114
rsvg_handle_get_intrinsic_dimensions(rsvg, &has_l1, &l1, &has_l2, &l2, &has_vb, &vb);
115
width = ceil(vb.width);
116
height = ceil(vb.height);
119
rsvg_handle_get_dimensions(rsvg, &dim);
124
if ((width < 1) || (height < 1)) return 0;
129
height /= scale_down;
133
width = (width * dpi) / 75;
134
height = (height * dpi) / 75;
136
else if (size_w > 0 && size_h > 0)
141
h = (size_w * height) / width;
145
w = (size_h * width) / height;
150
if (width < 1) width = 1;
151
if (height < 1) height = 1;
159
cairo_surface_t *surface;
162
shm_alloc(width * height * (sizeof(DATA32)));
163
if (!shm_addr) return 0;
165
memset(shm_addr, 0, width * height * sizeof (DATA32));
166
surface = cairo_image_surface_create_for_data((unsigned char *)shm_addr,
169
width * sizeof(DATA32));;
170
if (!surface) return 0;
172
cr = cairo_create(surface);
175
if ((dim.em > 0.0) && (dim.ex > 0.0))
176
cairo_scale(cr, (double) width / dim.em, (double) height / dim.ex);
178
cairo_scale(cr, (double)1, (double)1);
188
rsvg_handle_render_document(rsvg, cr, &vp, NULL);
190
rsvg_handle_render_cairo(rsvg, cr);
193
cairo_surface_destroy(surface);
200
main(int argc, char **argv)
207
int size_w = 0, size_h = 0;
209
if (argc < 2) return -1;
212
for (i = 2; i < argc; ++i)
214
if (!strcmp(argv[i], "-head"))
216
else if (!strcmp(argv[i], "-key"))
217
{ // not used by svg loader
219
// const char *key = argv[i];
221
else if (!strcmp(argv[i], "-opt-scale-down-by"))
224
scale_down = atoi(argv[i]);
226
else if (!strcmp(argv[i], "-opt-dpi"))
229
dpi = ((double)atoi(argv[i])) / 1000.0;
231
else if (!strcmp(argv[i], "-opt-size"))
234
size_w = atoi(argv[i]);
236
size_h = atoi(argv[i]);
242
if (!_svg_init(file)) return -1;
243
if (!read_svg_header(scale_down, dpi, size_w, size_h)) return -1;
247
printf("size %d %d\n", width, height);
255
printf("size %d %d\n", width, height);
258
if (shm_fd) printf("shmfile %s\n", shmfile);
260
if (shm_fd >= 0) printf("shmfile %s\n", shmfile);
265
if (fwrite(shm_addr, width * height * sizeof(DATA32), 1, stdout) != 1)
267
// nothing much to do, the receiver will simply ignore the
268
// data as it's too short
269
//D("fwrite failed (%d bytes): %m\n", width * height * sizeof(DATA32));