efl_canvas_vg : Propagates the alpha color of the parent
authorJunsuChoi <jsuya.choi@samsung.com>
Wed, 16 Oct 2019 06:12:13 +0000 (15:12 +0900)
committerWonki Kim <wonki_.kim@samsung.com>
Mon, 11 Nov 2019 02:18:25 +0000 (11:18 +0900)
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
src/lib/evas/canvas/efl_canvas_vg_gradient_linear.c
src/lib/evas/canvas/efl_canvas_vg_gradient_radial.c
src/lib/evas/canvas/efl_canvas_vg_image.c
src/lib/evas/canvas/efl_canvas_vg_object.c
src/lib/evas/canvas/efl_canvas_vg_shape.c
src/lib/evas/canvas/evas_vg_private.h

index f4bf4d7..471ea3d 100644 (file)
@@ -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);
      }
 }
 
index 1d4eb6a..2781ce9 100644 (file)
@@ -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);
index e54df09..7e09e13 100644 (file)
@@ -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);
index 80729bb..1d0ba17 100644 (file)
@@ -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);
 }
index 800dbef..1027907 100644 (file)
@@ -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
@@ -775,7 +775,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 */
index 6ddec04..5ddff89 100644 (file)
@@ -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);
index bbac468..036604b 100644 (file)
@@ -70,7 +70,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;
@@ -171,13 +171,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;
 }
 
@@ -202,5 +203,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