Evas Map, little clarifications and an overview example
authorsachiel <sachiel@7cbeb6ba-43b4-40fd-8cce-4c39aea84d33>
Mon, 4 Jul 2011 15:22:53 +0000 (15:22 +0000)
committersachiel <sachiel@7cbeb6ba-43b4-40fd-8cce-4c39aea84d33>
Mon, 4 Jul 2011 15:22:53 +0000 (15:22 +0000)
git-svn-id: svn+ssh://svn.enlightenment.org/var/svn/e/trunk/evas@61010 7cbeb6ba-43b4-40fd-8cce-4c39aea84d33

doc/examples.dox
src/examples/Makefile.am
src/examples/cube1.png [new file with mode: 0644]
src/examples/evas-map-utils.c [new file with mode: 0644]
src/examples/im1.png [new file with mode: 0644]
src/lib/Evas.h

index 545f463..96d65b7 100644 (file)
  * @include evas-stacking.c
  * @example evas-stacking.c
  */
+
+/**
+ * @page Example_Evas_Map_Overview Evas Map - Overview
+ * @dontinclude evas-map-utils.c
+ *
+ * Down to the very bottom, Map is simple: it takes an object and transforms
+ * the way it will be shown on screen. But using it properly can be a bit
+ * troublesome.
+ *
+ * For the most common operations there are utility functions that help in
+ * setting up the map to achieve the desired effects. Now we'll go through
+ * an overview of the map API and some of the things that can be done with
+ * it.
+ *
+ * The full code can be found @ref evas-map-utils.c "here".
+ *
+ * To show how some funtions work, this example listens to keys pressed to
+ * toggle several options.
+ * @skip typedef
+ * @until App_Data
+ * @until ;
+ *
+ * In this program, we divide the window in four quadrants, each holding an
+ * object that will have different map configurations applied to them in each
+ * call to an animator function.
+ * @skip static Eina_Bool
+ * @until evas_output_size_get
+ *
+ * Let's first create a map and set some of our options to it. Only four
+ * points maps are supported, so we'll stick to that magic number. We can
+ * set a color for each vertex or apply one for all of them at once
+ * @until evas_map_util_points_color_set
+ *
+ * For the first object, we'll have a plain rectangle. At its cration, this
+ * rectangle was set to be semi-transparent, but whether its own alpha is
+ * used will be defined by the map's alpha setting. If the map's alpha is
+ * disabled, then the object will be completely opaque. The map's own color,
+ * however, will use any alpha set to it.
+ *
+ * So we get our object, initialize our map geometry to match the rectangle
+ * and make it rotate around its own center, then apply the map to the
+ * object so it takes effect.
+ * @until evas_object_map_enable_set
+ *
+ * The second object is an image. Here we don't have any color set for the
+ * object, but the image itself contains an alpha channel that will not be
+ * affected by the map settings, so even with alpha set to be off, the image
+ * will still be transparent. Color applied to the map will tint it though.
+ * Since setting a map copies it into the object, we can reuse the same one
+ * we created before. We initialize it to the new object while all other
+ * options are kept the same. Notice that no rotation will be done here, as
+ * that's just an utility function that takes the coordinates set for each
+ * point of the map and transforms it accordingly.
+ * @until evas_map_util_points_populate_from_object_full
+ *
+ * This time the object is a bit farther into the screen, by using a @c z
+ * value higher than 0 to init the map. We also need to map the image used
+ * by the object, so Evas knows how to transform it properly. For this we
+ * use the evas_map_point_image_uv_set() to tell the map what coordinate
+ * within the image corresponds to each point of the map.
+ * @until evas_map_point_image_uv_set(m, 3
+ *
+ * This object will also be rotated, but in all three axis and around some
+ * other point, not its center, chosen mostly at random. If enabled, lighting
+ * will be applied to, from a light source at the center of the window.
+ * @until evas_object_map_enable_set
+ *
+ * For the third object we are doing, once more, a 3D rotation, but this time
+ * perspective will be applied to our map to make it look more realistic.
+ * The lighting source also follows the mouse cursor and it's possible to
+ * toggle backface culling, so that the object is hidden whenever we are
+ * not seeing its front face.
+ * @until evas_object_map_enable_set
+ *
+ * And we free this map, since since we messed too much with it and for the
+ * last object we want something cleaner.
+ * @until evas_map_free
+ *
+ * The last object is actually two. One image, with an image set to it, and
+ * one image proxying the first one with evas_object_image_source_set(). This
+ * way, the second object will show whatever content its source has.
+ * This time we'll be using a map more manually to simulate a simple reflection
+ * of the original image.
+ *
+ * We know that the reflection object is placed just like the original, so
+ * we take a shortcut by just getting the geometry of our to-be-mapped object.
+ * We also need to get the image size of the source.
+ * @until evas_object_image_size_get
+ *
+ * For this we'll create a map shaped so that it begins at the base of our
+ * image and it expands horizontally as it grows (downwards) in height.
+ * @until evas_map_point_coord_set(m, 3
+ *
+ * Since the reflection should show the image inverted, we need to map it
+ * this way. The first point of the map (top-left) will be mapped to the
+ * mapped to the first pixel of the last row. There's no horizontal reflection
+ * and we want the full width of the image, but as we map its upper side ww
+ * will only take two thirds of the image.
+ * @until evas_map_point_image_uv_set(m, 3
+ *
+ * Finally, to fade out our reflection we set the colors for each point in
+ * the map. The two at the top need to be visible, but we'll tone them down
+ * a bit and make them a bit translucent. The other two will go straight to
+ * full transparency. Evas interpolates the colors from one point to the next,
+ * so this will make them fade out.
+ * @until evas_object_map_enable_set
+ *
+ * Close up by freeing the map and do some other things needed to keep stuff
+ * moving in our animations and we are done.
+ * @until }
+ *
+ * The rest of the program is setup and listening to key events. Nothing that
+ * matters within the scope of this example, so we are going to skip it.
+ * Refer to it @ref evas-map-utils.c "here" however to see how everything
+ * fits together.
+ *
+ * @example evas-map-utils.c
+ */
index 4d6a199..5b4c1fe 100644 (file)
@@ -77,6 +77,10 @@ evas_aspect_hints_DEPS = $(srcdir)/aspect.edc
 evas_aspect_hints_SOURCES = evas-aspect-hints.c
 evas_aspect_hints_LDADD = $(top_builddir)/src/lib/libevas.la @ECORE_EVAS_LIBS@ @EDJE_LIBS@
 
