evas vector: Fixed gradients rendering in thorvg mode. 90/247590/2
authorMichal Szczecinski <m.szczecinsk@partner.samsung.com>
Thu, 5 Nov 2020 11:14:26 +0000 (12:14 +0100)
committerHermet Park <chuneon.park@samsung.com>
Mon, 16 Nov 2020 05:33:56 +0000 (05:33 +0000)
This commit fixed possible crash in gradients rendering pipeline.
This crash was caused by invalid fill and duplicate function
implementaiton.

Change-Id: I42bb9935bcaf009f33e7abeeed39552bb57ab28b

src/lib/evas/canvas/efl_canvas_vg_shape.c
src/lib/evas/canvas/evas_vg_private.h

index 0976a54..5dbcb8c 100644 (file)
@@ -67,7 +67,6 @@ struct _Efl_Canvas_Vg_Shape_Data
 };
 
 #ifdef HAVE_THORVG
-
 static inline double
 _interpolate(double from, double to, double pos_map)
 {
@@ -190,7 +189,6 @@ _assign_command(Efl_Canvas_Vg_Shape_Data *sd, Efl_Tvg_Path_Cmd_Type c_prev)
    sd->cmd_prev = c_prev;
 }
 
-
 static void
 _append_scubic_to(Evas_Vg_Shape *obj, double x, double y,
                   double ctrl_x1, double ctrl_y1)
@@ -411,6 +409,16 @@ _shape_dup(Evas_Vg_Shape *obj, Evas_Vg_Shape *dup_from)
    if (sd->shape) tvg_paint_del(sd->shape);
    sd->shape = tvg_paint_duplicate(sd_from->shape);
 
+   if (sd_from->fill)
+     {
+        Efl_Canvas_Vg_Gradient_Data *gd = NULL;
+        Tvg_Gradient *grad = NULL;
+        sd->fill = efl_duplicate(sd_from->fill);
+        tvg_shape_get_gradient(sd_from->shape, &grad);
+        gd = efl_data_scope_get(sd->fill, EFL_CANVAS_VG_GRADIENT_CLASS);
+        if (gd) gd->gradient = grad;
+     }
+
    sd->curr_ctrl.x = sd_from->curr_ctrl.x;
    sd->curr_ctrl.y = sd_from->curr_ctrl.y;
 
@@ -580,16 +588,26 @@ _efl_canvas_vg_shape_fill_set(Eo *obj EINA_UNUSED,
                        Efl_Canvas_Vg_Node *f)
 {
    if (pd->fill == f) return;
-#ifdef HAVE_THORVG
+
    if (efl_isa(pd->fill, EFL_CANVAS_VG_GRADIENT_CLASS))
      {
         efl_del(pd->fill);
         pd->fill = NULL;
      }
-#endif
+
    Efl_Canvas_Vg_Node *tmp = pd->fill;
    pd->fill = efl_ref(f);
    efl_unref(tmp);
+
+#ifdef HAVE_THORVG
+   Efl_Canvas_Vg_Gradient_Data *gd = NULL;
+   gd = efl_data_scope_get(pd->fill, EFL_CANVAS_VG_GRADIENT_CLASS);
+
+   if (efl_isa(pd->fill, EFL_CANVAS_VG_GRADIENT_LINEAR_CLASS))
+     tvg_shape_set_linear_gradient(pd->shape, gd->gradient);
+   else if (efl_isa(pd->fill, EFL_CANVAS_VG_GRADIENT_RADIAL_CLASS))
+     tvg_shape_set_radial_gradient(pd->shape, gd->gradient);
+#endif
 }
 
 static Efl_Canvas_Vg_Node *
@@ -714,7 +732,6 @@ _efl_canvas_vg_shape_render_pre_tvg(EINA_UNUSED Evas_Object_Protected_Data *vg_p
                                     void *canvas)
 {
    Efl_Canvas_Vg_Shape_Data *sd = NULL;
-   Efl_Canvas_Vg_Gradient_Data *gd = NULL;
 
    Tvg_Matrix trans_mat = { 0 };
    const Eina_Matrix3 *m = NULL;
@@ -727,12 +744,10 @@ _efl_canvas_vg_shape_render_pre_tvg(EINA_UNUSED Evas_Object_Protected_Data *vg_p
    nd->flags = EFL_GFX_CHANGE_FLAG_NONE;
    tvg_paint_translate(sd->shape, nd->x, nd->y);
 
-   // set color fill
-   if (sd->fill != NULL && efl_isa(sd->fill, EFL_CANVAS_VG_GRADIENT_CLASS))
+   if (sd->fill == NULL)
      {
-        gd = efl_data_scope_get(sd->fill, EFL_CANVAS_VG_GRADIENT_CLASS);
-        gd->shape = obj;
-        gd->gradient_render_pre_tvg(sd->fill, gd, sd->shape);
+        efl_gfx_color_get(obj, &r, &g, &b, &a);
+        tvg_shape_set_fill_color(sd->shape, r, g, b, a);
      }
 
    m = evas_vg_node_transformation_get(obj);
index 317751e..0e124ed 100644 (file)
@@ -137,12 +137,10 @@ struct _Efl_Canvas_Vg_Gradient_Data
    // FIXME: Later on we should deduplicate it somehow (Using Ector ?).
    Efl_Gfx_Gradient_Stop *colors;
    unsigned int colors_count;
-
    Efl_Gfx_Gradient_Spread spread;
+
 #ifdef HAVE_THORVG
    Tvg_Gradient *gradient;
-   Evas_Vg_Shape *shape;    // we need handle to shape to call node_change with it
-   void (*gradient_render_pre_tvg)(Efl_Canvas_Vg_Node *nd, Efl_Canvas_Vg_Gradient_Data *gd, Tvg_Paint *shape);
 #endif
 };