evas: add initial Evas_Object_VG. 31/43131/1
authorCedric BAIL <cedric@osg.samsung.com>
Thu, 4 Dec 2014 10:12:57 +0000 (11:12 +0100)
committerSubhransu Mohanty <sub.mohanty@samsung.com>
Wed, 8 Jul 2015 01:54:16 +0000 (10:54 +0900)
Evas_Object_VG is meant to become an object that can hold a SVG
scenegraph inside of it.

Change-Id: Iafdfa614a98738b38ec9cdeedca68ee38618716e

20 files changed:
src/Makefile_Evas.am
src/lib/evas/Evas_Eo.h
src/lib/evas/canvas/evas_object_vg.c [new file with mode: 0644]
src/lib/evas/canvas/evas_vg.eo [new file with mode: 0644]
src/lib/evas/canvas/evas_vg_container.c [new file with mode: 0644]
src/lib/evas/canvas/evas_vg_container.eo [new file with mode: 0644]
src/lib/evas/canvas/evas_vg_gradient.c [new file with mode: 0644]
src/lib/evas/canvas/evas_vg_gradient.eo [new file with mode: 0644]
src/lib/evas/canvas/evas_vg_gradient_linear.c [new file with mode: 0644]
src/lib/evas/canvas/evas_vg_gradient_linear.eo [new file with mode: 0644]
src/lib/evas/canvas/evas_vg_gradient_radial.c [new file with mode: 0644]
src/lib/evas/canvas/evas_vg_gradient_radial.eo [new file with mode: 0644]
src/lib/evas/canvas/evas_vg_node.c [new file with mode: 0644]
src/lib/evas/canvas/evas_vg_node.eo [new file with mode: 0644]
src/lib/evas/canvas/evas_vg_private.h [new file with mode: 0644]
src/lib/evas/canvas/evas_vg_root_node.c [new file with mode: 0644]
src/lib/evas/canvas/evas_vg_root_node.eo [new file with mode: 0644]
src/lib/evas/canvas/evas_vg_shape.c [new file with mode: 0644]
src/lib/evas/canvas/evas_vg_shape.eo [new file with mode: 0644]
src/lib/evas/include/evas_private.h

index 27047cf..5602264 100644 (file)
@@ -31,7 +31,15 @@ evas_eolian_files = \
        lib/evas/canvas/evas_3d_mesh.eo\
        lib/evas/canvas/evas_3d_node.eo\
        lib/evas/canvas/evas_3d_scene.eo\
-       lib/evas/canvas/evas_3d_object.eo
+       lib/evas/canvas/evas_3d_object.eo \
+       lib/evas/canvas/evas_vg.eo \
+       lib/evas/canvas/evas_vg_node.eo \
+       lib/evas/canvas/evas_vg_container.eo \
+       lib/evas/canvas/evas_vg_shape.eo \
+       lib/evas/canvas/evas_vg_root_node.eo \
+       lib/evas/canvas/evas_vg_gradient.eo \
+       lib/evas/canvas/evas_vg_gradient_radial.eo \
+       lib/evas/canvas/evas_vg_gradient_linear.eo
 
 evas_eolian_c = $(evas_eolian_files:%.eo=%.eo.c)
 evas_eolian_h = $(evas_eolian_files:%.eo=%.eo.h) \
@@ -177,6 +185,7 @@ lib/evas/file/evas_path.h
 lib_evas_libevas_la_SOURCES += \
 $(lib_evas_file_SOURCES)
 
+# Evas_3D
 noinst_HEADERS += \
 lib/evas/include/evas_3d_utils.h
 
@@ -201,6 +210,16 @@ modules/evas/model_savers/obj/evas_model_save_obj.c \
 modules/evas/model_savers/ply/evas_model_save_ply.c \
 lib/evas/canvas/evas_3d_eet.c
 
+# Evas_VG
+lib_evas_libevas_la_SOURCES += \
+lib/evas/canvas/evas_object_vg.c \
+lib/evas/canvas/evas_vg_node.c \
+lib/evas/canvas/evas_vg_container.c \
+lib/evas/canvas/evas_vg_root_node.c \
+lib/evas/canvas/evas_vg_gradient.c \
+lib/evas/canvas/evas_vg_gradient_linear.c \
+lib/evas/canvas/evas_vg_gradient_radial.c
+
 # Engine
 lib_evas_libevas_la_SOURCES += \
 lib/evas/common/evas_op_copy_main_.c \
index d8ae826..f4c848e 100644 (file)
@@ -810,3 +810,90 @@ typedef enum _Evas_3D_Material_Attrib
 #include "canvas/evas_3d_scene.eo.h"
 
 #include "canvas/evas_3d_object.eo.h"
