From 62c0a4ef087ea71355961e030b0620a60b77a026 Mon Sep 17 00:00:00 2001 From: Subhransu Mohanty Date: Wed, 8 Jun 2016 11:26:07 -0700 Subject: [PATCH] edje: add new svg part to edc Reviewers: Hermet, cedric Reviewed By: cedric Subscribers: jpeg, cedric, Hermet Differential Revision: https://phab.enlightenment.org/D3894 Signed-off-by: Cedric BAIL --- src/Makefile_Edje.am | 1 + src/bin/edje/edje_cc_handlers.c | 124 ++++++++++++++++++++ src/bin/edje/edje_cc_out.c | 45 ++++++++ src/bin/edje/edje_convert.c | 3 + src/bin/edje/edje_inspector.c | 2 + src/lib/edje/Edje_Common.h | 3 +- src/lib/edje/edje_cache.c | 2 + src/lib/edje/edje_calc.c | 196 ++++++++++++++++++++++++++++++++ src/lib/edje/edje_convert.c | 3 + src/lib/edje/edje_data.c | 22 +++- src/lib/edje/edje_edit.c | 7 ++ src/lib/edje/edje_load.c | 121 ++++++++++++++++++++ src/lib/edje/edje_lua.c | 1 + src/lib/edje/edje_private.h | 43 ++++++- 14 files changed, 570 insertions(+), 3 deletions(-) diff --git a/src/Makefile_Edje.am b/src/Makefile_Edje.am index f85f7d9681..b213db5adc 100644 --- a/src/Makefile_Edje.am +++ b/src/Makefile_Edje.am @@ -95,6 +95,7 @@ lib/edje/edje_var.c \ lib/edje/edje_signal.c \ lib/edje/edje_containers.c + lib_edje_libedje_la_CPPFLAGS = -I$(top_builddir)/src/lib/efl $(EDJE_COMMON_CPPFLAGS) lib_edje_libedje_la_LIBADD = @EDJE_LIBS@ lib_edje_libedje_la_DEPENDENCIES = @EDJE_INTERNAL_LIBS@ diff --git a/src/bin/edje/edje_cc_handlers.c b/src/bin/edje/edje_cc_handlers.c index 0fa5a4f408..0435713e89 100644 --- a/src/bin/edje/edje_cc_handlers.c +++ b/src/bin/edje/edje_cc_handlers.c @@ -533,11 +533,16 @@ static void st_collections_group_mouse(void); static void st_collections_group_nomouse(void); static void st_collections_group_broadcast(void); static void st_collections_group_nobroadcast(void); + +static void st_images_vector(void); +static void _handle_vector_image(void); + /*****/ #define IMAGE_STATEMENTS(PREFIX) \ {PREFIX"images.image", st_images_image}, \ + {PREFIX"images.vector", st_images_vector}, \ {PREFIX"images.set.name", st_images_set_name}, \ {PREFIX"images.set.image.image", st_images_set_image_image}, \ {PREFIX"images.set.image.size", st_images_set_image_size}, \ @@ -1520,6 +1525,7 @@ New_Object_Handler object_handlers[] = proxy{} spacer{} snapshot{} + vector{} part { desc { } @@ -1547,6 +1553,7 @@ New_Object_Handler object_handlers_short[] = {"collections.group.parts.proxy", ob_collections_group_parts_part_short}, {"collections.group.parts.spacer", ob_collections_group_parts_part_short}, {"collections.group.parts.part.desc", ob_collections_group_parts_part_desc}, + {"collections.group.parts.vector", ob_collections_group_parts_part_short}, }; New_Nested_Handler nested_handlers[] = { @@ -1565,6 +1572,7 @@ New_Nested_Handler nested_handlers_short[] = { {"collections.group.parts", "external", NULL, edje_cc_handlers_hierarchy_pop }, {"collections.group.parts", "proxy", NULL, edje_cc_handlers_hierarchy_pop }, {"collections.group.parts", "spacer", NULL, edje_cc_handlers_hierarchy_pop }, + {"collections.group.parts", "vector", NULL, edje_cc_handlers_hierarchy_pop }, }; /*****/ @@ -1919,6 +1927,15 @@ _edje_part_description_alloc(unsigned char type, const char *collection, const c ed->camera.orientation.data[5] = 0.0; ed->camera.orientation.look_to = -1; + result = &ed->common; + break; + } + case EDJE_PART_TYPE_VECTOR: + { + Edje_Part_Description_Vector *ed; + + ed = mem_alloc(SZ(Edje_Part_Description_Vector)); + result = &ed->common; break; } @@ -2292,6 +2309,99 @@ st_images_image(void) } } + +static void +_handle_vector_image(void) +{ + Edje_Part_Description_Vector *ed; + unsigned int i = 0; + char *name; + + ed = (Edje_Part_Description_Vector*) current_desc; + + name = parse_str(0); + + ed->vg.id = -1; + + for (i = 0; i < edje_file->image_dir->vectors_count; ++i) + { + if (!strcmp(edje_file->image_dir->vectors[i].entry, name)) + { + ed->vg.set = EINA_TRUE; + ed->vg.id = edje_file->image_dir->vectors[i].id; + break; + } + } + + free(name); +} + +/** @edcsubsection{toplevel_images, + * Images} */ + +/** + @page edcref + + @block + images + @context + vector { + vector: "filename1.svg"; + vector: "filename2.svg"; + vector: "filename3.svg"; + .. + } + @description + The "vector" context in the "images" block is used to list each svg image file that will be used in + the theme. + @endblock + + @property + vector + @parameters + [image file] + @endproperty + */ +static void +st_images_vector(void) +{ + Edje_Vector_Directory_Entry *vector; + const char *tmp; + unsigned int i; + + check_min_arg_count(1); + + if (!edje_file->image_dir) + edje_file->image_dir = mem_alloc(SZ(Edje_Image_Directory)); + + tmp = parse_str(0); + + for (i = 0; i < edje_file->image_dir->vectors_count; ++i) + if (!strcmp(edje_file->image_dir->vectors[i].entry, tmp)) + { + free((char*) tmp); + return; + } + + edje_file->image_dir->vectors_count++; + vector = realloc(edje_file->image_dir->vectors, + sizeof (Edje_Vector_Directory_Entry) * edje_file->image_dir->vectors_count); + if (!vector) + { + ERR("No enough memory."); + exit(-1); + } + edje_file->image_dir->vectors = vector; + memset(edje_file->image_dir->vectors + edje_file->image_dir->vectors_count - 1, + 0, sizeof (Edje_Vector_Directory_Entry)); + + vector = edje_file->image_dir->vectors + edje_file->image_dir->vectors_count - 1; + + vector->entry = tmp; + vector->id = edje_file->image_dir->vectors_count; +} + + /** @edcsubsection{toplevel_models,model} */ @@ -5683,6 +5793,7 @@ _part_desc_free(Edje_Part_Collection *pc, case EDJE_PART_TYPE_TABLE: case EDJE_PART_TYPE_IMAGE: case EDJE_PART_TYPE_SNAPSHOT: + case EDJE_PART_TYPE_VECTOR: /* Nothing todo here */ break; case EDJE_PART_TYPE_TEXT: @@ -5801,6 +5912,7 @@ ob_collections_group_parts_part_short(void) "proxy", EDJE_PART_TYPE_PROXY, "spacer", EDJE_PART_TYPE_SPACER, "snapshot", EDJE_PART_TYPE_SNAPSHOT, + "vector", EDJE_PART_TYPE_VECTOR, NULL); stack_pop_quick(EINA_TRUE, EINA_TRUE); @@ -6205,6 +6317,7 @@ st_collections_group_parts_part_type(void) "CAMERA", EDJE_PART_TYPE_CAMERA, "SPACER", EDJE_PART_TYPE_SPACER, "SNAPSHOT", EDJE_PART_TYPE_SNAPSHOT, + "VECTOR", EDJE_PART_TYPE_VECTOR, NULL); pc = eina_list_data_get(eina_list_last(edje_collections)); @@ -8102,6 +8215,11 @@ st_collections_group_parts_part_description_inherit(void) data_queue_copied_part_lookup(pc, &(mparent->mesh_node.orientation.look_to), &(med->mesh_node.orientation.look_to)); + break; + } + case EDJE_PART_TYPE_VECTOR: + { + // TODO break; } } @@ -9102,6 +9220,7 @@ st_collections_group_parts_part_description_rel2_to_y(void) .. image { normal: "filename.ext"; + normal: "filename.svg"; tween: "filename2.ext"; .. tween: "filenameN.ext"; @@ -9131,6 +9250,11 @@ st_collections_group_parts_part_description_image_normal(void) check_arg_count(1); + if (current_part->type == EDJE_PART_TYPE_VECTOR) + { + return _handle_vector_image(); + } + if (current_part->type != EDJE_PART_TYPE_IMAGE) { ERR("parse error %s:%i. " diff --git a/src/bin/edje/edje_cc_out.c b/src/bin/edje/edje_cc_out.c index f55b56fdff..fff4440658 100644 --- a/src/bin/edje/edje_cc_out.c +++ b/src/bin/edje/edje_cc_out.c @@ -168,6 +168,13 @@ struct _Sound_Write int i; }; +struct _Vector_Write +{ + Eet_File *ef; + Svg_Node *root; + int i; +}; + struct _Mo_Write { Eet_File *ef; @@ -1225,6 +1232,41 @@ on_error: return EINA_FALSE; } +static void +data_write_vectors(Eet_File *ef, int *vector_num) +{ + int i; + Svg_Node *root; + Eet_Data_Descriptor *svg_node_eet; + Eina_List *ll; + char *s; + char buf[PATH_MAX]; + char id_str[15]; + Eina_File *f = NULL; + Edje_Vector_Directory_Entry *vector; + + if (!((edje_file) && (edje_file->image_dir))) return; + + svg_node_eet = _edje_svg_node_eet(); + + for (i = 0; i < (int)edje_file->image_dir->vectors_count; i++) + { + vector = &edje_file->image_dir->vectors[i]; + EINA_LIST_FOREACH(img_dirs, ll, s) + { + snprintf(buf, sizeof(buf), "%s/%s", s, vector->entry); + f = eina_file_open(buf, EINA_FALSE); + if (!f) continue; + root = _svg_load(f, NULL); + snprintf(id_str, sizeof(id_str), "edje/vectors/%i", vector->id); + eet_data_write(ef, svg_node_eet, id_str, root, compress_mode); + *vector_num += 1; + eina_file_close(f); + break; + } + } +} + static void data_write_images(Eet_File *ef, int *image_num) { @@ -2468,6 +2510,7 @@ data_write(void) int vibration_num = 0; int font_num = 0; int collection_num = 0; + int vector_num = 0; double t; if (!edje_file) @@ -2522,6 +2565,8 @@ data_write(void) INF("fontmap: %3.5f", ecore_time_get() - t); t = ecore_time_get(); data_write_images(ef, &image_num); INF("images: %3.5f", ecore_time_get() - t); t = ecore_time_get(); + data_write_vectors(ef, &vector_num); + INF("vectors: %3.5f", ecore_time_get() - t); t = ecore_time_get(); data_check_models(ef, &model_num); INF("models: %3.5f", ecore_time_get() - t); t = ecore_time_get(); data_write_fonts(ef, &font_num); diff --git a/src/bin/edje/edje_convert.c b/src/bin/edje/edje_convert.c index e9712c13c6..3d765b0ae0 100644 --- a/src/bin/edje/edje_convert.c +++ b/src/bin/edje/edje_convert.c @@ -234,6 +234,7 @@ _edje_collection_convert(Eet_File *ef, Edje_Part_Collection_Directory_Entry *ce, CSP(BOX, ce); CSP(TABLE, ce); CSP(EXTERNAL, ce); + CSP(VECTOR, ce); default: count = &dummy; break; @@ -258,6 +259,7 @@ _edje_collection_convert(Eet_File *ef, Edje_Part_Collection_Directory_Entry *ce, CONVERT_EMN(TABLE, Edje_Part_Description_Table, ce); CONVERT_EMN(EXTERNAL, Edje_Part_Description_External, ce); CONVERT_EMN(part, Edje_Part, ce); + CONVERT_EMN(VECTOR, Edje_Part_Description_Vector, ce); /* Change structure layout */ edc = calloc(1, sizeof (Edje_Part_Collection)); @@ -451,6 +453,7 @@ _edje_description_convert(int type, CONVERT_ALLOC_POOL(BOX, Box, box); CONVERT_ALLOC_POOL(TABLE, Table, table); CONVERT_ALLOC_POOL(EXTERNAL, External, external_params); + CONVERT_ALLOC_POOL(VECTOR, Vector, vector); } if (result) diff --git a/src/bin/edje/edje_inspector.c b/src/bin/edje/edje_inspector.c index c6f8bd3c57..b0710343ca 100644 --- a/src/bin/edje/edje_inspector.c +++ b/src/bin/edje/edje_inspector.c @@ -208,6 +208,8 @@ part_type_name_get(Edje_Part_Type t) return "EXTERNAL"; case EDJE_PART_TYPE_SPACER: return "SPACER"; + case EDJE_PART_TYPE_VECTOR: + return "VECTOR"; case EDJE_PART_TYPE_NONE: case EDJE_PART_TYPE_LAST: diff --git a/src/lib/edje/Edje_Common.h b/src/lib/edje/Edje_Common.h index 06211c632a..b9f2b852f9 100644 --- a/src/lib/edje/Edje_Common.h +++ b/src/lib/edje/Edje_Common.h @@ -1268,7 +1268,8 @@ typedef enum _Edje_Part_Type EDJE_PART_TYPE_LIGHT = 14, EDJE_PART_TYPE_CAMERA = 15, EDJE_PART_TYPE_SNAPSHOT = 16, /**< Snapshot @since 1.16 */ - EDJE_PART_TYPE_LAST = 17 /**< Last type value */ + EDJE_PART_TYPE_VECTOR = 17, /**< Vector @since 1.18 */ + EDJE_PART_TYPE_LAST = 18 /**< Last type value */ } Edje_Part_Type; /** * @} diff --git a/src/lib/edje/edje_cache.c b/src/lib/edje/edje_cache.c index 4c232b9c28..42ed166d5f 100644 --- a/src/lib/edje/edje_cache.c +++ b/src/lib/edje/edje_cache.c @@ -37,6 +37,7 @@ edje_cache_emp_alloc(Edje_Part_Collection_Directory_Entry *ce) INIT_EMP_BOTH(MESH_NODE, Edje_Part_Description_Mesh_Node, ce); INIT_EMP_BOTH(LIGHT, Edje_Part_Description_Light, ce); INIT_EMP_BOTH(CAMERA, Edje_Part_Description_Camera, ce); + INIT_EMP_BOTH(VECTOR, Edje_Part_Description_Vector, ce); INIT_EMP(part, Edje_Part, ce); } @@ -59,6 +60,7 @@ edje_cache_emp_free(Edje_Part_Collection_Directory_Entry *ce) eina_mempool_del(ce->mp.MESH_NODE); eina_mempool_del(ce->mp.LIGHT); eina_mempool_del(ce->mp.CAMERA); + eina_mempool_del(ce->mp.VECTOR); eina_mempool_del(ce->mp.part); memset(&ce->mp, 0, sizeof (ce->mp)); diff --git a/src/lib/edje/edje_calc.c b/src/lib/edje/edje_calc.c index c28900d02a..5b2f4ab3a8 100644 --- a/src/lib/edje/edje_calc.c +++ b/src/lib/edje/edje_calc.c @@ -411,6 +411,7 @@ case EDJE_PART_TYPE_##Short: \ EDIT_ALLOC_POOL_RTL(CAMERA, Camera, camera); EDIT_ALLOC_POOL_RTL(LIGHT, Light, light); EDIT_ALLOC_POOL_RTL(MESH_NODE, Mesh_Node, mesh_node); + EDIT_ALLOC_POOL_RTL(VECTOR, Vector, vector); } if (desc_rtl) @@ -2872,6 +2873,7 @@ _edje_part_recalc_single(Edje *ed, case EDJE_PART_TYPE_GROUP: case EDJE_PART_TYPE_PROXY: case EDJE_PART_TYPE_SNAPSHOT: + case EDJE_PART_TYPE_VECTOR: break; case EDJE_PART_TYPE_LIGHT: @@ -3162,6 +3164,7 @@ _edje_proxy_recalc_apply(Edje *ed, Edje_Real_Part *ep, Edje_Calc_Params *p3, Edj case EDJE_PART_TYPE_TABLE: case EDJE_PART_TYPE_PROXY: case EDJE_PART_TYPE_SNAPSHOT: + case EDJE_PART_TYPE_VECTOR: evas_object_image_source_set(ep->object, pp->object); break; @@ -3252,6 +3255,194 @@ _edje_image_recalc_apply(Edje *ed, Edje_Real_Part *ep, Edje_Calc_Params *p3, Edj evas_object_image_border_center_fill_set(ep->object, EVAS_BORDER_FILL_SOLID); } +static void +_edje_svg_recalc_apply(Edje *ed, Edje_Real_Part *ep, Edje_Calc_Params *p3 EINA_UNUSED, Edje_Part_Description_Vector *chosen_desc, FLOAT_T pos) +{ + int w, h; + int new_svg = 0; + Efl_VG *vg_tree, *root_vg; + double sx, sy, vx, vy, vw, vh; + + evas_object_geometry_get(ep->object, NULL, NULL, &w, &h); + + if( (w == 0) || (h == 0)) return; + + root_vg = evas_object_vg_root_node_get(ep->object); + + if (ep->param2) + { + Edje_Part_Description_Vector *next_state = (Edje_Part_Description_Vector *)ep->param2->description; + if (chosen_desc->vg.id != next_state->vg.id) + { + new_svg = next_state->vg.id; + } + } + if (new_svg) // animation with svg id change + { + Efl_VG *container; + if (ep->typedata.vector->cache.svg_id != new_svg) + { + //create it + vg_tree = _edje_create_vg_tree(ed->file->ef, new_svg, w, h, &vx, &vy, &vw, &vh); + if (vg_tree) + { + //1. clear the cache + if (ep->typedata.vector->cache.vg) + { + eo_unref(ep->typedata.vector->cache.vg); + ep->typedata.vector->cache.vg = NULL; + ep->typedata.vector->cache.svg_id = 0; + } + //2. update current + ep->typedata.vector->cache.svg_id = new_svg; + ep->typedata.vector->cache.x = vx; + ep->typedata.vector->cache.y = vy; + ep->typedata.vector->cache.w = vw; + ep->typedata.vector->cache.h = vh; + ep->typedata.vector->cache.vg = vg_tree; + } + } + // just do the interpolation + if (eo_parent_get(ep->typedata.vector->cur.vg)) + { + // remove it from the hirarchy + eo_ref(ep->typedata.vector->cur.vg); + eo_parent_set(ep->typedata.vector->cur.vg, NULL); + } + // create a container + container = evas_vg_container_add(NULL); + // reset the matrix. + Eina_Matrix3 matrix; + sx = w/ep->typedata.vector->cur.w; + sy = h/ep->typedata.vector->cur.h; + // for current vg + eina_matrix3_identity(&matrix); + eina_matrix3_translate(&matrix, -ep->typedata.vector->cur.x, -ep->typedata.vector->cur.y); + eina_matrix3_scale(&matrix, sx, sy); + evas_vg_node_transformation_set(ep->typedata.vector->cur.vg, &matrix); + // for next vg + sx = w/ep->typedata.vector->cache.w; + sy = h/ep->typedata.vector->cache.h; + eina_matrix3_identity(&matrix); + eina_matrix3_translate(&matrix, -ep->typedata.vector->cache.x, -ep->typedata.vector->cache.y); + eina_matrix3_scale(&matrix, sx, sy); + evas_vg_node_transformation_set(ep->typedata.vector->cache.vg, &matrix); + // do the interpolation + if (evas_vg_node_interpolate(container, ep->typedata.vector->cur.vg, ep->typedata.vector->cache.vg, pos)) + { + // can interpolate between two svg file + eo_parent_set(container, root_vg); + } + else + { + // can't interpolate between 2 shape + // keep the current vg tree + eo_parent_set(ep->typedata.vector->cur.vg, root_vg); + // delete the container + eo_unref(container); + } + } + else + { + if (ep->typedata.vector->cur.svg_id == chosen_desc->vg.id) // no svg file change + { + Eina_Matrix3 matrix; + sx = w/ep->typedata.vector->cur.w; + sy = h/ep->typedata.vector->cur.h; + eina_matrix3_identity(&matrix); + eina_matrix3_translate(&matrix, -ep->typedata.vector->cur.x, -ep->typedata.vector->cur.y); + eina_matrix3_scale(&matrix, sx, sy); + evas_vg_node_transformation_set(ep->typedata.vector->cur.vg, &matrix); + return; + } + else + { + Eina_Matrix3 matrix; + // check in cache if the vg tree already exists + if (ep->typedata.vector->cache.svg_id == chosen_desc->vg.id) + { + int id = ep->typedata.vector->cache.svg_id; + int vx = ep->typedata.vector->cache.x; + int vy = ep->typedata.vector->cache.y; + int vw = ep->typedata.vector->cache.w; + int vh = ep->typedata.vector->cache.h; + Efl_VG *vg = ep->typedata.vector->cache.vg; + + //1. update the cache from current. + ep->typedata.vector->cache.svg_id = ep->typedata.vector->cur.svg_id; + ep->typedata.vector->cache.vg = ep->typedata.vector->cur.vg; + ep->typedata.vector->cache.x = ep->typedata.vector->cur.x; + ep->typedata.vector->cache.y = ep->typedata.vector->cur.y; + ep->typedata.vector->cache.w = ep->typedata.vector->cur.w; + ep->typedata.vector->cache.h = ep->typedata.vector->cur.h; + eo_ref(ep->typedata.vector->cache.vg); + eo_parent_set(ep->typedata.vector->cache.vg, NULL); + + //2. update the root node + sx = w/vw; + sy = h/vh; + eina_matrix3_identity(&matrix); + eina_matrix3_translate(&matrix, -vx, -vy); + eina_matrix3_scale(&matrix, sx, sy); + evas_vg_node_transformation_set(vg, &matrix); + // update parent and ref + eo_parent_set(vg, root_vg); + + //3.update the cur + ep->typedata.vector->cur.svg_id = id; + ep->typedata.vector->cur.x = vx; + ep->typedata.vector->cur.y = vy; + ep->typedata.vector->cur.w = vw; + ep->typedata.vector->cur.h = vh; + ep->typedata.vector->cur.vg = vg; + } + else + { + //create it + vg_tree = _edje_create_vg_tree(ed->file->ef, chosen_desc->vg.id, w, h, &vx, &vy, &vw, &vh); + if (vg_tree) + { + //1. clear the cache + if (ep->typedata.vector->cache.vg) + { + eo_unref(ep->typedata.vector->cache.vg); + ep->typedata.vector->cache.vg = NULL; + ep->typedata.vector->cache.svg_id = 0; + } + // 2. move the current tree to cache + if (ep->typedata.vector->cur.vg) + { + eo_ref(ep->typedata.vector->cur.vg); + eo_parent_set(ep->typedata.vector->cur.vg, NULL); + // copy to the cache. + ep->typedata.vector->cache.svg_id = ep->typedata.vector->cur.svg_id; + ep->typedata.vector->cache.vg = ep->typedata.vector->cur.vg; + ep->typedata.vector->cache.x = ep->typedata.vector->cur.x; + ep->typedata.vector->cache.y = ep->typedata.vector->cur.y; + ep->typedata.vector->cache.w = ep->typedata.vector->cur.w; + ep->typedata.vector->cache.h = ep->typedata.vector->cur.h; + } + //3. update current + ep->typedata.vector->cur.svg_id = chosen_desc->vg.id; + ep->typedata.vector->cur.x = vx; + ep->typedata.vector->cur.y = vy; + ep->typedata.vector->cur.w = vw; + ep->typedata.vector->cur.h = vh; + ep->typedata.vector->cur.vg = vg_tree; + eo_parent_set(vg_tree, root_vg); + } + else + { + //1. clear current + ep->typedata.vector->cur.svg_id = 0; + eo_parent_set(ep->typedata.vector->cur.vg, NULL); + ep->typedata.vector->cur.vg = NULL; + } + } + } + } +} + static Edje_Real_Part * _edje_real_part_state_get(Edje *ed, Edje_Real_Part *ep, int flags, int id, int *state) { @@ -4564,6 +4755,7 @@ _edje_part_recalc(Edje *ed, Edje_Real_Part *ep, int flags, Edje_Calc_Params *sta case EDJE_PART_TYPE_BOX: case EDJE_PART_TYPE_TABLE: case EDJE_PART_TYPE_SNAPSHOT: + case EDJE_PART_TYPE_VECTOR: evas_object_color_set(ep->object, (pf->color.r * pf->color.a) / 255, (pf->color.g * pf->color.a) / 255, @@ -4873,6 +5065,10 @@ _edje_part_recalc(Edje *ed, Edje_Real_Part *ep, int flags, Edje_Calc_Params *sta _edje_textblock_recalc_apply(ed, ep, pf, (Edje_Part_Description_Text *)chosen_desc); break; + case EDJE_PART_TYPE_VECTOR: + _edje_svg_recalc_apply(ed, ep, pf, (Edje_Part_Description_Vector *)chosen_desc, pos); + break; + case EDJE_PART_TYPE_EXTERNAL: case EDJE_PART_TYPE_RECTANGLE: case EDJE_PART_TYPE_SWALLOW: diff --git a/src/lib/edje/edje_convert.c b/src/lib/edje/edje_convert.c index a6a8439715..f70b6ea954 100644 --- a/src/lib/edje/edje_convert.c +++ b/src/lib/edje/edje_convert.c @@ -287,6 +287,7 @@ case EDJE_PART_TYPE_##Tp: \ CSP(BOX, ce); CSP(TABLE, ce); CSP(EXTERNAL, ce); + CSP(VECTOR, ce); default: count = &dummy; @@ -310,6 +311,7 @@ case EDJE_PART_TYPE_##Tp: \ CONVERT_EMN(TABLE, Edje_Part_Description_Table, ce); CONVERT_EMN(EXTERNAL, Edje_Part_Description_External, ce); CONVERT_EMN(part, Edje_Part, ce); + CONVERT_EMN(VECTOR, Edje_Part_Description_Vector, ce); /* Change structure layout */ edc = calloc(1, sizeof (Edje_Part_Collection)); @@ -494,6 +496,7 @@ case EDJE_PART_TYPE_##Short: CONVERT_ALLOC_POOL(BOX, Box, box); CONVERT_ALLOC_POOL(TABLE, Table, table); CONVERT_ALLOC_POOL(EXTERNAL, External, external_params); + CONVERT_ALLOC_POOL(VECTOR, Vector, vector); } *result = oed->common; diff --git a/src/lib/edje/edje_data.c b/src/lib/edje/edje_data.c index 154c2ed1d3..d56e0cc5a3 100644 --- a/src/lib/edje/edje_data.c +++ b/src/lib/edje/edje_data.c @@ -82,6 +82,9 @@ Eet_Data_Descriptor *_edje_edd_edje_map_colors = NULL; Eet_Data_Descriptor *_edje_edd_edje_map_colors_pointer = NULL; Eet_Data_Descriptor *_edje_edd_edje_filter = NULL; Eet_Data_Descriptor *_edje_edd_edje_filter_directory = NULL; +Eet_Data_Descriptor *_edje_edd_edje_part_description_vector = NULL; +Eet_Data_Descriptor *_edje_edd_edje_part_description_vector_pointer = NULL; + Eet_Data_Descriptor *_edje_edd_edje_rect_node = NULL; Eet_Data_Descriptor *_edje_edd_edje_circle_node = NULL; @@ -531,6 +534,7 @@ EMP(MESH_NODE, mesh_node) EMP(LIGHT, light) EMP(CAMERA, camera) EMP(SNAPSHOT, snapshot) +EMP(VECTOR, vector) #undef EMP EAPI Eina_Mempool *_emp_part = NULL; @@ -580,7 +584,8 @@ struct { EDJE_PART_TYPE_MESH_NODE, "mesh_node" }, { EDJE_PART_TYPE_LIGHT, "light" }, { EDJE_PART_TYPE_CAMERA, "camera" }, - { EDJE_PART_TYPE_SNAPSHOT, "snapshot" } + { EDJE_PART_TYPE_SNAPSHOT, "snapshot" }, + { EDJE_PART_TYPE_VECTOR, "vector" } }; static const char * @@ -918,6 +923,7 @@ _edje_edd_init(void) EET_DATA_DESCRIPTOR_ADD_BASIC(_edje_edd_edje_part_collection_directory_entry, Edje_Part_Collection_Directory_Entry, "count.CAMERA", count.CAMERA, EET_T_INT); EET_DATA_DESCRIPTOR_ADD_BASIC(_edje_edd_edje_part_collection_directory_entry, Edje_Part_Collection_Directory_Entry, "count.part", count.part, EET_T_INT); EET_DATA_DESCRIPTOR_ADD_BASIC(_edje_edd_edje_part_collection_directory_entry, Edje_Part_Collection_Directory_Entry, "group_alias", group_alias, EET_T_UCHAR); + EET_DATA_DESCRIPTOR_ADD_BASIC(_edje_edd_edje_part_collection_directory_entry, Edje_Part_Collection_Directory_Entry, "count.VECTOR", count.VECTOR, EET_T_INT); EET_EINA_FILE_DATA_DESCRIPTOR_CLASS_SET(&eddc, Edje_Style_Tag); _edje_edd_edje_style_tag = @@ -1311,6 +1317,17 @@ _edje_edd_init(void) eet_data_descriptor_file_new(&eddc); EDJE_DATA_DESCRIPTOR_DESCRIPTION_COMMON(_edje_edd_edje_part_description_rectangle, Edje_Part_Description_Common); + // SVG, since 1.18 + EET_EINA_FILE_DATA_DESCRIPTOR_CLASS_SET(&eddc, Edje_Part_Description_Vector); + eddc.func.mem_free = mem_free_vector; + eddc.func.mem_alloc = mem_alloc_vector; + _edje_edd_edje_part_description_vector = + eet_data_descriptor_file_new(&eddc); + EDJE_DATA_DESCRIPTOR_DESCRIPTION_COMMON_SUB(_edje_edd_edje_part_description_vector, Edje_Part_Description_Vector, common); + EET_DATA_DESCRIPTOR_ADD_BASIC(_edje_edd_edje_part_description_vector, Edje_Part_Description_Vector, "vg.id", vg.id, EET_T_INT); + EET_DATA_DESCRIPTOR_ADD_BASIC(_edje_edd_edje_part_description_vector, Edje_Part_Description_Vector, "vg.set", vg.set, EET_T_UCHAR); + + EET_EINA_FILE_DATA_DESCRIPTOR_CLASS_SET(&eddc, Edje_Part_Description_Common); eddc.func.mem_free = mem_free_spacer; eddc.func.mem_alloc = mem_alloc_spacer; @@ -1596,6 +1613,7 @@ _edje_edd_init(void) EDJE_DEFINE_POINTER_TYPE(Part_Description_Mesh_Node, part_description_mesh_node); EDJE_DEFINE_POINTER_TYPE(Part_Description_Camera, part_description_camera); EDJE_DEFINE_POINTER_TYPE(Part_Description_Light, part_description_light); + EDJE_DEFINE_POINTER_TYPE(Part_Description_Vector, part_description_vector); eddc.version = EET_DATA_DESCRIPTOR_CLASS_VERSION; eddc.func.type_get = _edje_description_variant_type_get; @@ -1617,6 +1635,7 @@ _edje_edd_init(void) EET_DATA_DESCRIPTOR_ADD_MAPPING(_edje_edd_edje_part_description_variant, "mesh_node", _edje_edd_edje_part_description_mesh_node); EET_DATA_DESCRIPTOR_ADD_MAPPING(_edje_edd_edje_part_description_variant, "light", _edje_edd_edje_part_description_light); EET_DATA_DESCRIPTOR_ADD_MAPPING(_edje_edd_edje_part_description_variant, "camera", _edje_edd_edje_part_description_camera); + EET_DATA_DESCRIPTOR_ADD_MAPPING(_edje_edd_edje_part_description_variant, "vector", _edje_edd_edje_part_description_vector); #define EDJE_ADD_ARRAY_MAPPING(Variant, Type, Minus) \ { \ @@ -1646,6 +1665,7 @@ _edje_edd_init(void) EDJE_ADD_ARRAY_MAPPING(_edje_edd_edje_part_description_variant_list, "mesh_node", mesh_node); EDJE_ADD_ARRAY_MAPPING(_edje_edd_edje_part_description_variant_list, "light", light); EDJE_ADD_ARRAY_MAPPING(_edje_edd_edje_part_description_variant_list, "camera", camera); + EDJE_ADD_ARRAY_MAPPING(_edje_edd_edje_part_description_variant_list, "vector", vector); EET_EINA_FILE_DATA_DESCRIPTOR_CLASS_SET(&eddc, Edje_Pack_Element); _edje_edd_edje_pack_element = diff --git a/src/lib/edje/edje_edit.c b/src/lib/edje/edje_edit.c index caf5c58604..134a15cf9d 100644 --- a/src/lib/edje/edje_edit.c +++ b/src/lib/edje/edje_edit.c @@ -3137,6 +3137,12 @@ _edje_edit_real_part_add(Evas_Object *obj, const char *name, Edje_Part_Type type if (ep->type == EDJE_PART_TYPE_RECTANGLE) rp->object = evas_object_rectangle_add(ed->base->evas); + else if (ep->type == EDJE_PART_TYPE_VECTOR) + { + rp->type = EDJE_PART_TYPE_VECTOR; + rp->typedata.vector = calloc(1, sizeof(Edje_Real_Part_Vector)); + rp->object = evas_object_vg_add(ed->base->evas); + } else if (ep->type == EDJE_PART_TYPE_IMAGE || ep->type == EDJE_PART_TYPE_PROXY) rp->object = evas_object_image_add(ed->base->evas); else if (ep->type == EDJE_PART_TYPE_TEXT) @@ -6240,6 +6246,7 @@ case EDJE_PART_TYPE_##Short: \ EDIT_ALLOC_POOL(BOX, Box, box); EDIT_ALLOC_POOL(TABLE, Table, table); EDIT_ALLOC_POOL(EXTERNAL, External, external_params); + EDIT_ALLOC_POOL(VECTOR, Vector, vector); } return pd; diff --git a/src/lib/edje/edje_load.c b/src/lib/edje/edje_load.c index 2d08526fd8..d1f6417ddb 100644 --- a/src/lib/edje/edje_load.c +++ b/src/lib/edje/edje_load.c @@ -699,6 +699,12 @@ _edje_object_file_set_internal(Evas_Object *obj, const Eina_File *file, const ch if (!rp->typedata.text) memerr = EINA_TRUE; break; + case EDJE_PART_TYPE_VECTOR: + rp->type = EDJE_PART_TYPE_VECTOR; + rp->typedata.vector = calloc(1, sizeof(Edje_Real_Part_Vector)); + if (!rp->typedata.vector) memerr = EINA_TRUE; + break; + case EDJE_PART_TYPE_GROUP: case EDJE_PART_TYPE_SWALLOW: case EDJE_PART_TYPE_EXTERNAL: @@ -744,6 +750,10 @@ _edje_object_file_set_internal(Evas_Object *obj, const Eina_File *file, const ch rp->object = evas_object_rectangle_add(ed->base->evas); break; + case EDJE_PART_TYPE_VECTOR: + rp->object = evas_object_vg_add(ed->base->evas); + break; + case EDJE_PART_TYPE_PROXY: case EDJE_PART_TYPE_IMAGE: rp->object = evas_object_image_add(ed->base->evas); @@ -2299,3 +2309,114 @@ _cb_signal_repeat(void *data, Evas_Object *obj, const char *sig, const char *sou EDJE_MESSAGE_SIGNAL, 0, &emsg); } +// vg tree creation +static void +_apply_vg_property(Svg_Node *node, Efl_VG *vg) +{ + if (node->id) + evas_vg_node_name_set(vg, node->id); + if (node->style) + { + evas_vg_node_color_set(vg, node->style->fill.r, node->style->fill.g, node->style->fill.b, node->style->fill.a); + efl_gfx_shape_fill_rule_set(vg, node->style->fill.fill_rule); + evas_vg_shape_stroke_color_set(vg, node->style->stroke.r, node->style->stroke.g, node->style->stroke.b, node->style->stroke.a); + evas_vg_shape_stroke_width_set(vg, node->style->stroke.width); + evas_vg_shape_stroke_cap_set(vg, node->style->stroke.cap); + evas_vg_shape_stroke_join_set(vg, node->style->stroke.join); + evas_vg_shape_stroke_scale_set(vg, node->style->stroke.scale); + } +} + +static void +_create_vg_node(Svg_Node *node, Efl_VG *parent) +{ + Efl_VG *vg = NULL; + int i; + Svg_Node *child; + Eina_List *l; + + switch (node->type) + { + case SVG_NODE_G: + { + vg = evas_vg_container_add(parent); + _apply_vg_property(node, vg); + EINA_LIST_FOREACH(node->child, l, child) + { + _create_vg_node(child, vg); + } + return; + } + break; + case SVG_NODE_PATH: + vg = evas_vg_shape_add(parent); + evas_vg_shape_shape_append_svg_path(vg, node->node.path.path); + break; + case SVG_NODE_POLYGON: + vg = evas_vg_shape_add(parent); + for (i=0; i < node->node.polygon.points_count; i+=2) + { + if (!i) + evas_vg_shape_shape_append_move_to(vg, node->node.polygon.points[i], node->node.polygon.points[i+1]); + evas_vg_shape_shape_append_line_to(vg, node->node.polygon.points[i], node->node.polygon.points[i+1]); + } + break; + case SVG_NODE_ELLIPSE: + vg = evas_vg_shape_add(parent); + evas_vg_shape_shape_append_circle(vg, node->node.ellipse.cx, node->node.ellipse.cy, node->node.ellipse.rx); + break; + case SVG_NODE_CIRCLE: + vg = evas_vg_shape_add(parent); + evas_vg_shape_shape_append_circle(vg, node->node.circle.cx, node->node.circle.cy, node->node.circle.r); + break; + case SVG_NODE_RECT: + vg = evas_vg_shape_add(parent); + evas_vg_shape_shape_append_rect(vg, node->node.rect.x, node->node.rect.y, node->node.rect.w, node->node.rect.h, + node->node.rect.rx, node->node.rect.ry); + break; + default: + break; + } + _apply_vg_property(node, vg); +} + +Efl_VG* +_edje_create_vg_tree(Eet_File *ef, int svg_id, double width, double height, + double *vx, double *vy, double *vw, double *vh) +{ + double sx=1.0, sy=1.0; + Eina_Matrix3 matrix; + Efl_VG *root = NULL; + Svg_Node *child; + Eina_List *l; + Svg_Node *node; + char svg_key[20]; + Eet_Data_Descriptor *svg_node_eet; + + snprintf(svg_key, sizeof(svg_key), "edje/vectors/%i", svg_id); + svg_node_eet = _edje_svg_node_eet(); + node = eet_data_read(ef, svg_node_eet, svg_key); + + if (!node && (node->type != SVG_NODE_DOC)) return NULL; + if (node->node.doc.vw && node->node.doc.vh) + { + sx = width/node->node.doc.vw; + sy = height/node->node.doc.vh; + root = evas_vg_container_add(NULL); + eina_matrix3_identity(&matrix); + eina_matrix3_translate(&matrix, -node->node.doc.vx, -node->node.doc.vy); + eina_matrix3_scale(&matrix, sx, sy); + evas_vg_node_transformation_set(root, &matrix); + } + + EINA_LIST_FOREACH(node->child, l, child) + { + _create_vg_node(child, root); + } + *vx = node->node.doc.vx; + *vy = node->node.doc.vy; + *vw = node->node.doc.vw; + *vh = node->node.doc.vh; + return root; +} + diff --git a/src/lib/edje/edje_lua.c b/src/lib/edje/edje_lua.c index 9253dbe2c9..63021a2c2d 100644 --- a/src/lib/edje/edje_lua.c +++ b/src/lib/edje/edje_lua.c @@ -4982,6 +4982,7 @@ _edje_lua_open(lua_State *L) _edje_lua_new_const(L, "PART_TYPE_GRADIENT", EDJE_PART_TYPE_GRADIENT); _edje_lua_new_const(L, "PART_TYPE_GROUP", EDJE_PART_TYPE_GROUP); _edje_lua_new_const(L, "PART_TYPE_BOX", EDJE_PART_TYPE_BOX); + _edje_lua_new_const(L, "PART_TYPE_VECTOR", EDJE_PART_TYPE_VECTOR); _edje_lua_new_const(L, "TEXT_EFFECT_NONE", EDJE_TEXT_EFFECT_NONE); _edje_lua_new_const(L, "TEXT_EFFECT_PLAIN", EDJE_TEXT_EFFECT_PLAIN); diff --git a/src/lib/edje/edje_private.h b/src/lib/edje/edje_private.h index f5c3bb8cb6..7de6b58425 100644 --- a/src/lib/edje/edje_private.h +++ b/src/lib/edje/edje_private.h @@ -325,6 +325,8 @@ typedef struct _Edje_Mo_Directory Edje_Mo_Directory; typedef struct _Edje_Gfx_Filter Edje_Gfx_Filter; typedef struct _Edje_Gfx_Filter_Directory Edje_Gfx_Filter_Directory; typedef struct _Edje_Color_Tree_Node Edje_Color_Tree_Node; +typedef struct _Edje_Vector_Directory_Entry Edje_Vector_Directory_Entry; + typedef struct _Edje_Vibration_Sample Edje_Vibration_Sample; typedef struct _Edje_Vibration_Directory Edje_Vibration_Directory; @@ -365,6 +367,9 @@ typedef struct _Edje_Physics_Face Edje_Physics_Face; typedef struct _Edje_Patterns Edje_Patterns; typedef struct _Edje_Part_Box_Animation Edje_Part_Box_Animation; typedef struct _Edje_Part_Limit Edje_Part_Limit; +typedef struct _Edje_Part_Description_Vector Edje_Part_Description_Vector; +typedef struct _Edje_Part_Description_Spec_Svg Edje_Part_Description_Spec_Svg; +typedef struct _Edje_Real_Part_Vector Edje_Real_Part_Vector; typedef struct _Edje Edje; typedef struct _Edje_Real_Part_Text Edje_Real_Part_Text; @@ -632,6 +637,15 @@ struct _Edje_Image_Directory Edje_Image_Directory_Set *sets; /* an array of Edje_Image_Directory_Set */ unsigned int sets_count; + + Edje_Vector_Directory_Entry *vectors; /* an array of Edje_Image_Directory_Entry */ + unsigned int vectors_count; +}; + +struct _Edje_Vector_Directory_Entry +{ + const char *entry; /* the nominal name of the vector image - if any */ + int id; /* the id no. of the image */ }; struct _Edje_Image_Directory_Entry @@ -857,7 +871,8 @@ struct _Edje_Limit TYPE MESH_NODE; \ TYPE LIGHT; \ TYPE CAMERA; \ - TYPE SNAPSHOT; + TYPE SNAPSHOT; \ + TYPE VECTOR; struct _Edje_Part_Collection_Directory_Entry { @@ -1522,6 +1537,12 @@ struct _Edje_Part_Description_Spec_Camera } orientation; }; +struct _Edje_Part_Description_Spec_Svg +{ + int id; /* the svg id to use */ + Eina_Bool set; /* if vg condition it's content */ +}; + struct _Edje_Part_Description_Image { Edje_Part_Description_Common common; @@ -1585,6 +1606,12 @@ struct _Edje_Part_Description_Camera Edje_Part_Description_Spec_Camera camera; }; +struct _Edje_Part_Description_Vector +{ + Edje_Part_Description_Common common; + Edje_Part_Description_Spec_Svg vg; +}; + /*----------*/ struct _Edje_Signal_Source_Char @@ -1908,6 +1935,16 @@ struct _Edje_Real_Part_Swallow } swallow_params; // 28 // FIXME: only if type SWALLOW }; +struct _Edje_Real_Part_Vector +{ + struct { + int svg_id; + double x, y, w, h; + Eina_Bool preserve_aspect; + Efl_VG *vg; + }cur, cache; +}; + struct _Edje_Real_Part { Edje_Real_Part_State param1; // 32 @@ -1930,6 +1967,7 @@ struct _Edje_Real_Part Edje_Real_Part_Text *text; Edje_Real_Part_Container *container; Edje_Real_Part_Swallow *swallow; + Edje_Real_Part_Vector *vector; } typedata; // 4 FLOAT_T description_pos; // 8 Edje_Rectangle req; // 16 @@ -2283,6 +2321,7 @@ EAPI extern Eina_Mempool *_emp_LIGHT; EAPI extern Eina_Mempool *_emp_CAMERA; EAPI extern Eina_Mempool *_emp_SNAPSHOT; EAPI extern Eina_Mempool *_emp_part; +EAPI extern Eina_Mempool *_emp_VECTOR; void _edje_part_pos_set(Edje *ed, Edje_Real_Part *ep, int mode, FLOAT_T pos, FLOAT_T v1, FLOAT_T v2, FLOAT_T v3, FLOAT_T v4); @@ -3190,6 +3229,8 @@ enum _Svg_Style_Type EAPI Eet_Data_Descriptor * _edje_svg_node_eet(void); void _edje_svg_node_destroy_eet(void); +Efl_VG* _edje_create_vg_tree(Eet_File *ef, int svg_id, double width, double height, + double *vx, double *vy, double *vw, double *vh); #ifdef HAVE_LIBREMIX #include