kwo pushed a commit to branch master.

http://git.enlightenment.org/legacy/imlib2.git/commit/?id=a542fb672406be26599c089eee2c6e350bace9dd

commit a542fb672406be26599c089eee2c6e350bace9dd
Author: Kim Woelders <[email protected]>
Date:   Thu Jan 6 14:56:38 2022 +0100

    Add svg loader
---
 configure.ac                     |   2 +
 src/lib/loaders.c                |   6 ++
 src/modules/loaders/Makefile.am  |   9 ++
 src/modules/loaders/loader_svg.c | 200 +++++++++++++++++++++++++++++++++++++++
 test/images/icon-64.svg          |   9 ++
 test/test_load.cpp               |   3 +
 6 files changed, 229 insertions(+)

diff --git a/configure.ac b/configure.ac
index 90d0cfa..90273ad 100644
--- a/configure.ac
+++ b/configure.ac
@@ -196,6 +196,7 @@ loader_check_gif() {
 EC_LOADER_CHECK(GIF,  auto, , loader_check_gif)
 EC_LOADER_CHECK(JPEG, auto, libjpeg)
 EC_LOADER_CHECK(PNG,  auto, libpng)
+EC_LOADER_CHECK(SVG,  auto, librsvg-2.0)
 EC_LOADER_CHECK(TIFF, auto, libtiff-4)
 EC_LOADER_CHECK(WEBP, auto, libwebpdemux)
 
@@ -274,6 +275,7 @@ echo " Regular image loaders"
 echo "  GIF.....................: $gif_ok"
 echo "  JPEG....................: $jpeg_ok"
 echo "  PNG.....................: $png_ok"
+echo "  SVG.....................: $svg_ok"
 echo "  TIFF....................: $tiff_ok"
 echo "  WEBP....................: $webp_ok"
 echo " Decompressors"
diff --git a/src/lib/loaders.c b/src/lib/loaders.c
index 1849677..757894b 100644
--- a/src/lib/loaders.c
+++ b/src/lib/loaders.c
@@ -35,6 +35,9 @@ static const char  *const ext_lbm[] = { "iff", "ilbm", "lbm", 
NULL };
 #ifdef BUILD_PNG_LOADER
 static const char  *const ext_png[] = { "png", NULL };
 #endif
+#ifdef BUILD_SVG_LOADER
+static const char  *const ext_svg[] = { "svg", NULL };
+#endif
 static const char  *const ext_pnm[] =
    { "pnm", "ppm", "pgm", "pbm", "pam", NULL };
 static const char  *const ext_tga[] = { "tga", NULL };
@@ -77,6 +80,9 @@ static const KnownLoader loaders_known[] = {
    {"png", ext_png},
 #endif
    {"pnm", ext_pnm},
+#ifdef BUILD_SVG_LOADER
+   {"svg", ext_svg},
+#endif
    {"tga", ext_tga},
 #ifdef BUILD_TIFF_LOADER
    {"tiff", ext_tiff},
diff --git a/src/modules/loaders/Makefile.am b/src/modules/loaders/Makefile.am
index 29866fb..d7fea3a 100644
--- a/src/modules/loaders/Makefile.am
+++ b/src/modules/loaders/Makefile.am
@@ -23,6 +23,9 @@ endif
 if BUILD_PNG_LOADER
 pkg_LTLIBRARIES += png.la
 endif
+if BUILD_SVG_LOADER
+pkg_LTLIBRARIES += svg.la
+endif
 if BUILD_TIFF_LOADER
 pkg_LTLIBRARIES += tiff.la
 endif
@@ -93,6 +96,12 @@ pnm_la_LDFLAGS       = -module -avoid-version
 pnm_la_LIBADD        = $(top_builddir)/src/lib/libImlib2.la
 pnm_la_LIBTOOLFLAGS  = --tag=disable-static
 
+svg_la_SOURCES       = loader_svg.c
+svg_la_CPPFLAGS      = $(SVG_CFLAGS) $(AM_CPPFLAGS)
+svg_la_LDFLAGS       = -module -avoid-version
+svg_la_LIBADD        = $(SVG_LIBS) $(top_builddir)/src/lib/libImlib2.la
+svg_la_LIBTOOLFLAGS  = --tag=disable-static
+
 tga_la_SOURCES       = loader_tga.c
 tga_la_LDFLAGS       = -module -avoid-version
 tga_la_LIBADD        = $(top_builddir)/src/lib/libImlib2.la
diff --git a/src/modules/loaders/loader_svg.c b/src/modules/loaders/loader_svg.c
new file mode 100644
index 0000000..78ddd73
--- /dev/null
+++ b/src/modules/loaders/loader_svg.c
@@ -0,0 +1,200 @@
+#include "loader_common.h"
+
+#include <math.h>
+#include <sys/mman.h>
+#include <librsvg/rsvg.h>
+
+#define DBG_PFX "LDR-svg"
+
+#define DPI 96
+
+static double
+u2pix(double x, int unit)
+{
+   switch (unit)
+     {
+     default:
+     case RSVG_UNIT_PERCENT:   /* 0  percentage values where 1.0 means 100% */
+     case RSVG_UNIT_PX:        /* 1  pixels */
+     case RSVG_UNIT_EM:        /* 2  em, or the current font size */
+     case RSVG_UNIT_EX:        /* 3  x-height of the current font */
+        return x;
+     case RSVG_UNIT_IN:        /* 4  inches */
+        return x * DPI;
+     case RSVG_UNIT_CM:        /* 5  centimeters */
+        return x * DPI / 2.54;
+     case RSVG_UNIT_MM:        /* 6  millimeters */
+        return x * DPI / 25.4;
+     case RSVG_UNIT_PT:        /* 7  points, or 1/72 inch */
+        return x * DPI / 72;
+     case RSVG_UNIT_PC:        /* 8  picas, or 1/6 inch (12 points) */
+        return x * DPI / 6;
+     }
+}
+
+int
+load2(ImlibImage * im, int load_data)
+{
+   int                 rc;
+   void               *fdata;
+   RsvgHandle         *rsvg;
+   GError             *error;
+   gboolean            ok;
+   cairo_surface_t    *surface;
+   cairo_t            *cr;
+   RsvgRectangle       cvb;
+
+   rc = LOAD_FAIL;
+
+   fdata = mmap(NULL, im->fsize, PROT_READ, MAP_SHARED, fileno(im->fp), 0);
+   if (fdata == MAP_FAILED)
+      return LOAD_BADFILE;
+
+   surface = NULL;
+   cr = NULL;
+
+   error = NULL;
+   rsvg = rsvg_handle_new_from_data(fdata, im->fsize, &error);
+   if (!rsvg)
+      goto quit;
+
+   rc = LOAD_BADIMAGE;          /* Format accepted */
+
+   {
+      gboolean            out_has_width, out_has_height, out_has_viewbox;
+      RsvgLength          out_width = { }, out_height = { };
+      RsvgRectangle       out_viewbox = { };
+      rsvg_handle_get_intrinsic_dimensions(rsvg,
+                                           &out_has_width,
+                                           &out_width,
+                                           &out_has_height,
+                                           &out_height,
+                                           &out_has_viewbox, &out_viewbox);
+      D("WH:%d%d %.1fx%.1f (%d/%d: %.1fx%.1f) VB:%d %.1f,%.1f %.1fx%.1f\n",
+        out_has_width, out_has_height,
+        out_width.length, out_height.length, out_width.unit, out_height.unit,
+        u2pix(out_width.length, out_width.unit),
+        u2pix(out_height.length, out_height.unit),
+        out_has_viewbox,
+        out_viewbox.x, out_viewbox.y, out_viewbox.width, out_viewbox.height);
+
+      if (out_has_width && out_has_height)
+        {
+           im->w = lrint(u2pix(out_width.length, out_width.unit));
+           im->h = lrint(u2pix(out_height.length, out_height.unit));
+           D("Choose rsvg_handle_get_intrinsic_dimensions width/height\n");
+#if !IMLIB2_DEBUG
+           goto got_size;
+#endif
+        }
+
+      if (out_has_viewbox && (im->w <= 0 || im->w <= 0))
+        {
+           im->w = ceil(out_viewbox.width);
+           im->h = ceil(out_viewbox.height);
+           D("Choose rsvg_handle_get_intrinsic_dimensions viewbox\n");
+#if !IMLIB2_DEBUG
+           goto got_size;
+#endif
+        }
+   }
+
+#if 0
+#if LIBRSVG_CHECK_VERSION(2, 52, 0)
+   {
+      gdouble             dw = 0, dh = 0;
+
+      ok = rsvg_handle_get_intrinsic_size_in_pixels(rsvg, &dw, &dh);
+      D("ok=%d WxH=%.1fx%.1f\n", ok, dw, dh);
+      if (ok && (im->w <= 0 || im->w <= 0))
+        {
+           im->w = ceil(dw);
+           im->h = ceil(dh);
+           D("Choose rsvg_handle_get_intrinsic_size_in_pixels width/height\n");
+#if !IMLIB2_DEBUG
+           goto got_size;
+#endif
+        }
+   }
+#endif
+#endif
+
+   {
+      RsvgRectangle       out_ink_rect = { }, out_logical_rect = { };
+
+      ok = rsvg_handle_get_geometry_for_element(rsvg, NULL,
+                                                &out_ink_rect,
+                                                &out_logical_rect, &error);
+      D("ok=%d Ink: %.1f,%.1f %.1fx%.1f Log: %.1f,%.1f %.1fx%.1f\n", ok,
+        out_ink_rect.x, out_ink_rect.y, out_ink_rect.width, 
out_ink_rect.height,
+        out_logical_rect.x, out_logical_rect.y, out_logical_rect.width,
+        out_logical_rect.height);
+      if (ok && (im->w <= 0 || im->w <= 0))
+        {
+           im->w = ceil(out_ink_rect.width);
+           im->h = ceil(out_ink_rect.height);
+           D("Choose rsvg_handle_get_geometry_for_element ink rect 
width/height\n");
+#if !IMLIB2_DEBUG
+           goto got_size;
+#endif
+        }
+   }
+
+#if !IMLIB2_DEBUG
+ got_size:
+#endif
+   if (!IMAGE_DIMENSIONS_OK(im->w, im->h))
+      goto quit;
+
+   UPDATE_FLAG(im->flags, F_HAS_ALPHA, 1);
+
+   if (!load_data)
+      QUIT_WITH_RC(LOAD_SUCCESS);
+
+   /* Load data */
+
+   if (!__imlib_AllocateData(im))
+      QUIT_WITH_RC(LOAD_OOM);
+
+   memset(im->data, 0, im->w * im->h * sizeof(DATA32));
+   surface =
+      cairo_image_surface_create_for_data((void *)im->data, 
CAIRO_FORMAT_ARGB32,
+                                          im->w, im->h,
+                                          im->w * sizeof(DATA32));;
+   if (!surface)
+      QUIT_WITH_RC(LOAD_OOM);
+
+   cr = cairo_create(surface);
+   if (!cr)
+      QUIT_WITH_RC(LOAD_OOM);
+
+   cvb.x = cvb.y = 0;
+   cvb.width = im->w;
+   cvb.height = im->h;
+   rsvg_handle_render_document(rsvg, cr, &cvb, &error);
+
+   if (im->lc)
+      __imlib_LoadProgress(im, im->frame_x, im->frame_y, im->w, im->h);
+
+   rc = LOAD_SUCCESS;
+
+ quit:
+   if (surface)
+      cairo_surface_destroy(surface);
+   if (cr)
+      cairo_destroy(cr);
+   if (rc <= 0)
+      __imlib_FreeData(im);
+   if (rsvg)
+      g_object_unref(rsvg);
+   munmap(fdata, im->fsize);
+
+   return rc;
+}
+
+void
+formats(ImlibLoader * l)
+{
+   static const char  *const list_formats[] = { "svg" };
+   __imlib_LoaderSetFormats(l, list_formats, ARRAY_SIZE(list_formats));
+}
diff --git a/test/images/icon-64.svg b/test/images/icon-64.svg
new file mode 100644
index 0000000..72558ce
--- /dev/null
+++ b/test/images/icon-64.svg
@@ -0,0 +1,9 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<svg xmlns="http://www.w3.org/2000/svg"; 
xmlns:xlink="http://www.w3.org/1999/xlink"; width="64px" height="64px" 
viewBox="0 0 64 64" version="1.1">
+<g id="surface1">
+<path style=" 
stroke:none;fill-rule:nonzero;fill:rgb(0%,0%,0%);fill-opacity:1;" d="M 64 0 L 
50.910156 0 L 0 64 L 13.089844 64 "/>
+<path style=" 
stroke:none;fill-rule:nonzero;fill:rgb(100%,100%,100%);fill-opacity:1;" d="M 
5.816406 64 L 32 32 L 39.273438 32 L 13.089844 64 Z M 58.183594 0 L 32 32 L 
24.726562 32 L 50.910156 0 "/>
+<path style=" 
stroke:none;fill-rule:nonzero;fill:rgb(0%,0%,0%);fill-opacity:1;" d="M 0 0 L 16 
0 L 64 64 L 48 64 "/>
+<path style=" 
stroke:none;fill-rule:nonzero;fill:rgb(100%,100%,100%);fill-opacity:1;" d="M 
58.183594 0 L 56.726562 0 L 5.816406 64 L 7.273438 64 "/>
+</g>
+</svg>
diff --git a/test/test_load.cpp b/test/test_load.cpp
index b15fe9a..1728263 100644
--- a/test/test_load.cpp
+++ b/test/test_load.cpp
@@ -30,6 +30,9 @@ static const char  *const pfxs[] = {
    "pbm",                       // pnm
    "ppm",                       // pnm
    "tga",
+#ifdef BUILD_SVG_LOADER
+   "svg",
+#endif
    "tiff",
    "webp",
    "xbm",

-- 


Reply via email to