From e896c5d8670d48c7d3e59f8161d85c7c0c88b0f8 Mon Sep 17 00:00:00 2001 From: JunsuChoi Date: Thu, 18 Apr 2019 10:22:34 +0900 Subject: [PATCH] vg_json: Set multiple mask from json Summary: This patch supports multiple masks for multiple attributes on a layer. Make main_mask_layer and make each mask EFL_CANVAS_VG_CONTAINER_CLASS and connect them. main_mask_layer is made for masks The masks are composited into main_mask_layer in order. main_mask_layer exists for the intersect option in last order This can be optimized later, and is created and used temporarily in this patch. Test Plan: If there are three masks, they can be created as below. mask_set(clayer, main_mask); mask_set(main_mask, mask_1); mask_set(mask_1, mask_2); mask_set(mask_2, mask_3); Reviewers: Hermet Reviewed By: Hermet Subscribers: cedric, kimcinoo, #reviewers, smohanty, #committers Tags: #efl Differential Revision: https://phab.enlightenment.org/D8507 Change-Id: I5a75640308a69e8e7e50800ff2444d6078c4fe4d --- src/static_libs/vg_common/vg_common_json.c | 205 ++++++++++++++++------------- 1 file changed, 115 insertions(+), 90 deletions(-) diff --git a/src/static_libs/vg_common/vg_common_json.c b/src/static_libs/vg_common/vg_common_json.c index cabeade..764db87 100644 --- a/src/static_libs/vg_common/vg_common_json.c +++ b/src/static_libs/vg_common/vg_common_json.c @@ -9,10 +9,25 @@ #include +//FIXME: This enum add temporarily to help understanding of additional code +//related to masking in prepare_mask. +//This needs to be formally declared through the eo class. +typedef enum _EFL_CANVAS_VG_NODE_BLEND_TYPE +{ + EFL_CANVAS_VG_NODE_BLEND_TYPE_NONE = 0, + EFL_CANVAS_VG_NODE_BLEND_TYPE_ALPHA, + EFL_CANVAS_VG_NODE_BLEND_TYPE_ALPHA_INV, + EFL_CANVAS_VG_NODE_BLEND_TYPE_MASK_ADD, + EFL_CANVAS_VG_NODE_BLEND_TYPE_MASK_SUBSTRACT, + EFL_CANVAS_VG_NODE_BLEND_TYPE_MASK_INTERSECT, + EFL_CANVAS_VG_NODE_BLEND_TYPE_MASK_DIFFERENCE +}EFL_CANVAS_VG_NODE_BLEND_TYPE; +// + static char* _get_key_val(void *key) { - static char buf[20]; + static char buf[30]; snprintf(buf, sizeof(buf), "%ld", (size_t) key); return buf; } @@ -193,65 +208,56 @@ _construct_drawable_nodes(Efl_Canvas_Vg_Container *parent, const LOTLayerNode *l } static void -_construct_mask_nodes(Efl_Canvas_Vg_Container *parent, const LOTLayerNode *layer, int depth EINA_UNUSED) +_construct_mask_nodes(Efl_Canvas_Vg_Container *parent, LOTMask *mask, int depth EINA_UNUSED) { - if (!parent) return; + const float *data = mask->mPath.ptPtr; + if (!data) return; - for (unsigned int i = 0; i < layer->mMaskList.size; i++) + char *key = _get_key_val(mask); + Efl_Canvas_Vg_Shape *shape = efl_key_data_get(parent, key); + if (!shape) { - LOTMask *mask = &layer->mMaskList.ptr[i]; - if (!mask) continue; - - const float *data = mask->mPath.ptPtr; - if (!data) continue; - - char *key = _get_key_val(mask); - Efl_Canvas_Vg_Shape *shape = efl_key_data_get(parent, key); - if (!shape) - { - shape = efl_add(EFL_CANVAS_VG_SHAPE_CLASS, parent); - efl_key_data_set(parent, key, shape); - } - else - efl_gfx_path_reset(shape); + shape = efl_add(EFL_CANVAS_VG_SHAPE_CLASS, parent); + efl_key_data_set(parent, key, shape); + } + else + efl_gfx_path_reset(shape); - efl_gfx_entity_visible_set(shape, EINA_TRUE); + efl_gfx_entity_visible_set(shape, EINA_TRUE); - efl_gfx_path_reserve(shape, mask->mPath.elmCount, mask->mPath.ptCount); + efl_gfx_path_reserve(shape, mask->mPath.elmCount, mask->mPath.ptCount); - for (int i = 0; i < mask->mPath.elmCount; i++) + for (int i = 0; i < mask->mPath.elmCount; i++) + { + switch (mask->mPath.elmPtr[i]) { - switch (mask->mPath.elmPtr[i]) - { - case 0: - efl_gfx_path_append_move_to(shape, data[0], data[1]); - data += 2; - break; - case 1: - efl_gfx_path_append_line_to(shape, data[0], data[1]); - data += 2; - break; - case 2: - efl_gfx_path_append_cubic_to(shape, data[0], data[1], data[2], data[3], data[4], data[5]); - data += 6; - break; - case 3: - efl_gfx_path_append_close(shape); - break; - default: - ERR("No reserved path type = %d", mask->mPath.elmPtr[i]); - break; - } + case 0: + efl_gfx_path_append_move_to(shape, data[0], data[1]); + data += 2; + break; + case 1: + efl_gfx_path_append_line_to(shape, data[0], data[1]); + data += 2; + break; + case 2: + efl_gfx_path_append_cubic_to(shape, data[0], data[1], data[2], data[3], data[4], data[5]); + data += 6; + break; + case 3: + efl_gfx_path_append_close(shape); + break; + default: + ERR("No reserved path type = %d", mask->mPath.elmPtr[i]); + break; } - - //Temporary solid type setting. - float pa = ((float)mask->mAlpha) / 255; - int r = (int)(((float) 255) * pa); - int g = (int)(((float) 255) * pa); - int b = (int)(((float) 255) * pa); - int a = (int)(((float) 255) * pa); - efl_gfx_color_set(shape, r, g, b, a); } + //White color and alpha setting + float pa = ((float)mask->mAlpha) / 255; + int r = (int) (255.0f * pa); + int g = (int) (255.0f * pa); + int b = (int) (255.0f * pa); + int a = mask->mAlpha; + efl_gfx_color_set(shape, r, g, b, a); } static void @@ -288,6 +294,62 @@ _update_vg_tree(Efl_Canvas_Vg_Container *root, const LOTLayerNode *layer, int de #endif _update_vg_tree(ctree, clayer, depth+1); + if (clayer->mMaskList.size > 0) + { + Efl_Canvas_Vg_Container *mtarget = ctree; + Efl_Canvas_Vg_Container *msource = NULL; + + key = _get_key_val(clayer); + msource = efl_key_data_get(mtarget, key); + if (!msource) + { + msource = efl_add(EFL_CANVAS_VG_CONTAINER_CLASS, ctree); + efl_key_data_set(mtarget, key, msource); + } + + //FIXME : EFL_CANVAS_VG_NODE_BLEND_TYPE_ALPHA option is temporary + //Currently matte alpha implemtnes is same the mask intersect impletment. + //It has been implemented as a multiplication calculation. + efl_canvas_vg_node_mask_set(mtarget, msource, EFL_CANVAS_VG_NODE_BLEND_TYPE_ALPHA); + + mtarget = msource; + + //Make mask layers + for (unsigned int i = 0; i < clayer->mMaskList.size; i++) + { + LOTMask *mask = &clayer->mMaskList.ptr[i]; + key = _get_key_val(mask); + msource = efl_key_data_get(mtarget, key); + + if (!msource) + { + msource = efl_add(EFL_CANVAS_VG_CONTAINER_CLASS, mtarget); + efl_key_data_set(mtarget, key, msource); + } + _construct_mask_nodes(msource, mask, depth + 1); + + EFL_CANVAS_VG_NODE_BLEND_TYPE mask_mode; + switch (mask->mMode) + { + case MaskSubstract: + mask_mode = EFL_CANVAS_VG_NODE_BLEND_TYPE_MASK_SUBSTRACT; + break; + case MaskIntersect: + mask_mode = EFL_CANVAS_VG_NODE_BLEND_TYPE_MASK_INTERSECT; + break; + case MaskDifference: + mask_mode = EFL_CANVAS_VG_NODE_BLEND_TYPE_MASK_DIFFERENCE; + break; + case MaskAdd: + default: + mask_mode = EFL_CANVAS_VG_NODE_BLEND_TYPE_MASK_ADD; + break; + } + efl_canvas_vg_node_mask_set(mtarget, msource, mask_mode); + mtarget = msource; + } + } + if (matte_mode != 0) efl_canvas_vg_node_mask_set(ptree, ctree, matte_mode); @@ -301,10 +363,10 @@ _update_vg_tree(Efl_Canvas_Vg_Container *root, const LOTLayerNode *layer, int de matte_mode = 0; break; case MatteAlpha: - matte_mode = 1; + matte_mode = EFL_CANVAS_VG_NODE_BLEND_TYPE_ALPHA; break; case MatteAlphaInv: - matte_mode = 2; + matte_mode = EFL_CANVAS_VG_NODE_BLEND_TYPE_ALPHA_INV; break; case MatteLuma: matte_mode = 0; @@ -319,43 +381,6 @@ _update_vg_tree(Efl_Canvas_Vg_Container *root, const LOTLayerNode *layer, int de break; } - //This layer has a mask - if (clayer->mMaskList.size > 0) - { - key = _get_key_val(clayer->mMaskList.ptr); - Efl_Canvas_Vg_Container *mtree = efl_key_data_get(ctree, key); - if (!mtree) - { - mtree = efl_add(EFL_CANVAS_VG_CONTAINER_CLASS, ctree); - efl_key_data_set(ctree, key, mtree); - } - _construct_mask_nodes(mtree, clayer, depth); - - int mask_mode = 0; - - //Remap Mask Mode - switch (clayer->mMaskList.ptr->mMode) - { - case MaskAdd: - mask_mode = 1; - break; - case MaskSubstract: - mask_mode = 2; - break; - case MaskIntersect: - ERR("TODO: MaskIntersect"); - mask_mode = 3; - break; - case MaskDifference: - ERR("TODO: MaskDifference"); - mask_mode = 0; - break; - default: - mask_mode = 0; - break; - } - efl_canvas_vg_node_mask_set(ctree, mtree, mask_mode); - } } //Construct drawable nodes. if (layer->mNodeList.size > 0) -- 2.7.4