+
+/**
+ * Path command enum.
+ *
+ * @since 1.13
+ * @ingroup Evas_VG_Shape
+ */
+typedef enum _Evas_VG_Path_Command
+{
+  EVAS_VG_PATH_COMMAND_TYPE_END = 0, /**< End of the stream of command */
+  EVAS_VG_PATH_COMMAND_TYPE_MOVE_TO, /**< A move command type */
+  EVAS_VG_PATH_COMMAND_TYPE_LINE_TO, /**< A line command type */
+  EVAS_VG_PATH_COMMAND_TYPE_QUADRATIC_TO, /**< A quadratic command type */
+  EVAS_VG_PATH_COMMAND_TYPE_SQUADRATIC_TO, /**< A smooth quadratic command type */
+  EVAS_VG_PATH_COMMAND_TYPE_CUBIC_TO, /**< A cubic command type */
+  EVAS_VG_PATH_COMMAND_TYPE_SCUBIC_TO, /**< A smooth cubic command type */
+  EVAS_VG_PATH_COMMAND_TYPE_ARC_TO, /**< An arc command type */
+  EVAS_VG_PATH_COMMAND_TYPE_CLOSE, /**< A close command type */
+  EVAS_VG_PATH_COMMAND_TYPE_LAST, /**< Not a valid command, but last one according to this version header */
+} Evas_VG_Path_Command;
+
+/**
+ * Type of abstract VG node
+ */
+typedef Eo      Evas_VG_Node;
+
+
+/**
+ * Type describing dash
+ */
+typedef struct _Evas_VG_Dash Evas_VG_Dash;
+struct _Evas_VG_Dash
+{
+   double length;
+   double gap;
+};
+
+typedef struct _Evas_VG_Gradient_Stop Evas_VG_Gradient_Stop;
+struct _Evas_VG_Gradient_Stop
+{
+   double offset;
+   int r;
+   int g;
+   int b;
+   int a;
+};
+
+typedef enum _Evas_VG_Cap
+{
+  EVAS_VG_CAP_BUTT,
+  EVAS_VG_CAP_ROUND,
+  EVAS_VG_CAP_SQUARE,
+  EVAS_VG_CAP_LAST
+} Evas_VG_Cap;
+
+typedef enum _Evas_VG_Join
+{
+  EVAS_VG_JOIN_MITER,
+  EVAS_VG_JOIN_ROUND,
+  EVAS_VG_JOIN_BEVEL,
+  EVAS_VG_JOIN_LAST
+} Evas_VG_Join;
+
+typedef enum _Evas_VG_Gradient_Spread
+{
+  EVAS_VG_GRADIENT_SPREAD_PAD,
+  EVAS_VG_GRADIENT_SPREAD_REFLECT,
+  EVAS_VG_GRADIENT_SPREAD_REPEAT,
+  EVAS_VG_GRADIENT_SPREAD_LAST
+} Evas_VG_Gradient_Spread;
+
+/**
+ * @ingroup Evas_Object_VG
+ *
+ * @{
+ */
+#include "canvas/evas_vg.eo.h"
+/**
+ * @}
+ */
+
+#include "canvas/evas_vg_node.eo.h"
+#include "canvas/evas_vg_container.eo.h"
+#include "canvas/evas_vg_shape.eo.h"
+#include "canvas/evas_vg_gradient.eo.h"
+#include "canvas/evas_vg_gradient_linear.eo.h"
+#include "canvas/evas_vg_gradient_radial.eo.h"
diff --git a/src/lib/evas/canvas/evas_object_vg.c b/src/lib/evas/canvas/evas_object_vg.c
new file mode 100644 (file)
index 0000000..c956fb8
--- /dev/null
@@ -0,0 +1,315 @@
+#include "evas_common_private.h"
+#include "evas_private.h"
+
+#include "evas_vg_root_node.eo.h"
+
+#define MY_CLASS EVAS_VG_CLASS
+
+
+/* private magic number for rectangle objects */
+static const char o_type[] = "rectangle";
+
+const char *o_vg_type = o_type;
+
+/* private struct for rectangle object internal data */
+typedef struct _Evas_VG_Data      Evas_VG_Data;
+
+struct _Evas_VG_Data
+{
+   void             *engine_data;
+   Evas_VG_Node     *root;
+};
+
+static void evas_object_vg_render(Evas_Object *eo_obj,
+                                  Evas_Object_Protected_Data *obj,
+                                  void *type_private_data,
+                                  void *output, void *context, void *surface,
+                                  int x, int y, Eina_Bool do_async);
+static void evas_object_vg_render_pre(Evas_Object *eo_obj,
+                                      Evas_Object_Protected_Data *obj,
+                                      void *type_private_data);
+static void evas_object_vg_render_post(Evas_Object *eo_obj,
+                                       Evas_Object_Protected_Data *obj,
+                                       void *type_private_data);
+static unsigned int evas_object_vg_id_get(Evas_Object *eo_obj);
+static unsigned int evas_object_vg_visual_id_get(Evas_Object *eo_obj);
+static void *evas_object_vg_engine_data_get(Evas_Object *eo_obj);
+static int evas_object_vg_is_opaque(Evas_Object *eo_obj,
+                                    Evas_Object_Protected_Data *obj,
+                                    void *type_private_data);
+static int evas_object_vg_was_opaque(Evas_Object *eo_obj,
+                                     Evas_Object_Protected_Data *obj,
+                                     void *type_private_data);
+
+static const Evas_Object_Func object_func =
+{
+   /* methods (compulsory) */
+   NULL,
+     evas_object_vg_render,
+     evas_object_vg_render_pre,
+     evas_object_vg_render_post,
+     evas_object_vg_id_get,
+     evas_object_vg_visual_id_get,
+     evas_object_vg_engine_data_get,
+   /* these are optional. NULL = nothing */
+     NULL,
+     NULL,
+     NULL,
+     NULL,
+     evas_object_vg_is_opaque,
+     evas_object_vg_was_opaque,
+     NULL,
+     NULL,
+     NULL,
+     NULL,
+     NULL,
+     NULL,
+     NULL
+};
+
+/* the actual api call to add a vector graphic object */
+EAPI Evas_Object *
+evas_object_vg_add(Evas *e)
+{
+   MAGIC_CHECK(e, Evas, MAGIC_EVAS);
+   return NULL;
+   MAGIC_CHECK_END();
+   Evas_Object *eo_obj = eo_add(MY_CLASS, e);
+   return eo_obj;
+}
+
+void
+_evas_vg_root_node_set(Eo *obj EINA_UNUSED, Evas_VG_Data *pd, Evas_VG_Node *container)
+{
+   Evas_VG_Node *tmp;
+
+   tmp = pd->root;
+   pd->root = eo_ref(container);
+   eo_unref(tmp);
+}
+
+Evas_VG_Node *
+_evas_vg_root_node_get(Eo *obj EINA_UNUSED, Evas_VG_Data *pd)
+{
+   return pd->root;
+}
+
+void
+_evas_vg_eo_base_constructor(Eo *eo_obj, Evas_VG_Data *pd EINA_UNUSED)
+{
+   Evas_Object_Protected_Data *obj = eo_data_scope_get(eo_obj, EVAS_OBJECT_CLASS);
+   Eo *parent = NULL;
+
+   eo_do_super(eo_obj, MY_CLASS, eo_constructor());
+
+   /* set up methods (compulsory) */
+   obj->func = &object_func;
+   obj->private_data = eo_data_ref(eo_obj, MY_CLASS);
+   obj->type = o_type;
+
+   eo_do(eo_obj, parent = eo_parent_get());
+   evas_object_inject(eo_obj, obj, evas_object_evas_get(parent));
+}
+
+static void
+evas_object_vg_render(Evas_Object *eo_obj EINA_UNUSED,
+                      Evas_Object_Protected_Data *obj EINA_UNUSED,
+                      void *type_private_data EINA_UNUSED,
+                      void *output EINA_UNUSED, void *context EINA_UNUSED, void *surface EINA_UNUSED,
+                      int x EINA_UNUSED, int y EINA_UNUSED, Eina_Bool do_async EINA_UNUSED)
+{
+   /* render object to surface with context, and offxet by x,y */
+   /* obj->layer->evas->engine.func->context_color_set(output, */
+   /*                                                  context, */
+   /*                                                  obj->cur->cache.clip.r, */
+   /*                                                  obj->cur->cache.clip.g, */
+   /*                                                  obj->cur->cache.clip.b, */
+   /*                                                  obj->cur->cache.clip.a); */
+   /* obj->layer->evas->engine.func->context_anti_alias_set(output, context, */
+   /*                                                       obj->cur->anti_alias); */
+   /* obj->layer->evas->engine.func->context_multiplier_unset(output, */
+   /*                                                         context); */
+   /* obj->layer->evas->engine.func->context_render_op_set(output, context, */
+   /*                                                      obj->cur->render_op); */
+   /* obj->layer->evas->engine.func->rectangle_draw(output, */
+   /*                                               context, */
+   /*                                               surface, */
+   /*                                               obj->cur->geometry.x + x, */
+   /*                                               obj->cur->geometry.y + y, */
+   /*                                               obj->cur->geometry.w, */
+   /*                                               obj->cur->geometry.h, */
+   /*                                               do_async); */
+   // FIXME: I guess I should create an image, get the pixels data and
+   // start using that for Cairo.
+}
+
+static void
+evas_object_vg_render_pre(Evas_Object *eo_obj,
+                          Evas_Object_Protected_Data *obj,
+                          void *type_private_data EINA_UNUSED)
+{
+   int is_v, was_v;
+
+   // FIXME: Later on start doing precalc of span and stuff for all shape.
+
+   /* dont pre-render the obj twice! */
+   if (obj->pre_render_done) return;
+   obj->pre_render_done = EINA_TRUE;
+   /* pre-render phase. this does anything an object needs to do just before */
+   /* rendering. this could mean loading the image data, retrieving it from */
+   /* elsewhere, decoding video etc. */
+   /* then when this is done the object needs to figure if it changed and */
+   /* if so what and where and add the appropriate redraw rectangles */
+   /* if someone is clipping this obj - go calculate the clipper */
+   if (obj->cur->clipper)
+     {
+        if (obj->cur->cache.clip.dirty)
+          evas_object_clip_recalc(obj->cur->clipper);
+        obj->cur->clipper->func->render_pre(obj->cur->clipper->object,
+                                            obj->cur->clipper,
+                                            obj->cur->clipper->private_data);
+     }
+   /* now figure what changed and add draw rects */
+   /* if it just became visible or invisible */
+   is_v = evas_object_is_visible(eo_obj, obj);
+   was_v = evas_object_was_visible(eo_obj,obj);
+   if (!(is_v | was_v)) goto done;
+   if (is_v != was_v)
+     {
+        evas_object_render_pre_visible_change(&obj->layer->evas->clip_changes, eo_obj, is_v, was_v);
+        goto done;
+     }
+   if (obj->changed_map || obj->changed_src_visible)
+     {
+        evas_object_render_pre_prev_cur_add(&obj->layer->evas->clip_changes, eo_obj, obj);
+        goto done;
+     }
+   /* it's not visible - we accounted for it appearing or not so just abort */
+   if (!is_v) goto done;
+   /* clipper changed this is in addition to anything else for obj */
+   evas_object_render_pre_clipper_change(&obj->layer->evas->clip_changes, eo_obj);
+   /* if we restacked (layer or just within a layer) and don't clip anyone */
+   if ((obj->restack) && (!obj->clip.clipees))
+     {
+        evas_object_render_pre_prev_cur_add(&obj->layer->evas->clip_changes, eo_obj, obj);
+        goto done;
+     }
+   /* if it changed render op */
+   if (obj->cur->render_op != obj->prev->render_op)
+     {
+        evas_object_render_pre_prev_cur_add(&obj->layer->evas->clip_changes, eo_obj, obj);
+        goto done;
+     }
+   /* if it changed color */
+   if ((obj->cur->color.r != obj->prev->color.r) ||
+       (obj->cur->color.g != obj->prev->color.g) ||
+       (obj->cur->color.b != obj->prev->color.b) ||
+       (obj->cur->color.a != obj->prev->color.a))
+     {
+        evas_object_render_pre_prev_cur_add(&obj->layer->evas->clip_changes, eo_obj, obj);
+        goto done;
+     }
+   /* if it changed geometry - and obviously not visibility or color */
+   /* calculate differences since we have a constant color fill */
+   /* we really only need to update the differences */
+   if ((obj->cur->geometry.x != obj->prev->geometry.x) ||
+       (obj->cur->geometry.y != obj->prev->geometry.y) ||
+       (obj->cur->geometry.w != obj->prev->geometry.w) ||
+       (obj->cur->geometry.h != obj->prev->geometry.h))
+     {
+        evas_rects_return_difference_rects(&obj->layer->evas->clip_changes,
+                                           obj->cur->geometry.x,
+                                           obj->cur->geometry.y,
+                                           obj->cur->geometry.w,
+                                           obj->cur->geometry.h,
+                                           obj->prev->geometry.x,
+                                           obj->prev->geometry.y,
+                                           obj->prev->geometry.w,
+                                           obj->prev->geometry.h);
+        goto done;
+     }
+   /* it obviously didn't change - add a NO obscure - this "unupdates"  this */
+   /* area so if there were updates for it they get wiped. don't do it if we */
+   /* arent fully opaque and we are visible */
+   if (evas_object_is_visible(eo_obj, obj) &&
+       evas_object_is_opaque(eo_obj, obj) &&
+       (!obj->clip.clipees))
+     {
+        Evas_Coord x, y, w, h;
+
+        x = obj->cur->cache.clip.x;
+        y = obj->cur->cache.clip.y;
+        w = obj->cur->cache.clip.w;
+        h = obj->cur->cache.clip.h;
+        if (obj->cur->clipper)
+          {
+             RECTS_CLIP_TO_RECT(x, y, w, h,
+                                obj->cur->clipper->cur->cache.clip.x,
+                                obj->cur->clipper->cur->cache.clip.y,
+                                obj->cur->clipper->cur->cache.clip.w,
+                                obj->cur->clipper->cur->cache.clip.h);
+          }
+        obj->layer->evas->engine.func->output_redraws_rect_del
+        (obj->layer->evas->engine.data.output,
+         x + obj->layer->evas->framespace.x,
+         y + obj->layer->evas->framespace.y,
+         w, h);
+     }
+   done:
+   evas_object_render_pre_effect_updates(&obj->layer->evas->clip_changes, eo_obj, is_v, was_v);
+}
+
+static void
+evas_object_vg_render_post(Evas_Object *eo_obj,
+                           Evas_Object_Protected_Data *obj EINA_UNUSED,
+                           void *type_private_data EINA_UNUSED)
+{
+   /* this moves the current data to the previous state parts of the object */
+   /* in whatever way is safest for the object. also if we don't need object */
+   /* data anymore we can free it if the object deems this is a good idea */
+   /* remove those pesky changes */
+   evas_object_clip_changes_clean(eo_obj);
+   /* move cur to prev safely for object data */
+   evas_object_cur_prev(eo_obj);
+}
+
+static unsigned int
+evas_object_vg_id_get(Evas_Object *eo_obj)
+{
+   Evas_VG_Data *o = eo_data_scope_get(eo_obj, MY_CLASS);
+   if (!o) return 0;
+   return MAGIC_OBJ_VG;
+}
+
+static unsigned int
+evas_object_vg_visual_id_get(Evas_Object *eo_obj)
+{
+   Evas_VG_Data *o = eo_data_scope_get(eo_obj, MY_CLASS);
+   if (!o) return 0;
+   return MAGIC_OBJ_SHAPE;
+}
+
+static void *
+evas_object_vg_engine_data_get(Evas_Object *eo_obj)
+{
+   Evas_VG_Data *o = eo_data_scope_get(eo_obj, MY_CLASS);
+   return o->engine_data;
+}
+
+static int
+evas_object_vg_is_opaque(Evas_Object *eo_obj EINA_UNUSED,
+                         Evas_Object_Protected_Data *obj EINA_UNUSED,
+                         void *type_private_data EINA_UNUSED)
+{
+   return 0;
+}
+
+static int
+evas_object_vg_was_opaque(Evas_Object *eo_obj EINA_UNUSED,
+                          Evas_Object_Protected_Data *obj EINA_UNUSED,
+                          void *type_private_data EINA_UNUSED)
+{
+   return 0;
+}
+
+#include "evas_vg.eo.c"
diff --git a/src/lib/evas/canvas/evas_vg.eo b/src/lib/evas/canvas/evas_vg.eo
new file mode 100644 (file)
index 0000000..fef9e8a
--- /dev/null
@@ -0,0 +1,17 @@
+class Evas.VG (Evas.Object)
+{
+   legacy_prefix: evas_object_vg;
+   eo_prefix: evas_obj_vg;
+   properties {
+      root_node {
+        get {
+        }
+        values {
+           Evas_VG_Node *container;
+        }
+      }
+   }
+   implements {
+      Eo.Base.constructor;
+   }
+}
\ No newline at end of file
diff --git a/src/lib/evas/canvas/evas_vg_container.c b/src/lib/evas/canvas/evas_vg_container.c
new file mode 100644 (file)
index 0000000..fc008bb
--- /dev/null
@@ -0,0 +1,33 @@
+#include "evas_common_private.h"
+#include "evas_private.h"
+
+#include "evas_vg_private.h"
+
+#define MY_CLASS EVAS_VG_CONTAINER_CLASS
+
+void
+_evas_vg_container_eo_base_constructor(Eo *obj, Evas_VG_Container_Data *pd)
+{
+   Eo *parent;
+
+   eo_do_super(obj, MY_CLASS, eo_constructor());
+
+   eo_do(obj, parent = eo_parent_get());
+   if (!eo_isa(obj, EVAS_VG_CONTAINER_CLASS) &&
+       !eo_isa(obj, EVAS_VG_CLASS))
+     {
+        ERR("Parent must be either an Evas_Object_VG or an Evas_VG_Container.");
+        eo_error_set(obj);
+     }
+}
+
+Eina_Bool
+_evas_vg_container_evas_vg_node_bound_get(Eo *obj,
+                                          Evas_VG_Container_Data *pd,
+                                          Eina_Rectangle *r)
+{
+   // FIXME: iterate children and get their boundary to
+}
+
+
+#include "evas_vg_container.eo.c"
diff --git a/src/lib/evas/canvas/evas_vg_container.eo b/src/lib/evas/canvas/evas_vg_container.eo
new file mode 100644 (file)
index 0000000..423a202
--- /dev/null
@@ -0,0 +1,8 @@
+class Evas.VG_Container (Evas.VG_Node)
+{
+   eo_prefix: evas_vg_container;
+   implements {
+      Eo.Base.constructor;
+      Evas.VG_Node.bound_get;
+   }
+}
diff --git a/src/lib/evas/canvas/evas_vg_gradient.c b/src/lib/evas/canvas/evas_vg_gradient.c
new file mode 100644 (file)
index 0000000..df7edc6
--- /dev/null
@@ -0,0 +1,58 @@
+#include "evas_common_private.h"
+#include "evas_private.h"
+
+#include <strings.h>
+
+typedef struct _Evas_VG_Gradient_Data Evas_VG_Gradient_Data;
+struct _Evas_VG_Gradient_Data
+{
+   // FIXME: Later on we should deduplicate it somehow.
+   Evas_VG_Gradient_Stop *colors;
+   unsigned int colors_count;
+
+   Evas_VG_Gradient_Spread s;
+};
+
+void
+_evas_vg_gradient_stop_set(Eo *obj EINA_UNUSED,
+                           Evas_VG_Gradient_Data *pd,
+                           const Evas_VG_Gradient_Stop *colors,
+                           unsigned int length)
+{
+   pd->colors = realloc(pd->colors, length * sizeof(Evas_VG_Gradient_Stop));
+   if (!pd->colors)
+     {
+        pd->colors_count = 0;
+        return ;
+     }
+
+   memcpy(pd->colors, colors, length * sizeof(Evas_VG_Gradient_Stop));
+   pd->colors_count = length;
+}
+
+void
+_evas_vg_gradient_stop_get(Eo *obj EINA_UNUSED,
+                           Evas_VG_Gradient_Data *pd,
+                           const Evas_VG_Gradient_Stop **colors,
+                           unsigned int *length)
+{
+   if (colors) *colors = pd->colors;
+   if (length) *length = pd->colors_count;
+}
+
+void
+_evas_vg_gradient_spread_set(Eo *obj EINA_UNUSED,
+                             Evas_VG_Gradient_Data *pd,
+                             Evas_VG_Gradient_Spread s)
+{
+   pd->s = s;
+}
+
+Evas_VG_Gradient_Spread
+_evas_vg_gradient_spread_get(Eo *obj EINA_UNUSED,
+                             Evas_VG_Gradient_Data *pd)
+{
+   return pd->s;
+}
+
+#include "evas_vg_gradient.eo.c"
diff --git a/src/lib/evas/canvas/evas_vg_gradient.eo b/src/lib/evas/canvas/evas_vg_gradient.eo
new file mode 100644 (file)
index 0000000..549d28a
--- /dev/null
@@ -0,0 +1,26 @@
+abstract Evas.VG_Gradient (Evas.VG_Node)
+{
+   eo_prefix: evas_vg_gradient;
+   legacy_prefix: null;
+   properties {
+      stop {
+         set {
+        }
+        get {
+        }
+        values {
+           const(Evas_VG_Gradient_Stop) *colors;
+           uint length;
+        }
+      }
+      spread {
+         set {
+        }
+        get {
+        }
+        values {
+           Evas_VG_Gradient_Spread s;
+        }
+      }
+   }
+}
diff --git a/src/lib/evas/canvas/evas_vg_gradient_linear.c b/src/lib/evas/canvas/evas_vg_gradient_linear.c
new file mode 100644 (file)
index 0000000..9332178
--- /dev/null
@@ -0,0 +1,50 @@
+#include "evas_common_private.h"
+#include "evas_private.h"
+
+#include <strings.h>
+
+typedef struct _Evas_VG_Gradient_Linear_Data Evas_VG_Gradient_Linear_Data;
+struct _Evas_VG_Gradient_Linear_Data
+{
+   struct {
+      double x, y;
+   } start, end;
+};
+
+void
+_evas_vg_gradient_linear_start_set(Eo *obj EINA_UNUSED,
+                                   Evas_VG_Gradient_Linear_Data *pd,
+                                   double x, double y)
+{
+   pd->start.x = x;
+   pd->start.y = y;
+}
+
+void
+_evas_vg_gradient_linear_start_get(Eo *obj EINA_UNUSED,
+                                   Evas_VG_Gradient_Linear_Data *pd,
+                                   double *x, double *y)
+{
+   if (x) *x = pd->start.x;
+   if (y) *y = pd->start.y;
+}
+
+void
+_evas_vg_gradient_linear_end_set(Eo *obj EINA_UNUSED,
+                                 Evas_VG_Gradient_Linear_Data *pd,
+                                 double x, double y)
+{
+   pd->end.x = x;
+   pd->end.y = y;
+}
+
+void
+_evas_vg_gradient_linear_end_get(Eo *obj EINA_UNUSED,
+                                 Evas_VG_Gradient_Linear_Data *pd,
+                                 double *x, double *y)
+{
+   if (x) *x = pd->end.x;
+   if (y) *y = pd->end.y;
+}
+
+#include "evas_vg_gradient_linear.eo.c"
diff --git a/src/lib/evas/canvas/evas_vg_gradient_linear.eo b/src/lib/evas/canvas/evas_vg_gradient_linear.eo
new file mode 100644 (file)
index 0000000..07c0539
--- /dev/null
@@ -0,0 +1,27 @@
+class Evas.VG_Gradient_Linear (Evas.VG_Gradient)
+{
+   eo_prefix: evas_vg_gradient_linear;
+   legacy_prefix: null;
+   properties {
+      start {
+         set {
+        }
+        get {
+        }
+        values {
+           double x;
+           double y;
+        }
+      }
+      end {
+         set {
+        }
+        get {
+        }
+        values {
+           double x;
+           double y;
+        }
+      }
+   }
+}
diff --git a/src/lib/evas/canvas/evas_vg_gradient_radial.c b/src/lib/evas/canvas/evas_vg_gradient_radial.c
new file mode 100644 (file)
index 0000000..04ab5bb
--- /dev/null
@@ -0,0 +1,64 @@
+#include "evas_common_private.h"
+#include "evas_private.h"
+
+typedef struct _Evas_VG_Gradient_Radial_Data Evas_VG_Gradient_Radial_Data;
+struct _Evas_VG_Gradient_Radial_Data
+{
+   struct {
+      double x, y;
+   } center, focal;
+   double radius;
+};
+
+void
+_evas_vg_gradient_radial_center_set(Eo *obj EINA_UNUSED,
+                                    Evas_VG_Gradient_Radial_Data *pd,
+                                    double x, double y)
+{
+   pd->center.x = x;
+   pd->center.y = y;
+}
+
+void
+_evas_vg_gradient_radial_center_get(Eo *obj EINA_UNUSED,
+                                    Evas_VG_Gradient_Radial_Data *pd,
+                                    double *x, double *y)
+{
+   if (x) *x = pd->center.x;
+   if (y) *y = pd->center.y;
+}
+
+void
+_evas_vg_gradient_radial_radius_set(Eo *obj EINA_UNUSED,
+                                    Evas_VG_Gradient_Radial_Data *pd,
+                                    double r)
+{
+   pd->radius = r;
+}
+
+double
+_evas_vg_gradient_radial_radius_get(Eo *obj EINA_UNUSED,
+                                    Evas_VG_Gradient_Radial_Data *pd)
+{
+   return pd->radius;
+}
+
+void
+_evas_vg_gradient_radial_focal_set(Eo *obj EINA_UNUSED,
+                                   Evas_VG_Gradient_Radial_Data *pd,
+                                   double x, double y)
+{
+   pd->focal.x = x;
+   pd->focal.y = y;
+}
+
+void
+_evas_vg_gradient_radial_focal_get(Eo *obj EINA_UNUSED,
+                                   Evas_VG_Gradient_Radial_Data *pd,
+                                   double *x, double *y)
+{
+   if (x) *x = pd->focal.x;
+   if (y) *y = pd->focal.y;
+}
+
+#include "evas_vg_gradient_radial.eo.c"
diff --git a/src/lib/evas/canvas/evas_vg_gradient_radial.eo b/src/lib/evas/canvas/evas_vg_gradient_radial.eo
new file mode 100644 (file)
index 0000000..0a7d548
--- /dev/null
@@ -0,0 +1,36 @@
+class Evas.VG_Gradient_Radial (Evas.VG_Gradient)
+{
+   eo_prefix: evas_vg_gradient_radial;
+   legacy_prefix: null;
+   properties {
+      center {
+         set {
+        }
+        get {
+        }
+        values {
+           double x;
+           double y;
+        }
+      }
+      radius {
+         set {
+        }
+        get {
+        }
+        values {
+           double r;
+        }
+      }
+      focal {
+         set {
+        }
+        get {
+        }
+        values {
+           double x;
+           double y;
+        }
+      }
+   }
+}
diff --git a/src/lib/evas/canvas/evas_vg_node.c b/src/lib/evas/canvas/evas_vg_node.c
new file mode 100644 (file)
index 0000000..029b986
--- /dev/null
@@ -0,0 +1,167 @@
+#include "evas_common_private.h"
+#include "evas_private.h"
+
+#include <string.h>
+
+#define MY_CLASS EVAS_VG_NODE_CLASS
+
+typedef struct _Evas_VG_Node_Data Evas_VG_Node_Data;
+struct _Evas_VG_Node_Data
+{
+   Eina_Matrix3 *m;
+   Evas_VG_Node *mask;
+
+   double x, y;
+   int r, g, b, a;
+   Eina_Bool visibility;
+};
+
+// FIXME:
+// - share private structure with evas_object_vg
+// - mark parent canvas evas_object dirty after any change on the object
+// - add a virtual render function as part of the private data field
+
+void
+_evas_vg_node_transformation_set(Eo *obj EINA_UNUSED,
+                                 Evas_VG_Node_Data *pd,
+                                 const Eina_Matrix3 *m)
+{
+   if (!pd->m)
+     {
+        pd->m = malloc(sizeof (Eina_Matrix3));
+        if (!pd->m) return ;
+     }
+   memcpy(pd->m, m, sizeof (Eina_Matrix3));
+}
+
+const Eina_Matrix3 *
+_evas_vg_node_transformation_get(Eo *obj EINA_UNUSED, Evas_VG_Node_Data *pd)
+{
+   return pd->m;
+}
+
+void
+_evas_vg_node_origin_set(Eo *obj EINA_UNUSED,
+                         Evas_VG_Node_Data *pd,
+                         double x, double y)
+{
+   pd->x = x;
+   pd->y = y;
+}
+
+void
+_evas_vg_node_origin_get(Eo *obj EINA_UNUSED,
+                         Evas_VG_Node_Data *pd,
+                         double *x, double *y)
+{
+   if (x) *x = pd->x;
+   if (y) *y = pd->y;
+}
+
+void
+_evas_vg_node_visibility_set(Eo *obj EINA_UNUSED,
+                             Evas_VG_Node_Data *pd,
+                             Eina_Bool v)
+{
+   pd->visibility = v;
+}
+
+Eina_Bool
+_evas_vg_node_visibility_get(Eo *obj EINA_UNUSED, Evas_VG_Node_Data *pd)
+{
+   return pd->visibility;
+}
+
+void
+_evas_vg_node_color_set(Eo *obj EINA_UNUSED,
+                        Evas_VG_Node_Data *pd,
+                        int r, int g, int b, int a)
+{
+   pd->r = r;
+   pd->g = g;
+   pd->b = b;
+   pd->a = a;
+}
+
+void
+_evas_vg_node_color_get(Eo *obj EINA_UNUSED,
+                        Evas_VG_Node_Data *pd,
+                        int *r, int *g, int *b, int *a)
+{
+   if (r) *r = pd->r;
+   if (g) *g = pd->g;
+   if (b) *b = pd->b;
+   if (a) *a = pd->a;
+}
+
+void
+_evas_vg_node_mask_set(Eo *obj EINA_UNUSED,
+                       Evas_VG_Node_Data *pd,
+                       Evas_VG_Node *r)
+{
+   Evas_VG_Node *tmp = pd->mask;
+
+   pd->mask = eo_ref(r);
+   eo_unref(tmp);
+}
+
+Evas_VG_Node*
+_evas_vg_node_mask_get(Eo *obj EINA_UNUSED, Evas_VG_Node_Data *pd)
+{
+   return pd->mask;
+}
+
+// Parent should be a container otherwise dismissing the stacking operation
+void
+_evas_vg_node_eo_base_constructor(Eo *obj, Evas_VG_Node_Data *pd)
+{
+   Eo *parent;
+
+   eo_do_super(obj, MY_CLASS, eo_constructor());
+   eo_do(obj, parent = eo_parent_get());
+   if (!eo_isa(parent, EVAS_VG_CONTAINER_CLASS))
+     eo_error_set(obj);
+}
+
+void
+_evas_vg_node_eo_base_parent_set(Eo *obj, Evas_VG_Node_Data *pd, Eo *parent)
+{
+}
+
+void
+_evas_vg_node_raise(Eo *obj, Evas_VG_Node_Data *pd EINA_UNUSED)
+{
+   Eo *parent;
+
+   eo_do(obj, parent = eo_parent_get());
+}
+
+void
+_evas_vg_node_stack_above(Eo *obj,
+                          Evas_VG_Node_Data *pd EINA_UNUSED,
+                          Evas_VG_Node *above)
+{
+   Eo *parent;
+
+   eo_do(obj, parent = eo_parent_get());
+}
+
+void
+_evas_vg_node_stack_below(Eo *obj,
+                          Evas_VG_Node_Data *pd EINA_UNUSED,
+                          Evas_Object *below)
+{
+   Eo *parent;
+
+   eo_do(obj, parent = eo_parent_get());
+}
+
+void
+_evas_vg_node_lower(Eo *obj, Evas_VG_Node_Data *pd EINA_UNUSED)
+{
+   Eo *parent;
+
+   eo_do(obj, parent = eo_parent_get());
+}
+
+#include "evas_vg_node.eo.c"
diff --git a/src/lib/evas/canvas/evas_vg_node.eo b/src/lib/evas/canvas/evas_vg_node.eo
new file mode 100644 (file)
index 0000000..e989f7a
--- /dev/null
@@ -0,0 +1,162 @@
+abstract Evas.VG_Node (Eo.Base)
+{
+   eo_prefix: evas_vg_node;
+   legacy_prefix: null;
+   properties {
+      transformation {
+         set {
+        }
+        get {
+        }
+        values {
+           const(Eina_Matrix3) *m;
+        }
+      }
+      origin {
+         set {
+        }
+        get {
+        }
+        values {
+           double x;
+           double y;
+        }
+      }
+      visibility {
+         set {
+            /*@ Makes the given Evas_VG node visible or invisible. */
+        }
+        get {
+            /*@ Retrieves whether or not the given Evas_VG node is visible. */
+        }
+        values {
+           Eina_Bool v; /*@ @c EINA_TRUE if to make the object visible, @c EINA_FALSE otherwise */
+        }
+      }
+      color {
+         set {
+            /*@
+            Sets the general/main color of the given Evas_VG node to the given
+            one.
+
+            @note These color values are expected to be premultiplied by @p a.
+
+            @ingroup Evas_VG_Node_Group */
+         }
+         get {
+            /*@
+            Retrieves the general/main color of the given Evas_VG node.
+
+            Retrieves the “main” color's RGB component (and alpha channel)
+            values, <b>which range from 0 to 255</b>. For the alpha channel,
+            which defines the object's transparency level, 0 means totally
+            transparent, while 255 means opaque. These color values are
+            premultiplied by the alpha value.
+
+            @note Use @c NULL pointers on the components you're not interested
+            in: they'll be ignored by the function.
+
+            @ingroup Evas_VG_Node_Group */
+        }
+        values {
+            int r; /*@ The red component of the given color. */
+            int g; /*@ The green component of the given color. */
+            int b; /*@ The blue component of the given color. */
+            int a; /*@ The alpha component of the given color. */
+        }
+      }
+      mask {
+         set {
+        }
+        get {
+        }
+        values {
+           Evas_VG_Node *m;
+        }
+      }
+/*      quality {
+         set {
+        }
+        get {
+        }
+        values {
+           Evas_VG_Quality q;
+        }
+      } */
+   }
+   methods {
+      bound_get {
+         return: bool @warn_unused;
+        params {
+           @out Eina_Rectangle r;
+        }
+      }
+      raise {
+        /*@
+         Raise @p obj to the top of its layer.
+
+         @p obj will, then, be the highest one in the layer it belongs
+         to. Object on other layers won't get touched.
+
+         @see evas_vg_node_stack_above()
+         @see evas_vg_node_stack_below()
+         @see evas_vg_node_lower() */
+      }
+      stack_above {
+         /*@
+         Stack @p obj immediately above @p above
+
+         Objects, in a given Evas_VG_Container, are stacked in the order they get added
+         to it.  This means that, if they overlap, the highest ones will
+         cover the lowest ones, in that order. This function is a way to
+         change the stacking order for the objects.
+
+         This function is intended to be used with <b>objects belonging to
+         the same container</b>, otherwise it will fail (and
+         accomplish nothing).
+
+         @see evas_vg_node_stack_below() */
+
+         params {
+            @in Evas_VG_Node *above @nonull; /*@ the object above which to stack */
+         }
+      }
+      stack_below {
+         /*@
+         Stack @p obj immediately below @p below
+
+         Objects, in a given container, are stacked in the order they get added
+         to it.  This means that, if they overlap, the highest ones will
+         cover the lowest ones, in that order. This function is a way to
+         change the stacking order for the objects.
+
+         This function is intended to be used with <b>objects belonging to
+         the same container</b>, otherwise it will fail (and
+         accomplish nothing).
+
+         @see evas_vg_node_layer_get()
+         @see evas_vg_node_layer_set()
+         @see evas_vg_node_stack_below() */
+
+         params {
+            @in Evas_Object *below @nonull; /*@ the object below which to stack */
+         }
+      }
+      lower {
+         /*@
+         Lower @p obj to the bottom of its layer.
+
+         @p obj will, then, be the lowest one in the layer it belongs
+         to. Objects on other layers won't get touched.
+
+         @see evas_vg_node_stack_above()
+         @see evas_vg_node_stack_below()
+         @see evas_vg_node_raise() */
+      }
+   }
+   implements {
+      Eo.Base.parent.set;
+      Eo.Base.constructor;
+      @virtual .bound_get;
+   }
+}
\ No newline at end of file
diff --git a/src/lib/evas/canvas/evas_vg_private.h b/src/lib/evas/canvas/evas_vg_private.h
new file mode 100644 (file)
index 0000000..0578b53
--- /dev/null
@@ -0,0 +1,10 @@
+#ifndef EVAS_VG_PRIVATE_H_
+# define EVAS_VG_PRIVATE_H_
+
+typedef struct _Evas_VG_Container_Data Evas_VG_Container_Data;
+struct _Evas_VG_Container_Data
+{
+   Eina_List *children;
+};
+
+#endif
diff --git a/src/lib/evas/canvas/evas_vg_root_node.c b/src/lib/evas/canvas/evas_vg_root_node.c
new file mode 100644 (file)
index 0000000..33f9d21
--- /dev/null
@@ -0,0 +1,41 @@
+#include "evas_common_private.h"
+#include "evas_private.h"
+
+#include "evas_vg_root_node.eo.h"
+
+#include <string.h>
+
+#define MY_CLASS EVAS_VG_ROOT_NODE_CLASS
+
+typedef struct _Evas_VG_Root_Node_Data Evas_VG_Root_Node_Data;
+struct _Evas_VG_Root_Node_Data
+{
+};
+
+void
+_evas_vg_root_node_eo_base_parent_set(Eo *obj,
+                                      Evas_VG_Root_Node_Data *pd EINA_UNUSED,
+                                      Eo *parent)
+{
+   // Nice little hack, jump over parent parent_set in Evas_VG_Root
+   eo_do_super(obj, EVAS_VG_NODE_CLASS, eo_constructor());
+   if (!eo_isa(parent, EVAS_VG_CLASS) &&
+       !eo_isa(parent, EVAS_VG_CONTAINER_CLASS))
+     eo_error_set(obj);
+}
+
+void
+_evas_vg_root_node_eo_base_constructor(Eo *obj,
+                                       Evas_VG_Root_Node_Data *pd EINA_UNUSED)
+{
+   Eo *parent;
+
+   // Nice little hack, jump over parent constructor in Evas_VG_Root
+   eo_do_super(obj, EVAS_VG_NODE_CLASS, eo_constructor());
+   eo_do(obj, parent = eo_parent_get());
+   if (!eo_isa(parent, EVAS_VG_CLASS) &&
+       !eo_isa(parent, EVAS_VG_CONTAINER_CLASS))
+     eo_error_set(obj);
+}
+
+#include "evas_vg_root_node.eo.c"
diff --git a/src/lib/evas/canvas/evas_vg_root_node.eo b/src/lib/evas/canvas/evas_vg_root_node.eo
new file mode 100644 (file)
index 0000000..db0837d
--- /dev/null
@@ -0,0 +1,8 @@
+class Evas.VG_Root_Node (Evas.VG_Node)
+{
+   eo_prefix: evas_vg_root_node;
+   implements {
+      Eo.Base.parent.set;
+      Eo.Base.constructor;
+   }
+}
diff --git a/src/lib/evas/canvas/evas_vg_shape.c b/src/lib/evas/canvas/evas_vg_shape.c
new file mode 100644 (file)
index 0000000..878cc7e
--- /dev/null
@@ -0,0 +1,39 @@
+#include "evas_common_private.h"
+#include "evas_private.h"
+
+#define MY_CLASS EVAS_VG_SHAPE_CLASS
+
+typedef struct _Evas_VG_Shape_Data Evas_VG_Shape_Data;
+struct _Evas_VG_Shape_Data
+{
+   Evas_VG_Path_Command *op;
+   double *points;
+   unsigned int op_count;
+   unsigned int pts_counts;
+};
+
+Eina_Bool
+_evas_vg_shape_path_set(Eo *obj, Evas_VG_Shape_Data *pd, Evas_VG_Path_Command *op, double *points)
+{
+}
+
+Eina_Bool
+_evas_vg_shape_bounds_get(Eo *obj, Evas_VG_Shape_Data *pd, Eina_Rectangle *r)
+{
+}
+
+void
+_evas_vg_shape_eo_base_constructor(Eo *obj, Evas_VG_Shape_Data *pd)
+{
+   Eo *parent;
+
+   eo_super_do(obj, MY_CLASS, eo_constructor());
+
+   eo_do(obj, parent = eo_parent_get());
+   if (!eo_isa(obj, EVAS_VG_CONTAINER_CLASS) &&
+       !eo_isa(obj, EVAS_VG_CLASS))
+     {
+        ERR("Parent must be either an Evas_Object_VG or an Evas_VG_Container.");
+        eo_error_set(obj);
+     }
+}
diff --git a/src/lib/evas/canvas/evas_vg_shape.eo b/src/lib/evas/canvas/evas_vg_shape.eo
new file mode 100644 (file)
index 0000000..32d959d
--- /dev/null
@@ -0,0 +1,113 @@
+class Evas.VG_Shape (Evas.VG_Node)
+{
+   eo_prefix: evas_vg_shape;
+   properties {
+      fill {
+         set {
+        }
+        get {
+        }
+        values {
+           Evas_VG_Node *f;
+        }
+      }
+      stroke_scale {
+         set {
+        }
+        get {
+        }
+        values {
+           double s;
+        }
+      }
+      stroke_color {
+         set {
+        }
+        get {
+        }
+        values {
+           int r;
+           int g;
+           int b;
+           int a;
+        }
+      }
+      stroke_fill {
+         set {
+        }
+        get {
+        }
+        values {
+           Evas_VG_Node *f;
+        }
+      }
+      stroke_width {
+         set {
+        }
+        get {
+        }
+        values {
+           double w;
+        }
+      }
+      stroke_location {
+         set {
+        }
+        get {
+        }
+        values {
+           double centered;
+        }
+      }
+      stroke_dash {
+         set {
+        }
+        get {
+        }
+        values {
+            const(Evas_VG_Dash) *dash;
+            uint length;
+        }
+      }
+      stroke_marker {
+         set {
+        }
+        get {
+        }
+        values {
+           Evas_VG_Shape *m;
+        }
+      }
+      stroke_cap {
+         set {
+        }
+        get {
+        }
+        values {
+           Evas_VG_Cap c;
+        }
+      }
+      stroke_join {
+         set {
+        }
+        get {
+        }
+        values {
+           Evas_VG_Join j;
+        }
+      }
+   }
+   methods {
+      path_set {
+         return: bool;
+        params {
+           @in const(Evas_VG_Path_Command) *op;
+           @in const(double) *points;
+        }
+      }
+   }
+   implements {
+      Eo.Base.constructor;
+      Eo.Base.destructor;
+   }
+}
index a852979..d2500b3 100644 (file)
@@ -471,6 +471,7 @@ OPAQUE_TYPE(Evas_Font_Instance); /* General type for RGBA_Font_Int */
 #define MAGIC_SMART                0x7c6977c5
 #define MAGIC_OBJ_SHAPE            0x747297f7
 #define MAGIC_OBJ_CONTAINER        0x71877776
+#define MAGIC_OBJ_VG               0x77817EE7
 #define MAGIC_OBJ_CUSTOM           0x7b7857ab
 #define MAGIC_EVAS_GL              0x77976718
 #define MAGIC_MAP                  0x7575177d