Revert "Revert "Backported missing svg loader from upstream"" 23/211223/2
authorHermet Park <hermetpark@gmail.com>
Wed, 31 Jul 2019 07:30:03 +0000 (16:30 +0900)
committerHermet Park <chuneon.park@samsung.com>
Mon, 5 Aug 2019 12:48:47 +0000 (12:48 +0000)
This reverts commit b016b078d8baa2d0d8d753415133aac0cdc1364a.

Change-Id: I038c93d2e2faae9658b82283320480849f75fdb7

src/generic/evas/svg/main.c [new file with mode: 0644]
src/generic/evas/svg/meson.build [new file with mode: 0644]

diff --git a/src/generic/evas/svg/main.c b/src/generic/evas/svg/main.c
new file mode 100644 (file)
index 0000000..f197330
--- /dev/null
@@ -0,0 +1,236 @@
+#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;
+
+}
+
diff --git a/src/generic/evas/svg/meson.build b/src/generic/evas/svg/meson.build
new file mode 100644 (file)
index 0000000..4e39e74
--- /dev/null
@@ -0,0 +1,12 @@
+generic_src = files([
+  'main.c'
+])
+
+rsvg = dependency('librsvg-2.0')
+
+if rsvg.version() >= '2.36.0'
+  config_h.set('HAVE_SVG_2_36', '1')
+endif
+
+generic_deps = [rsvg]
+generic_support = ['svgz', 'svg.gz']