+pkglib_PROGRAMS += evas_map_utils
+evas_map_utils_SOURCES = evas-map-utils.c
+evas_map_utils_LDADD = $(top_builddir)/src/lib/libevas.la @ECORE_EVAS_LIBS@
+
 aspect.edj: ${evas_aspect_hints_DEPS}
 
 .edc.edj:
@@ -92,7 +96,9 @@ if INSTALL_EXAMPLES
 
 #put here additional data when installing examples
 files_DATA += $(srcdir)/enlightenment.png \
-       $(srcdir)/red.png
+       $(srcdir)/red.png \
+       $(srcdir)/im1.png \
+       $(srcdir)/cube1.png
 
 files_DATA += \
        $(EDCS) \
@@ -104,7 +110,8 @@ files_DATA += \
        $(srcdir)/evas-events.c \
        $(srcdir)/evas-aspect-hints.c \
        $(srcdir)/evas-hints.c \
-       $(srcdir)/evas-stacking.c
+       $(srcdir)/evas-stacking.c \
+       $(srcdir)/evas-map-utils.c
 endif
 
 EXTRA_DIST = $(EDCS) \
@@ -118,4 +125,6 @@ EXTRA_DIST = $(EDCS) \
        $(srcdir)/evas-hints.c \
        $(srcdir)/evas-stacking.c \
        $(srcdir)/enlightenment.png \
