summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorcaro <caro@7cbeb6ba-43b4-40fd-8cce-4c39aea84d33>2012-05-16 21:28:36 +0000
committercaro <caro@7cbeb6ba-43b4-40fd-8cce-4c39aea84d33>2012-05-16 21:28:36 +0000
commit35b235bee955c4957738abe613d4f56492da4329 (patch)
tree89d7c0f6d90546a1262cfc7bef792999dcb72026
parentf3578316ab423f08c7fb6738524b737c14ea5362 (diff)
downloadevas-35b235bee955c4957738abe613d4f56492da4329.tar.gz
evas-35b235bee955c4957738abe613d4f56492da4329.tar.bz2
evas-35b235bee955c4957738abe613d4f56492da4329.zip
Evas: use Esvg for svg rendering.
If Esvg is not found, librsvg is used (if found) See README to see how to installe Esvg git-svn-id: svn+ssh://svn.enlightenment.org/var/svn/e/trunk/evas@71180 7cbeb6ba-43b4-40fd-8cce-4c39aea84d33
-rw-r--r--README25
-rw-r--r--m4/evas_check_loader.m420
-rw-r--r--src/modules/loaders/svg/Makefile.am12
-rw-r--r--src/modules/loaders/svg/evas_image_load_esvg.c301
-rw-r--r--src/modules/loaders/svg/evas_image_load_rsvg.c (renamed from src/modules/loaders/svg/evas_image_load_svg.c)0
5 files changed, 344 insertions, 14 deletions
diff --git a/README b/README
index 78c068b2..f7b07634 100644
--- a/README
+++ b/README
@@ -27,7 +27,7 @@ Recommended:
liblinebreak
Optional:
- XCB SDL OpenGL librsvg libtiff libgif edb DirectFB evas_generic_loaders
+ XCB SDL OpenGL esvg/librsvg libtiff libgif edb DirectFB evas_generic_loaders
Evas is a clean display canvas API for several target display systems
that can draw anti-aliased text, smooth super and sub-sampled scaled
@@ -506,11 +506,24 @@ bitmap data in binary or ascii format
--enable-image-loader-svg[=static]
-this loader can load svg files via librsvg (thus it is a dependency).
-this loader supports load options to set the dpi to decode the svg at
-etc. which can then be used to create scalable images that scale to
-any size without becoming blocky or blurry, if the source is an svg
-file.
+this loader can load svg files via esvg or librsvg (thus it is a
+dependency). This loader supports load options to set the dpi to
+decode the svg at etc. which can then be used to create scalable
+images that scale to any size without becoming blocky or blurry, if
+the source is an svg file.
+
+Esvg can be found here:
+
+http://code.google.com/p/enesim/
+
+Install (in that order):
+
+enesim
+emage
+etex
+ender
+etch
+egueb
--enable-image-loader-tiff[=static]
diff --git a/m4/evas_check_loader.m4 b/m4/evas_check_loader.m4
index a2650940..ea501570 100644
--- a/m4/evas_check_loader.m4
+++ b/m4/evas_check_loader.m4
@@ -228,15 +228,21 @@ AC_DEFUN([EVAS_CHECK_LOADER_DEP_SVG],
[
requirement=""
-have_dep="no"
+have_esvg="no"
evas_image_loader_[]$1[]_cflags=""
evas_image_loader_[]$1[]_libs=""
-PKG_CHECK_MODULES([SVG], [librsvg-2.0 >= 2.14.0
- cairo >= 1.0.0],
- [have_dep="yes" requirement="librsvg-2.0 cairo"],
- [have_svg="no"]
-)
+PKG_CHECK_MODULES([SVG],
+ [esvg >= 0.0.16],
+ [have_dep="yes" have_esvg="yes" requirement="esvg"],
+ [have_dep="no"])
+
+if test "x${have_dep}" = "xno" ; then
+ PKG_CHECK_MODULES([SVG],
+ [librsvg-2.0 >= 2.14.0 cairo >= 1.0.0],
+ [have_dep="yes" requirement="librsvg-2.0 cairo"],
+ [have_dep="no"])
+fi
if test "x${have_dep}" = "xyes" ; then
evas_image_loader_[]$1[]_cflags="${SVG_CFLAGS}"
@@ -250,6 +256,8 @@ if test "x$2" = "xstatic" ; then
requirement_evas="${requirement} ${requirement_evas}"
fi
+AM_CONDITIONAL(BUILD_LOADER_SVG_ESVG, [test "x${have_esvg}" = "xyes"])
+
if test "x${have_dep}" = "xyes" ; then
m4_default([$3], [:])
else
diff --git a/src/modules/loaders/svg/Makefile.am b/src/modules/loaders/svg/Makefile.am
index 39cb1b00..2b47de32 100644
--- a/src/modules/loaders/svg/Makefile.am
+++ b/src/modules/loaders/svg/Makefile.am
@@ -17,7 +17,11 @@ if !EVAS_STATIC_BUILD_SVG
pkgdir = $(libdir)/evas/modules/loaders/svg/$(MODULE_ARCH)
pkg_LTLIBRARIES = module.la
-module_la_SOURCES = evas_image_load_svg.c
+if BUILD_LOADER_SVG_ESVG
+module_la_SOURCES = evas_image_load_esvg.c
+else
+module_la_SOURCES = evas_image_load_rsvg.c
+endif
module_la_LIBADD = @EINA_LIBS@ @evas_image_loader_svg_libs@ $(top_builddir)/src/lib/libevas.la
module_la_LDFLAGS = -no-undefined @lt_enable_auto_import@ -module -avoid-version
@@ -26,7 +30,11 @@ module_la_LIBTOOLFLAGS = --tag=disable-static
else
noinst_LTLIBRARIES = libevas_loader_svg.la
-libevas_loader_svg_la_SOURCES = evas_image_load_svg.c
+if BUILD_LOADER_SVG_ESVG
+libevas_loader_svg_la_SOURCES = evas_image_load_esvg.c
+else
+libevas_loader_svg_la_SOURCES = evas_image_load_rsvg.c
+endif
libevas_loader_svg_la_LIBADD = @evas_image_loader_svg_libs@
endif
diff --git a/src/modules/loaders/svg/evas_image_load_esvg.c b/src/modules/loaders/svg/evas_image_load_esvg.c
new file mode 100644
index 00000000..92100f6e
--- /dev/null
+++ b/src/modules/loaders/svg/evas_image_load_esvg.c
@@ -0,0 +1,301 @@
+#include <math.h>
+
+#include "evas_common.h"
+#include "evas_private.h"
+
+#include <Esvg.h>
+
+static inline Eina_Bool evas_image_load_file_is_svg(const char *file) EINA_ARG_NONNULL(1) EINA_PURE;
+static Eina_Bool evas_image_load_file_head_svg(Image_Entry *ie, const char *file, const char *key, int *error) EINA_ARG_NONNULL(1, 2, 4);
+static Eina_Bool evas_image_load_file_data_svg(Image_Entry *ie, const char *file, const char *key, int *error) EINA_ARG_NONNULL(1, 2, 4);
+
+Evas_Image_Load_Func evas_image_load_svg_func =
+{
+ EINA_FALSE,
+ evas_image_load_file_head_svg,
+ evas_image_load_file_data_svg,
+ NULL,
+ EINA_FALSE
+};
+
+static Eina_Bool esvg_initialized = EINA_FALSE;
+
+
+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 Eina_Bool
+evas_image_load_file_head_svg(Image_Entry *ie, const char *file, const char *key __UNUSED__, int *error)
+{
+ Ender_Element *e;
+ int w, h;
+ double sw, sh;
+
+ /* ignore all files not called .svg or .svg.gz - because rsvg has a leak
+ * where closing the handle doesn't free mem */
+ if (!evas_image_load_file_is_svg(file))
+ {
+ *error = EVAS_LOAD_ERROR_UNKNOWN_FORMAT;
+ return EINA_FALSE;
+ }
+
+ e = esvg_parser_load(file, NULL, NULL);
+ if (!e)
+ {
+ *error = EVAS_LOAD_ERROR_DOES_NOT_EXIST;
+ return EINA_FALSE;
+ }
+
+ esvg_renderable_x_dpi_set(e, 75.0);
+ esvg_renderable_y_dpi_set(e, 75.0);
+ esvg_svg_actual_width_get(e, &sw);
+ esvg_svg_actual_height_get(e, &sh);
+ esvg_element_setup(e, NULL);
+ w = (int)ceil(sw);
+ h = (int)ceil(sh);
+ if ((w < 1) || (h < 1) || (w > IMG_MAX_SIZE) || (h > IMG_MAX_SIZE) ||
+ IMG_TOO_BIG(w, h))
+ {
+ ender_element_delete(e);
+ if (IMG_TOO_BIG(w, h))
+ *error = EVAS_LOAD_ERROR_RESOURCE_ALLOCATION_FAILED;
+ else
+ *error = EVAS_LOAD_ERROR_GENERIC;
+ return EINA_FALSE;
+ }
+ if (ie->load_opts.scale_down_by > 1)
+ {
+ w /= ie->load_opts.scale_down_by;
+ h /= ie->load_opts.scale_down_by;
+ }
+ else if (ie->load_opts.dpi > 0.0)
+ {
+ w = (w * ie->load_opts.dpi) / 75.0;
+ h = (h * ie->load_opts.dpi) / 75.0;
+ }
+ else if ((ie->load_opts.w > 0) &&
+ (ie->load_opts.h > 0))
+ {
+ unsigned int w2, h2;
+
+ w2 = ie->load_opts.w;
+ h2 = (ie->load_opts.w * h) / w;
+ if (h2 > ie->load_opts.h)
+ {
+ h2 = ie->load_opts.h;
+ w2 = (ie->load_opts.h * w) / h;
+ }
+ w = w2;
+ h = h2;
+ }
+ if (w < 1) w = 1;
+ if (h < 1) h = 1;
+ ie->w = w;
+ ie->h = h;
+ ie->flags.alpha = 1;
+
+ ender_element_delete(e);
+
+ *error = EVAS_LOAD_ERROR_NONE;
+ return EINA_TRUE;
+}
+
+/** FIXME: All evas loaders need to be tightened up **/
+static Eina_Bool
+evas_image_load_file_data_svg(Image_Entry *ie, const char *file, const char *key __UNUSED__, int *error)
+{
+ DATA32 *pixels;
+ Ender_Element *e;
+ Enesim_Error *err = NULL;
+ Enesim_Surface *s;
+ void *data;
+ size_t stride;
+ int w, h;
+ double sw, sh;
+
+ if (!evas_image_load_file_is_svg(file))
+ {
+ *error = EVAS_LOAD_ERROR_UNKNOWN_FORMAT;
+ return EINA_FALSE;
+ }
+
+ e = esvg_parser_load(file, NULL, NULL);
+ if (!e)
+ {
+ *error = EVAS_LOAD_ERROR_DOES_NOT_EXIST;
+ return EINA_FALSE;
+ }
+
+ esvg_renderable_x_dpi_set(e, 75.0);
+ esvg_renderable_y_dpi_set(e, 75.0);
+ esvg_svg_actual_width_get(e, &sw);
+ esvg_svg_actual_height_get(e, &sh);
+ w = (int)ceil(sw);
+ h = (int)ceil(sh);
+ if ((w < 1) || (h < 1) || (w > IMG_MAX_SIZE) || (h > IMG_MAX_SIZE))
+ {
+ ender_element_delete(e);
+ if (IMG_TOO_BIG(w, h))
+ *error = EVAS_LOAD_ERROR_RESOURCE_ALLOCATION_FAILED;
+ else
+ *error = EVAS_LOAD_ERROR_GENERIC;
+ goto unref_renderer;
+ }
+ if (ie->load_opts.scale_down_by > 1)
+ {
+ w /= ie->load_opts.scale_down_by;
+ h /= ie->load_opts.scale_down_by;
+ }
+ else if (ie->load_opts.dpi > 0.0)
+ {
+ w = (w * ie->load_opts.dpi) / 75.0;
+ h = (h * ie->load_opts.dpi) / 75.0;
+ }
+ else if ((ie->load_opts.w > 0) &&
+ (ie->load_opts.h > 0))
+ {
+ unsigned int w2, h2;
+
+ w2 = ie->load_opts.w;
+ h2 = (ie->load_opts.w * h) / w;
+ if (h2 > ie->load_opts.h)
+ {
+ h2 = ie->load_opts.h;
+ w2 = (ie->load_opts.h * w) / h;
+ }
+ w = w2;
+ h = h2;
+ }
+ if (w < 1) w = 1;
+ if (h < 1) h = 1;
+ if ((w != (int)ie->w) || (h != (int)ie->h))
+ {
+ *error = EVAS_LOAD_ERROR_GENERIC;
+ goto unref_renderer;
+ }
+ ie->flags.alpha = 1;
+ evas_cache_image_surface_alloc(ie, w, h);
+ pixels = evas_cache_image_pixels(ie);
+ if (!pixels)
+ {
+ *error = EVAS_LOAD_ERROR_RESOURCE_ALLOCATION_FAILED;
+ goto unref_renderer;
+ }
+
+ memset(pixels, 0, w * h * sizeof(DATA32));
+
+ s = enesim_surface_new(ENESIM_FORMAT_ARGB8888, w, h);
+ if (!s)
+ {
+ *error = EVAS_LOAD_ERROR_RESOURCE_ALLOCATION_FAILED;
+ goto unref_renderer;
+ }
+
+ esvg_element_setup(e, NULL);
+
+ if (!esvg_renderable_draw(e, s, NULL, 0, 0, &err))
+ {
+ *error = EVAS_LOAD_ERROR_GENERIC;
+ enesim_error_dump(err);
+ goto unref_surface;
+ }
+
+ if (!enesim_surface_data_get(s, &data, &stride))
+ {
+ *error = EVAS_LOAD_ERROR_GENERIC;
+ goto unref_surface;
+ }
+
+/* printf("test : %d %d\n", w * h * sizeof(int), h * stride); */
+/* if ((w * h * sizeof(int)) != (h * stride)) */
+/* { */
+/* *error = EVAS_LOAD_ERROR_GENERIC; */
+/* goto unref_surface; */
+/* } */
+
+ /* FIXME: scale to (double)ie->w / dim.em, (double)ie->h / dim.ex */
+
+ memcpy (pixels, data, h * stride);
+
+ enesim_surface_unref(s);
+ ender_element_delete(e);
+
+ evas_common_image_set_alpha_sparse(ie);
+
+ return EINA_TRUE;
+
+ unref_surface:
+ enesim_surface_unref(s);
+ unref_renderer:
+ ender_element_delete(e);
+
+ return EINA_FALSE;
+}
+
+static int
+module_open(Evas_Module *em)
+{
+ if (!em) return 0;
+ em->functions = (void *)(&evas_image_load_svg_func);
+ if (!esvg_initialized) esvg_init();
+ esvg_initialized = EINA_TRUE;
+ return 1;
+}
+
+static void
+module_close(Evas_Module *em __UNUSED__)
+{
+ if (!esvg_initialized) return;
+ esvg_shutdown();
+ esvg_initialized = EINA_FALSE;
+}
+
+static Evas_Module_Api evas_modapi =
+{
+ EVAS_MODULE_API_VERSION,
+ "svg",
+ "none",
+ {
+ module_open,
+ module_close
+ }
+};
+
+EVAS_MODULE_DEFINE(EVAS_MODULE_TYPE_IMAGE_LOADER, image_loader, svg);
+
+#ifndef EVAS_STATIC_BUILD_SVG
+EVAS_EINA_MODULE_DEFINE(image_loader, svg);
+#endif
diff --git a/src/modules/loaders/svg/evas_image_load_svg.c b/src/modules/loaders/svg/evas_image_load_rsvg.c
index dc0fc8d3..dc0fc8d3 100644
--- a/src/modules/loaders/svg/evas_image_load_svg.c
+++ b/src/modules/loaders/svg/evas_image_load_rsvg.c