efl/vector: backported the refactoring of ector code 81/80081/1 accepted/tizen/common/20160721.174820 accepted/tizen/ivi/20160721.002545 accepted/tizen/mobile/20160721.002300 accepted/tizen/tv/20160721.002447 accepted/tizen/wearable/20160721.002425 submit/tizen/20160720.122528
authorSubhransu Mohanty <sub.mohanty@samsung.com>
Thu, 14 Jul 2016 07:33:09 +0000 (16:33 +0900)
committerSubhransu Mohanty <sub.mohanty@samsung.com>
Thu, 14 Jul 2016 10:56:42 +0000 (19:56 +0900)
Change-Id: I51bd6ce907c3e4a25feb6e9e92c5b13e1230a570

15 files changed:
src/lib/ector/cairo/ector_renderer_cairo_shape.c
src/lib/ector/ector_private.h
src/lib/ector/ector_renderer_generic_shape.eo
src/lib/ector/ector_renderer_shape.c
src/lib/ector/software/ector_renderer_software_shape.c
src/lib/efl/Efl.h
src/lib/efl/interfaces/efl_gfx_shape.c
src/lib/efl/interfaces/efl_gfx_shape.eo
src/lib/evas/canvas/efl_vg_shape.eo
src/lib/evas/canvas/evas_vg_container.c
src/lib/evas/canvas/evas_vg_gradient_linear.c
src/lib/evas/canvas/evas_vg_gradient_radial.c
src/lib/evas/canvas/evas_vg_node.c
src/lib/evas/canvas/evas_vg_private.h
src/lib/evas/canvas/evas_vg_shape.c

index 5169db6..3e5f47e 100644 (file)
@@ -60,6 +60,8 @@ static void (*cairo_set_dash) (cairo_t *cr, const double *dashes, int num_dashes
 typedef struct _Ector_Renderer_Cairo_Shape_Data Ector_Renderer_Cairo_Shape_Data;
 struct _Ector_Renderer_Cairo_Shape_Data
 {
+   Efl_Gfx_Shape_Public *public_shape;
+
    Ector_Cairo_Surface_Data *parent;
    Ector_Renderer_Generic_Shape_Data *shape;
    Ector_Renderer_Generic_Base_Data *base;
@@ -181,7 +183,7 @@ _ector_renderer_cairo_shape_ector_renderer_generic_base_draw(Eo *obj, Ector_Rend
    if (pd->shape->fill)
      eo_do(pd->shape->fill, ector_renderer_cairo_base_fill(mul_col));
 
-   if (pd->shape->stroke.fill || pd->shape->stroke.color.a > 0)
+   if (pd->shape->stroke.fill || pd->public_shape->stroke.color.a > 0)
      {
         USE(obj, cairo_fill_preserve, EINA_FALSE);
         USE(obj, cairo_set_source_rgba, EINA_FALSE);
@@ -196,33 +198,33 @@ _ector_renderer_cairo_shape_ector_renderer_generic_base_draw(Eo *obj, Ector_Rend
           eo_do(pd->shape->stroke.fill, ector_renderer_cairo_base_fill(mul_col));
        else
          {
-            r = (((pd->shape->stroke.color.r * R_VAL(&mul_col)) + 0xff) >> 8);
-            g = (((pd->shape->stroke.color.g * G_VAL(&mul_col)) + 0xff) >> 8);
-            b = (((pd->shape->stroke.color.b * B_VAL(&mul_col)) + 0xff) >> 8);
-            a = (((pd->shape->stroke.color.a * A_VAL(&mul_col)) + 0xff) >> 8);
+            r = (((pd->public_shape->stroke.color.r * R_VAL(&mul_col)) + 0xff) >> 8);
+            g = (((pd->public_shape->stroke.color.g * G_VAL(&mul_col)) + 0xff) >> 8);
+            b = (((pd->public_shape->stroke.color.b * B_VAL(&mul_col)) + 0xff) >> 8);
+            a = (((pd->public_shape->stroke.color.a * A_VAL(&mul_col)) + 0xff) >> 8);
             ector_color_argb_unpremul(a, &r, &g, &b);
             cairo_set_source_rgba(pd->parent->cairo, r/255.0, g/255.0, b/255.0, a/255.0);
-            if (pd->shape->stroke.dash)
+            if (pd->public_shape->stroke.dash)
               {
                  double *dashinfo;
 
                  USE(obj, cairo_set_dash, EINA_FALSE);
 
-                 dashinfo = (double *) malloc(2 * pd->shape->stroke.dash_length * sizeof(double));
-                 for (i = 0; i < pd->shape->stroke.dash_length; i++)
+                 dashinfo = (double *) malloc(2 * pd->public_shape->stroke.dash_length * sizeof(double));
+                 for (i = 0; i < pd->public_shape->stroke.dash_length; i++)
                    {
-                      dashinfo[i*2] = pd->shape->stroke.dash[i].length;
-                      dashinfo[i*2 + 1] = pd->shape->stroke.dash[i].gap;
+                      dashinfo[i*2] = pd->public_shape->stroke.dash[i].length;
+                      dashinfo[i*2 + 1] = pd->public_shape->stroke.dash[i].gap;
                    }
-                 cairo_set_dash(pd->parent->cairo, dashinfo, pd->shape->stroke.dash_length * 2, 0);
+                 cairo_set_dash(pd->parent->cairo, dashinfo, pd->public_shape->stroke.dash_length * 2, 0);
                  free(dashinfo);
               }
          }
 
        // Set dash, cap and join
-       cairo_set_line_width(pd->parent->cairo, (pd->shape->stroke.width * pd->shape->stroke.scale * 2));
-       cairo_set_line_cap(pd->parent->cairo, (cairo_line_cap_t) pd->shape->stroke.cap);
-       cairo_set_line_join(pd->parent->cairo, (cairo_line_join_t) pd->shape->stroke.join);
+       cairo_set_line_width(pd->parent->cairo, (pd->public_shape->stroke.width * pd->public_shape->stroke.scale * 2));
+       cairo_set_line_cap(pd->parent->cairo, (cairo_line_cap_t) pd->public_shape->stroke.cap);
+       cairo_set_line_join(pd->parent->cairo, (cairo_line_join_t) pd->public_shape->stroke.join);
        cairo_stroke(pd->parent->cairo);
      }
    else
@@ -266,6 +268,9 @@ Eo *
 _ector_renderer_cairo_shape_eo_base_constructor(Eo *obj, Ector_Renderer_Cairo_Shape_Data *pd)
 {
    obj = eo_do_super_ret(obj, ECTOR_RENDERER_CAIRO_SHAPE_CLASS, obj, eo_constructor());
+   if (!obj) return NULL;
+
+   pd->public_shape = eo_data_xref(obj, EFL_GFX_SHAPE_MIXIN, obj);
    pd->shape = eo_data_xref(obj, ECTOR_RENDERER_GENERIC_SHAPE_MIXIN, obj);
    pd->base = eo_data_xref(obj, ECTOR_RENDERER_GENERIC_BASE_CLASS, obj);
 
@@ -305,17 +310,17 @@ _ector_renderer_cairo_shape_ector_renderer_generic_base_crc_get(Eo *obj,
                crc = ector_renderer_crc_get());
 
    crc = eina_crc((void*) &pd->shape->stroke.marker, sizeof (pd->shape->stroke.marker), crc, EINA_FALSE);
-   crc = eina_crc((void*) &pd->shape->stroke.scale, sizeof (pd->shape->stroke.scale) * 3, crc, EINA_FALSE); // scale, width, centered
-   crc = eina_crc((void*) &pd->shape->stroke.color, sizeof (pd->shape->stroke.color), crc, EINA_FALSE);
-   crc = eina_crc((void*) &pd->shape->stroke.cap, sizeof (pd->shape->stroke.cap), crc, EINA_FALSE);
-   crc = eina_crc((void*) &pd->shape->stroke.join, sizeof (pd->shape->stroke.join), crc, EINA_FALSE);
+   crc = eina_crc((void*) &pd->public_shape->stroke.scale, sizeof (pd->public_shape->stroke.scale) * 3, crc, EINA_FALSE); // scale, width, centered
+   crc = eina_crc((void*) &pd->public_shape->stroke.color, sizeof (pd->public_shape->stroke.color), crc, EINA_FALSE);
+   crc = eina_crc((void*) &pd->public_shape->stroke.cap, sizeof (pd->public_shape->stroke.cap), crc, EINA_FALSE);
+   crc = eina_crc((void*) &pd->public_shape->stroke.join, sizeof (pd->public_shape->stroke.join), crc, EINA_FALSE);
 
    if (pd->shape->fill) crc = _renderer_crc_get(pd->shape->fill, crc);
    if (pd->shape->stroke.fill) crc = _renderer_crc_get(pd->shape->stroke.fill, crc);
    if (pd->shape->stroke.marker) crc = _renderer_crc_get(pd->shape->stroke.marker, crc);
-   if (pd->shape->stroke.dash_length)
+   if (pd->public_shape->stroke.dash_length)
      {
-        crc = eina_crc((void*) pd->shape->stroke.dash, sizeof (Efl_Gfx_Dash) * pd->shape->stroke.dash_length, crc, EINA_FALSE);
+        crc = eina_crc((void*) pd->public_shape->stroke.dash, sizeof (Efl_Gfx_Dash) * pd->public_shape->stroke.dash_length, crc, EINA_FALSE);
      }
 
    return crc;
index 099542b..34d8493 100644 (file)
@@ -128,20 +128,6 @@ struct _Ector_Renderer_Generic_Shape_Data
    struct {
       Ector_Renderer *fill;
       Ector_Renderer *marker;
-
-      double scale;
-      double width;
-      double centered;
-
-      struct {
-         int r, g, b, a;
-      } color;
-
-      Efl_Gfx_Dash *dash;
-      unsigned int dash_length;
-
-      Efl_Gfx_Cap cap;
-      Efl_Gfx_Join join;
    } stroke;
 };
 
index 1dc2be3..37d27b7 100644 (file)
@@ -31,13 +31,4 @@ mixin Ector.Renderer.Generic.Shape (Efl.Gfx.Shape)
         }
       }
    }
-   implements {
-      Efl.Gfx.Shape.stroke_scale;
-      Efl.Gfx.Shape.stroke_color;
-      Efl.Gfx.Shape.stroke_width;
-      Efl.Gfx.Shape.stroke_location;
-      Efl.Gfx.Shape.stroke_dash;
-      Efl.Gfx.Shape.stroke_cap;
-      Efl.Gfx.Shape.stroke_join;
-   }
 }
