The canvas will here use the buffer engine.


\begin{DoxyCodeInclude}

\textcolor{preprocessor}{#include <Evas.h>}
\textcolor{preprocessor}{#include <Evas\_Engine\_Buffer.h>}
\textcolor{preprocessor}{#include <stdio.h>}
\textcolor{preprocessor}{#include <errno.h>}

\textcolor{preprocessor}{#define WIDTH (320)}
\textcolor{preprocessor}{#define HEIGHT (240)}

\textcolor{keyword}{static} \mbox{\hyperlink{group__Evas__Canvas_ga5ff87cc4ce6bc43e3b640a6d37f73043}{Evas}} *create\_canvas(\textcolor{keywordtype}{int} width, \textcolor{keywordtype}{int} height);
\textcolor{keyword}{static} \textcolor{keywordtype}{void} destroy\_canvas(\mbox{\hyperlink{group__Evas__Canvas_ga5ff87cc4ce6bc43e3b640a6d37f73043}{Evas}} *canvas);
\textcolor{keyword}{static} \textcolor{keywordtype}{void} draw\_scene(\mbox{\hyperlink{group__Evas__Canvas_ga5ff87cc4ce6bc43e3b640a6d37f73043}{Evas}} *canvas);
\textcolor{keyword}{static} \textcolor{keywordtype}{void} save\_scene(\mbox{\hyperlink{group__Evas__Canvas_ga5ff87cc4ce6bc43e3b640a6d37f73043}{Evas}} *canvas, \textcolor{keyword}{const} \textcolor{keywordtype}{char} *dest);

\textcolor{keywordtype}{int} main(\textcolor{keywordtype}{void})
\{
   \mbox{\hyperlink{group__Evas__Canvas_ga5ff87cc4ce6bc43e3b640a6d37f73043}{Evas}} *canvas;
   \mbox{\hyperlink{group__Evas__Object__Group_ga9e19e6dd1f517a0ba437c0114d3e7c97}{Evas\_Object}} *bg, *r1, *r2, *r3;

   \mbox{\hyperlink{group__Evas__Main__Group_ga65b3f060b6dd9e488afd0b8cbe101869}{evas\_init}}();

   \textcolor{comment}{/* After turning Evas on, we create an Evas canvas to work in.}
\textcolor{comment}{    * Canvases are graphical workspaces used for placing and organizing}
\textcolor{comment}{    * graphical objects.  Normally we'd be using Ecore-Evas to create}
\textcolor{comment}{    * the canvas, but for this example we'll hide the details in a}
\textcolor{comment}{    * separate routine for convenience.}
\textcolor{comment}{    */}
   canvas = create\_canvas(WIDTH, HEIGHT);
   \textcolor{keywordflow}{if} (!canvas)
     \textcolor{keywordflow}{return} -1;

   \textcolor{comment}{/* Next set the background to solid white.  This is typically done by}
\textcolor{comment}{    * creating a rectangle sized to the canvas, placed at the canvas}
\textcolor{comment}{    * origin.}
\textcolor{comment}{    *}
\textcolor{comment}{    * Note that if the canvas were to change size, our background}
\textcolor{comment}{    * rectangle will not automatically resize itself; we'd need to do}
\textcolor{comment}{    * that manually with another evas\_object\_resize() call.  In a real}
\textcolor{comment}{    * application using Ecore-Evas, functionality in Ecore will take}
\textcolor{comment}{    * care of resizing things.  For this example, we'll just keep the}
\textcolor{comment}{    * canvas dimensions fixed to avoid the problem.}
\textcolor{comment}{    */}
   bg = \mbox{\hyperlink{group__Evas__Object__Rectangle_ga4d80fc32ad1cac28428cebd65d746751}{evas\_object\_rectangle\_add}}(canvas);
   \mbox{\hyperlink{group__Evas__Object__Group__Basic_gae34bdcfd7f5100151f6ea8ef4a392949}{evas\_object\_color\_set}}(bg, 255, 255, 255, 255); \textcolor{comment}{// white bg, no transparency}
   evas\_object\_move(bg, 0, 0);                    \textcolor{comment}{// at origin}
   evas\_object\_resize(bg, WIDTH, HEIGHT);         \textcolor{comment}{// covers full canvas}
   \mbox{\hyperlink{group__Evas__Object__Group__Basic_ga9cbc13661584e49fb9d9cdab514a1eeb}{evas\_object\_show}}(bg);

   puts(\textcolor{stringliteral}{"initial scene, with just background:"});
   draw\_scene(canvas);

   \textcolor{comment}{/* To make the scene interesting let's add a few more rectangles of}
\textcolor{comment}{    * various sizes and colors, starting with a big red one.}
\textcolor{comment}{    *}
\textcolor{comment}{    * By default all Evas objects are created in a 'hidden' state,}
\textcolor{comment}{    * meaning they are not visible, won't be checked for changes during}
\textcolor{comment}{    * canvas rendering, and won't receive input events.  Thus, like we}
\textcolor{comment}{    * did for the background object we must call evas\_object\_show() to}
\textcolor{comment}{    * make our graphics objects usable.}
\textcolor{comment}{    */}
   r1 = \mbox{\hyperlink{group__Evas__Object__Rectangle_ga4d80fc32ad1cac28428cebd65d746751}{evas\_object\_rectangle\_add}}(canvas);
   \mbox{\hyperlink{group__Evas__Object__Group__Basic_gae34bdcfd7f5100151f6ea8ef4a392949}{evas\_object\_color\_set}}(r1, 255, 0, 0, 255); \textcolor{comment}{// 100% opaque red}
   evas\_object\_move(r1, 10, 10);
   evas\_object\_resize(r1, 100, 100);
   \mbox{\hyperlink{group__Evas__Object__Group__Basic_ga9cbc13661584e49fb9d9cdab514a1eeb}{evas\_object\_show}}(r1);

   \textcolor{comment}{/* Let's add a partly transparent rectangle on top of the red one.}
\textcolor{comment}{    *}
\textcolor{comment}{    * Graphics objects are treated as a stack in the canvas for drawing}
\textcolor{comment}{    * purposes, so subsequent objects are drawn above the ones we've}
\textcolor{comment}{    * already added to the canvas.  This is important in objects that}
\textcolor{comment}{    * have partially transparent fill coloring since we'll see part of}
\textcolor{comment}{    * what's "behind" our object.}
\textcolor{comment}{    *}
\textcolor{comment}{    * In Evas, color values are pre-multiplied by their alpha.  This means}
\textcolor{comment}{    * that if we want a green rectangle that's half transparent, we'd have:}
\textcolor{comment}{    *}
\textcolor{comment}{    * non-premul: r=0, g=255, b=0    a=128 (50% alpha)}
\textcolor{comment}{    * premul:}
\textcolor{comment}{    *         r\_premul = r * a / 255 =      0 * 128 / 255 =      0}
\textcolor{comment}{    *         g\_premul = g * a / 255 =    255 * 128 / 255 =    128}
\textcolor{comment}{    *         b\_premul = b * a / 255 =      0 * 128 / 255 =      0}
\textcolor{comment}{    *}
\textcolor{comment}{    * Since we're placing our half transparent green rectangle on top of}
\textcolor{comment}{    * a red one, in the final output we will actually see a yellow square}
\textcolor{comment}{    * (since in RGBA color green + red = yellow).}
\textcolor{comment}{    */}
   r2 = \mbox{\hyperlink{group__Evas__Object__Rectangle_ga4d80fc32ad1cac28428cebd65d746751}{evas\_object\_rectangle\_add}}(canvas);
   \mbox{\hyperlink{group__Evas__Object__Group__Basic_gae34bdcfd7f5100151f6ea8ef4a392949}{evas\_object\_color\_set}}(r2, 0, 128, 0, 128); \textcolor{comment}{// 50% opaque green}
   evas\_object\_move(r2, 10, 10);
   evas\_object\_resize(r2, 50, 50);
   \mbox{\hyperlink{group__Evas__Object__Group__Basic_ga9cbc13661584e49fb9d9cdab514a1eeb}{evas\_object\_show}}(r2);

   \textcolor{comment}{/* Lastly, for comparison add a dark green rectangle with no}
\textcolor{comment}{    * transparency. */}
   r3 = \mbox{\hyperlink{group__Evas__Object__Rectangle_ga4d80fc32ad1cac28428cebd65d746751}{evas\_object\_rectangle\_add}}(canvas);
   \mbox{\hyperlink{group__Evas__Object__Group__Basic_gae34bdcfd7f5100151f6ea8ef4a392949}{evas\_object\_color\_set}}(r3, 0, 128, 0, 255); \textcolor{comment}{// 100% opaque dark green}
   evas\_object\_move(r3, 60, 60);
   evas\_object\_resize(r3, 50, 50);
   \mbox{\hyperlink{group__Evas__Object__Group__Basic_ga9cbc13661584e49fb9d9cdab514a1eeb}{evas\_object\_show}}(r3);

   puts(\textcolor{stringliteral}{"final scene (note updates):"});
   draw\_scene(canvas);

   \textcolor{comment}{/* In addition to displaying the canvas to the screen, let's also}
\textcolor{comment}{    * output the buffer to a graphics file, for comparison.  Evas}
\textcolor{comment}{    * supports a range of graphics file formats, but PPM is particularly}
\textcolor{comment}{    * trivial to write, so our save\_scene routine will output as PPM.}
\textcolor{comment}{    */}
   save\_scene(canvas, \textcolor{stringliteral}{"/tmp/evas-buffer-simple-render.ppm"});

   destroy\_canvas(canvas);

   \mbox{\hyperlink{group__Evas__Main__Group_ga95a8864f81d944a92bb012b77ffd1b09}{evas\_shutdown}}();

   \textcolor{keywordflow}{return} 0;
\}

\textcolor{comment}{/* Convenience routine to allocate and initialize the canvas.}
\textcolor{comment}{ * In a real application we'd be using ecore\_evas\_buffer\_new() instead.}
\textcolor{comment}{ */}
\textcolor{keyword}{static} \mbox{\hyperlink{group__Evas__Canvas_ga5ff87cc4ce6bc43e3b640a6d37f73043}{Evas}} *create\_canvas(\textcolor{keywordtype}{int} width, \textcolor{keywordtype}{int} height)
\{
   \mbox{\hyperlink{group__Evas__Canvas_ga5ff87cc4ce6bc43e3b640a6d37f73043}{Evas}} *canvas;
   Evas\_Engine\_Info\_Buffer *einfo;
   \textcolor{keywordtype}{int} method;
   \textcolor{keywordtype}{void} *pixels;

   \textcolor{comment}{/* Request a handle for the 'buffer' type of rendering engine. */}
   method = \mbox{\hyperlink{group__Evas__Output__Method_ga9f9871fdcc40ce1062d6565308020eb8}{evas\_render\_method\_lookup}}(\textcolor{stringliteral}{"buffer"});
   \textcolor{keywordflow}{if} (method <= 0)
     \{
        fputs(\textcolor{stringliteral}{"ERROR: evas was not compiled with 'buffer' engine!\(\backslash\)n"}, stderr);
        \textcolor{keywordflow}{return} NULL;
     \}

   \textcolor{comment}{/* Create a general canvas object.}
\textcolor{comment}{    * Note that we are responsible for freeing the canvas when we're done. */}
   canvas = \mbox{\hyperlink{group__Evas__Canvas_ga67e8eb17d2a676bfdfb8794fc5f72bc0}{evas\_new}}();
   \textcolor{keywordflow}{if} (!canvas)
     \{
        fputs(\textcolor{stringliteral}{"ERROR: could not instantiate new evas canvas.\(\backslash\)n"}, stderr);
        \textcolor{keywordflow}{return} NULL;
     \}

   \textcolor{comment}{/* Specify that the canvas will be rendering using the buffer engine method.}
\textcolor{comment}{    * We also size the canvas and viewport to the same width and height, with}
\textcolor{comment}{    * the viewport set to the origin of the canvas.}
\textcolor{comment}{    */}
   \mbox{\hyperlink{group__Evas__Canvas_ga15b85dc673baa6aa40f91f8bfcd3cbaa}{evas\_output\_method\_set}}(canvas, method);
   \mbox{\hyperlink{group__Evas__Canvas_gaf6478cb249ed09fa0fe961085773fe1e}{evas\_output\_size\_set}}(canvas, width, height);
   \mbox{\hyperlink{group__Evas__Canvas_ga6dcd13997f7825f03807dc0ec38dd38e}{evas\_output\_viewport\_set}}(canvas, 0, 0, width, height);

   \textcolor{comment}{/* Before we can use the engine, we *must* set its configuration}
\textcolor{comment}{    * parameters.  The available parameters are kept in a struct}
\textcolor{comment}{    * named Evas\_Engine\_Info which is internal to Evas.  Thus to set}
\textcolor{comment}{    * parameters we must first request the current info object from}
\textcolor{comment}{    * our canvas:}
\textcolor{comment}{    */}
   einfo = (Evas\_Engine\_Info\_Buffer *)\mbox{\hyperlink{group__Evas__Canvas_gaf396b44e1b97ec0d9dce49fcf9ad54b7}{evas\_engine\_info\_get}}(canvas);
   \textcolor{keywordflow}{if} (!einfo)
     \{
        fputs(\textcolor{stringliteral}{"ERROR: could not get evas engine info!\(\backslash\)n"}, stderr);
        \mbox{\hyperlink{group__Evas__Canvas_gaa0d5d3f1a1e1ffa3b14b09bb374215b4}{evas\_free}}(canvas);
        \textcolor{keywordflow}{return} NULL;
     \}

   \textcolor{comment}{/* Create the underlying data buffer that our canvas will use.  This}
\textcolor{comment}{    * is a simple array of ARGB32 pixels.  Each color component}
\textcolor{comment}{    * (including alpha) is one byte, resulting in 4 bytes per pixel (or}
\textcolor{comment}{    * 32 bits).  We can thus store each pixel in an integer data type,}
\textcolor{comment}{    * thus calculating our data buffer as W x H x sizeof(int) bytes in}
\textcolor{comment}{    * length.}
\textcolor{comment}{    */}
   pixels = malloc(width * height * \textcolor{keyword}{sizeof}(\textcolor{keywordtype}{int}));
   \textcolor{keywordflow}{if} (!pixels)
     \{
        fputs(\textcolor{stringliteral}{"ERROR: could not allocate canvas pixels!\(\backslash\)n"}, stderr);
        \mbox{\hyperlink{group__Evas__Canvas_gaa0d5d3f1a1e1ffa3b14b09bb374215b4}{evas\_free}}(canvas);
        \textcolor{keywordflow}{return} NULL;
     \}

   \textcolor{comment}{/* Next set the various configuration parameters.  We}
\textcolor{comment}{    * register the pixel buffer that the canvas will use,}
\textcolor{comment}{    * indicate the pixel format as ARGB32, and the size of}
\textcolor{comment}{    * each row of data. */}
   einfo->info.depth\_type = EVAS\_ENGINE\_BUFFER\_DEPTH\_ARGB32;
   einfo->info.dest\_buffer = pixels;
   einfo->info.dest\_buffer\_row\_bytes = width * \textcolor{keyword}{sizeof}(int);
   einfo->info.use\_color\_key = 0;
   einfo->info.alpha\_threshold = 0;
   einfo->info.func.new\_update\_region = NULL;
   einfo->info.func.free\_update\_region = NULL;

   \textcolor{comment}{/* Finally, we configure the canvas with our chosen parameters. */}
   \mbox{\hyperlink{group__Evas__Canvas_gae917a8b0d52df622498bbf55357c1af3}{evas\_engine\_info\_set}}(canvas, (\mbox{\hyperlink{struct__Evas__Engine__Info}{Evas\_Engine\_Info}} *)einfo);

   \textcolor{keywordflow}{return} canvas;
\}

\textcolor{comment}{/* Convenience routine to shut down the canvas.}
\textcolor{comment}{ * In a real application we'd be using ecore\_evas\_free() instead}
\textcolor{comment}{ */}
\textcolor{keyword}{static} \textcolor{keywordtype}{void} destroy\_canvas(\mbox{\hyperlink{group__Evas__Canvas_ga5ff87cc4ce6bc43e3b640a6d37f73043}{Evas}} *canvas)
\{
   Evas\_Engine\_Info\_Buffer *einfo;

   einfo = (Evas\_Engine\_Info\_Buffer *)\mbox{\hyperlink{group__Evas__Canvas_gaf396b44e1b97ec0d9dce49fcf9ad54b7}{evas\_engine\_info\_get}}(canvas);
   \textcolor{keywordflow}{if} (!einfo)
     \{
        fputs(\textcolor{stringliteral}{"ERROR: could not get evas engine info!\(\backslash\)n"}, stderr);
        \mbox{\hyperlink{group__Evas__Canvas_gaa0d5d3f1a1e1ffa3b14b09bb374215b4}{evas\_free}}(canvas);
        \textcolor{keywordflow}{return};
     \}

   \textcolor{comment}{/* Free the data buffer we allocated in create\_buffer() */}
   free(einfo->info.dest\_buffer);

   \textcolor{comment}{/* Finally, free the canvas itself. */}
   \mbox{\hyperlink{group__Evas__Canvas_gaa0d5d3f1a1e1ffa3b14b09bb374215b4}{evas\_free}}(canvas);
\}

\textcolor{comment}{/* Convenience routine to update the scene.}
\textcolor{comment}{ * In a real application Ecore Evas would be doing this for us.}
\textcolor{comment}{ */}
\textcolor{keyword}{static} \textcolor{keywordtype}{void} draw\_scene(\mbox{\hyperlink{group__Evas__Canvas_ga5ff87cc4ce6bc43e3b640a6d37f73043}{Evas}} *canvas)
\{
   \mbox{\hyperlink{struct__Eina__List}{Eina\_List}} *updates, *n;
   \mbox{\hyperlink{struct__Eina__Rectangle}{Eina\_Rectangle}} *update;

   \textcolor{comment}{/* Render the canvas, and get a list of the updated rectangles. */}
   updates = \mbox{\hyperlink{group__Evas__Canvas_ga1867d9f5f97545418598496af93e4c71}{evas\_render\_updates}}(canvas);

   \textcolor{comment}{/* Just for informative purposes, print out the areas being updated: */}
   \mbox{\hyperlink{group__Eina__List__Group_gac6efafc19f526d916cdb9757240a8773}{EINA\_LIST\_FOREACH}}(updates, n, update)
     printf(\textcolor{stringliteral}{"UPDATED REGION: pos: %3d, %3d    size: %3dx%3d\(\backslash\)n"},
            update->\mbox{\hyperlink{struct__Eina__Rectangle_a8358c0791dcf476432687510ca4e5d5c}{x}}, update->\mbox{\hyperlink{struct__Eina__Rectangle_ae74dc834fb71a1f4cd9e3fe11dec3940}{y}}, update->\mbox{\hyperlink{struct__Eina__Rectangle_af6a92d51ec25ee3464c81297ffc3a330}{w}}, update->\mbox{\hyperlink{struct__Eina__Rectangle_a7570ed17f58fc94be997414a86130074}{h}});

   \textcolor{comment}{/* Free the list of update rectangles */}
   \mbox{\hyperlink{group__Evas__Canvas_ga038d98c7c13a86b6ba4de51f8aba3595}{evas\_render\_updates\_free}}(updates);
\}

\textcolor{comment}{/* Output the canvas buffer to a Portable Pixel Map (PPM) file */}
\textcolor{keyword}{static} \textcolor{keywordtype}{void} save\_scene(\mbox{\hyperlink{group__Evas__Canvas_ga5ff87cc4ce6bc43e3b640a6d37f73043}{Evas}} *canvas, \textcolor{keyword}{const} \textcolor{keywordtype}{char} *dest)
\{
   Evas\_Engine\_Info\_Buffer *einfo;
   \textcolor{keyword}{const} \textcolor{keywordtype}{unsigned} \textcolor{keywordtype}{int} *pixels, *pixels\_end;
   \textcolor{keywordtype}{int} width, height;
   FILE *f;

   \textcolor{comment}{/* Retrieve the current data buffer. */}
   einfo = (Evas\_Engine\_Info\_Buffer *)\mbox{\hyperlink{group__Evas__Canvas_gaf396b44e1b97ec0d9dce49fcf9ad54b7}{evas\_engine\_info\_get}}(canvas);
   \textcolor{keywordflow}{if} (!einfo)
     \{
        fputs(\textcolor{stringliteral}{"ERROR: could not get evas engine info!\(\backslash\)n"}, stderr);
        \textcolor{keywordflow}{return};
     \}

   \textcolor{comment}{/* Retrieve the canvas dimensions */}
   \mbox{\hyperlink{group__Evas__Canvas_gadd22b11c786b3b00448ef58550aa55c4}{evas\_output\_size\_get}}(canvas, &width, &height);

   \textcolor{comment}{/* Open our output PPM file for writing */}
   f = fopen(dest, \textcolor{stringliteral}{"wb+"});
   \textcolor{keywordflow}{if} (!f)
     \{
        fprintf(stderr, \textcolor{stringliteral}{"ERROR: could not open for writing '%s': %s\(\backslash\)n"},
                dest, strerror(errno));
        \textcolor{keywordflow}{return};
     \}

   \textcolor{comment}{/* Write out the pixel data to the PPM file */}
   pixels = einfo->info.dest\_buffer;
   pixels\_end = pixels + (width * height);

   \textcolor{comment}{/* PPM P6 format is dead simple to write.  First we output a magic}
\textcolor{comment}{    * number 'P6' to designate the file as PPM, then the width and}
\textcolor{comment}{    * height on their own line in ASCII decimal, followed by the maximum}
\textcolor{comment}{    * color value (255) on its own line in ASCII decimal, and finally a}
\textcolor{comment}{    * the pixel data in RGB order with each color component written as}
\textcolor{comment}{    * a char (byte).  No alpha information is stored.}
\textcolor{comment}{    */}
   fprintf(f, \textcolor{stringliteral}{"P6\(\backslash\)n%d %d\(\backslash\)n255\(\backslash\)n"},  width, height);
   \textcolor{keywordflow}{for} (; pixels < pixels\_end; pixels++)
     \{
        \textcolor{keywordtype}{int} r, g, b;

        r = ((*pixels) & 0xff0000) >> 16;
        g = ((*pixels) & 0x00ff00) >> 8;
        b = (*pixels) & 0x0000ff;

        fprintf(f, \textcolor{stringliteral}{"%c%c%c"}, r, g, b);
     \}

   fclose(f);
   printf(\textcolor{stringliteral}{"saved scene as '%s'\(\backslash\)n"}, dest);
\}
\end{DoxyCodeInclude}
 