--- /dev/null
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include <stdio.h>
+#include "shmfile.h"
+#include "timeout.h"
+
+#include <Eina.h>
+
+#include <librsvg/rsvg.h>
+#ifndef LIBRSVG_CHECK_VERSION
+# include <librsvg/librsvg-features.h>
+#endif
+#if LIBRSVG_CHECK_VERSION(2,36,2)
+#else
+# include <librsvg/rsvg-cairo.h>
+#endif
+
+#define DATA32 unsigned int
+
+static RsvgHandle *rsvg = NULL;
+static int width = 0;
+static int height = 0;
+static RsvgDimensionData dim;
+
+static inline Eina_Bool evas_image_load_file_is_svg(const char *file)
+{
+ int i, len = strlen(file);
+ Eina_Bool is_gz = EINA_FALSE;
+
+ for (i = len - 1; i > 0; i--)
+ {
+ if (file[i] == '.')
+ {
+ if (is_gz)
+ break;
+ else if (strcasecmp(file + i + 1, "gz") == 0)
+ is_gz = EINA_TRUE;
+ else
+ break;
+ }
+ }
+
+ if (i < 1) return EINA_FALSE;
+ i++;
+ if (i >= len) return EINA_FALSE;
+ if (strncasecmp(file + i, "svg", 3) != 0) return EINA_FALSE;
+ i += 3;
+ if (is_gz)
+ {
+ if (file[i] == '.') return EINA_TRUE;
+ else return EINA_FALSE;
+ }
+ else
+ {
+ if (file[i] == '\0') return EINA_TRUE;
+ else if (((file[i] == 'z') || (file[i] == 'Z')) && (!file[i + 1])) return EINA_TRUE;
+ else return EINA_FALSE;
+ }
+}
+
+static int
+_svg_init(const char *file)
+{
+#ifdef HAVE_SVG_2_36
+# if !defined(GLIB_VERSION_2_36)
+ g_type_init();
+# endif
+#else
+ rsvg_init();
+#endif
+
+ if (!evas_image_load_file_is_svg(file)) return 0;
+
+ rsvg = rsvg_handle_new_from_file(file, NULL);
+ if (!rsvg) return 0;
+
+ return 1;
+}
+
+static void
+_svg_shutdown(void)
+{
+ if (rsvg)
+ {
+ rsvg_handle_close(rsvg, NULL);
+ g_object_unref(rsvg);
+ }
+ // Maybe it's not crashing anymore, let's try it.
+#ifndef HAVE_SVG_2_36
+ rsvg_term();
+#endif
+}
+
+static int
+read_svg_header(int scale_down, double dpi, int size_w, int size_h)
+{
+ rsvg_handle_set_dpi(rsvg, 75.0);
+ rsvg_handle_get_dimensions(rsvg, &dim);
+ width = dim.width;
+ height = dim.height;
+
+ if ((width < 1) || (height < 1)) return 0;
+
+ if (scale_down > 1)
+ {
+ width /= scale_down;
+ height /= scale_down;
+ }
+ else if (dpi > 0.0)
+ {
+ width = (width * dpi) / 75;
+ height = (height * dpi) / 75;
+ }
+ else if (size_w > 0 && size_h > 0)
+ {
+ int w, h;
+
+ w = size_w;
+ h = (size_w * height) / width;
+ if (h > size_h)
+ {
+ h = size_h;
+ w = (size_h * width) / height;
+ }
+ width = w;
+ height = h;
+ }
+ if (width < 1) width = 1;
+ if (height < 1) height = 1;
+
+ return 1;
+}
+
+static int
+read_svg_data(void)
+{
+ cairo_surface_t *surface;
+ cairo_t *cr;
+
+ shm_alloc(width * height * (sizeof(DATA32)));
+ if (!shm_addr) return 0;
+
+ memset(shm_addr, 0, width * height * sizeof (DATA32));
+ surface = cairo_image_surface_create_for_data((unsigned char *)shm_addr, CAIRO_FORMAT_ARGB32,
+ width, height, width * sizeof(DATA32));;
+ if (!surface) return 0;
+
+ cr = cairo_create(surface);
+ if (!cr) return 0;
+
+ cairo_scale(cr, (double) width / dim.em, (double) height / dim.ex);
+ rsvg_handle_render_cairo(rsvg, cr);
+ cairo_surface_destroy(surface);
+ cairo_destroy(cr);
+
+ return 1;
+}
+
+int main(int argc, char **argv)
+{
+ char *file;
+ int i;
+ int head_only = 0;
+ int scale_down = 0;
+ double dpi = 0.0;
+ int size_w = 0, size_h = 0;
+
+ if (argc < 2) return -1;
+ file = argv[1];
+
+ for (i = 2; i < argc; ++i)
+ {
+ if (!strcmp(argv[i], "-head"))
+ head_only = 1;
+ else if (!strcmp(argv[i], "-key"))
+ { // not used by svg loader
+ i++;
+ // const char *key = argv[i];
+ }
+ else if (!strcmp(argv[i], "-opt-scale-down-by"))
+ {
+ i++;
+ scale_down = atoi(argv[i]);
+ }
+ else if (!strcmp(argv[i], "-opt-dpi"))
+ {
+ i++;
+ dpi = ((double)atoi(argv[i])) / 1000.0;
+ }
+ else if (!strcmp(argv[i], "-opt-size"))
+ {
+ i++;
+ size_w = atoi(argv[i]);
+ i++;
+ size_h = atoi(argv[i]);
+ }
+ }
+
+ timeout_init(5);
+
+ if (!_svg_init(file)) return -1;
+ if (!read_svg_header(scale_down, dpi, size_w, size_h)) return -1;
+
+ if (head_only != 0)
+ {
+ printf("size %d %d\n", width, height);
+ printf("alpha 1\n");
+ printf("done\n");
+ }
+ else
+ {
+ if (read_svg_data())
+ {
+ printf("size %d %d\n", width, height);
+ printf("alpha 1\n");
+ if (shm_fd >= 0) printf("shmfile %s\n", shmfile);
+ else
+ {
+ printf("data\n");
+ if (fwrite(shm_addr, width * height * sizeof(DATA32), 1, stdout) != 1)
+ {
+ // nothing much to do, the receiver will simply ignore the
+ // data as it's too short
+ //D("fwrite failed (%d bytes): %m\n", width * height * sizeof(DATA32));
+ }
+ }
+ shm_free();
+ }
+ }
+ _svg_shutdown();
+ fflush(stdout);
+ return 0;
+
+}
+