index cda749d..c5b09e0 100644 (file)
@@ -52,135 +52,4 @@ _ector_renderer_generic_shape_stroke_marker_get(Eo *obj EINA_UNUSED,
    return pd->stroke.marker;
 }
 
-static void
-_ector_renderer_generic_shape_efl_gfx_shape_stroke_scale_set(Eo *obj EINA_UNUSED,
-                                                             Ector_Renderer_Generic_Shape_Data *pd,
-                                                             double s)
-{
-   pd->stroke.scale = s;
-}
-
-static double
-_ector_renderer_generic_shape_efl_gfx_shape_stroke_scale_get(Eo *obj EINA_UNUSED,
-                                                             Ector_Renderer_Generic_Shape_Data *pd)
-{
-   return pd->stroke.scale;
-}
-
-static void
-_ector_renderer_generic_shape_efl_gfx_shape_stroke_color_set(Eo *obj EINA_UNUSED,
-                                                             Ector_Renderer_Generic_Shape_Data *pd,
-                                                             int r, int g, int b, int a)
-{
-   pd->stroke.color.r = r;
-   pd->stroke.color.g = g;
-   pd->stroke.color.b = b;
-   pd->stroke.color.a = a;
-}
-
-static void
-_ector_renderer_generic_shape_efl_gfx_shape_stroke_color_get(Eo *obj EINA_UNUSED,
-                                                             Ector_Renderer_Generic_Shape_Data *pd,
-                                                             int *r, int *g, int *b, int *a)
-{
-   if (r) *r = pd->stroke.color.r;
-   if (g) *g = pd->stroke.color.g;
-   if (b) *b = pd->stroke.color.b;
-   if (a) *a = pd->stroke.color.a;
-}
-
-static void
-_ector_renderer_generic_shape_efl_gfx_shape_stroke_width_set(Eo *obj EINA_UNUSED,
-                                                             Ector_Renderer_Generic_Shape_Data *pd,
-                                                             double w)
-{
-   pd->stroke.width = w;
-}
-
-static double
-_ector_renderer_generic_shape_efl_gfx_shape_stroke_width_get(Eo *obj EINA_UNUSED,
-                                                             Ector_Renderer_Generic_Shape_Data *pd)
-{
-   return pd->stroke.width;
-}
-
-static void
-_ector_renderer_generic_shape_efl_gfx_shape_stroke_location_set(Eo *obj EINA_UNUSED,
-                                                                Ector_Renderer_Generic_Shape_Data *pd,
-                                                                double centered)
-{
-   pd->stroke.centered = centered;
-}
-
-static double
-_ector_renderer_generic_shape_efl_gfx_shape_stroke_location_get(Eo *obj EINA_UNUSED,
-                                                                Ector_Renderer_Generic_Shape_Data *pd)
-{
-   return pd->stroke.centered;
-}
-
-static void
-_ector_renderer_generic_shape_efl_gfx_shape_stroke_dash_set(Eo *obj EINA_UNUSED,
-                                                            Ector_Renderer_Generic_Shape_Data *pd,
-                                                            const Efl_Gfx_Dash *dash,
-                                                            unsigned int length)
-{
-   Efl_Gfx_Dash *tmp;
-
-   if (!dash)
-     {
-        free(pd->stroke.dash);
-        pd->stroke.dash = NULL;
-        pd->stroke.dash_length = 0;
-        return ;
-     }
-
-   tmp = realloc(pd->stroke.dash, length * sizeof (Efl_Gfx_Dash));
-   if (!tmp && length) return ;
-   memcpy(tmp, dash, length * sizeof (Efl_Gfx_Dash));
-
-   pd->stroke.dash = tmp;
-   pd->stroke.dash_length = length;
-}
-
-static void
-_ector_renderer_generic_shape_efl_gfx_shape_stroke_dash_get(Eo *obj EINA_UNUSED,
-                                                            Ector_Renderer_Generic_Shape_Data *pd,
-                                                            const Efl_Gfx_Dash **dash,
-                                                            unsigned int *length)
-{
-   if (dash) *dash = pd->stroke.dash;
-   if (length) *length = pd->stroke.dash_length;
-}
-
-static void
-_ector_renderer_generic_shape_efl_gfx_shape_stroke_cap_set(Eo *obj EINA_UNUSED,
-                                                           Ector_Renderer_Generic_Shape_Data *pd,
-                                                           Efl_Gfx_Cap c)
-{
-   pd->stroke.cap = c;
-}
-
-static Efl_Gfx_Cap
-_ector_renderer_generic_shape_efl_gfx_shape_stroke_cap_get(Eo *obj EINA_UNUSED,
-                                                           Ector_Renderer_Generic_Shape_Data *pd)
-{
-   return pd->stroke.cap;
-}
-
-static void
-_ector_renderer_generic_shape_efl_gfx_shape_stroke_join_set(Eo *obj EINA_UNUSED,
-                                                            Ector_Renderer_Generic_Shape_Data *pd,
-                                                            Efl_Gfx_Join j)
-{
-   pd->stroke.join = j;
-}
-
-static Efl_Gfx_Join
-_ector_renderer_generic_shape_efl_gfx_shape_stroke_join_get(Eo *obj EINA_UNUSED,
-                                                            Ector_Renderer_Generic_Shape_Data *pd)
-{
-   return pd->stroke.join;
-}
-
 #include "ector_renderer_generic_shape.eo.c"
