From 40ee9a57095711da63aae2773c41ffee2875caa1 Mon Sep 17 00:00:00 2001 From: Michal Maciola Date: Tue, 8 Dec 2020 12:31:10 +0100 Subject: [PATCH] JSON Lottie and vg image fix In this push some crucial things for json animations was fixed: 1. vg_common_json.c is fixed and will load json files properly. 2. efl_canvas_vg_image.c was fixed for proper raw images loading. Change-Id: I69e6913c2e8771c100555cd968c87c5c88a0eb44 --- src/lib/evas/canvas/efl_canvas_vg_image.c | 85 +++++++++++++++++++++++++++--- src/lib/evas/canvas/efl_canvas_vg_shape.c | 2 +- src/lib/evas/canvas/evas_vg_private.h | 4 ++ src/static_libs/vg_common/vg_common_json.c | 80 +++++++++++++++------------- 4 files changed, 124 insertions(+), 47 deletions(-) diff --git a/src/lib/evas/canvas/efl_canvas_vg_image.c b/src/lib/evas/canvas/efl_canvas_vg_image.c index bc95ad2..64a73b1 100644 --- a/src/lib/evas/canvas/efl_canvas_vg_image.c +++ b/src/lib/evas/canvas/efl_canvas_vg_image.c @@ -10,12 +10,15 @@ struct _Efl_Canvas_Vg_Image_Data { #ifndef HAVE_THORVG Ector_Buffer *buffer; - void *image; +#else + Tvg_Paint *picture; #endif + void *image; int w; int h; }; +#ifndef HAVE_THORVG static void _efl_canvas_vg_image_render_pre(Evas_Object_Protected_Data *vg_pd, Efl_VG *obj EINA_UNUSED, @@ -38,7 +41,6 @@ _efl_canvas_vg_image_render_pre(Evas_Object_Protected_Data *vg_pd, nd->flags = EFL_GFX_CHANGE_FLAG_NONE; -#ifndef HAVE_THORVG EFL_CANVAS_VG_COMPUTE_MATRIX(ctransform, ptransform, nd); EFL_CANVAS_VG_COMPUTE_ALPHA(c_r, c_g, c_b, c_a, p_opacity, nd); @@ -69,10 +71,73 @@ _efl_canvas_vg_image_render_pre(Evas_Object_Protected_Data *vg_pd, ector_renderer_visibility_set(nd->renderer, nd->visibility); ector_renderer_comp_method_set(nd->renderer, comp, comp_method); ector_renderer_prepare(nd->renderer); -#else - //TODO: implement using thorvg +} #endif + +#ifdef HAVE_THORVG +void +_convert_eina_to_tvg_mat_transpose(const Eina_Matrix3 *eina_mat, Tvg_Matrix *tvg_mat) +{ + if (!eina_mat || !tvg_mat) return; + + tvg_mat->e11 = eina_mat->xx; + tvg_mat->e21 = eina_mat->xy; + tvg_mat->e31 = eina_mat->xz; + + tvg_mat->e12 = eina_mat->yx; + tvg_mat->e22 = eina_mat->yy; + tvg_mat->e32 = eina_mat->yz; + + tvg_mat->e13 = eina_mat->zx; + tvg_mat->e23 = eina_mat->zy; + tvg_mat->e33 = eina_mat->zz; } +static void +_efl_canvas_vg_image_render_pre_tvg(EINA_UNUSED Evas_Object_Protected_Data *vg_pd, + Efl_VG *obj, + Efl_Canvas_Vg_Node_Data *nd, + Eina_Matrix3 *pTransform, + void *canvas) +{ + int alpha; + Tvg_Matrix trans_mat = { 0 }; + Efl_Canvas_Vg_Image_Data *pd = nd->data; + + if (!nd || !nd->data) return; + if (nd->flags == EFL_GFX_CHANGE_FLAG_NONE) return; + + nd->flags = EFL_GFX_CHANGE_FLAG_NONE; + + if (!pd->picture && pd->image) + { + Evas_Object_Protected_Data *obj = vg_pd; + pd->picture = tvg_picture_new(); + if (tvg_picture_load_raw(pd->picture, pd->image, pd->w, pd->h, true) != TVG_RESULT_SUCCESS) + { + printf("Error loading image buffer \n"); + return; + } + tvg_canvas_push((Tvg_Canvas *) canvas, pd->picture); + } + + EFL_CANVAS_VG_COMPUTE_MATRIX(cTransform, pTransform, nd); + tvg_paint_translate(pd->picture, nd->x, nd->y); + if (cTransform) + { + _convert_eina_to_tvg_mat_transpose(cTransform, &trans_mat); + trans_mat.e13 += nd->x; + trans_mat.e23 += nd->y; + tvg_paint_transform(pd->picture, &trans_mat); + } + + efl_gfx_color_get(obj, NULL, NULL, NULL, &alpha); + EFL_CANVAS_VG_COMPUTE_ALPHA(c_r, c_g, c_b, c_a, alpha, nd); + // TODO: apply color tvg_shape_set_fill_color + tvg_paint_set_opacity(pd->picture, alpha); + + tvg_canvas_update_paint((Tvg_Canvas *) canvas, pd->picture); +} +#endif static Eo * _efl_canvas_vg_image_efl_object_constructor(Eo *obj, Efl_Canvas_Vg_Image_Data *pd) @@ -81,13 +146,13 @@ _efl_canvas_vg_image_efl_object_constructor(Eo *obj, Efl_Canvas_Vg_Image_Data *p obj = efl_constructor(efl_super(obj, MY_CLASS)); nd = efl_data_scope_get(obj, EFL_CANVAS_VG_NODE_CLASS); - nd->render_pre = _efl_canvas_vg_image_render_pre; nd->data = pd; #ifndef HAVE_THORVG + nd->render_pre = _efl_canvas_vg_image_render_pre; efl_gfx_color_set(obj , 255, 255, 255, 255); #else - //TODO: implement using thorvg + nd->render_pre_tvg = _efl_canvas_vg_image_render_pre_tvg; #endif return obj; @@ -104,6 +169,11 @@ _efl_canvas_vg_image_efl_object_destructor(Eo *obj, Efl_Canvas_Vg_Image_Data *pd efl_unref(pd->buffer); pd->buffer = NULL; } +#else + if (pd->picture) + { + pd->picture = NULL; + } #endif } @@ -119,10 +189,9 @@ _efl_canvas_vg_image_data_set(Eo *obj EINA_UNUSED, Efl_Canvas_Vg_Image_Data *pd, efl_unref(pd->buffer); pd->buffer= NULL; } - - pd->image = data; #endif + pd->image = data; pd->w = size.w; pd->h = size.h; } diff --git a/src/lib/evas/canvas/efl_canvas_vg_shape.c b/src/lib/evas/canvas/efl_canvas_vg_shape.c index df433a7..912d350 100644 --- a/src/lib/evas/canvas/efl_canvas_vg_shape.c +++ b/src/lib/evas/canvas/efl_canvas_vg_shape.c @@ -701,7 +701,7 @@ _efl_canvas_vg_shape_render_pre(Evas_Object_Protected_Data *vg_pd, #endif #ifdef HAVE_THORVG -static void +void _convert_eina_to_tvg_mat(const Eina_Matrix3 *eina_mat, Tvg_Matrix *tvg_mat) { if (!eina_mat || !tvg_mat) return; diff --git a/src/lib/evas/canvas/evas_vg_private.h b/src/lib/evas/canvas/evas_vg_private.h index 1c9189a..013ac30 100644 --- a/src/lib/evas/canvas/evas_vg_private.h +++ b/src/lib/evas/canvas/evas_vg_private.h @@ -183,6 +183,10 @@ void efl_canvas_vg_container_blend_buffer_clear(Efl_VG *o Eina_Inarray* evas_cache_vg_anim_sector_list_get(const Vg_Cache_Entry* vg_entry); // +#ifdef HAVE_THORVG +void _convert_eina_to_tvg_mat(const Eina_Matrix3 *eina_mat, Tvg_Matrix *tvg_mat); +#endif + static inline void efl_canvas_vg_object_change(Efl_Canvas_Vg_Object_Data *vd) { diff --git a/src/static_libs/vg_common/vg_common_json.c b/src/static_libs/vg_common/vg_common_json.c index dba226f..352f1b3 100644 --- a/src/static_libs/vg_common/vg_common_json.c +++ b/src/static_libs/vg_common/vg_common_json.c @@ -54,8 +54,8 @@ _construct_drawable_nodes(Efl_Canvas_Vg_Container *parent, const LOTLayerNode *l node->mImageInfo.mMatrix.m31, node->mImageInfo.mMatrix.m32, node->mImageInfo.mMatrix.m33); efl_canvas_vg_node_transformation_set(image, &m); efl_canvas_vg_image_data_set(image, node->mImageInfo.data, EINA_SIZE2D(node->mImageInfo.width, node->mImageInfo.height)); - efl_gfx_color_set(image, node->mImageInfo.mAlpha, node->mImageInfo.mAlpha, node->mImageInfo.mAlpha, node->mImageInfo.mAlpha); - efl_gfx_entity_visible_set(image, EINA_TRUE); + evas_vg_node_color_set(image, node->mImageInfo.mAlpha, node->mImageInfo.mAlpha, node->mImageInfo.mAlpha, node->mImageInfo.mAlpha); + evas_vg_node_visible_set(image, EINA_TRUE); continue; } @@ -69,17 +69,17 @@ _construct_drawable_nodes(Efl_Canvas_Vg_Container *parent, const LOTLayerNode *l } else { - efl_gfx_path_reset(shape); + evas_vg_shape_reset(shape); //Layer order is mismatched! if (eina_list_data_get(list) != shape) - efl_gfx_stack_raise_to_top(shape); + evas_vg_node_raise(shape); } //Skip Invisible Stroke? if (node->mStroke.enable && node->mStroke.width == 0) { - efl_gfx_entity_visible_set(shape, EINA_FALSE); + evas_vg_node_visible_set(shape, EINA_FALSE); continue; } @@ -87,7 +87,7 @@ _construct_drawable_nodes(Efl_Canvas_Vg_Container *parent, const LOTLayerNode *l if (!data) continue; if (node->keypath) efl_key_data_set(shape, "_lot_node_name", node->keypath); - efl_gfx_entity_visible_set(shape, EINA_TRUE); + evas_vg_node_visible_set(shape, EINA_TRUE); #if DEBUG for (int i = 0; i < depth; i++) printf(" "); printf("%s (%p) keypath : %s\n", efl_class_name_get(efl_class_get(shape)), shape, node->keypath); @@ -100,19 +100,19 @@ _construct_drawable_nodes(Efl_Canvas_Vg_Container *parent, const LOTLayerNode *l switch (node->mPath.elmPtr[i]) { case 0: - efl_gfx_path_append_move_to(shape, data[0], data[1]); + evas_vg_shape_append_move_to(shape, data[0], data[1]); data += 2; break; case 1: - efl_gfx_path_append_line_to(shape, data[0], data[1]); + evas_vg_shape_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]); + evas_vg_shape_append_cubic_to(shape, data[4], data[5], data[0], data[1], data[2], data[3]); data += 6; break; case 3: - efl_gfx_path_append_close(shape); + evas_vg_shape_append_close(shape); break; default: ERR("No reserved path type = %d", node->mPath.elmPtr[i]); @@ -123,7 +123,7 @@ _construct_drawable_nodes(Efl_Canvas_Vg_Container *parent, const LOTLayerNode *l if (node->mStroke.enable) { //Stroke Width - efl_gfx_shape_stroke_width_set(shape, node->mStroke.width); + evas_vg_shape_stroke_width_set(shape, node->mStroke.width); //Stroke Cap Efl_Gfx_Cap cap; @@ -134,7 +134,7 @@ _construct_drawable_nodes(Efl_Canvas_Vg_Container *parent, const LOTLayerNode *l case CapRound: cap = EFL_GFX_CAP_ROUND; break; default: cap = EFL_GFX_CAP_BUTT; break; } - efl_gfx_shape_stroke_cap_set(shape, cap); + evas_vg_shape_stroke_cap_set(shape, cap); //Stroke Join Efl_Gfx_Join join; @@ -145,15 +145,17 @@ _construct_drawable_nodes(Efl_Canvas_Vg_Container *parent, const LOTLayerNode *l case JoinRound: join = EFL_GFX_JOIN_ROUND; break; default: join = EFL_GFX_JOIN_MITER; break; } - efl_gfx_shape_stroke_join_set(shape, join); + evas_vg_shape_stroke_join_set(shape, join); + #ifndef HAVE_THORVG efl_gfx_shape_stroke_miterlimit_set(shape, node->mStroke.miterLimit); + #endif //Stroke Dash if (node->mStroke.dashArraySize > 0) { int size = (node->mStroke.dashArraySize / 2); - Efl_Gfx_Dash *dash = malloc(sizeof(Efl_Gfx_Dash) * size); + Evas_Vg_Dash *dash = malloc(sizeof(Efl_Gfx_Dash) * size); if (dash) { for (int i = 0; i <= size; i+=2) @@ -161,7 +163,7 @@ _construct_drawable_nodes(Efl_Canvas_Vg_Container *parent, const LOTLayerNode *l dash[i].length = node->mStroke.dashArray[i]; dash[i].gap = node->mStroke.dashArray[i + 1]; } - efl_gfx_shape_stroke_dash_set(shape, dash, size); + evas_vg_shape_stroke_dash_set(shape, dash, size); free(dash); } } @@ -179,9 +181,9 @@ _construct_drawable_nodes(Efl_Canvas_Vg_Container *parent, const LOTLayerNode *l int a = node->mColor.a; if (node->mStroke.enable) - efl_gfx_shape_stroke_color_set(shape, r, g, b, a); + evas_vg_shape_stroke_color_set(shape, r, g, b, a); else - efl_gfx_color_set(shape, r, g, b, a); + evas_vg_node_color_set(shape, r, g, b, a); } break; case BrushGradient: @@ -197,9 +199,9 @@ _construct_drawable_nodes(Efl_Canvas_Vg_Container *parent, const LOTLayerNode *l grad = efl_add(EFL_CANVAS_VG_GRADIENT_LINEAR_CLASS, parent); efl_key_data_set(shape, key, grad); } - efl_gfx_entity_visible_set(grad, EINA_TRUE); - efl_gfx_gradient_linear_start_set(grad, node->mGradient.start.x, node->mGradient.start.y); - efl_gfx_gradient_linear_end_set(grad, node->mGradient.end.x, node->mGradient.end.y); + evas_vg_node_visible_set(grad, EINA_TRUE); + evas_vg_gradient_linear_start_set(grad, node->mGradient.start.x, node->mGradient.start.y); + evas_vg_gradient_linear_end_set(grad, node->mGradient.end.x, node->mGradient.end.y); } else if (node->mGradient.type == GradientRadial) { @@ -210,10 +212,10 @@ _construct_drawable_nodes(Efl_Canvas_Vg_Container *parent, const LOTLayerNode *l grad = efl_add(EFL_CANVAS_VG_GRADIENT_RADIAL_CLASS, parent); efl_key_data_set(shape, key, grad); } - efl_gfx_entity_visible_set(grad, EINA_TRUE); - efl_gfx_gradient_radial_center_set(grad, node->mGradient.center.x, node->mGradient.center.y); - efl_gfx_gradient_radial_focal_set(grad, node->mGradient.focal.x, node->mGradient.focal.y); - efl_gfx_gradient_radial_radius_set(grad, node->mGradient.cradius); + evas_vg_node_visible_set(grad, EINA_TRUE); + evas_vg_gradient_radial_center_set(grad, node->mGradient.center.x, node->mGradient.center.y); + evas_vg_gradient_radial_focal_set(grad, node->mGradient.focal.x, node->mGradient.focal.y); + evas_vg_gradient_radial_radius_set(grad, node->mGradient.cradius); } else ERR("No reserved gradient type = %d", node->mGradient.type); @@ -221,7 +223,7 @@ _construct_drawable_nodes(Efl_Canvas_Vg_Container *parent, const LOTLayerNode *l if (grad) { //Gradient Stop - Efl_Gfx_Gradient_Stop* stops = malloc(sizeof(Efl_Gfx_Gradient_Stop) * node->mGradient.stopCount); + Evas_Vg_Gradient_Stop* stops = malloc(sizeof(Efl_Gfx_Gradient_Stop) * node->mGradient.stopCount); if (stops) { for (unsigned int i = 0; i < node->mGradient.stopCount; i++) @@ -233,7 +235,7 @@ _construct_drawable_nodes(Efl_Canvas_Vg_Container *parent, const LOTLayerNode *l stops[i].b = (int)(((float)node->mGradient.stopPtr[i].b) * pa); stops[i].a = node->mGradient.stopPtr[i].a; } - efl_gfx_gradient_stop_set(grad, stops, node->mGradient.stopCount); + evas_vg_gradient_stop_set(grad, stops, node->mGradient.stopCount); free(stops); } if (node->mStroke.enable) @@ -248,10 +250,12 @@ _construct_drawable_nodes(Efl_Canvas_Vg_Container *parent, const LOTLayerNode *l } //3: Fill Rule + #ifndef HAVE_THORVG if (node->mFillRule == FillEvenOdd) efl_gfx_shape_fill_rule_set(shape, EFL_GFX_FILL_RULE_ODD_EVEN); else if (node->mFillRule == FillWinding) efl_gfx_shape_fill_rule_set(shape, EFL_GFX_FILL_RULE_WINDING); + #endif } } @@ -269,14 +273,14 @@ _construct_mask_nodes(Efl_Canvas_Vg_Container *parent, LOTMask *mask, int depth efl_key_data_set(parent, key, shape); } else - efl_gfx_path_reset(shape); + evas_vg_shape_reset(shape); #if DEBUG for (int i = 0; i < depth; i++) printf(" "); printf("%s (%p)\n", efl_class_name_get(efl_class_get(shape)), shape); #endif - efl_gfx_entity_visible_set(shape, EINA_TRUE); + evas_vg_node_visible_set(shape, EINA_TRUE); efl_gfx_path_reserve(shape, mask->mPath.elmCount, mask->mPath.ptCount); for (size_t i = 0; i < mask->mPath.elmCount; i++) @@ -284,19 +288,19 @@ _construct_mask_nodes(Efl_Canvas_Vg_Container *parent, LOTMask *mask, int depth switch (mask->mPath.elmPtr[i]) { case 0: - efl_gfx_path_append_move_to(shape, data[0], data[1]); + evas_vg_shape_append_move_to(shape, data[0], data[1]); data += 2; break; case 1: - efl_gfx_path_append_line_to(shape, data[0], data[1]); + evas_vg_shape_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]); + evas_vg_shape_append_cubic_to(shape, data[4], data[5], data[0], data[1], data[2], data[3]); data += 6; break; case 3: - efl_gfx_path_append_close(shape); + evas_vg_shape_append_close(shape); break; default: ERR("No reserved path type = %d", mask->mPath.elmPtr[i]); @@ -309,7 +313,7 @@ _construct_mask_nodes(Efl_Canvas_Vg_Container *parent, LOTMask *mask, int depth 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); + evas_vg_node_color_set(shape, r, g, b, a); } static Efl_Canvas_Vg_Container* @@ -326,7 +330,7 @@ _construct_masks(Efl_Canvas_Vg_Container *mtarget, LOTMask *masks, unsigned int msource = efl_add(EFL_CANVAS_VG_CONTAINER_CLASS, mtarget); efl_key_data_set(mtarget, key, msource); } - efl_gfx_entity_visible_set(msource, EINA_TRUE); + evas_vg_node_visible_set(msource, EINA_TRUE); #if DEBUG for (int i = 0; i < depth; i++) printf(" "); @@ -353,7 +357,7 @@ _construct_masks(Efl_Canvas_Vg_Container *mtarget, LOTMask *masks, unsigned int msource = efl_add(EFL_CANVAS_VG_CONTAINER_CLASS, mtarget); efl_key_data_set(mtarget, key, msource); } - efl_gfx_entity_visible_set(msource, EINA_TRUE); + evas_vg_node_visible_set(msource, EINA_TRUE); #if DEBUG for (int i = 0; i < depth; i++) printf(" "); @@ -397,7 +401,7 @@ _reset_vg_tree(Efl_VG *node) EINA_LIST_FOREACH(list, list2, child) _reset_vg_tree(child); } - efl_gfx_entity_visible_set(node, EINA_FALSE); + evas_vg_node_visible_set(node, EINA_FALSE); } static void @@ -405,8 +409,8 @@ _update_vg_tree(Efl_Canvas_Vg_Container *root, const LOTLayerNode *layer, int de { if (!layer->mVisible) return; - efl_gfx_entity_visible_set(root, EINA_TRUE); - efl_gfx_color_set(root, layer->mAlpha, layer->mAlpha, layer->mAlpha, layer->mAlpha); + evas_vg_node_visible_set(root, EINA_TRUE); + evas_vg_node_color_set(root, layer->mAlpha, layer->mAlpha, layer->mAlpha, layer->mAlpha); //Don't need to update it anymore since its layer is invisible. if (layer->mAlpha == 0) return; -- 2.7.4