diff options
author | Cedric BAIL <cedric.bail@free.fr> | 2012-05-18 04:53:35 +0000 |
---|---|---|
committer | Cedric BAIL <cedric.bail@free.fr> | 2012-05-18 04:53:35 +0000 |
commit | 1d6358d92d908463eb43c4f08a7a1b27abcb2a9e (patch) | |
tree | f622636bc6ed188615aceb0acd48a44ac4f1179f | |
parent | c3724967687040771c140ee5688ded7e58b3b10e (diff) | |
download | evas_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-- | ChangeLog | 5 | ||||
-rw-r--r-- | NEWS | 9 | ||||
-rw-r--r-- | configure.ac | 5 | ||||
-rw-r--r-- | src/bin/Makefile.am | 3 | ||||
-rw-r--r-- | src/bin/svg/Makefile.am | 21 | ||||
-rw-r--r-- | src/bin/svg/main.c | 212 |
6 files changed, 255 insertions, 0 deletions
@@ -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. @@ -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; + +} + |