index 02abe16..e04ce45 100644 (file)
@@ -16,6 +16,8 @@
 typedef struct _Ector_Renderer_Software_Shape_Data Ector_Renderer_Software_Shape_Data;
 struct _Ector_Renderer_Software_Shape_Data
 {
+   Efl_Gfx_Shape_Public                *public_shape;
+
    Ector_Software_Surface_Data         *surface;
    Ector_Renderer_Generic_Shape_Data   *shape;
    Ector_Renderer_Generic_Base_Data    *base;
@@ -28,7 +30,7 @@ typedef struct _Outline
    SW_FT_Outline ft_outline;
    int points_alloc;
    int contours_alloc;
-}Outline;
+} Outline;
 
 
 #define TO_FT_COORD(x) ((x) * 64) // to freetype 26.6 coordinate.
@@ -492,8 +494,8 @@ _generate_stroke_data(Ector_Renderer_Software_Shape_Data *pd)
    if (pd->outline_data) return EINA_FALSE;
 
    if (!pd->shape->stroke.fill &&
-       ((pd->shape->stroke.color.a == 0) ||
-        (pd->shape->stroke.width < 0.01)))
+       ((pd->public_shape->stroke.color.a == 0) ||
+        (pd->public_shape->stroke.width < 0.01)))
      return EINA_FALSE;
 
    return EINA_TRUE;
@@ -533,17 +535,17 @@ _update_rle(Eo *obj, Ector_Renderer_Software_Shape_Data *pd)
         if ( _generate_stroke_data(pd))
           {
              ector_software_rasterizer_stroke_set(pd->surface->software,
-                                                  (pd->shape->stroke.width *
-                                                   pd->shape->stroke.scale),
-                                                  pd->shape->stroke.cap,
-                                                  pd->shape->stroke.join);
+                                                  (pd->public_shape->stroke.width *
+                                                   pd->public_shape->stroke.scale),
+                                                   pd->public_shape->stroke.cap,
+                                                   pd->public_shape->stroke.join);
 
