From 829b9aacde72650b303502d2e2ffa632a226c5f1 Mon Sep 17 00:00:00 2001 From: Thiep Ha Date: Thu, 8 Jun 2017 15:32:09 +0900 Subject: [PATCH] efl.gfx.map: support for map points as multiples of 4 This patch adds support for map with more than 4 points. However, we only support points with multiples of 4. This also adds efl_gfx_map_point_count_set/get APIs to set number of points. @feature --- src/Makefile_Elementary.am | 1 + src/bin/elementary/test.c | 2 + src/bin/elementary/test_efl_gfx_map.c | 69 +++++++++++++++++++++++ src/lib/evas/canvas/efl_gfx_map.c | 100 +++++++++++++++++++++++++++------- src/lib/evas/canvas/efl_gfx_map.eo | 10 ++++ 5 files changed, 161 insertions(+), 21 deletions(-) create mode 100644 src/bin/elementary/test_efl_gfx_map.c diff --git a/src/Makefile_Elementary.am b/src/Makefile_Elementary.am index cde70880..7103ae9 100644 --- a/src/Makefile_Elementary.am +++ b/src/Makefile_Elementary.am @@ -777,6 +777,7 @@ bin/elementary/test_entry_anchor2.c \ bin/elementary/test_events.c \ bin/elementary/test_evas_mask.c \ bin/elementary/test_evas_map.c \ +bin/elementary/test_efl_gfx_map.c \ bin/elementary/test_evas_snapshot.c \ bin/elementary/test_external.c \ bin/elementary/test_fileselector_button.c \ diff --git a/src/bin/elementary/test.c b/src/bin/elementary/test.c index 554cdb2..477cc58 100644 --- a/src/bin/elementary/test.c +++ b/src/bin/elementary/test.c @@ -312,6 +312,7 @@ void test_evas_mask(void *data, Edje_Object *obj, void *event_info); void test_gfx_filters(void *data, Evas_Object *obj, void *event_info); void test_evas_snapshot(void *data, Evas_Object *obj, void *event_info); void test_evas_map(void *data, Edje_Object *obj, void *event_info); +void test_efl_gfx_map(void *data, Edje_Object *obj, void *event_info); Evas_Object *win, *tbx; // TODO: refactoring void *tt; @@ -1032,6 +1033,7 @@ add_tests: ADD_TEST(NULL, "Evas", "Gfx Filters", test_gfx_filters); ADD_TEST(NULL, "Evas", "Snapshot", test_evas_snapshot); ADD_TEST(NULL, "Evas", "Map", test_evas_map); + ADD_TEST(NULL, "Evas", "Gfx Map", test_efl_gfx_map); //------------------------------// ADD_TEST(NULL, "Widgets Disable/Enable", "Box", test_box_disable); diff --git a/src/bin/elementary/test_efl_gfx_map.c b/src/bin/elementary/test_efl_gfx_map.c new file mode 100644 index 0000000..dc70843 --- /dev/null +++ b/src/bin/elementary/test_efl_gfx_map.c @@ -0,0 +1,69 @@ +#ifdef HAVE_CONFIG_H +# include "elementary_config.h" +#endif +#include + +static void +_map_set(Evas_Object *obj) +{ + efl_gfx_map_reset(obj); + efl_gfx_map_point_count_set(obj, 8); + //1st rect + efl_gfx_map_coord_absolute_set(obj, 0, 100, 0, 0); + efl_gfx_map_coord_absolute_set(obj, 1, 200, 0, 0); + efl_gfx_map_coord_absolute_set(obj, 2, 200, 100, 0); + efl_gfx_map_coord_absolute_set(obj, 3, 100, 100, 0); + //2nd rect + efl_gfx_map_coord_absolute_set(obj, 4, 200, 0, 0); + efl_gfx_map_coord_absolute_set(obj, 5, 100, 200, 0); + efl_gfx_map_coord_absolute_set(obj, 6, 100, 300, 0); + efl_gfx_map_coord_absolute_set(obj, 7, 200, 100, 0); + + //uv: 1st rect: uv: [0-1] + efl_gfx_map_uv_set(obj, 0, 0, 0); + efl_gfx_map_uv_set(obj, 1, 0.5, 0); + efl_gfx_map_uv_set(obj, 2, 0.5, 1); + efl_gfx_map_uv_set(obj, 3, 0, 1); + //uv: 2nd rect + efl_gfx_map_uv_set(obj, 4, 0.5, 0); + efl_gfx_map_uv_set(obj, 5, 1, 0); + efl_gfx_map_uv_set(obj, 6, 1, 1); + efl_gfx_map_uv_set(obj, 7, 0.5, 1); +} + +static void +_image_resize_cb(void *data EINA_UNUSED, Evas *e EINA_UNUSED, Evas_Object *obj, void *event_info EINA_UNUSED) +{ + _map_set(obj); +} + +void +test_efl_gfx_map(void *data EINA_UNUSED, Evas_Object *obj EINA_UNUSED, + void *event_info EINA_UNUSED) +{ + const Evas_Coord W = 300, H = 300; + Evas_Object *win, *img; + char buf[PATH_MAX]; + + win = efl_add(EFL_UI_WIN_CLASS, NULL, + efl_text_set(efl_added, "Efl Gfx Map"), + efl_ui_win_autodel_set(efl_added, EINA_TRUE)); + + /* image with a min size */ + snprintf(buf, sizeof(buf), "%s/images/rock_02.jpg", elm_app_data_dir_get()); + img = efl_add(EFL_UI_IMAGE_CLASS, win, + efl_gfx_size_hint_align_set(efl_added, EFL_GFX_SIZE_HINT_FILL, EFL_GFX_SIZE_HINT_FILL), + efl_gfx_size_hint_weight_set(efl_added, EFL_GFX_SIZE_HINT_EXPAND, EFL_GFX_SIZE_HINT_EXPAND), + efl_gfx_size_hint_min_set(efl_added, 64, 64), + efl_file_set(efl_added, buf, NULL), + efl_gfx_visible_set(efl_added, EINA_TRUE)); + efl_ui_image_scale_type_set(img, EFL_UI_IMAGE_SCALE_TYPE_FILL); + evas_object_event_callback_add(img, EVAS_CALLBACK_RESIZE, + _image_resize_cb, NULL); + + _map_set(img); + + efl_content_set(win, img); + efl_gfx_size_set(win, W, H); + efl_gfx_visible_set(win, EINA_TRUE); +} diff --git a/src/lib/evas/canvas/efl_gfx_map.c b/src/lib/evas/canvas/efl_gfx_map.c index ab530c3..8577ebf 100644 --- a/src/lib/evas/canvas/efl_gfx_map.c +++ b/src/lib/evas/canvas/efl_gfx_map.c @@ -14,6 +14,7 @@ typedef struct _Gfx_Map Gfx_Map; typedef struct _Gfx_Map_Op Gfx_Map_Op; typedef struct _Gfx_Map_Pivot Gfx_Map_Pivot; typedef struct _Efl_Gfx_Map_Data Efl_Gfx_Map_Data; +typedef struct _Gfx_Map_Point Gfx_Map_Point; typedef enum _Gfx_Map_Op_Type Gfx_Map_Op_Type; enum _Gfx_Map_Op_Type { @@ -84,16 +85,19 @@ struct _Gfx_Map_Pivot Eina_Bool changed; }; +struct _Gfx_Map_Point { + double u, v; +}; + struct _Gfx_Map { Gfx_Map_Op *ops; - struct { - double u, v; - } point[4]; + Gfx_Map_Point *points; Gfx_Map_Pivot *pivots; Evas_Map *map; Gfx_Map_Op *last_calc_op; int imw, imh; + int count; // FIXME: Those need a quality vs. performance setting instead Eina_Bool alpha; @@ -111,10 +115,12 @@ static Eo *gfx_map_absolute = NULL; static Eina_Cow *gfx_map_cow = NULL; static const Gfx_Map gfx_map_cow_default = { NULL, - { { 0.0, 0.0 }, { 1.0, 0.0 }, { 1.0, 1.0 }, { 0.0, 1.0 } }, + NULL, + NULL, NULL, NULL, 0, 0, + 4, EINA_TRUE, EINA_TRUE, EINA_FALSE @@ -169,6 +175,8 @@ _efl_gfx_map_efl_object_destructor(Eo *eo_obj, Efl_Gfx_Map_Data *pd) if (pd->cow) { _map_ops_clean(eo_obj, pd); + if (pd->cow->points) + free(pd->cow->points); eina_cow_free(gfx_map_cow, (const Eina_Cow_Data **) &pd->cow); } efl_destructor(efl_super(eo_obj, MY_CLASS)); @@ -244,6 +252,7 @@ _map_calc(Eo *eo_obj, Evas_Object_Protected_Data *obj, Efl_Gfx_Map_Data *pd) Gfx_Map *mcow; Evas_Map *m; int imw, imh; + int count; if (pd->cow == &gfx_map_cow_default) return NULL; @@ -252,6 +261,7 @@ _map_calc(Eo *eo_obj, Evas_Object_Protected_Data *obj, Efl_Gfx_Map_Data *pd) if (!obj->gfx_map_update) return m; last_op = pd->cow->last_calc_op; + count = pd->cow->count < 4 ? 4 : pd->cow->count; EINA_INLIST_FOREACH(pd->cow->pivots, pivot) { @@ -276,6 +286,20 @@ _map_calc(Eo *eo_obj, Evas_Object_Protected_Data *obj, Efl_Gfx_Map_Data *pd) } } + if (!pd->cow->points) + { + Gfx_Map_Point *ps = calloc(1, count * sizeof(Gfx_Map_Point)); + if (!ps) return m; + if (count == 4) + { + ps[0].u = 0.0; ps[0].v = 0.0; + ps[1].u = 1.0; ps[1].v = 0.0; + ps[2].u = 1.0; ps[2].v = 1.0; + ps[3].u = 0.0; ps[3].v = 1.0; + } + MAPCOW_WRITE(pd, points, ps); + } + if (m && last_op) { first_op = EINA_INLIST_NEXT(last_op); @@ -284,7 +308,7 @@ _map_calc(Eo *eo_obj, Evas_Object_Protected_Data *obj, Efl_Gfx_Map_Data *pd) } else { - if (!m) m = evas_map_new(4); + if (!m) m = evas_map_new(count); else _evas_map_reset(m); m->alpha = pd->cow->alpha; m->smooth = pd->cow->smooth; @@ -310,16 +334,16 @@ _map_calc(Eo *eo_obj, Evas_Object_Protected_Data *obj, Efl_Gfx_Map_Data *pd) first_op = pd->cow->ops; } - for (int k = 0; k < 4; k++) + for (int k = 0; k < count; k++) { Evas_Map_Point *p = &(m->points[k]); - p->u = pd->cow->point[k].u * imw; - p->v = pd->cow->point[k].v * imh; + p->u = pd->cow->points[k].u * imw; + p->v = pd->cow->points[k].v * imh; } EINA_INLIST_FOREACH(first_op, op) { - int k, kmin = 0, kmax = 3; + int k, kmin = 0, kmax = count - 1; double cx, cy, cz; Evas_Map_Point *p; @@ -493,6 +517,33 @@ _efl_gfx_map_map_reset(Eo *eo_obj, Efl_Gfx_Map_Data *pd) obj->gfx_map_has = EINA_FALSE; } +EOLIAN static int +_efl_gfx_map_map_point_count_get(Eo *eo_obj EINA_UNUSED, Efl_Gfx_Map_Data *pd) +{ + return pd->cow->count; +} + +EOLIAN static void +_efl_gfx_map_map_point_count_set(Eo *eo_obj EINA_UNUSED, Efl_Gfx_Map_Data *pd, int count) +{ + Gfx_Map *mcow; + + if (count % 4 != 0) + { + ERR("Map point count (%d) should be multiples of 4", count); + return; + } + if (pd->cow->count == count) return; + + mcow = MAPCOW_BEGIN(pd); + mcow->count = count; + if (mcow->points == NULL) + mcow->points = calloc(1, count * sizeof(Gfx_Map_Point)); + else + mcow->points = realloc(mcow->points, count * sizeof(Gfx_Map_Point)); + MAPCOW_END(mcow, pd); +} + EOLIAN static Eina_Bool _efl_gfx_map_map_clockwise_get(Eo *eo_obj, Efl_Gfx_Map_Data *pd) { @@ -543,7 +594,7 @@ _efl_gfx_map_map_coord_absolute_get(Eo *eo_obj, Efl_Gfx_Map_Data *pd, Evas_Object_Protected_Data *obj = EVAS_OBJ_GET_OR_RETURN(eo_obj); Evas_Map *m; - EINA_SAFETY_ON_FALSE_RETURN((idx >= 0) && (idx < 4)); + EINA_SAFETY_ON_FALSE_RETURN((idx >= 0) && (idx < pd->cow->count)); m = _map_calc(eo_obj, obj, pd); if (!m) @@ -578,15 +629,21 @@ _efl_gfx_map_map_uv_set(Eo *eo_obj, Efl_Gfx_Map_Data *pd, { Gfx_Map *mcow; - EINA_SAFETY_ON_FALSE_RETURN((idx >= 0) && (idx < 4)); + EINA_SAFETY_ON_FALSE_RETURN((idx >= 0) && (idx < pd->cow->count)); - if (EINA_DBL_EQ(pd->cow->point[idx].u, u) && - EINA_DBL_EQ(pd->cow->point[idx].v, v)) + if (!pd->cow->points) + { + Gfx_Map_Point *ps = calloc(1, pd->cow->count * sizeof(Gfx_Map_Point)); + if (!ps) return; + MAPCOW_WRITE(pd, points, ps); + } + if (EINA_DBL_EQ(pd->cow->points[idx].u, u) && + EINA_DBL_EQ(pd->cow->points[idx].v, v)) return; mcow = MAPCOW_BEGIN(pd); - mcow->point[idx].u = CLAMP(0.0, u, 1.0); - mcow->point[idx].v = CLAMP(0.0, v, 1.0); + mcow->points[idx].u = CLAMP(0.0, u, 1.0); + mcow->points[idx].v = CLAMP(0.0, v, 1.0); MAPCOW_END(mcow, pd); _map_dirty(eo_obj, pd, EINA_FALSE); @@ -596,10 +653,11 @@ EOLIAN static void _efl_gfx_map_map_uv_get(Eo *eo_obj EINA_UNUSED, Efl_Gfx_Map_Data *pd, int idx, double *u, double *v) { - EINA_SAFETY_ON_FALSE_RETURN((idx >= 0) && (idx < 4)); + EINA_SAFETY_ON_FALSE_RETURN((idx >= 0) && (idx < pd->cow->count) + && (pd->cow->points)); - if (u) *u = pd->cow->point[idx].u; - if (v) *v = pd->cow->point[idx].v; + if (u) *u = pd->cow->points[idx].u; + if (v) *v = pd->cow->points[idx].v; } EOLIAN static void @@ -610,7 +668,7 @@ _efl_gfx_map_map_color_get(Eo *eo_obj EINA_UNUSED, Efl_Gfx_Map_Data *pd, Evas_Map_Point *p; Evas_Map *m; - EINA_SAFETY_ON_FALSE_RETURN((idx >= 0) && (idx < 4)); + EINA_SAFETY_ON_FALSE_RETURN((idx >= 0) && (idx < pd->cow->count)); if (!r && !g && !b && !a) return; @@ -699,7 +757,7 @@ _efl_gfx_map_map_coord_absolute_set(Eo *eo_obj, Efl_Gfx_Map_Data *pd, { Gfx_Map_Op *op; - EINA_SAFETY_ON_FALSE_RETURN((idx >= 0) && (idx < 4)); + EINA_SAFETY_ON_FALSE_RETURN((idx >= 0) && (idx < pd->cow->count)); op = _gfx_map_op_add(eo_obj, pd, GFX_MAP_RAW_COORD, NULL, 0, 0, 0, EINA_FALSE); if (!op) return; @@ -716,7 +774,7 @@ _efl_gfx_map_map_color_set(Eo *eo_obj, Efl_Gfx_Map_Data *pd, { Gfx_Map_Op *op; - EINA_SAFETY_ON_FALSE_RETURN((idx >= -1) && (idx < 4)); + EINA_SAFETY_ON_FALSE_RETURN((idx >= -1) && (idx < pd->cow->count)); op = _gfx_map_op_add(eo_obj, pd, GFX_MAP_COLOR, NULL, 0, 0, 0, EINA_FALSE); if (!op) return; diff --git a/src/lib/evas/canvas/efl_gfx_map.eo b/src/lib/evas/canvas/efl_gfx_map.eo index 39d3445..90d4927 100644 --- a/src/lib/evas/canvas/efl_gfx_map.eo +++ b/src/lib/evas/canvas/efl_gfx_map.eo @@ -33,6 +33,16 @@ mixin Efl.Gfx.Map (Efl.Interface, Efl.Object) not modify the values of @.map_smooth or @.map_alpha. ]] } + @property map_point_count { + [[Number of points of a map. + + This sets the number of points of map. + Currently, the number of points must be multiples of 4. + ]] + values { + count: int; [[The number of points of map]] + } + } @property map_clockwise { [[Clockwise state of a map (read-only). -- 2.7.4