summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCedric BAIL <cedric.bail@free.fr>2012-05-18 04:53:35 +0000
committerCedric BAIL <cedric.bail@free.fr>2012-05-18 04:53:35 +0000
commit1d6358d92d908463eb43c4f08a7a1b27abcb2a9e (patch)
treef622636bc6ed188615aceb0acd48a44ac4f1179f
parentc3724967687040771c140ee5688ded7e58b3b10e (diff)
downloadevas_generic_loaders-1d6358d92d908463eb43c4f08a7a1b27abcb2a9e.tar.gz
evas_generic_loaders: add a rsvg generic loader.
NOTE: we have to much user complaining about instability in e17 due to librsvg. Moving it to a generic loader "resolve" this issue... SVN revision: 71222
-rw-r--r--ChangeLog5
-rw-r--r--NEWS9
-rw-r--r--configure.ac5
-rw-r--r--src/bin/Makefile.am3
-rw-r--r--src/bin/svg/Makefile.am21
-rw-r--r--src/bin/svg/main.c212
6 files changed, 255 insertions, 0 deletions
diff --git a/ChangeLog b/ChangeLog
index affb093..487d24a 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -13,3 +13,8 @@
2012-04-26 Carsten Haitzler (The Rasterman)
1.2.0 release
+
+2012-05-18 Cedric Bail
+
+ * Make rsvg backend use the generic backend as it is our main
+ source of crash in e17.
diff --git a/NEWS b/NEWS
index c3ffaf3..a76ebdd 100644
--- a/NEWS
+++ b/NEWS
@@ -1,3 +1,12 @@
+Evas Generic Loaders 1.3.0
+
+Changes since Evas Generic Loaders 1.2.0:
+-----------------------------------------
+
+Additions:
+
+ * Add a librsvg generic loader.
+
Evas Generic Loaders 1.2.0
Changes since Evas Generic Loaders 1.1.0:
diff --git a/configure.ac b/configure.ac
index cc20d90..c2b0573 100644
--- a/configure.ac
+++ b/configure.ac
@@ -66,6 +66,8 @@ PKG_CHECK_MODULES([SPECTRE], [libspectre], [have_ps="yes"], [have_ps="no"])
PKG_CHECK_MODULES([LIBRAW], [libraw], [have_raw="yes"], [have_raw="no"])
+PKG_CHECK_MODULES([SVG], [librsvg-2.0 >= 2.14.0 cairo >= 1.0.0], [have_svg="yes"], [have_svg="no"])
+
GST_REQS=0.10.13
GSTPLUG_REQS=0.10.13
GST_MAJORMINOR=0.10
@@ -81,6 +83,7 @@ AM_CONDITIONAL(HAVE_GST, test "x${have_gst}" = "xyes")
AM_CONDITIONAL([HAVE_PDF], [test "x${have_poppler}" = "xyes"])
AM_CONDITIONAL([HAVE_PS], [test "x${have_ps}" = "xyes"])
AM_CONDITIONAL(HAVE_RAW, [test "x${have_raw}" = "xyes"])
+AM_CONDITIONAL([HAVE_SVG], [test "x${have_svg}" = "xyes"])
### Checks for header files
@@ -137,6 +140,7 @@ src/bin/pdf/Makefile
src/bin/ps/Makefile
src/bin/raw/Makefile
src/bin/xcf/Makefile
+src/bin/svg/Makefile
])
AC_OUTPUT
@@ -160,6 +164,7 @@ echo " Gstreamer............: ${have_gst}"
echo " PDF..................: ${have_poppler}"
echo " PS...................: ${have_ps}"
echo " RAW..................: ${have_raw}"
+echo " SVG..................: ${have_svg}"
echo
echo "Compilation............: make (or gmake)"
echo " CPPFLAGS.............: $CPPFLAGS"
diff --git a/src/bin/Makefile.am b/src/bin/Makefile.am
index ac0215d..040ae49 100644
--- a/src/bin/Makefile.am
+++ b/src/bin/Makefile.am
@@ -19,3 +19,6 @@ if HAVE_RAW
SUBDIRS += raw
endif
+if HAVE_SVG
+SUBDIRS += svg
+endif
diff --git a/src/bin/svg/Makefile.am b/src/bin/svg/Makefile.am
new file mode 100644
index 0000000..6ea0778
--- /dev/null
+++ b/src/bin/svg/Makefile.am
@@ -0,0 +1,21 @@
+MAINTAINERCLEANFILES = Makefile.in
+
+AM_CPPFLAGS = \
+-I$(top_srcdir) \
+-I$(top_srcdir)/src \
+-I$(top_srcdir)/src/bin \
+-I$(top_srcdir)/src/bin/common \
+-I$(top_srcdir)/src/bin/svg \
+-DPACKAGE_BIN_DIR=\"$(bindir)\" \
+-DPACKAGE_LIB_DIR=\"$(libdir)\" \
+-DPACKAGE_DATA_DIR=\"$(datadir)/$(PACKAGE)\" \
+@EINA_CFLAGS@
+
+bin_PROGRAMS = evas_image_loader.svg
+bindir = $(libdir)/evas/utils
+
+evas_image_loader_svg_SOURCES = main.c $(top_srcdir)/src/bin/common/shmfile.c
+evas_image_loader_svg_CFLAGS = @SVG_CFLAGS@
+evas_image_loader_svg_LDADD = @SVG_LIBS@ @SHM_OPEN_LIBS@ -lm
+evas_image_loader_svg_LDFLAGS =
+
diff --git a/src/bin/svg/main.c b/src/bin/svg/main.c
new file mode 100644
index 0000000..021fc64
--- /dev/null
+++ b/src/bin/svg/main.c
@@ -0,0 +1,212 @@
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include <stdio.h>
+#include "shmfile.h"
+
+#include <Eina.h>
+
+#include <librsvg/rsvg.h>
+#include <librsvg/rsvg-cairo.h>
+
+#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)
+{
+ rsvg_init();
+
+ if (!evas_image_load_file_is_svg(file)) return 0;
+
+ rsvg = rsvg_handle_new_from_file(file, NULL);
+
+ 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.
+ rsvg_term();
+}
+
+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]);
+ }
+ }
+
+ 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");
+ fwrite(shm_addr, width * height * sizeof(DATA32), 1, stdout);
+ }
+ shm_free();
+ }
+ }
+ _svg_shutdown();
+ return 0;
+
+}
+