Ecore_Evas buffer example

Between the Evas examples, there is one in which one creates a canvas bound to the Evas buffer engine and uses its pixel contents to create an PPM image on disk. There, one does that by creating the canvas "by hand", with evas_new(), evas_engine_info_set(), etc.

On this example, we accomplish the very same task, but by using the Ecore_Evas helper wrapper functions on a buffer engine canvas. If you compare both codes, you'll see how much code one is saved from by using the Ecore_Evas wrapper functions.

The code is simple as it can be. After instantianting our canvas window, with ecore_evas_buffer_new(), we grab its canvas pointer and create the desired objects scene on it, which in this case is formed by 3 rectangles over the top left corner of a white background:

main(void)
{
Evas *canvas;
Evas_Object *bg, *r1, *r2, *r3;
ee = ecore_evas_buffer_new(WIDTH, HEIGHT);
if (!ee) goto error;
canvas = ecore_evas_get(ee);
evas_object_color_set(bg, 255, 255, 255, 255); /* white bg */
evas_object_move(bg, 0, 0); /* at origin */
evas_object_resize(bg, WIDTH, HEIGHT); /* covers full canvas */
evas_object_color_set(r1, 255, 0, 0, 255); /* 100% opaque red */
evas_object_move(r1, 10, 10);
evas_object_resize(r1, 100, 100);
evas_object_color_set(r2, 0, 128, 0, 128); /* 50% opaque green */
evas_object_move(r2, 10, 10);
evas_object_resize(r2, 50, 50);
evas_object_color_set(r3, 0, 128, 0, 255); /* 100% opaque dark green */
evas_object_move(r3, 60, 60);
evas_object_resize(r3, 50, 50);

Since it's a buffer canvas and we're using it to only save its contents on a file, we even needn't ecore_evas_show() it. We make it render itself, forcefully, without the aid of Ecore's main loop, with ecore_evas_manual_render():

And we're ready to save the window's shiny rendered contents as a simple PPM image. We do so by grabbing the pixels of the Ecore_Evas' internal canvas, with ecore_evas_buffer_pixels_get():

_scene_save(Evas *canvas,
const char *dest)
{
const unsigned int *pixels, *pixels_end;
int width, height;
FILE *f;
evas_output_size_get(canvas, &width, &height);
f = fopen(dest, "wb+");
if (!f)
{
fprintf(stderr, "ERROR: could not open for writing '%s': %s\n",
dest, strerror(errno));
return;
}
/* support function to save scene as PPM image */
static void
_scene_save(Evas *canvas,
const char *dest)
{
const unsigned int *pixels, *pixels_end;
int width, height;
FILE *f;
evas_output_size_get(canvas, &width, &height);
f = fopen(dest, "wb+");
if (!f)
{
fprintf(stderr, "ERROR: could not open for writing '%s': %s\n",
dest, strerror(errno));
return;
}
pixels_end = pixels + (width * height);
/* PPM P6 format is dead simple to write: */
fprintf(f, "P6\n%d %d\n255\n", width, height);
for (; pixels < pixels_end; pixels++)
{
int r, g, b;
r = ((*pixels) & 0xff0000) >> 16;
g = ((*pixels) & 0x00ff00) >> 8;
b = (*pixels) & 0x0000ff;
fprintf(f, "%c%c%c", r, g, b);
}
fclose(f);
printf("Saved scene as '%s'\n", dest);
}

Check that destination file for the result. The full example follows.

#ifdef HAVE_CONFIG_H
#include "config.h"
#else
#define EINA_UNUSED
#endif
#include <Ecore_Evas.h>
#include <stdio.h>
#define WIDTH (320)
#define HEIGHT (240)
static Ecore_Evas *ee;
/* support function to save scene as PPM image */
static void
_scene_save(Evas *canvas,
const char *dest)
{
const unsigned int *pixels, *pixels_end;
int width, height;
FILE *f;
evas_output_size_get(canvas, &width, &height);
f = fopen(dest, "wb+");
if (!f)
{
fprintf(stderr, "ERROR: could not open for writing '%s': %s\n",
dest, strerror(errno));
return;
}
pixels_end = pixels + (width * height);
/* PPM P6 format is dead simple to write: */
fprintf(f, "P6\n%d %d\n255\n", width, height);
for (; pixels < pixels_end; pixels++)
{
int r, g, b;
r = ((*pixels) & 0xff0000) >> 16;
g = ((*pixels) & 0x00ff00) >> 8;
b = (*pixels) & 0x0000ff;
fprintf(f, "%c%c%c", r, g, b);
}
fclose(f);
printf("Saved scene as '%s'\n", dest);
}
int
main(void)
{
Evas *canvas;
Evas_Object *bg, *r1, *r2, *r3;
ee = ecore_evas_buffer_new(WIDTH, HEIGHT);
if (!ee) goto error;
canvas = ecore_evas_get(ee);
evas_object_color_set(bg, 255, 255, 255, 255); /* white bg */
evas_object_move(bg, 0, 0); /* at origin */
evas_object_resize(bg, WIDTH, HEIGHT); /* covers full canvas */
evas_object_color_set(r1, 255, 0, 0, 255); /* 100% opaque red */
evas_object_move(r1, 10, 10);
evas_object_resize(r1, 100, 100);
evas_object_color_set(r2, 0, 128, 0, 128); /* 50% opaque green */
evas_object_move(r2, 10, 10);
evas_object_resize(r2, 50, 50);
evas_object_color_set(r3, 0, 128, 0, 255); /* 100% opaque dark green */
evas_object_move(r3, 60, 60);
evas_object_resize(r3, 50, 50);
_scene_save(canvas, "/tmp/evas-buffer-simple-render.ppm");
return 0;
error:
fprintf(stderr, "error: Requires at least one Evas engine built"
" and linked to ecore-evas for this example to run"
" properly.\n");
return -1;
}
ecore_evas_shutdown
EAPI int ecore_evas_shutdown(void)
Shuts down the Ecore_Evas system.
Definition: ecore_evas.c:674
ecore_evas_buffer_new
EAPI Ecore_Evas * ecore_evas_buffer_new(int w, int h)
Creates a new Ecore_Evas canvas bound to the Evas buffer engine.
Definition: ecore_evas_buffer.c:896
ecore_evas_free
EAPI void ecore_evas_free(Ecore_Evas *ee)
Frees an Ecore_Evas.
Definition: ecore_evas.c:1109
ecore_evas_init
EAPI int ecore_evas_init(void)
Inits the Ecore_Evas system.
Definition: ecore_evas.c:606
Evas_Object
Efl_Canvas_Object Evas_Object
Definition: Evas_Common.h:180
evas_object_resize
void evas_object_resize(Evas_Object *obj, Evas_Coord w, Evas_Coord h)
Changes the size of the given Evas object.
Definition: evas_object_main.c:1236
Ecore_Evas.h
Evas wrapper functions.
ecore_evas_get
EAPI Evas * ecore_evas_get(const Ecore_Evas *ee)
Gets an Ecore_Evas's Evas.
Definition: ecore_evas.c:1326
ecore_evas_manual_render
EAPI void ecore_evas_manual_render(Ecore_Evas *ee)
Forces immediate rendering on a given Ecore_Evas window.
Definition: ecore_evas.c:2671
evas_output_size_get
void evas_output_size_get(const Evas *eo_e, int *w, int *h)
Retrieve the output size of the render engine of the given evas.
Definition: evas_main.c:1400
evas_object_show
void evas_object_show(Evas_Object *eo_obj)
Makes the given Evas object visible.
Definition: evas_object_main.c:1814
Evas
Eo Evas
Definition: Evas_Common.h:158
evas_object_rectangle_add
Evas_Object * evas_object_rectangle_add(Evas *e)
Adds a rectangle to the given evas.
Definition: evas_object_rectangle.c:78
evas_object_move
void evas_object_move(Evas_Object *obj, Evas_Coord x, Evas_Coord y)
Move the given Evas object to the given location inside its canvas' viewport.
Definition: evas_object_main.c:1171
ecore_evas_buffer_pixels_get
EAPI const void * ecore_evas_buffer_pixels_get(Ecore_Evas *ee)
Grabs a pointer to the actual pixels array of a given Ecore_Evas buffer canvas/window.
Definition: ecore_evas_buffer.c:918
evas_object_color_set
void evas_object_color_set(Evas_Object *obj, int r, int g, int b, int a)
Sets the general/main color of the given Evas object to the given one.
Definition: evas_object_main.c:2024