Page Example

Cairo Basic Sample Overview

Mobile native

The Cairo Basic sample application demonstrates how to use a Cairo image backend with the Tizen SDK.

Note
The application presented in this overview is not a full Tizen application, since it does not use the Application Framework. The application simply starts and runs.

The following figure illustrates the main screen of the Cairo Basic.

Figure: Cairo Basic screen

Cairo Basic rectangular screen

Implementation

First create a basic application. This provides a basic UI application skeleton which already makes available the window object that can contain the Cairo drawing.

  1. Include the <cairo.h> and <math.h> header files, which are needed for this sample application.
    #include <cairo.h>
    #include <math.h>
    
  2. You can define the appdata structure that contains all the pointers to objects to be manipulated.
    typedef struct appdata 
    {
       Evas_Object *win;	
       Evas_Object *img;
       cairo_surface_t *surface;
       cairo_t *cairo;
       unsigned char *pixels;
    } appdata_s;
    
  3. To display the Cairo drawing on the screen, create the Elm_window and the Evas_Object image.

    When creating the Elm_window, you can set the name as your PACKAGE name. It is created when you create this project in the Tizen SDK.

    // Window
    ad->win = elm_win_util_standard_add(PACKAGE, PACKAGE);
    elm_win_autodel_set(ad->win, EINA_TRUE);
    if (elm_win_wm_rotation_supported_get(ad->win))
    {
       int rots[4] = {0, 90, 180, 270};
       elm_win_wm_rotation_available_rotations_set(ad->win, (const int *)(&rots), 4);
    }
    evas_object_smart_callback_add(ad->win, "delete,request", win_delete_request_cb, NULL);
    eext_object_event_callback_add(ad->win, EEXT_CALLBACK_BACK, win_back_cb, ad);
    evas_object_show(ad->win);
    
    // Image
    ad->img = evas_object_image_filled_add(evas_object_evas_get(ad->win));
    evas_object_show(ad->img);
    

Drawing a Polygon and Rectangle with Cairo

To create the Cairo drawing, you need the window size to set the Cairo surface. You can get the window size with the evas_object_geometry_get() function after the evas_object_show(ad->win) function is called.

To draw Cairo with some specific vector positions, you can use the window size as before.

evas_object_geometry_get(ad->win, NULL, NULL, &ad->width, &ad->height);
ad->surface = cairo_image_surface_create(CAIRO_FORMAT_ARGB32, ad->width, ad->height);
ad->cairo = cairo_create(ad->surface);

In this example, a Cairo image is drawn on a square screen. You can compare the windows width and height and get the smaller length to set the square side.

void 
cairo_drawing(void *data)
{
   appdata_s *ad = data;
   int d = 0;
   if(ad->width < ad->height)
      d = ad->width;
   else
      d = ad->height;

To set the background as white color, set the color as white and paint the Cairo.

   // Clear background as white
   cairo_set_source_rgba(ad->cairo, 1, 1, 1, 1);
   cairo_paint(ad->cairo);

In the following example, you can draw the polygon and rectangle. You must use the cairo_surface_flush() function. This function call implements any pending drawings for the surface.

   cairo_translate(ad->cairo, 0.1 * d, 0.1 * d);
   cairo_set_line_width(ad->cairo, 2);
   cairo_set_source_rgba(ad->cairo, 0.0, 0.0, 1.0, 1.0);

   cairo_move_to(ad->cairo, 0.2 * d , 0.2 * d);
   cairo_line_to(ad->cairo, 0.4 * d, 0.3 * d);
   cairo_rel_line_to(ad->cairo, 0.2 * d, -0.1 * d);
   cairo_arc(ad->cairo, 0.4 * d, 0.4 * d, 0.2* d * sqrt(2), -0.25 * M_PI, 0.25 * M_PI);
   cairo_rel_curve_to(ad->cairo, -0.2* d, -0.1 * d, -0.2* d, 0.1 * d, -0.4 * d, 0);
   cairo_close_path(ad->cairo);
   cairo_fill(ad->cairo);

   cairo_rectangle(ad->cairo, 0, 0, 0.8 * d, 0.8 * d);
   cairo_stroke(ad->cairo);
   cairo_surface_flush(ad->surface);

To update the Evas object image on the screen:

   // Display the Cairo drawing on screen
   unsigned char * imageData = cairo_image_surface_get_data(cairo_get_target(ad->cairo));
   evas_object_image_data_set(ad->img, imageData);
   evas_object_image_data_update_add(ad->img, 0, 0, ad->width, ad->height);
}

Deleting Cairo

The delete callback is triggered when the Window is destroyed from the main loop.

static void win_delete_request_cb(void *data, Evas_Object *obj, void *event_info)
{
   appdata_s *ad = data;
   cairo_surface_destroy(ad->surface);
   cairo_destroy(ad->cairo);
   ui_app_exit();
}