

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\textquotesingle{}ll go through an overview of the map A\+PI and some of the things that can be done with it.

The full code can be found \mbox{\hyperlink{evas-map-utils_8c-example}{here}}.

To show how some functions work, this example listens to keys pressed to toggle several options. 
\begin{DoxyCodeInclude}
\textcolor{keyword}{typedef} \textcolor{keyword}{struct}
\{
   Ecore\_Evas *ee;
   \mbox{\hyperlink{group__Evas__Canvas_ga5ff87cc4ce6bc43e3b640a6d37f73043}{Evas}}       *canvas;
   \textcolor{keyword}{struct }\{
        \textcolor{keywordtype}{int} r, g, b, a;
   \} colors[6];
   \textcolor{keywordtype}{int} colors\_index;
   \textcolor{keywordtype}{int} frame;
   \mbox{\hyperlink{group__Eina__Types__Group_ga3fe0caf72e93b1bab1ca8ee3ccf3f226}{Eina\_Bool}}   alpha : 1;
   \mbox{\hyperlink{group__Eina__Types__Group_ga3fe0caf72e93b1bab1ca8ee3ccf3f226}{Eina\_Bool}}   smooth : 1;
   \mbox{\hyperlink{group__Eina__Types__Group_ga3fe0caf72e93b1bab1ca8ee3ccf3f226}{Eina\_Bool}}   backface\_culling : 1;
   \mbox{\hyperlink{group__Eina__Types__Group_ga3fe0caf72e93b1bab1ca8ee3ccf3f226}{Eina\_Bool}}   apply\_perspective : 1;
   \mbox{\hyperlink{group__Eina__Types__Group_ga3fe0caf72e93b1bab1ca8ee3ccf3f226}{Eina\_Bool}}   apply\_lighting : 1;
\} App\_Data;

\textcolor{keyword}{static} \textcolor{keyword}{const} \textcolor{keywordtype}{char} *img1\_path = PACKAGE\_EXAMPLES\_DIR EVAS\_IMAGE\_FOLDER \textcolor{stringliteral}{"/cube1.png"};

