From 8461bad6248d5ed78a6766c68569c2c9a5919932 Mon Sep 17 00:00:00 2001 From: Michal Szczecinski Date: Thu, 5 Nov 2020 12:14:26 +0100 Subject: [PATCH] evas vector: Fixed gradients rendering in thorvg mode. 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 | 35 ++++++++++++++++++++++--------- src/lib/evas/canvas/evas_vg_private.h | 4 +--- 2 files changed, 26 insertions(+), 13 deletions(-) diff --git a/src/lib/evas/canvas/efl_canvas_vg_shape.c b/src/lib/evas/canvas/efl_canvas_vg_shape.c index 0976a54..5dbcb8c 100644 --- a/src/lib/evas/canvas/efl_canvas_vg_shape.c +++ b/src/lib/evas/canvas/efl_canvas_vg_shape.c @@ -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); diff --git a/src/lib/evas/canvas/evas_vg_private.h b/src/lib/evas/canvas/evas_vg_private.h index 317751e..0e124ed 100644 --- a/src/lib/evas/canvas/evas_vg_private.h +++ b/src/lib/evas/canvas/evas_vg_private.h @@ -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 }; -- 2.7.4