From 1c9f63677fa97ffdde198f765f3ef48f1553d76a Mon Sep 17 00:00:00 2001 From: JunsuChoi Date: Wed, 16 Oct 2019 15:12:13 +0900 Subject: [PATCH] efl_canvas_vg : Propagates the alpha color of the parent Summary: The current color is affected by the parent's opacity. If p_opacity is set, it will be applied to the current color. Test Plan: N/A Reviewers: Hermet, smohanty, kimcinoo Reviewed By: Hermet Subscribers: cedric, #reviewers, #committers Tags: #efl Differential Revision: https://phab.enlightenment.org/D10399 --- src/lib/evas/canvas/efl_canvas_vg_container.c | 12 ++++++++---- .../canvas/efl_canvas_vg_gradient_linear.c | 4 +++- .../canvas/efl_canvas_vg_gradient_radial.c | 4 +++- src/lib/evas/canvas/efl_canvas_vg_image.c | 10 ++++------ src/lib/evas/canvas/efl_canvas_vg_object.c | 4 ++-- src/lib/evas/canvas/efl_canvas_vg_shape.c | 10 ++++++---- src/lib/evas/canvas/evas_vg_private.h | 19 +++++++++++++++++-- 7 files changed, 43 insertions(+), 20 deletions(-) diff --git a/src/lib/evas/canvas/efl_canvas_vg_container.c b/src/lib/evas/canvas/efl_canvas_vg_container.c index f4bf4d7637..471ea3dd6c 100644 --- a/src/lib/evas/canvas/efl_canvas_vg_container.c +++ b/src/lib/evas/canvas/efl_canvas_vg_container.c @@ -54,6 +54,8 @@ _prepare_comp(Evas_Object_Protected_Data *obj, //vector object Ector_Surface *surface, Eina_Matrix3 *ptransform, Eina_Matrix3 *ctransform, + int p_opacity, + int c_opacity, Ector_Buffer *comp, Efl_Gfx_Vg_Composite_Method comp_method) { @@ -127,7 +129,7 @@ _prepare_comp(Evas_Object_Protected_Data *obj, //vector object src_pd = efl_data_scope_get(eina_list_nth(target_pd->comp.src, 0), MY_CLASS); _evas_vg_render_pre(obj, comp_target, engine, output, context, surface, - ctransform, comp, src_pd->comp.method); + ctransform, c_opacity, comp, src_pd->comp.method); } } @@ -135,7 +137,7 @@ _prepare_comp(Evas_Object_Protected_Data *obj, //vector object _evas_vg_render_pre(obj, comp_target, engine, output, context, surface, - ptransform, comp, comp_method); + ptransform, p_opacity, comp, comp_method); //4. Generating Composite Image. ector_buffer_pixels_set(surface, pd->comp.pixels, size.w, size.h, pd->comp.stride, @@ -153,6 +155,7 @@ _efl_canvas_vg_container_render_pre(Evas_Object_Protected_Data *vg_pd, void *engine, void *output, void *context, Ector_Surface *surface, Eina_Matrix3 *ptransform, + int p_opacity, Ector_Buffer *comp, Efl_Gfx_Vg_Composite_Method comp_method, void *data) @@ -168,6 +171,7 @@ _efl_canvas_vg_container_render_pre(Evas_Object_Protected_Data *vg_pd, nd->flags = EFL_GFX_CHANGE_FLAG_NONE; EFL_CANVAS_VG_COMPUTE_MATRIX(ctransform, ptransform, nd); + EFL_CANVAS_VG_COMPUTE_ALPHA(c_r, c_g, c_b, c_a, p_opacity, nd); //Container may have composite target. //FIXME : _prepare_comp() should only work in cases with matte or masking. @@ -179,7 +183,7 @@ _efl_canvas_vg_container_render_pre(Evas_Object_Protected_Data *vg_pd, comp_method = pd->comp.method; comp = _prepare_comp(vg_pd, pd->comp_target, engine, output, context, surface, - ptransform, ctransform, comp, comp_method); + ptransform, ctransform, p_opacity, c_a, comp, comp_method); } EINA_LIST_FOREACH(pd->children, l, child) @@ -204,7 +208,7 @@ _efl_canvas_vg_container_render_pre(Evas_Object_Protected_Data *vg_pd, _evas_vg_render_pre(vg_pd, child, engine, output, context, surface, - ctransform, comp, comp_method); + ctransform, c_a, comp, comp_method); } } diff --git a/src/lib/evas/canvas/efl_canvas_vg_gradient_linear.c b/src/lib/evas/canvas/efl_canvas_vg_gradient_linear.c index 1d4eb6a154..2781ce9d11 100644 --- a/src/lib/evas/canvas/efl_canvas_vg_gradient_linear.c +++ b/src/lib/evas/canvas/efl_canvas_vg_gradient_linear.c @@ -64,6 +64,7 @@ _efl_canvas_vg_gradient_linear_render_pre(Evas_Object_Protected_Data *vg_pd EINA void *context EINA_UNUSED, Ector_Surface *surface, Eina_Matrix3 *ptransform, + int p_opacity, Ector_Buffer *comp, Efl_Gfx_Vg_Composite_Method comp_method, void *data) @@ -77,6 +78,7 @@ _efl_canvas_vg_gradient_linear_render_pre(Evas_Object_Protected_Data *vg_pd EINA gd = efl_data_scope_get(obj, EFL_CANVAS_VG_GRADIENT_CLASS); EFL_CANVAS_VG_COMPUTE_MATRIX(ctransform, ptransform, nd); + EFL_CANVAS_VG_COMPUTE_ALPHA(c_r, c_g, c_b, c_a, p_opacity, nd); if (!nd->renderer) { @@ -87,7 +89,7 @@ _efl_canvas_vg_gradient_linear_render_pre(Evas_Object_Protected_Data *vg_pd EINA ector_renderer_transformation_set(nd->renderer, ctransform); ector_renderer_origin_set(nd->renderer, nd->x, nd->y); - ector_renderer_color_set(nd->renderer, nd->r, nd->g, nd->b, nd->a); + ector_renderer_color_set(nd->renderer, c_r, c_g, c_b, c_a); ector_renderer_visibility_set(nd->renderer, nd->visibility); efl_gfx_gradient_stop_set(nd->renderer, gd->colors, gd->colors_count); efl_gfx_gradient_spread_set(nd->renderer, gd->spread); diff --git a/src/lib/evas/canvas/efl_canvas_vg_gradient_radial.c b/src/lib/evas/canvas/efl_canvas_vg_gradient_radial.c index e54df094ba..7e09e138c2 100644 --- a/src/lib/evas/canvas/efl_canvas_vg_gradient_radial.c +++ b/src/lib/evas/canvas/efl_canvas_vg_gradient_radial.c @@ -80,6 +80,7 @@ _efl_canvas_vg_gradient_radial_render_pre(Evas_Object_Protected_Data *vg_pd EINA void *context EINA_UNUSED, Ector_Surface *surface, Eina_Matrix3 *ptransform, + int p_opacity, Ector_Buffer *comp, Efl_Gfx_Vg_Composite_Method comp_method, void *data) @@ -93,6 +94,7 @@ _efl_canvas_vg_gradient_radial_render_pre(Evas_Object_Protected_Data *vg_pd EINA gd = efl_data_scope_get(obj, EFL_CANVAS_VG_GRADIENT_CLASS); EFL_CANVAS_VG_COMPUTE_MATRIX(ctransform, ptransform, nd); + EFL_CANVAS_VG_COMPUTE_ALPHA(c_r, c_g, c_b, c_a, p_opacity, nd); if (!nd->renderer) { @@ -103,7 +105,7 @@ _efl_canvas_vg_gradient_radial_render_pre(Evas_Object_Protected_Data *vg_pd EINA ector_renderer_transformation_set(nd->renderer, ctransform); ector_renderer_origin_set(nd->renderer, nd->x, nd->y); - ector_renderer_color_set(nd->renderer, nd->r, nd->g, nd->b, nd->a); + ector_renderer_color_set(nd->renderer, c_r, c_g, c_b, c_a); ector_renderer_visibility_set(nd->renderer, nd->visibility); efl_gfx_gradient_stop_set(nd->renderer, gd->colors, gd->colors_count); efl_gfx_gradient_spread_set(nd->renderer, gd->spread); diff --git a/src/lib/evas/canvas/efl_canvas_vg_image.c b/src/lib/evas/canvas/efl_canvas_vg_image.c index 80729bb07c..1d0ba1772a 100644 --- a/src/lib/evas/canvas/efl_canvas_vg_image.c +++ b/src/lib/evas/canvas/efl_canvas_vg_image.c @@ -21,21 +21,23 @@ _efl_canvas_vg_image_render_pre(Evas_Object_Protected_Data *vg_pd, void *engine EINA_UNUSED, void *output EINA_UNUSED, void *context EINA_UNUSED, Ector_Surface *surface, Eina_Matrix3 *ptransform, + int p_opacity, Ector_Buffer *comp, Efl_Gfx_Vg_Composite_Method comp_method, void *data) { Efl_Canvas_Vg_Image_Data *pd = data; + int a; if (nd->flags == EFL_GFX_CHANGE_FLAG_NONE) return; - int a; efl_gfx_color_get(obj, NULL, NULL, NULL, &a); if (a <= 0) return; nd->flags = EFL_GFX_CHANGE_FLAG_NONE; EFL_CANVAS_VG_COMPUTE_MATRIX(ctransform, ptransform, nd); + EFL_CANVAS_VG_COMPUTE_ALPHA(c_r, c_g, c_b, c_a, p_opacity, nd); if (!nd->renderer) { @@ -60,13 +62,9 @@ _efl_canvas_vg_image_render_pre(Evas_Object_Protected_Data *vg_pd, } ector_renderer_image_buffer_set(nd->renderer, pd->buffer); ector_renderer_transformation_set(nd->renderer, ctransform); - - - ector_renderer_origin_set(nd->renderer, nd->x, nd->y); - ector_renderer_color_set(nd->renderer, nd->r, nd->g, nd->b, nd->a); + ector_renderer_color_set(nd->renderer, c_r, c_g, c_b, c_a); ector_renderer_visibility_set(nd->renderer, nd->visibility); - ector_renderer_comp_method_set(nd->renderer, comp, comp_method); ector_renderer_prepare(nd->renderer); } diff --git a/src/lib/evas/canvas/efl_canvas_vg_object.c b/src/lib/evas/canvas/efl_canvas_vg_object.c index 0c8e50bed3..7d0598869c 100644 --- a/src/lib/evas/canvas/efl_canvas_vg_object.c +++ b/src/lib/evas/canvas/efl_canvas_vg_object.c @@ -502,7 +502,7 @@ _render_to_buffer(Evas_Object_Protected_Data *obj, Efl_Canvas_Vg_Object_Data *pd //ector begin - end for drawing composite images. //ENFN->ector_begin(engine, buffer, context, ector, 0, 0, EINA_FALSE, EINA_FALSE); - _evas_vg_render_pre(obj, root, engine, buffer, context, ector, NULL, NULL, 0); + _evas_vg_render_pre(obj, root, engine, buffer, context, ector, NULL, 255, NULL, 0); //ENFN->ector_end(engine, buffer, context, ector, EINA_FALSE); //Actual content drawing @@ -773,7 +773,7 @@ _efl_canvas_vg_object_render_pre(Evas_Object *eo_obj, // FIXME: Move this render_pre to efl_canvas_vg_render() s = evas_ector_get(obj->layer->evas); if (pd->root && s) - _evas_vg_render_pre(obj, pd->root, NULL, NULL, NULL, s, NULL, NULL, 0); + _evas_vg_render_pre(obj, pd->root, NULL, NULL, NULL, s, NULL, 255, NULL, 0); /* now figure what changed and add draw rects */ /* if it just became visible or invisible */ diff --git a/src/lib/evas/canvas/efl_canvas_vg_shape.c b/src/lib/evas/canvas/efl_canvas_vg_shape.c index 6ddec04869..5ddff89350 100644 --- a/src/lib/evas/canvas/efl_canvas_vg_shape.c +++ b/src/lib/evas/canvas/efl_canvas_vg_shape.c @@ -81,6 +81,7 @@ _efl_canvas_vg_shape_render_pre(Evas_Object_Protected_Data *vg_pd, void *engine, void *output, void *context, Ector_Surface *surface, Eina_Matrix3 *ptransform, + int p_opacity, Ector_Buffer *comp, Efl_Gfx_Vg_Composite_Method comp_method, void *data) @@ -93,16 +94,17 @@ _efl_canvas_vg_shape_render_pre(Evas_Object_Protected_Data *vg_pd, nd->flags = EFL_GFX_CHANGE_FLAG_NONE; EFL_CANVAS_VG_COMPUTE_MATRIX(ctransform, ptransform, nd); + EFL_CANVAS_VG_COMPUTE_ALPHA(c_r, c_g, c_b, c_a, p_opacity, nd); fill = _evas_vg_render_pre(vg_pd, pd->fill, engine, output, context, - surface, ctransform, comp, comp_method); + surface, ctransform, c_a, comp, comp_method); stroke_fill = _evas_vg_render_pre(vg_pd, pd->stroke.fill, engine, output, context, - surface, ctransform, comp, comp_method); + surface, ctransform, c_a, comp, comp_method); stroke_marker = _evas_vg_render_pre(vg_pd, pd->stroke.marker, engine, output, context, - surface, ctransform, comp, comp_method); + surface, ctransform, c_a, comp, comp_method); if (!nd->renderer) { @@ -112,7 +114,7 @@ _efl_canvas_vg_shape_render_pre(Evas_Object_Protected_Data *vg_pd, } ector_renderer_transformation_set(nd->renderer, ctransform); ector_renderer_origin_set(nd->renderer, nd->x, nd->y); - ector_renderer_color_set(nd->renderer, nd->r, nd->g, nd->b, nd->a); + ector_renderer_color_set(nd->renderer, c_r, c_g, c_b, c_a); ector_renderer_visibility_set(nd->renderer, nd->visibility); ector_renderer_shape_fill_set(nd->renderer, fill ? fill->renderer : NULL); ector_renderer_shape_stroke_fill_set(nd->renderer, stroke_fill ? stroke_fill->renderer : NULL); diff --git a/src/lib/evas/canvas/evas_vg_private.h b/src/lib/evas/canvas/evas_vg_private.h index 6dcd7215dd..4381e3ccfe 100644 --- a/src/lib/evas/canvas/evas_vg_private.h +++ b/src/lib/evas/canvas/evas_vg_private.h @@ -68,7 +68,7 @@ struct _Efl_Canvas_Vg_Node_Data void (*render_pre)(Evas_Object_Protected_Data *vg_pd, Efl_VG *node, Efl_Canvas_Vg_Node_Data *nd, void *engine, void *output, void *contenxt, Ector_Surface *surface, - Eina_Matrix3 *ptransform, Ector_Buffer *comp, Efl_Gfx_Vg_Composite_Method comp_method, void *data); + Eina_Matrix3 *ptransform, int opacity, Ector_Buffer *comp, Efl_Gfx_Vg_Composite_Method comp_method, void *data); void *data; double x, y; @@ -159,13 +159,14 @@ _evas_vg_render_pre(Evas_Object_Protected_Data *vg_pd, Efl_VG *child, void *engine, void *output, void *context, Ector_Surface *surface, Eina_Matrix3 *transform, + int opacity, Ector_Buffer *comp, Efl_Gfx_Vg_Composite_Method comp_method) { if (!child) return NULL; Efl_Canvas_Vg_Node_Data *nd = efl_data_scope_get(child, EFL_CANVAS_VG_NODE_CLASS); if (nd) nd->render_pre(vg_pd, child, nd, engine, output, context, surface, - transform, comp, comp_method, nd->data); + transform, opacity, comp, comp_method, nd->data); return nd; } @@ -190,5 +191,19 @@ _evas_vg_render_pre(Evas_Object_Protected_Data *vg_pd, Efl_VG *child, } \ } +#define EFL_CANVAS_VG_COMPUTE_ALPHA(Current_r, Current_g, Current_b, Current_a, Parent_Opacity, Nd) \ + int Current_r = Nd->r; \ + int Current_g = Nd->g; \ + int Current_b = Nd->b; \ + int Current_a = Nd->a; \ + \ + if (Parent_Opacity < 255) \ + { \ + double pa = (double)Parent_Opacity / 255.0; \ + Current_r = (double)Current_r * pa; \ + Current_g = (double)Current_g * pa; \ + Current_b = (double)Current_b * pa; \ + Current_a = (double)Current_a * pa; \ + } #endif