-             if (pd->shape->stroke.dash)
+             if (pd->public_shape->stroke.dash)
                {
                   dash_outline = _outline_create();
                   close_path = _generate_dashed_outline(cmds, pts, dash_outline,
-                                                        pd->shape->stroke.dash,
-                                                        pd->shape->stroke.dash_length);
+                                                        pd->public_shape->stroke.dash,
+                                                        pd->public_shape->stroke.dash_length);
                   _outline_transform(dash_outline, pd->base->m);
                   pd->outline_data = ector_software_rasterizer_generate_stroke_rle_data(pd->surface->software,
                                                                                         &dash_outline->ft_outline,
@@ -635,13 +637,13 @@ _ector_renderer_software_shape_ector_renderer_generic_base_draw(Eo *obj,
      }
    else
      {
-        if (pd->shape->stroke.color.a > 0)
+        if (pd->public_shape->stroke.color.a > 0)
           {
              ector_software_rasterizer_color_set(pd->surface->software,
-                                                 pd->shape->stroke.color.r,
-                                                 pd->shape->stroke.color.g,
-                                                 pd->shape->stroke.color.b,
-                                                 pd->shape->stroke.color.a);
+                                                 pd->public_shape->stroke.color.r,
+                                                 pd->public_shape->stroke.color.g,
+                                                 pd->public_shape->stroke.color.b,
+                                                 pd->public_shape->stroke.color.a);
              ector_software_rasterizer_draw_rle_data(pd->surface->software,
                                                      x, y, mul_col, op,
                                                      pd->outline_data);
@@ -695,6 +697,9 @@ Eo *
 _ector_renderer_software_shape_eo_base_constructor(Eo *obj, Ector_Renderer_Software_Shape_Data *pd)
 {
    obj = eo_do_super_ret(obj, ECTOR_RENDERER_SOFTWARE_SHAPE_CLASS, obj, eo_constructor());
+   if (!obj) return NULL;
+
+   pd->public_shape = eo_data_xref(obj, EFL_GFX_SHAPE_MIXIN, obj);
    pd->shape = eo_data_xref(obj, ECTOR_RENDERER_GENERIC_SHAPE_MIXIN, obj);
    pd->base = eo_data_xref(obj, ECTOR_RENDERER_GENERIC_BASE_CLASS, obj);
    eo_do(obj,
@@ -731,18 +736,33 @@ _ector_renderer_software_shape_ector_renderer_generic_base_crc_get(Eo *obj,
 
    eo_do_super(obj, ECTOR_RENDERER_SOFTWARE_SHAPE_CLASS, crc = ector_renderer_crc_get());
 
-   crc = eina_crc((void*) &pd->shape->stroke.marker, sizeof (pd->shape->stroke.marker), crc, EINA_FALSE);
-   crc = eina_crc((void*) &pd->shape->stroke.scale, sizeof (pd->shape->stroke.scale) * 3, crc, EINA_FALSE); // scale, width, centered
-   crc = eina_crc((void*) &pd->shape->stroke.color, sizeof (pd->shape->stroke.color), crc, EINA_FALSE);
-   crc = eina_crc((void*) &pd->shape->stroke.cap, sizeof (pd->shape->stroke.cap), crc, EINA_FALSE);
-   crc = eina_crc((void*) &pd->shape->stroke.join, sizeof (pd->shape->stroke.join), crc, EINA_FALSE);
+   crc = eina_crc((void*) &pd->shape->stroke.marker,
+                  sizeof (pd->shape->stroke.marker),
+                  crc, EINA_FALSE);
+   crc = eina_crc((void*) &pd->public_shape->stroke.scale,
+                  sizeof (pd->public_shape->stroke.scale) * 3,
+                  crc, EINA_FALSE); // scale, width, centered
+   crc = eina_crc((void*) &pd->public_shape->stroke.color,
+                  sizeof (pd->public_shape->stroke.color),
+                  crc, EINA_FALSE);
+   crc = eina_crc((void*) &pd->public_shape->stroke.cap,
+                  sizeof (pd->public_shape->stroke.cap),
+                  crc, EINA_FALSE);
+   crc = eina_crc((void*) &pd->public_shape->stroke.join,
+                  sizeof (pd->public_shape->stroke.join),
+                  crc, EINA_FALSE);
 
-   if (pd->shape->fill) crc = _renderer_crc_get(pd->shape->fill, crc);
-   if (pd->shape->stroke.fill) crc = _renderer_crc_get(pd->shape->stroke.fill, crc);
-   if (pd->shape->stroke.marker) crc = _renderer_crc_get(pd->shape->stroke.marker, crc);
-   if (pd->shape->stroke.dash_length)
+   if (pd->shape->fill)
+     crc = _renderer_crc_get(pd->shape->fill, crc);
+   if (pd->shape->stroke.fill)
+     crc = _renderer_crc_get(pd->shape->stroke.fill, crc);
+   if (pd->shape->stroke.marker)
+     crc = _renderer_crc_get(pd->shape->stroke.marker, crc);
+   if (pd->public_shape->stroke.dash_length)
      {
-        crc = eina_crc((void*) pd->shape->stroke.dash, sizeof (Efl_Gfx_Dash) * pd->shape->stroke.dash_length, crc, EINA_FALSE);
+        crc = eina_crc((void*) pd->public_shape->stroke.dash,
+                       sizeof (Efl_Gfx_Dash) * pd->public_shape->stroke.dash_length,
+                       crc, EINA_FALSE);
      }
 
    return crc;
index 8358a1f..b39fdf7 100644 (file)
@@ -123,6 +123,7 @@ typedef enum _Efl_Gfx_Gradient_Spread
   EFL_GFX_GRADIENT_SPREAD_LAST /**< End of enum value */
 } Efl_Gfx_Gradient_Spread;
 
+
 /**
  * Type defining how an image content get filled.
  * @since 1.14
@@ -137,10 +138,88 @@ typedef enum _Efl_Gfx_Fill_Spread
   EFL_GFX_FILL_PAD = 5 /**< tiling extends with end values */
 } Efl_Gfx_Fill_Spread;
 
+/** Type defining how an image content get filled.
+ *
+ * @since 1.14
+ *
+ * @ingroup Efl_Gfx_Fill
+ */
+typedef enum
+{
+  EFL_GFX_FILL_RULE_WINDING = 0, /** Draw a horizontal line from the point to a
+                                  * location outside the shape. Determine
+                                  * whether the direction of the line at each
+                                  * intersection point is up or down. The
+                                  * winding number is determined by summing the
+                                  * direction of each intersection. If the
+                                  * number is non zero, the point is inside the
+                                  * shape. This mode is the default */
+  EFL_GFX_FILL_RULE_ODD_EVEN = 1 /** Draw a horizontal line from the point to a
+                                  * location outside the shape, and count the
+                                  * number of intersections. If the number of
+                                  * intersections is an odd number, the point
+                                  * is inside the shape. */
+} Efl_Gfx_Fill_Rule;
+
+/** Internal structure for @ref Efl_Gfx_Stroke.
+ *
+ * @ingroup Efl_Gfx_Stroke
+ */
+typedef struct _Efl_Gfx_Stroke_Color
+{
+  int r;
+  int g;
+  int b;
+  int a;
+} Efl_Gfx_Stroke_Color;
+
+/**
+ * Type defining stroke information.
+ * @note Describe the properties to define the path stroke.
+ * @since 1.14
+ */
+typedef struct _Efl_Gfx_Stroke Efl_Gfx_Stroke;
+struct _Efl_Gfx_Stroke
+{
+  double scale;
+  double width;
+  double centered;
+
+  struct {
+     int r, g, b, a;
+  } color;
+
+  Efl_Gfx_Dash *dash;
+  unsigned int dash_length;
+
+  Efl_Gfx_Cap cap;
+  Efl_Gfx_Join join;
+};
+
+typedef struct _Efl_Gfx_Shape_Public Efl_Gfx_Shape_Public;
+struct _Efl_Gfx_Shape_Public
+{
+   Efl_Gfx_Stroke stroke;
+};
+
+/** What property got changed for this object
+ *
+ * @since 1.18
+ *
+ * @ingroup Efl_Gfx_Change
+ */
+typedef enum
+{
+  EFL_GFX_CHANGE_FLAG_NONE = 0, /** No change */
+  EFL_GFX_CHANGE_FLAG_MATRIX = 1, /** matrix got changed */
+  EFL_GFX_CHANGE_FLAG_PATH = 2, /** path got changes */
+  EFL_GFX_CHANGE_FLAG_ALL = -1 /** all property got changed */
+} Efl_Gfx_Change_Flag;
+
 #ifdef EFL_BETA_API_SUPPORT
 
 #include <Efl_Model_Common.h>
-  
+
 /* Interfaces */
 #include "interfaces/efl_control.eo.h"
 #include "interfaces/efl_file.eo.h"
index c9edc29..f7c306f 100644 (file)
 typedef struct _Efl_Gfx_Shape_Data Efl_Gfx_Shape_Data;
 struct _Efl_Gfx_Shape_Data
 {
+   Efl_Gfx_Shape_Public public;
+
+   Efl_Gfx_Fill_Rule fill_rule;
+
    struct {
       double x;
       double y;
@@ -24,6 +28,7 @@ struct _Efl_Gfx_Shape_Data
 
    unsigned int commands_count;
    unsigned int points_count;
+   Eina_Bool convex;
 };
 
 static inline unsigned int
@@ -92,7 +97,7 @@ efl_gfx_path_grow(Efl_Gfx_Path_Command command,
    cmd_tmp[cmd_length - 1] = command;
    // NULL terminate the stream
    cmd_tmp[cmd_length] = EFL_GFX_PATH_COMMAND_TYPE_END;
-
+   pd->convex = EINA_FALSE;
    return EINA_TRUE;
 }
 
@@ -433,46 +438,6 @@ _efl_gfx_shape_equal_commands(Eo *obj EINA_UNUSED,
 }
 
 static void
-_efl_gfx_shape_dup(Eo *obj, Efl_Gfx_Shape_Data *pd, const Eo *dup_from)
-{
-   const Efl_Gfx_Dash *dash = NULL;
-   Efl_Gfx_Shape_Data *from;
-   unsigned int dash_length = 0;
-   Efl_Gfx_Cap cap;
-   Efl_Gfx_Join j;
-   int sr, sg, sb, sa;
-   double scale, location;
-   double sw;
-
-   if (obj == dup_from) return ;
-   from = eo_data_scope_get(dup_from, EFL_GFX_SHAPE_MIXIN);
-   if (!from) return ;
-
-   eo_do(dup_from,
-         scale = efl_gfx_shape_stroke_scale_get(),
-         efl_gfx_shape_stroke_color_get(&sr, &sg, &sb, &sa),
-         sw = efl_gfx_shape_stroke_width_get(),
-         location = efl_gfx_shape_stroke_location_get(),
-         efl_gfx_shape_stroke_dash_get(&dash, &dash_length),
-         cap = efl_gfx_shape_stroke_cap_get(),
-         j = efl_gfx_shape_stroke_join_get());
-   eo_do(obj,
-         efl_gfx_shape_stroke_scale_set(scale),
-         efl_gfx_shape_stroke_color_set(sr, sg, sb, sa),
-         efl_gfx_shape_stroke_width_set(sw),
-         efl_gfx_shape_stroke_location_set(location),
-         efl_gfx_shape_stroke_dash_set(dash, dash_length),
-         efl_gfx_shape_stroke_cap_set(cap),
-         efl_gfx_shape_stroke_join_set(j));
-
-   _efl_gfx_shape_path_set(obj, pd, from->commands, from->points);
-
-   eo_do(obj,
-         eo_event_callback_call(EFL_GFX_PATH_CHANGED, NULL),
-         eo_event_callback_call(EFL_GFX_CHANGED, NULL));
-}
-
-static void
 _efl_gfx_shape_reset(Eo *obj, Efl_Gfx_Shape_Data *pd)
 {
    free(pd->commands);
@@ -487,7 +452,7 @@ _efl_gfx_shape_reset(Eo *obj, Efl_Gfx_Shape_Data *pd)
    pd->current.y = 0;
    pd->current_ctrl.x = 0;
    pd->current_ctrl.y = 0;
-
+   pd->convex = EINA_FALSE;
    eo_do(obj,
          eo_event_callback_call(EFL_GFX_PATH_CHANGED, NULL),
          eo_event_callback_call(EFL_GFX_CHANGED, NULL));
@@ -1152,7 +1117,8 @@ _efl_gfx_shape_append_circle(Eo *obj, Efl_Gfx_Shape_Data *pd,
    Eina_Bool first = (pd->commands_count <= 0);
    _efl_gfx_shape_append_arc(obj, pd, xc - radius, yc - radius, 2*radius, 2*radius, 0, 360);
    _efl_gfx_shape_append_close(obj, pd);
-
+   //update convex flag
+   pd->convex = first;
 }
 
 static void
@@ -1188,6 +1154,9 @@ _efl_gfx_shape_append_rect(Eo *obj, Efl_Gfx_Shape_Data *pd,
    _efl_gfx_shape_append_arc(obj, pd, x + w - rx, y, rx, ry, 0, 90);
    _efl_gfx_shape_append_arc(obj, pd, x, y, rx, ry, 90, 90);
    _efl_gfx_shape_append_close(obj, pd);
+
+   //update convex flag
+   pd->convex = first;
 }
 
 static void
@@ -1269,7 +1238,6 @@ _efl_gfx_path_parse_pair_to(const char *content, char **end,
              x += *current_x;
              y += *current_y;
           }
-
         func(obj, pd, x, y);
         content = *end;
 
@@ -1707,4 +1675,202 @@ error:
 //
 }
 
+static void
+_efl_gfx_shape_stroke_scale_set(Eo *obj EINA_UNUSED,
+                                Efl_Gfx_Shape_Data *pd,
+                                double s)
+{
+   pd->public.stroke.scale = s;
+   eo_do(obj,
+         eo_event_callback_call(EFL_GFX_PATH_CHANGED, NULL),
+         eo_event_callback_call(EFL_GFX_CHANGED, NULL));
+}
+
+static double
+_efl_gfx_shape_stroke_scale_get(Eo *obj EINA_UNUSED,
+                                Efl_Gfx_Shape_Data *pd)
+{
+   return pd->public.stroke.scale;
+}
+
+static void
+_efl_gfx_shape_stroke_color_set(Eo *obj EINA_UNUSED,
+                                Efl_Gfx_Shape_Data *pd,
+                                int r, int g, int b, int a)
+{
+   pd->public.stroke.color.r = r;
+   pd->public.stroke.color.g = g;
+   pd->public.stroke.color.b = b;
+   pd->public.stroke.color.a = a;
+   eo_do(obj, eo_event_callback_call(EFL_GFX_CHANGED, NULL));
+}
+
+static void
+_efl_gfx_shape_stroke_color_get(Eo *obj EINA_UNUSED,
+                                Efl_Gfx_Shape_Data *pd,
+                                int *r, int *g, int *b, int *a)
+{
+   if (r) *r = pd->public.stroke.color.r;
+   if (g) *g = pd->public.stroke.color.g;
+   if (b) *b = pd->public.stroke.color.b;
+   if (a) *a = pd->public.stroke.color.a;
+}
+
+static void
+_efl_gfx_shape_stroke_width_set(Eo *obj EINA_UNUSED,
+                                Efl_Gfx_Shape_Data *pd,
+                                double w)
+{
+   pd->public.stroke.width = w;
+   eo_do(obj,
+         eo_event_callback_call(EFL_GFX_PATH_CHANGED, NULL),
+         eo_event_callback_call(EFL_GFX_CHANGED, NULL));
+}
+
+static double
+_efl_gfx_shape_stroke_width_get(Eo *obj EINA_UNUSED,
+                                Efl_Gfx_Shape_Data *pd)
+{
+   return pd->public.stroke.width;
+}
+
+static void
+_efl_gfx_shape_stroke_location_set(Eo *obj EINA_UNUSED,
+                                   Efl_Gfx_Shape_Data *pd,
+                                   double centered)
+{
+   pd->public.stroke.centered = centered;
+   eo_do(obj,
+         eo_event_callback_call(EFL_GFX_PATH_CHANGED, NULL),
+         eo_event_callback_call(EFL_GFX_CHANGED, NULL));
+}
+
+static double
+_efl_gfx_shape_stroke_location_get(Eo *obj EINA_UNUSED,
+                                   Efl_Gfx_Shape_Data *pd)
+{
+   return pd->public.stroke.centered;
+}
+
+static void
+_efl_gfx_shape_stroke_dash_set(Eo *obj EINA_UNUSED,
+                               Efl_Gfx_Shape_Data *pd,
+                               const Efl_Gfx_Dash *dash, unsigned int length)
+{
+   Efl_Gfx_Dash *tmp;
+
+   if (!dash)
+     {
+        free(pd->public.stroke.dash);
+        pd->public.stroke.dash = NULL;
+        pd->public.stroke.dash_length = 0;
+        eo_do(obj,
+              eo_event_callback_call(EFL_GFX_PATH_CHANGED, NULL),
+              eo_event_callback_call(EFL_GFX_CHANGED, NULL));
+        return ;
+     }
+
+   tmp = realloc(pd->public.stroke.dash, length * sizeof (Efl_Gfx_Dash));
+   if (!tmp && length) return ;
+   memcpy(tmp, dash, length * sizeof (Efl_Gfx_Dash));
+
+   pd->public.stroke.dash = tmp;
+   pd->public.stroke.dash_length = length;
+   eo_do(obj,
+         eo_event_callback_call(EFL_GFX_PATH_CHANGED, NULL),
+         eo_event_callback_call(EFL_GFX_CHANGED, NULL));
+}
+
+static void
+_efl_gfx_shape_stroke_dash_get(Eo *obj EINA_UNUSED,
+                               Efl_Gfx_Shape_Data *pd,
+                               const Efl_Gfx_Dash **dash, unsigned int *length)
+{
+   if (dash) *dash = pd->public.stroke.dash;
+   if (length) *length = pd->public.stroke.dash_length;
+}
+
+static void
+_efl_gfx_shape_stroke_cap_set(Eo *obj EINA_UNUSED,
+                              Efl_Gfx_Shape_Data *pd,
+                              Efl_Gfx_Cap c)
+{
+   pd->public.stroke.cap = c;
+   eo_do(obj,
+         eo_event_callback_call(EFL_GFX_PATH_CHANGED, NULL),
+         eo_event_callback_call(EFL_GFX_CHANGED, NULL));
+}
+
+static Efl_Gfx_Cap
+_efl_gfx_shape_stroke_cap_get(Eo *obj EINA_UNUSED,
+                              Efl_Gfx_Shape_Data *pd)
+{
+   return pd->public.stroke.cap;
+}
+
+static void
+_efl_gfx_shape_stroke_join_set(Eo *obj EINA_UNUSED,
+                               Efl_Gfx_Shape_Data *pd,
+                               Efl_Gfx_Join j)
+{
+   pd->public.stroke.join = j;
+   eo_do(obj,
+         eo_event_callback_call(EFL_GFX_PATH_CHANGED, NULL),
+         eo_event_callback_call(EFL_GFX_CHANGED, NULL));
+}
+
+static Efl_Gfx_Join
+_efl_gfx_shape_stroke_join_get(Eo *obj EINA_UNUSED,
+                               Efl_Gfx_Shape_Data *pd)
+{
+   return pd->public.stroke.join;
+}
+
+static void
+_efl_gfx_shape_fill_rule_set(Eo *obj EINA_UNUSED,
+                             Efl_Gfx_Shape_Data *pd,
+                             Efl_Gfx_Fill_Rule fill_rule)
+{
+   pd->fill_rule = fill_rule;
+   eo_do(obj,
+         eo_event_callback_call(EFL_GFX_PATH_CHANGED, NULL),
+         eo_event_callback_call(EFL_GFX_CHANGED, NULL));
+}
+
+static Efl_Gfx_Fill_Rule
+_efl_gfx_shape_fill_rule_get(Eo *obj EINA_UNUSED,
+                             Efl_Gfx_Shape_Data *pd)
+{
+   return pd->fill_rule;
+}
+
+static void
+_efl_gfx_shape_dup(Eo *obj, Efl_Gfx_Shape_Data *pd, const Eo *dup_from)
+{
+   Efl_Gfx_Shape_Data *from;
+
+   if (obj == dup_from) return ;
+   from = eo_data_scope_get(dup_from, EFL_GFX_SHAPE_MIXIN);
+   if (!from) return ;
+
+   pd->public.stroke.scale = from->public.stroke.scale;
+   pd->public.stroke.width = from->public.stroke.width;
+   pd->public.stroke.centered = from->public.stroke.centered;
+   pd->public.stroke.cap = from->public.stroke.cap;
+   pd->public.stroke.join = from->public.stroke.join;
+   pd->public.stroke.color.r = from->public.stroke.color.r;
+   pd->public.stroke.color.g = from->public.stroke.color.g;
+   pd->public.stroke.color.b = from->public.stroke.color.b;
+   pd->public.stroke.color.a = from->public.stroke.color.a;
+   pd->fill_rule = from->fill_rule;
+   pd->convex = from->convex;
+
+   _efl_gfx_shape_stroke_dash_set(obj, pd, from->public.stroke.dash, from->public.stroke.dash_length);
+   _efl_gfx_shape_path_set(obj, pd, from->commands, from->points);
+
+   eo_do(obj,
+         eo_event_callback_call(EFL_GFX_PATH_CHANGED, NULL),
+         eo_event_callback_call(EFL_GFX_CHANGED, NULL));
+}
+
 #include "interfaces/efl_gfx_shape.eo.c"
index 005e9a4..9c50a17 100644 (file)
@@ -125,6 +125,21 @@ mixin Efl.Gfx.Shape
             j: Efl_Gfx_Join; [[join style to use, default is EFL_GFX_JOIN_MITER]]
          }
       }
+      @property fill_rule {
+         [[The fill rule of the given shape object.
+           $EFL_GFX_FILL_RULE_WINDING, or $EFL_GFX_FILL_RULE_ODD_EVEN.
+
+           @since 1.14
+         ]]
+         set {
+         }
+         get {
+         }
+         values {
+            fill_rule: Efl.Gfx.Fill.Rule; [[The current fill rule of the shape object.
+                                           One of $EFL_GFX_FILL_RULE_WINDING, $EFL_GFX_FILL_RULE_ODD_EVEN]]
+         }
+      }
       @property path {
          set {
             [[Set the list of commands and points to be used to create the
@@ -392,20 +407,4 @@ mixin Efl.Gfx.Shape
         }
       }
    }
-   implements {
-      @virtual .stroke_scale.get;
-      @virtual .stroke_scale.set;
-      @virtual .stroke_color.get;
-      @virtual .stroke_color.set;
-      @virtual .stroke_width.get;
-      @virtual .stroke_width.set;
-      @virtual .stroke_location.get;
-      @virtual .stroke_location.set;
-      @virtual .stroke_dash.get;
-      @virtual .stroke_dash.set;
-      @virtual .stroke_cap.get;
-      @virtual .stroke_cap.set;
-      @virtual .stroke_join.get;
-      @virtual .stroke_join.set;
-   }
 }
index 053a374..337c807 100644 (file)
@@ -31,13 +31,6 @@ class Efl.VG.Shape (Efl.VG.Base, Efl.Gfx.Shape)
       }
    }
    implements {
-      Efl.Gfx.Shape.stroke_scale;
-      Efl.Gfx.Shape.stroke_color;
-      Efl.Gfx.Shape.stroke_width;
-      Efl.Gfx.Shape.stroke_location;
-      Efl.Gfx.Shape.stroke_dash;
-      Efl.Gfx.Shape.stroke_cap;
-      Efl.Gfx.Shape.stroke_join;
       Efl.Gfx.Base.color_part.set;
       Efl.Gfx.Base.color_part.get;
       Efl.VG.Base.bounds_get;
index 32ffbfa..b985850 100644 (file)
@@ -15,14 +15,25 @@ _efl_vg_container_render_pre(Eo *obj EINA_UNUSED,
    Efl_VG_Container_Data *pd = data;
    Eina_List *l;
    Eo *child;
+   Efl_VG_Base_Data *child_nd;
+   Efl_Gfx_Change_Flag flag;
 
-   if (!nd->changed) return ;
-   nd->changed = EINA_FALSE;
+   if (nd->flags == EFL_GFX_CHANGE_FLAG_NONE) return ;
+
+   flag = nd->flags;
+   nd->flags = EFL_GFX_CHANGE_FLAG_NONE;
 
    EFL_VG_COMPUTE_MATRIX(current, parent, nd);
 
    EINA_LIST_FOREACH(pd->children, l, child)
-     _evas_vg_render_pre(child, s, current);
+     {
+        if (flag & EFL_GFX_CHANGE_FLAG_MATRIX)
+          {
+             child_nd = eo_data_scope_get(child, EFL_VG_BASE_CLASS);
+             child_nd->flags |= EFL_GFX_CHANGE_FLAG_MATRIX;
+          }
+        _evas_vg_render_pre(child, s, current);
+     }
 }
 
 static Eo *
@@ -38,6 +49,7 @@ _efl_vg_container_eo_base_constructor(Eo *obj,
    nd = eo_data_scope_get(obj, EFL_VG_BASE_CLASS);
    nd->render_pre = _efl_vg_container_render_pre;
    nd->data = pd;
+   nd->flags = EFL_GFX_CHANGE_FLAG_ALL;
 
    return obj;
 }
@@ -103,34 +115,38 @@ _efl_vg_container_efl_vg_base_interpolate(Eo *obj,
                                           const Efl_VG_Base *from, const Efl_VG_Base *to,
                                           double pos_map)
 {
-   Efl_VG_Container_Data *fd;
-   Efl_VG_Container_Data *td;
-   Eina_Iterator *it;
-   Eina_Hash_Tuple *tuple;
-   Eina_Bool r;
+   Eina_Iterator *from_it, *to_it;
+   Eina_List *l;
+   Eina_Bool r, res = EINA_TRUE;
+   Eo *from_child, *to_child, *child;
+
+   //1. check if both the object are containers
+   if (!(eo_isa(from, EFL_VG_CONTAINER_CLASS) &&
+         eo_isa(to, EFL_VG_CONTAINER_CLASS)))
+     return EINA_FALSE;
 
    eo_do_super(obj, EFL_VG_CONTAINER_CLASS, r = efl_vg_interpolate(from, to, pos_map));
 
    if (!r) return EINA_FALSE;
 
-   fd = eo_data_scope_get(from, EFL_VG_CONTAINER_CLASS);
-   td = eo_data_scope_get(to, EFL_VG_CONTAINER_CLASS);
-
-   it = eina_hash_iterator_tuple_new(pd->names);
-   EINA_ITERATOR_FOREACH(it, tuple)
+   eo_do(from, from_it = efl_vg_container_children_get());
+   eo_do(to, to_it = efl_vg_container_children_get());
+   EINA_LIST_FOREACH (pd->children, l, child)
      {
-        Eo *fromc, *toc;
-        Eo *cc = tuple->data;
-
-        fromc = eina_hash_find(fd->names, tuple->key);
-        toc = eina_hash_find(td->names, tuple->key);
-
-        if (!toc || !fromc) continue ;
-        if (eo_class_get(toc) != eo_class_get(fromc)) continue ;
-
-        eo_do(cc, r &= efl_vg_interpolate(fromc, toc, pos_map));
+        res &= eina_iterator_next(from_it, (void **)&from_child);
+        res &= eina_iterator_next(to_it, (void **)&to_child);
+        if (!res && (eo_class_get(from_child) != eo_class_get(to_child) ||
+            (eo_class_get(child) != eo_class_get(from_child))))
+          {
+             r = EINA_FALSE;
+             break;
+          }
+        eo_do(child, r &= efl_vg_interpolate(from_child, to_child, pos_map));
+        if (!r)
+          break;
      }
-   eina_iterator_free(it);
+   eina_iterator_free(from_it);
+   eina_iterator_free(to_it);
 
    return r;
 }
@@ -155,9 +171,7 @@ _efl_vg_container_efl_vg_base_dup(Eo *obj,
      {
         // By setting parent, we automatically reference
         // this new object as a child of obj. Magic at work !
-        eo_add_ref(eo_class_get(child),
-                   obj,
-                   efl_vg_dup(child));
+        (void) eo_add(eo_class_get(child), obj, efl_vg_dup(child));
      }
 }
 
index 7234d4b..712e80f 100644 (file)
@@ -65,8 +65,9 @@ _efl_vg_gradient_linear_render_pre(Eo *obj,
    Efl_VG_Gradient_Linear_Data *pd = data;
    Efl_VG_Gradient_Data *gd;
 
-   if (!nd->changed) return ;
-   nd->changed = EINA_FALSE;
+   if (nd->flags == EFL_GFX_CHANGE_FLAG_NONE) return ;
+
+   nd->flags = EFL_GFX_CHANGE_FLAG_NONE;
 
    gd = eo_data_scope_get(obj, EFL_VG_GRADIENT_CLASS);
    EFL_VG_COMPUTE_MATRIX(current, parent, nd);
index d6d62c5..d865cc2 100644 (file)
@@ -81,8 +81,9 @@ _efl_vg_gradient_radial_render_pre(Eo *obj,
    Efl_VG_Gradient_Radial_Data *pd = data;
    Efl_VG_Gradient_Data *gd;
 
-   if (!nd->changed) return ;
-   nd->changed = EINA_FALSE;
+   if (nd->flags == EFL_GFX_CHANGE_FLAG_NONE) return ;
+
+   nd->flags = EFL_GFX_CHANGE_FLAG_NONE;
 
    gd = eo_data_scope_get(obj, EFL_VG_GRADIENT_CLASS);
    EFL_VG_COMPUTE_MATRIX(current, parent, nd);
index d160b45..eae7b0a 100644 (file)
@@ -23,8 +23,7 @@ _efl_vg_base_property_changed(void *data, Eo *obj, const Eo_Event_Description *d
    Efl_VG_Base_Data *pd = data;
    Eo *parent;
 
-   if (pd->changed) return EINA_TRUE;
-   pd->changed = EINA_TRUE;
+   if (!pd->flags) pd->flags = EFL_GFX_CHANGE_FLAG_ALL;
 
    eo_do(obj, parent = eo_parent_get());
    eo_do(parent, eo_event_callback_call(desc, event_info));
@@ -128,10 +127,14 @@ _efl_vg_base_efl_gfx_base_color_set(Eo *obj EINA_UNUSED,
                                     Efl_VG_Base_Data *pd,
                                     int r, int g, int b, int a)
 {
-   if (r > 255) r = 255; if (r < 0) r = 0;
-   if (g > 255) g = 255; if (g < 0) g = 0;
-   if (b > 255) b = 255; if (b < 0) b = 0;
-   if (a > 255) a = 255; if (a < 0) a = 0;
+   if (r > 255) r = 255;
+   if (r < 0) r = 0;
+   if (g > 255) g = 255;
+   if (g < 0) g = 0;
+   if (b > 255) b = 255;
+   if (b < 0) b = 0;
+   if (a > 255) a = 255;
+   if (a < 0) a = 0;
    if (r > a)
      {
         r = a;
@@ -271,6 +274,7 @@ _efl_vg_base_eo_base_constructor(Eo *obj,
    }
 
    eo_do(obj, eo_event_callback_add(EFL_GFX_CHANGED, _efl_vg_base_property_changed, pd));
+   pd->flags = EFL_GFX_CHANGE_FLAG_ALL;
    pd->changed = EINA_TRUE;
 
    return obj;
index 102de5b..657e2a9 100644 (file)
@@ -23,6 +23,7 @@ struct _Efl_VG_Base_Data
 
    double x, y;
    int r, g, b, a;
+   Efl_Gfx_Change_Flag flags;
 
    Eina_Bool visibility : 1;
    Eina_Bool changed : 1;
index 27a43f6..9bfa8bb 100644 (file)
@@ -11,20 +11,8 @@ struct _Efl_VG_Shape_Data
    Efl_VG *fill;
 
    struct {
-      Efl_Gfx_Dash *dash;
       Efl_VG *fill;
       Efl_VG *marker;
-
-      double scale;
-      double width;
-      double centered; // from 0 to 1
-
-      int r, g, b, a;
-
-      unsigned int dash_count;
-
-      Efl_Gfx_Cap cap;
-      Efl_Gfx_Join join;
    } stroke;
 };
 
@@ -56,38 +44,8 @@ _efl_vg_shape_fill_get(Eo *obj EINA_UNUSED, Efl_VG_Shape_Data *pd)
    return pd->fill;
 }
 
-static void
-_efl_vg_shape_efl_gfx_shape_stroke_scale_set(Eo *obj EINA_UNUSED,
-                                             Efl_VG_Shape_Data *pd,
-                                             double s)
-{
-   pd->stroke.scale = s;
-
-   _efl_vg_base_changed(obj);
-}
-
-static double
-_efl_vg_shape_efl_gfx_shape_stroke_scale_get(Eo *obj EINA_UNUSED,
-                                             Efl_VG_Shape_Data *pd)
-{
-   return pd->stroke.scale;
-}
-
-static void
-_efl_vg_shape_efl_gfx_shape_stroke_color_set(Eo *obj EINA_UNUSED,
-                                             Efl_VG_Shape_Data *pd,
-                                             int r, int g, int b, int a)
-{
-   pd->stroke.r = r;
-   pd->stroke.g = g;
-   pd->stroke.b = b;
-   pd->stroke.a = a;
-
-   _efl_vg_base_changed(obj);
-}
-
 static Eina_Bool
-_efl_vg_shape_efl_gfx_base_color_part_set(Eo *obj, Efl_VG_Shape_Data *pd,
+_efl_vg_shape_efl_gfx_base_color_part_set(Eo *obj, Efl_VG_Shape_Data *pd EINA_UNUSED,
                                           const char * part,
                                           int r, int g, int b, int a)
 {
@@ -95,7 +53,7 @@ _efl_vg_shape_efl_gfx_base_color_part_set(Eo *obj, Efl_VG_Shape_Data *pd,
 
    if (part && !strcmp(part, "stroke"))
      {
-        _efl_vg_shape_efl_gfx_shape_stroke_color_set(obj, pd, r, g, b, a);
+         eo_do(obj, efl_gfx_shape_stroke_color_set(r, g, b, a));
         return EINA_TRUE;
      }
 
@@ -105,19 +63,8 @@ _efl_vg_shape_efl_gfx_base_color_part_set(Eo *obj, Efl_VG_Shape_Data *pd,
    return ret;
 }
 
-static void
-_efl_vg_shape_efl_gfx_shape_stroke_color_get(Eo *obj EINA_UNUSED,
-                                             Efl_VG_Shape_Data *pd,
-                                             int *r, int *g, int *b, int *a)
-{
-   if (r) *r = pd->stroke.r;
-   if (g) *g = pd->stroke.g;
-   if (b) *b = pd->stroke.b;
-   if (a) *a = pd->stroke.a;
-}
-
 static Eina_Bool
-_efl_vg_shape_efl_gfx_base_color_part_get(Eo *obj, Efl_VG_Shape_Data *pd,
+_efl_vg_shape_efl_gfx_base_color_part_get(Eo *obj, Efl_VG_Shape_Data *pd EINA_UNUSED,
                                           const char * part,
                                           int *r, int *g, int *b, int *a)
 {
@@ -125,7 +72,7 @@ _efl_vg_shape_efl_gfx_base_color_part_get(Eo *obj, Efl_VG_Shape_Data *pd,
 
    if (part && !strcmp(part, "stroke"))
      {
-        _efl_vg_shape_efl_gfx_shape_stroke_color_get(obj, pd, r, g, b, a);
+        eo_do(obj, efl_gfx_shape_stroke_color_get(r, g, b, a));
         return EINA_TRUE;
      }
 
@@ -156,72 +103,6 @@ _efl_vg_shape_stroke_fill_get(Eo *obj EINA_UNUSED,
 }
 
 static void
-_efl_vg_shape_efl_gfx_shape_stroke_width_set(Eo *obj EINA_UNUSED,
-                                             Efl_VG_Shape_Data *pd,
-                                             double w)
-{
-   pd->stroke.width = w;
-
-   _efl_vg_base_changed(obj);
-}
-
-static double
-_efl_vg_shape_efl_gfx_shape_stroke_width_get(Eo *obj EINA_UNUSED,
-                                             Efl_VG_Shape_Data *pd)
-{
-   return pd->stroke.width;
-}
-
-static void
-_efl_vg_shape_efl_gfx_shape_stroke_location_set(Eo *obj EINA_UNUSED,
-                                                Efl_VG_Shape_Data *pd,
-                                                double centered)
-{
-   pd->stroke.centered = centered;
-
-   _efl_vg_base_changed(obj);
-}
-
-static double
-_efl_vg_shape_efl_gfx_shape_stroke_location_get(Eo *obj EINA_UNUSED,
-                                                Efl_VG_Shape_Data *pd)
-{
-   return pd->stroke.centered;
-}
-
-static void
-_efl_vg_shape_efl_gfx_shape_stroke_dash_set(Eo *obj EINA_UNUSED,
-                                            Efl_VG_Shape_Data *pd,
-                                            const Efl_Gfx_Dash *dash,
-                                            unsigned int length)
-{
-   free(pd->stroke.dash);
-   pd->stroke.dash = NULL;
-   pd->stroke.dash_count = 0;
-
-   // check for null or empty dash
-   if (!dash || !length) return;
-
-   pd->stroke.dash = malloc(sizeof (Efl_Gfx_Dash) * length);
-   if (!pd->stroke.dash) return ;
-
-   memcpy(pd->stroke.dash, dash, sizeof (Efl_Gfx_Dash) * length);
-   pd->stroke.dash_count = length;
-
-   _efl_vg_base_changed(obj);
-}
-
-static void
-_efl_vg_shape_efl_gfx_shape_stroke_dash_get(Eo *obj EINA_UNUSED,
-                                            Efl_VG_Shape_Data *pd,
-                                            const Efl_Gfx_Dash **dash,
-                                            unsigned int *length)
-{
-   if (dash) *dash = pd->stroke.dash;
-   if (length) *length = pd->stroke.dash_count;
-}
-
-static void
 _efl_vg_shape_stroke_marker_set(Eo *obj EINA_UNUSED,
                                 Efl_VG_Shape_Data *pd,
                                 Efl_VG_Shape *m)
@@ -242,40 +123,6 @@ _efl_vg_shape_stroke_marker_get(Eo *obj EINA_UNUSED,
 }
 
 static void
-_efl_vg_shape_efl_gfx_shape_stroke_cap_set(Eo *obj EINA_UNUSED,
-                                           Efl_VG_Shape_Data *pd,
-                                           Efl_Gfx_Cap c)
-{
-   pd->stroke.cap = c;
-
-   _efl_vg_base_changed(obj);
-}
-
-static Efl_Gfx_Cap
-_efl_vg_shape_efl_gfx_shape_stroke_cap_get(Eo *obj EINA_UNUSED,
-                                           Efl_VG_Shape_Data *pd)
-{
-   return pd->stroke.cap;
-}
-
-static void
-_efl_vg_shape_efl_gfx_shape_stroke_join_set(Eo *obj EINA_UNUSED,
-                                            Efl_VG_Shape_Data *pd,
-                                            Efl_Gfx_Join j)
-{
-   pd->stroke.join = j;
-
-   _efl_vg_base_changed(obj);
-}
-
-static Efl_Gfx_Join
-_efl_vg_shape_efl_gfx_shape_stroke_join_get(Eo *obj EINA_UNUSED,
-                                            Efl_VG_Shape_Data *pd)
-{
-   return pd->stroke.join;
-}
-
-static void
 _efl_vg_shape_render_pre(Eo *obj EINA_UNUSED,
                          Eina_Matrix3 *parent,
                          Ector_Surface *s,
@@ -284,12 +131,10 @@ _efl_vg_shape_render_pre(Eo *obj EINA_UNUSED,
 {
    Efl_VG_Shape_Data *pd = data;
    Efl_VG_Base_Data *fill, *stroke_fill, *stroke_marker, *mask;
-   double xn = nd->x, yn = nd->y ;
 
-   if (!nd->changed) return ;
-   nd->changed = EINA_FALSE;
+   if (nd->flags == EFL_GFX_CHANGE_FLAG_NONE) return ;
 
-   if(parent) eina_matrix3_point_transform(parent, nd->x, nd->y, &xn, &yn);
+   nd->flags = EFL_GFX_CHANGE_FLAG_NONE;
 
    EFL_VG_COMPUTE_MATRIX(current, parent, nd);
 
@@ -305,7 +150,7 @@ _efl_vg_shape_render_pre(Eo *obj EINA_UNUSED,
 
    eo_do(nd->renderer,
          ector_renderer_transformation_set(current),
-         ector_renderer_origin_set(xn, yn),
+         ector_renderer_origin_set(nd->x, nd->y),
          ector_renderer_color_set(nd->r, nd->g, nd->b, nd->a),
          ector_renderer_visibility_set(nd->visibility),
          ector_renderer_mask_set(mask ? mask->renderer : NULL),
@@ -323,10 +168,11 @@ _efl_vg_shape_eo_base_constructor(Eo *obj, Efl_VG_Shape_Data *pd)
 
    obj = eo_do_super_ret(obj, MY_CLASS, obj, eo_constructor());
 
-   pd->stroke.cap = EFL_GFX_CAP_BUTT;
-   pd->stroke.join = EFL_GFX_JOIN_MITER;
-   pd->stroke.scale = 1;
-   pd->stroke.centered = 0.5;
+   eo_do(obj,
+         efl_gfx_shape_stroke_scale_set(1),
+         efl_gfx_shape_stroke_location_set(0.5),
+         efl_gfx_shape_stroke_cap_set(EFL_GFX_CAP_BUTT),
+         efl_gfx_shape_stroke_join_set(EFL_GFX_JOIN_MITER));
 
    nd = eo_data_scope_get(obj, EFL_VG_BASE_CLASS);
    nd->render_pre = _efl_vg_shape_render_pre;
@@ -393,6 +239,8 @@ _efl_vg_shape_efl_vg_base_dup(Eo *obj, Efl_VG_Shape_Data *pd EINA_UNUSED, const
         fill = eo_add(eo_class_get(fromd->fill),
                       parent,
                       efl_vg_dup(fromd->fill));
+        eo_do(obj, efl_vg_shape_fill_set(fill));
+               eo_unref(fill);
      }
 
    if (fromd->stroke.fill)
@@ -400,6 +248,8 @@ _efl_vg_shape_efl_vg_base_dup(Eo *obj, Efl_VG_Shape_Data *pd EINA_UNUSED, const
         stroke_fill = eo_add(eo_class_get(fromd->stroke.fill),
                              parent,
                              efl_vg_dup(fromd->stroke.fill));
+        eo_do(obj, efl_vg_shape_stroke_fill_set(stroke_fill));
+               eo_unref(stroke_fill);
      }
 
    if (fromd->stroke.marker)
@@ -407,13 +257,11 @@ _efl_vg_shape_efl_vg_base_dup(Eo *obj, Efl_VG_Shape_Data *pd EINA_UNUSED, const
         stroke_marker = eo_add(eo_class_get(fromd->stroke.marker),
                                parent,
                                efl_vg_dup(fromd->stroke.marker));
+        eo_do(obj, efl_vg_shape_stroke_marker_set(stroke_marker));
+               eo_unref(stroke_marker);
      }
 
-   eo_do(obj,
-         efl_vg_shape_fill_set(fill),
-         efl_vg_shape_stroke_fill_set(stroke_fill),
-         efl_vg_shape_stroke_marker_set(stroke_marker),
-         efl_gfx_shape_dup(from));
+   eo_do(obj, efl_gfx_shape_dup(from));
 }
 
 EAPI double