-       $(srcdir)/red.png
+       $(srcdir)/red.png \
+       $(srcdir)/im1.png \
+       $(srcdir)/cube1.png
diff --git a/src/examples/cube1.png b/src/examples/cube1.png
new file mode 100644 (file)
index 0000000..c2f4fda
Binary files /dev/null and b/src/examples/cube1.png differ
diff --git a/src/examples/evas-map-utils.c b/src/examples/evas-map-utils.c
new file mode 100644 (file)
index 0000000..2d15882
--- /dev/null
@@ -0,0 +1,321 @@
+/*
+ * gcc -o evas-map-utils evas-map-utils.c `pkg-config --cflags --libs evas ecore ecore-evas`
+ */
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#else
+#define __UNUSED__
+#endif
+
+#include <Ecore.h>
+#include <Ecore_Evas.h>
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <math.h>
+
+#define WIDTH  480
+#define HEIGHT 480
+
+typedef struct
+{
+   Ecore_Evas *ee;
+   Evas       *canvas;
+   struct {
+        int r, g, b, a;
+   } colors[6];
+   int colors_index;
+   int frame;
+   Eina_Bool   alpha : 1;
+   Eina_Bool   smooth : 1;
+   Eina_Bool   backface_culling : 1;
+   Eina_Bool   apply_perspective : 1;
+   Eina_Bool   apply_lighting : 1;
+} App_Data;
+
+static const char *help_string =
+        "Valid commands:\n"
+        "\ta - toggle alpha for maps\n"
+        "\ts - toggle smooth for maps\n"
+        "\tc - switch map color\n"
+        "\tb - toggle backface culling\n"
+        "\tp - toggle perspective\n"
+        "\tl - toggle lighting\n"
+        "\th - prints this help\n";
+
+static Eina_Bool
+_anim_cb(void *data)
+{
+   App_Data *ad = data;
+   Evas_Map *m;
+   const Evas_Map *old_map;
+   Evas_Object *o;
+   int r, g, b, a;
+   int win_w, win_h, img_w, img_h;
+   Evas_Coord x, y, w, h;
+
+   evas_output_size_get(ad->canvas, &win_w, &win_h);
+
+   m = evas_map_new(4);
+   evas_map_smooth_set(m, ad->smooth);
+   evas_map_alpha_set(m, ad->alpha);
+
+   r = ad->colors[ad->colors_index].r;
+   g = ad->colors[ad->colors_index].g;
+   b = ad->colors[ad->colors_index].b;
+   a = ad->colors[ad->colors_index].a;
+   evas_map_util_points_color_set(m, r, g, b, a);
+
+   o = evas_object_name_find(ad->canvas, "obj1");
+   evas_object_geometry_get(o, &x, &y, &w, &h);
+
+   evas_map_util_points_populate_from_object(m, o);
+   evas_map_util_rotate(m, 3 * ad->frame, x + (w / 2), y + (h / 2));
+   evas_object_map_set(o, m);
+   evas_object_map_enable_set(o, EINA_TRUE);
+
+   o = evas_object_name_find(ad->canvas, "obj2");
+   evas_object_geometry_get(o, &x, &y, &w, &h);
+   evas_object_image_size_get(o, &img_w, &img_h);
+
+   evas_map_util_points_populate_from_object_full(m, o, 100);
+   evas_map_point_image_uv_set(m, 0, 0, 0);
+   evas_map_point_image_uv_set(m, 1, img_w, 0);
+   evas_map_point_image_uv_set(m, 2, img_w, img_h);
+   evas_map_point_image_uv_set(m, 3, 0, img_h);
+   evas_map_util_3d_rotate(m, ad->frame * 6, ad->frame * 6, ad->frame * 6,
+                           x + (w / 3), y + 10, 0);
+   if (ad->apply_lighting)
+     evas_map_util_3d_lighting(m, win_w / 2, win_h / 2, -100,
+                               255, 255, 255, 0, 0, 0);
+   evas_object_map_set(o, m);
+   evas_object_map_enable_set(o, EINA_TRUE);
+
+   o = evas_object_name_find(ad->canvas, "obj3");
+   evas_object_geometry_get(o, &x, &y, &w, &h);
+   evas_object_image_size_get(o, &img_w, &img_h);
+
+   evas_map_util_points_populate_from_geometry(m, x, y + (h / 2), w, h, -20);
+   evas_map_point_image_uv_set(m, 0, 0, 0);
+   evas_map_point_image_uv_set(m, 1, img_w, 0);
+   evas_map_point_image_uv_set(m, 2, img_w, img_h);
+   evas_map_point_image_uv_set(m, 3, 0, img_h);
+   evas_map_util_3d_rotate(m, 20, ad->frame * 6, 0,
+                           x + (w / 2), y + (w / 2), w / 2);
+
+   if (ad->apply_perspective)
+     evas_map_util_3d_perspective(m, x + (w / 2), y + (h / 2), 0, 256);
+   if (ad->apply_lighting)
+     {
+        Evas_Coord mx, my;
+        evas_pointer_canvas_xy_get(ad->canvas, &mx, &my);
+        evas_map_util_3d_lighting(m, mx, my, -256,
+                                  255, 255, 255, 0, 0, 0);
+     }
+   if (ad->backface_culling)
+     {
+        if (evas_map_util_clockwise_get(m))
+          evas_object_show(o);
+        else
+          evas_object_hide(o);
+     }
+   else
+     evas_object_show(o);
+   evas_object_map_set(o, m);
+   evas_object_map_enable_set(o, EINA_TRUE);
+
+   evas_map_free(m);
+
+   o = evas_object_name_find(ad->canvas, "obj4");
+   evas_object_geometry_get(o, &x, &y, &w, &h);
+   evas_object_image_size_get(evas_object_image_source_get(o), &img_w, &img_h);
+
+   m = evas_map_new(4);
+   evas_map_point_coord_set(m, 0, x, y + h, 0);
+   evas_map_point_coord_set(m, 1, x + w, y + h, 0);
+   evas_map_point_coord_set(m, 2, win_w - 10, win_h - 30, 0);
+   evas_map_point_coord_set(m, 3, (win_w / 2) + 10, win_h - 30, 0);
+   evas_map_point_image_uv_set(m, 0, 0, img_h);
+   evas_map_point_image_uv_set(m, 1, img_w, img_h);
+   evas_map_point_image_uv_set(m, 2, img_w, 2 * (img_h / 3));
+   evas_map_point_image_uv_set(m, 3, 0, 2 * (img_h / 3));
+   evas_map_point_color_set(m, 0, 200, 200, 200, 150);
+   evas_map_point_color_set(m, 1, 200, 200, 200, 150);
+   evas_map_point_color_set(m, 2, 0, 0, 0, 0);
+   evas_map_point_color_set(m, 3, 0, 0, 0, 0);
+   evas_object_map_set(o, m);
+   evas_object_map_enable_set(o, EINA_TRUE);
+
+   evas_map_free(m);
+
+   ad->frame = (ad->frame + 1) % 60;
+
+   return EINA_TRUE;
+}
+
+static void
+_on_keydown(void *data, Evas *e, Evas_Object *o, void *event)
+{
+   App_Data *ad = data;
+   Evas_Event_Key_Down *ev = event;
+   const Evas_Modifier *mods;
+
+   mods = evas_key_modifier_get(ad->canvas);
+   switch (ev->keyname[0])
+     {
+      case 'a':
+         ad->alpha = !ad->alpha;
+         break;
+      case 's':
+         ad->smooth = !ad->smooth;
+         break;
+      case 'c':
+         ad->colors_index = (ad->colors_index + 1) % 6;
+         break;
+      case 'b':
+         ad->backface_culling = !ad->backface_culling;
+         break;
+      case 'p':
+         ad->apply_perspective = !ad->apply_perspective;
+         break;
+      case 'l':
+         ad->apply_lighting = !ad->apply_lighting;
+         break;
+      case 'h':
+         puts(help_string);
+         break;
+      default:
+         break;
+     }
+}
+
+static void
+_objs_fit(Evas *e)
+{
+   Evas_Object *o;
+   int w, h;
+
+   evas_output_size_get(e, &w, &h);
+   w /= 2;
+   h /= 2;
+
+   o = evas_object_name_find(e, "obj1");
+   evas_object_move(o, w / 4, h / 4);
+   evas_object_resize(o, w / 2, h / 2);
+
+   o = evas_object_name_find(e, "obj2");
+   evas_object_move(o, 5 * w / 4, h / 4);
+   evas_object_resize(o, w / 2, h / 2);
+
+   o = evas_object_name_find(e, "obj3");
+   evas_object_move(o, w / 4, 5 * h / 4);
+   evas_object_resize(o, w / 2, h / 2);
+
+   o = evas_object_name_find(e, "obj4_source");
+   evas_object_move(o, 5 * w / 4, 5 * h / 4);
+   evas_object_resize(o, w / 2, h / 2);
+
+   o = evas_object_name_find(e, "obj4");
+   evas_object_move(o, 5 * w / 4, 5 * h / 4);
+   evas_object_resize(o, w / 2, h / 2);
+}
+
+static void
+_on_resize(void *data __UNUSED__, Evas *e, Evas_Object *o __UNUSED__, void *event __UNUSED__)
+{
+   _objs_fit(e);
+}
+
+static void
+_on_free(void *data __UNUSED__, Evas *e __UNUSED__, Evas_Object *o __UNUSED__, void *event __UNUSED__)
+{
+   ecore_main_loop_quit();
+}
+
+int
+main(void)
+{
+   Evas_Object *bg, *o, *osrc;
+   static App_Data d = {
+        .ee = NULL,
+        .canvas = NULL,
+        .colors = {
+             { 255, 255, 255, 255 },
+             { 128, 128, 0, 128 },
+             { 255, 0, 0, 255 },
+             { 64, 128, 255, 255 },
+             { 11, 23, 58, 132 },
+             { 0, 0, 0, 255 }
+        },
+        .colors_index = 0,
+        .frame = 0,
+        .alpha = EINA_FALSE,
+        .smooth = EINA_FALSE,
+        .backface_culling = EINA_FALSE,
+        .apply_perspective = EINA_TRUE,
+        .apply_lighting = EINA_TRUE
+   };
+
+   if (!ecore_evas_init())
+     return EXIT_FAILURE;
+
+   d.ee = ecore_evas_new(NULL, 0, 0, WIDTH, HEIGHT, NULL);
+   if (!d.ee)
+     goto error;
+
+   d.canvas = ecore_evas_get(d.ee);
+
+   bg = evas_object_image_filled_add(d.canvas);
+   evas_object_image_file_set(bg, "cube1.png", NULL);
+   ecore_evas_object_associate(d.ee, bg, 0);
+   evas_object_focus_set(bg, EINA_TRUE);
+   evas_object_move(bg, 0, 0);
+   evas_object_resize(bg, WIDTH, HEIGHT);
+   evas_object_show(bg);
+
+   o = evas_object_rectangle_add(d.canvas);
+   evas_object_name_set(o, "obj1");
+   evas_object_color_set(o, 128, 0, 200, 200);
+   evas_object_show(o);
+
+   o = evas_object_image_filled_add(d.canvas);
+   evas_object_name_set(o, "obj2");
+   evas_object_image_file_set(o, "enlightenment.png", NULL);
+   evas_object_show(o);
+
+   o = evas_object_image_filled_add(d.canvas);
+   evas_object_name_set(o, "obj3");
+   evas_object_image_file_set(o, "enlightenment.png", NULL);
+   evas_object_show(o);
+
+   osrc = evas_object_image_filled_add(d.canvas);
+   evas_object_image_file_set(osrc, "im1.png", NULL);
+   evas_object_name_set(osrc, "obj4_source");
+   evas_object_show(osrc);
+
+   o = evas_object_image_filled_add(d.canvas);
+   evas_object_image_source_set(o, osrc);
+   evas_object_name_set(o, "obj4");
+   evas_object_show(o);
+
+   _objs_fit(d.canvas);
+
+   evas_object_event_callback_add(bg, EVAS_CALLBACK_KEY_DOWN, _on_keydown, &d);
+   evas_object_event_callback_add(bg, EVAS_CALLBACK_RESIZE, _on_resize, NULL);
+   evas_object_event_callback_add(bg, EVAS_CALLBACK_FREE, _on_free, NULL);
+
+   ecore_animator_add(_anim_cb, &d);
+
+   ecore_main_loop_begin();
+
+   ecore_evas_shutdown();
+   return 0;
+
+error:
+   fprintf(stderr, "you got to have at least one evas engine built and linked"
+                   " up to ecore-evas for this example to run properly.\n");
+panic:
+   ecore_evas_shutdown();
+   return -1;
+}
diff --git a/src/examples/im1.png b/src/examples/im1.png
new file mode 100644 (file)
index 0000000..aa37869
Binary files /dev/null and b/src/examples/im1.png differ
index 1c54e07..f051819 100644 (file)
@@ -3820,19 +3820,24 @@ EAPI Eina_Bool         evas_object_propagate_events_get   (const Evas_Object *ob
  *       care. The impact on performance depends on engine in
  *       use. Software is quite optimized, but not as fast as OpenGL.
  *
+ * Examples:
+ * @li @ref Example_Evas_Map_Overview
+ *
  * @ingroup Evas_Object_Group
+ *
+ * @{
  */
 
 /**
  * Enable or disable the map that is set.
  *
- * This enables the map that is set or disables it. On enable, the object
- * geometry will be saved, and the new geometry will change (position and
- * size) to reflect the map geometry set. If none is set yet, this may be
- * an undefined geometry, unless you have already set the map with
- * evas_object_map_set(). It is suggested you first set a map with
- * evas_object_map_set() with valid useful coordinates then enable and
- * disable the map with evas_object_map_enable_set() as needed.
+ * Enable or disable the use of map for the object @p obj.
+ * On enable, the object geometry will be saved, and the new geometry will
+ * change (position and size) to reflect the map geometry set.
+ *
+ * If the object doesn't have a map set (with evas_object_map_set()), the
+ * initial geometry will be undefined. It is adviced to always set a map
+ * to the object first, and then call this function to enable its use.
  *
  * @param obj object to enable the map on
  * @param enabled enabled state
@@ -3867,10 +3872,10 @@ EAPI void              evas_object_map_source_set        (Evas_Object *obj, Evas
 /**
  * Get the map source object
  *
- * See evas_object_map_source_set()
- *
  * @param obj object to set the map source of
  * @return the object set as the source
+ *
+ * @see evas_object_map_source_set()
  */
 EAPI Evas_Object      *evas_object_map_source_get        (const Evas_Object *obj);
 
@@ -4044,7 +4049,7 @@ EAPI void              evas_map_util_rotate                          (Evas_Map *
  *
  * Like evas_map_util_rotate(), this zooms the points of the map from a center
  * point. That center is defined by @p cx and @p cy. The @p zoomx and @p zoomy
- * parameters specific how much to zoom in the X and Y direction respectively.
+ * parameters specify how much to zoom in the X and Y direction respectively.
  * A value of 1.0 means "don't zoom". 2.0 means "dobule the size". 0.5 is
  * "half the size" etc. All coordinates are canvas global coordinates.
  *
@@ -4067,7 +4072,7 @@ EAPI void              evas_map_util_zoom                            (Evas_Map *
  * around the X, Y and Z axes. The Z axis points "into" the screen with low
  * values at the screen and higher values further away. The X axis runs from
  * left to right on the screen and the Y axis from top to bottom. Like with
- * evas_map_util_rotate(0 you provide a center point to rotate around (in 3D).
+ * evas_map_util_rotate() you provide a center point to rotate around (in 3D).
  *
  * @param m map to change.
  * @param dx amount of degrees from 0.0 to 360.0 to rotate arount X axis.
@@ -4148,7 +4153,7 @@ EAPI Eina_Bool         evas_map_util_clockwise_get                   (Evas_Map *
  * number for @p count will work). That is empty and ready to be modified
  * with evas_map calls.
  *
- * @param count number of points in the map. *
+ * @param count number of points in the map.
  * @return a newly allocated map or @c NULL on errors.
  *
  * @see evas_map_free()
@@ -4188,7 +4193,8 @@ EAPI Eina_Bool         evas_map_smooth_get               (const Evas_Map *m);
  *
  * This sets alpha flag for map rendering. If the object is a type that has
  * its own alpha settings, then this will take precedence. Only image objects
- * have this currently. Fits stops alpha blending of the map area, and is
+ * have this currently.
+ * Setting this off stops alpha blending of the map area, and is
  * useful if you know the object and/or all sub-objects is 100% solid.
  *
  * @param m map to modify. Must not be NULL.
@@ -4238,7 +4244,7 @@ EAPI int               evas_map_count_get               (const Evas_Map *m) EINA
 /**
  * Change the map point's coordinate.
  *
- * This sets the fixen point's coordinate in the map. Note that points
+ * This sets the fixed point's coordinate in the map. Note that points
  * describe the outline of a quadrangle and are ordered either clockwise
  * or anit-clock-wise. It is suggested to keep your quadrangles concave and
  * non-complex, though these polygon modes may work, they may not render
@@ -4351,6 +4357,9 @@ EAPI void              evas_map_point_color_set          (Evas_Map *m, int idx,
  * @see evas_object_map_set()
  */
 EAPI void              evas_map_point_color_get          (const Evas_Map *m, int idx, int *r, int *g, int *b, int *a);
+/**
+ * @}
+ */
 
 /**
  * @defgroup Evas_Object_Group_Size_Hints Size Hints