\end{DoxyCodeInclude}


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. 
\begin{DoxyCodeInclude}
\textcolor{keyword}{static} \mbox{\hyperlink{group__Eina__Types__Group_ga3fe0caf72e93b1bab1ca8ee3ccf3f226}{Eina\_Bool}}
\_anim\_cb(\textcolor{keywordtype}{void} *data)
\{
   App\_Data *ad = data;
   Evas\_Map *m;
   \mbox{\hyperlink{group__Evas__Object__Group_ga9e19e6dd1f517a0ba437c0114d3e7c97}{Evas\_Object}} *o;
   \textcolor{keywordtype}{int} r, g, b, a;
   \textcolor{keywordtype}{int} win\_w, win\_h, img\_w, img\_h;
   \mbox{\hyperlink{Evas__Common_8h_a2453e92182bad3b0e0d84e5aff433b07}{Evas\_Coord}} x, y, w, h;

   \mbox{\hyperlink{group__Evas__Canvas_gadd22b11c786b3b00448ef58550aa55c4}{evas\_output\_size\_get}}(ad->canvas, &win\_w, &win\_h);

\end{DoxyCodeInclude}


Let\textquotesingle{}s first create a map and set some of our options to it. Only four points maps are supported, so we\textquotesingle{}ll stick to that magic number. We can set a color for each vertex or apply one for all of them at once 
\begin{DoxyCodeInclude}

   m = \mbox{\hyperlink{group__Evas__Object__Group__Map_ga68a1a6d2dfdd5c9d88a9200eb78cca4e}{evas\_map\_new}}(4);
   \mbox{\hyperlink{group__Evas__Object__Group__Map_gab8575043030c84cd457419e33775d884}{evas\_map\_smooth\_set}}(m, ad->smooth);
   \mbox{\hyperlink{group__Evas__Object__Group__Map_gac40eaffef33cb5a9afe362c9e7759cae}{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;
   \mbox{\hyperlink{group__Evas__Object__Group__Map_gafad0e4df4fcd8258fff8c1c1b41c6671}{evas\_map\_util\_points\_color\_set}}(m, r, g, b, a);

\end{DoxyCodeInclude}


For the first object, we\textquotesingle{}ll have a plain rectangle. At its creation, this rectangle was set to be semi-\/transparent, but whether its own alpha is used will be defined by the map\textquotesingle{}s alpha setting. If the map\textquotesingle{}s alpha is disabled, then the object will be completely opaque. The map\textquotesingle{}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. 
\begin{DoxyCodeInclude}

   o = \mbox{\hyperlink{group__Evas__Canvas_gada08589c83deabc061fa3e6740ebae35}{evas\_object\_name\_find}}(ad->canvas, \textcolor{stringliteral}{"obj1"});
   \mbox{\hyperlink{group__Evas__Object__Group__Basic_ga6f52fab1a96dc58c85ee481d84bac871}{evas\_object\_geometry\_get}}(o, &x, &y, &w, &h);

   \mbox{\hyperlink{group__Evas__Object__Group__Map_gaa21f5c7338fbb125b8e50890b3fefb91}{evas\_map\_util\_points\_populate\_from\_object}}(m, o);
   \mbox{\hyperlink{group__Evas__Object__Group__Map_ga0db530bdf4f619b3c9c4c74c3e87ccac}{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, \mbox{\hyperlink{group__Eina__Types__Group_ga05c12dacc8b4058994df842b41be85fc}{EINA\_TRUE}});

\end{DoxyCodeInclude}


The second object is an image. Here we don\textquotesingle{}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\textquotesingle{}s just an utility function that takes the coordinates set for each point of the map and transforms it accordingly. 
\begin{DoxyCodeInclude}

   o = \mbox{\hyperlink{group__Evas__Canvas_gada08589c83deabc061fa3e6740ebae35}{evas\_object\_name\_find}}(ad->canvas, \textcolor{stringliteral}{"obj2"});
   \mbox{\hyperlink{group__Evas__Object__Group__Basic_ga6f52fab1a96dc58c85ee481d84bac871}{evas\_object\_geometry\_get}}(o, &x, &y, &w, &h);
   evas\_object\_image\_size\_get(o, &img\_w, &img\_h);

   \mbox{\hyperlink{group__Evas__Object__Group__Map_gaea5fa874b56c188ed001f38ad1d05d7d}{evas\_map\_util\_points\_populate\_from\_object\_full}}(m, o, 100);

\end{DoxyCodeInclude}


This time the object is a bit farther into the screen, by using a {\ttfamily 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 \mbox{\hyperlink{group__Evas__Object__Group__Map_ga2f1b4d78f055c1752ab254a7ebce13b3}{evas\+\_\+map\+\_\+point\+\_\+image\+\_\+uv\+\_\+set()}} to tell the map what coordinate within the image corresponds to each point of the map. 
\begin{DoxyCodeInclude}
   \mbox{\hyperlink{group__Evas__Object__Group__Map_ga2f1b4d78f055c1752ab254a7ebce13b3}{evas\_map\_point\_image\_uv\_set}}(m, 0, 0, 0);
   \mbox{\hyperlink{group__Evas__Object__Group__Map_ga2f1b4d78f055c1752ab254a7ebce13b3}{evas\_map\_point\_image\_uv\_set}}(m, 1, img\_w, 0);
   \mbox{\hyperlink{group__Evas__Object__Group__Map_ga2f1b4d78f055c1752ab254a7ebce13b3}{evas\_map\_point\_image\_uv\_set}}(m, 2, img\_w, img\_h);
   \mbox{\hyperlink{group__Evas__Object__Group__Map_ga2f1b4d78f055c1752ab254a7ebce13b3}{evas\_map\_point\_image\_uv\_set}}(m, 3, 0, img\_h);

\end{DoxyCodeInclude}


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. 
\begin{DoxyCodeInclude}
   \mbox{\hyperlink{group__Evas__Object__Group__Map_ga8ec45ba806d347d313556b0d5c5330c8}{evas\_map\_util\_3d\_rotate}}(m, ad->frame * 6, ad->frame * 6, ad->frame * 6,
                           x + (w / 3), y + 10, 0);
   \textcolor{keywordflow}{if} (ad->apply\_lighting)
     \mbox{\hyperlink{group__Evas__Object__Group__Map_gaffb11ebe4dfd914f97cdde7e9f713c97}{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, \mbox{\hyperlink{group__Eina__Types__Group_ga05c12dacc8b4058994df842b41be85fc}{EINA\_TRUE}});

\end{DoxyCodeInclude}


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\textquotesingle{}s possible to toggle backface culling, so that the object is hidden whenever we are not seeing its front face. 
\begin{DoxyCodeInclude}

   o = \mbox{\hyperlink{group__Evas__Canvas_gada08589c83deabc061fa3e6740ebae35}{evas\_object\_name\_find}}(ad->canvas, \textcolor{stringliteral}{"obj3"});
   \mbox{\hyperlink{group__Evas__Object__Group__Basic_ga6f52fab1a96dc58c85ee481d84bac871}{evas\_object\_geometry\_get}}(o, &x, &y, &w, &h);
   evas\_object\_image\_size\_get(o, &img\_w, &img\_h);

   \mbox{\hyperlink{group__Evas__Object__Group__Map_ga535ba6d2e0d57f0854c201507a74826e}{evas\_map\_util\_points\_populate\_from\_geometry}}(m, x, y + (h / 2)
      , w, h, -20);
   \mbox{\hyperlink{group__Evas__Object__Group__Map_ga2f1b4d78f055c1752ab254a7ebce13b3}{evas\_map\_point\_image\_uv\_set}}(m, 0, 0, 0);
   \mbox{\hyperlink{group__Evas__Object__Group__Map_ga2f1b4d78f055c1752ab254a7ebce13b3}{evas\_map\_point\_image\_uv\_set}}(m, 1, img\_w, 0);
   \mbox{\hyperlink{group__Evas__Object__Group__Map_ga2f1b4d78f055c1752ab254a7ebce13b3}{evas\_map\_point\_image\_uv\_set}}(m, 2, img\_w, img\_h);
   \mbox{\hyperlink{group__Evas__Object__Group__Map_ga2f1b4d78f055c1752ab254a7ebce13b3}{evas\_map\_point\_image\_uv\_set}}(m, 3, 0, img\_h);
   \mbox{\hyperlink{group__Evas__Object__Group__Map_ga8ec45ba806d347d313556b0d5c5330c8}{evas\_map\_util\_3d\_rotate}}(m, 20, ad->frame * 6, 0,
                           x + (w / 2), y + (w / 2), w / 2);

   \textcolor{keywordflow}{if} (ad->apply\_perspective)
     \mbox{\hyperlink{group__Evas__Object__Group__Map_ga2d28d92f2189d8ec098c6dd29da6cdca}{evas\_map\_util\_3d\_perspective}}(m, x + (w / 2), y + (h / 2), 0, 256);
   \textcolor{keywordflow}{if} (ad->apply\_lighting)
     \{
        \mbox{\hyperlink{Evas__Common_8h_a2453e92182bad3b0e0d84e5aff433b07}{Evas\_Coord}} mx, my;
        \mbox{\hyperlink{group__Evas__Canvas_gaaf560a4dc5371742c6177c6f77c9e444}{evas\_pointer\_canvas\_xy\_get}}(ad->canvas, &mx, &my);
        \mbox{\hyperlink{group__Evas__Object__Group__Map_gaffb11ebe4dfd914f97cdde7e9f713c97}{evas\_map\_util\_3d\_lighting}}(m, mx, my, -256,
                                  255, 255, 255, 0, 0, 0);
     \}
   \textcolor{keywordflow}{if} (ad->backface\_culling)
     \{
        \textcolor{keywordflow}{if} (\mbox{\hyperlink{group__Evas__Object__Group__Map_gaf9b0303984e52012014bdade3e8f2ad0}{evas\_map\_util\_clockwise\_get}}(m))
          \mbox{\hyperlink{group__Evas__Object__Group__Basic_ga9cbc13661584e49fb9d9cdab514a1eeb}{evas\_object\_show}}(o);
        \textcolor{keywordflow}{else}
          \mbox{\hyperlink{group__Evas__Object__Group__Basic_gacc307a0d7bfc9df151fd9ec75808c587}{evas\_object\_hide}}(o);
     \}
   \textcolor{keywordflow}{else}
     \mbox{\hyperlink{group__Evas__Object__Group__Basic_ga9cbc13661584e49fb9d9cdab514a1eeb}{evas\_object\_show}}(o);
   evas\_object\_map\_set(o, m);
   evas\_object\_map\_enable\_set(o, \mbox{\hyperlink{group__Eina__Types__Group_ga05c12dacc8b4058994df842b41be85fc}{EINA\_TRUE}});

\end{DoxyCodeInclude}


And we free this map, since since we messed too much with it and for the last object we want something cleaner. 
\begin{DoxyCodeInclude}

   \mbox{\hyperlink{group__Evas__Object__Group__Map_gab3e18d6086e352b121a57c130041bb24}{evas\_map\_free}}(m);

\end{DoxyCodeInclude}


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\textquotesingle{}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. 
\begin{DoxyCodeInclude}

   o = \mbox{\hyperlink{group__Evas__Canvas_gada08589c83deabc061fa3e6740ebae35}{evas\_object\_name\_find}}(ad->canvas, \textcolor{stringliteral}{"obj4"});
   \mbox{\hyperlink{group__Evas__Object__Group__Basic_ga6f52fab1a96dc58c85ee481d84bac871}{evas\_object\_geometry\_get}}(o, &x, &y, &w, &h);
   evas\_object\_image\_size\_get(o, &img\_w, &img\_h);

\end{DoxyCodeInclude}


For this we\textquotesingle{}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. 
\begin{DoxyCodeInclude}

   m = \mbox{\hyperlink{group__Evas__Object__Group__Map_ga68a1a6d2dfdd5c9d88a9200eb78cca4e}{evas\_map\_new}}(4);
   \mbox{\hyperlink{group__Evas__Object__Group__Map_ga46ab921df9fe617d6c241056784217b7}{evas\_map\_point\_coord\_set}}(m, 0, x, y + h, 0);
   \mbox{\hyperlink{group__Evas__Object__Group__Map_ga46ab921df9fe617d6c241056784217b7}{evas\_map\_point\_coord\_set}}(m, 1, x + w, y + h, 0);
   \mbox{\hyperlink{group__Evas__Object__Group__Map_ga46ab921df9fe617d6c241056784217b7}{evas\_map\_point\_coord\_set}}(m, 2, win\_w - 10, win\_h - 30, 0);
   \mbox{\hyperlink{group__Evas__Object__Group__Map_ga46ab921df9fe617d6c241056784217b7}{evas\_map\_point\_coord\_set}}(m, 3, (win\_w / 2) + 10, win\_h - 30, 0);

\end{DoxyCodeInclude}


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\textquotesingle{}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. 
\begin{DoxyCodeInclude}
   \mbox{\hyperlink{group__Evas__Object__Group__Map_ga2f1b4d78f055c1752ab254a7ebce13b3}{evas\_map\_point\_image\_uv\_set}}(m, 0, 0, img\_h);
   \mbox{\hyperlink{group__Evas__Object__Group__Map_ga2f1b4d78f055c1752ab254a7ebce13b3}{evas\_map\_point\_image\_uv\_set}}(m, 1, img\_w, img\_h);
   \mbox{\hyperlink{group__Evas__Object__Group__Map_ga2f1b4d78f055c1752ab254a7ebce13b3}{evas\_map\_point\_image\_uv\_set}}(m, 2, img\_w, 2 * (img\_h / 3));
   \mbox{\hyperlink{group__Evas__Object__Group__Map_ga2f1b4d78f055c1752ab254a7ebce13b3}{evas\_map\_point\_image\_uv\_set}}(m, 3, 0, 2 * (img\_h / 3));

\end{DoxyCodeInclude}


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\textquotesingle{}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. 
\begin{DoxyCodeInclude}
   \mbox{\hyperlink{group__Evas__Object__Group__Map_ga2ba9f77377f7cc1a79deecb938c8289c}{evas\_map\_point\_color\_set}}(m, 0, 200, 200, 200, 150);
   \mbox{\hyperlink{group__Evas__Object__Group__Map_ga2ba9f77377f7cc1a79deecb938c8289c}{evas\_map\_point\_color\_set}}(m, 1, 200, 200, 200, 150);
   \mbox{\hyperlink{group__Evas__Object__Group__Map_ga2ba9f77377f7cc1a79deecb938c8289c}{evas\_map\_point\_color\_set}}(m, 2, 0, 0, 0, 0);
   \mbox{\hyperlink{group__Evas__Object__Group__Map_ga2ba9f77377f7cc1a79deecb938c8289c}{evas\_map\_point\_color\_set}}(m, 3, 0, 0, 0, 0);
   evas\_object\_map\_set(o, m);
   evas\_object\_map\_enable\_set(o, \mbox{\hyperlink{group__Eina__Types__Group_ga05c12dacc8b4058994df842b41be85fc}{EINA\_TRUE}});

\end{DoxyCodeInclude}


Close up by freeing the map and do some other things needed to keep stuff moving in our animations and we are done. 
\begin{DoxyCodeInclude}

   \mbox{\hyperlink{group__Evas__Object__Group__Map_gab3e18d6086e352b121a57c130041bb24}{evas\_map\_free}}(m);

   ad->frame = (ad->frame + 1) % 60;

   \textcolor{keywordflow}{return} \mbox{\hyperlink{group__Eina__Types__Group_ga05c12dacc8b4058994df842b41be85fc}{EINA\_TRUE}};
\}

\end{DoxyCodeInclude}


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 \mbox{\hyperlink{evas-map-utils_8c-example}{here}} however to see how everything fits together. 