wearable surface: changed cairo to evasvector in surface renderer 86/152886/9
authorTaehyub Kim <taehyub.kim@samsung.com>
Wed, 27 Sep 2017 09:45:02 +0000 (18:45 +0900)
committerTaehyub Kim <taehyub.kim@samsung.com>
Mon, 11 Dec 2017 04:00:04 +0000 (13:00 +0900)
Change-Id: Id991e6837c1d21038878283b2fc7cf54d5d0dc0a

inc/wearable/circle/efl_extension_circle_private.h
src/wearable/circle/efl_extension_circle_object.c
src/wearable/circle/efl_extension_circle_surface.c

index a6046c3a7b24c3bfac7b54f15de31653f2b167d7..b6e3ef0817533d453ebb34b23083f64f465848c8 100644 (file)
@@ -46,6 +46,8 @@ typedef enum
 struct _Eext_Circle_Surface {
    Evas_Object         *parent;
    Evas_Object         *image_widget;
+   Evas_Object         *vector_widget;
+   Efl_VG              *vg_root;
    cairo_surface_t     *cairo_surface;
    cairo_t             *cairo;
    unsigned char       *buffer;
@@ -102,6 +104,9 @@ struct _Eext_Circle_Object_Item {
    const char *name;
    void *data;
 
+   //For rendering
+   Efl_VG *vg;
+
    // For text draw
    const char *text;
    const char *font;
index f5ad11da03609cf5a732f7f0ade657c2faffc9e5..f287bc90654eddfa09e5e7495bd0770311f70a93 100644 (file)
@@ -39,6 +39,8 @@ _eext_circle_object_del_cb(void *data,
 
    EINA_LIST_FOREACH_SAFE(circle_obj->items, l, l_next, item)
      {
+        if (item->vg)
+          evas_vg_shape_reset(item->vg);
         _eext_circle_object_item_free(item);
      }
 
@@ -271,6 +273,7 @@ EAPI void
 eext_circle_object_line_width_set(Evas_Object *obj, int line_width)
 {
    eext_circle_object_item_line_width_set(obj, "default", line_width);
+   eext_circle_object_item_line_width_set(obj, "bg", line_width);
 }
 
 EAPI int
@@ -355,6 +358,7 @@ EAPI void
 eext_circle_object_radius_set(Evas_Object *obj, double radius)
 {
    eext_circle_object_item_radius_set(obj, "default", radius);
+   eext_circle_object_item_radius_set(obj, "bg", radius);
 }
 
 EAPI double
index 22aadf4e438992b890dc1a646c92fb574aa321df..e1562f78b83d203ae3857300d1628b4e0aeb81e0 100644 (file)
@@ -37,34 +37,42 @@ _eext_circle_surface_image_widget_add(Evas_Object *parent)
    //for accessibility
    elm_atspi_accessible_role_set(image_widget, ELM_ATSPI_ROLE_REDUNDANT_OBJECT);
 
-   //FIXME: It's for adjusting evas_image geometry.
-   //       Image object has weird geometry during the window calc own size.
-   //       We need to recalc image object after buffer memory copy in render time.
-   //       But now we don't have any way to call image's internal sizing eval function.
-   elm_image_aspect_fixed_set(image_widget, EINA_FALSE);
-   evas_object_repeat_events_set(image_widget, EINA_TRUE);
-
    return image_widget;
 }
 
 static void
-_eext_circle_surface_cairo_draw_arc(cairo_t *cairo,
+_eext_circle_surface_vector_draw_arc(Efl_VG *vg,
                                     int line_width,
-                                    double center_x, double center_y, double radius,
-                                    double r, double g, double b, double a,
+                                    double surface_width, double radius,
+                                    int r, int g, int b, int a,
                                     double angle1, double angle2, Eina_Bool round_cap)
 {
-   cairo_set_line_width(cairo, line_width);
+   line_width /= 2;
+   evas_vg_shape_reset(vg);
 
-   if (round_cap) cairo_set_line_cap(cairo, CAIRO_LINE_CAP_ROUND);
+   evas_vg_shape_stroke_width_set(vg, line_width);
 
-   cairo_set_source_rgba(cairo, r, g, b, a);
+   r = (r * a) / 255;
+   g = (g * a) / 255;
+   b = (b * a) / 255;
+   evas_vg_shape_stroke_color_set(vg, r, g, b, a);
 
-   cairo_arc(cairo, center_x, center_y, radius,
-             angle1 * M_PI / 180, angle2 * M_PI / 180);
-   cairo_stroke(cairo);
+   int x, y, w, h;
+   w = radius  * 2;
+   h = w;
+   x = (surface_width - w) / 2;
+   y = x;
+
+   evas_vg_shape_append_arc(vg, x, y, w, h, (angle1 * -1) + 90, (angle2 - angle1) * -1);
+
+   if (round_cap)
+     evas_vg_shape_stroke_cap_set(vg, EFL_GFX_CAP_ROUND);
+   else
+     evas_vg_shape_stroke_cap_set(vg, EFL_GFX_CAP_BUTT);
 }
 
+/*
+//FIXME:: This code should be modified later when the curved text supports is done.
 static void
 _eext_circle_surface_cairo_draw_text(cairo_t *cairo,
                                      const char *text, const char *font, int font_size,
@@ -88,6 +96,7 @@ _eext_circle_surface_cairo_draw_text(cairo_t *cairo,
    cairo_show_text(cairo, text);
    cairo_stroke(cairo);
 }
+*/
 
 static void
 _eext_circle_surface_clear(Eext_Circle_Surface *surface)
@@ -101,9 +110,6 @@ _eext_circle_surface_clear(Eext_Circle_Surface *surface)
 
    buffer = (unsigned char *)evas_object_image_data_get(image_object, 1);
    memset(buffer, 0, surface->w * surface->h * 4);
-   cairo_set_source_rgba(surface->cairo, 0, 0, 0, 0);
-   cairo_rectangle(surface->cairo, 0.0, 0.0, surface->w, surface->h);
-   cairo_fill(surface->cairo);
 }
 
 static void
@@ -145,7 +151,15 @@ _eext_circle_surface_render(void *data)
    EINA_LIST_FOREACH(surface->render_objs, l, render_obj)
      {
         if (!render_obj->visible)
-          continue;
+          {
+             Eext_Circle_Object_Item *item;
+             EINA_LIST_FOREACH(render_obj->items, ll, item)
+             {
+               if (item->vg)
+                 evas_vg_shape_reset(item->vg);
+             }
+             continue;
+        }
 
         if (render_obj->bg_image_objs)
           {
@@ -181,8 +195,6 @@ _eext_circle_surface_render(void *data)
                        double angle1, angle2;
                        Eina_Bool is_mirrored = EINA_FALSE;
 
-                       cairo_save(surface->cairo);
-
                        if (render_obj->mirrored_state == EEXT_CIRCLE_MIRRORED_CONFIG)
                          is_mirrored = elm_config_mirrored_get();
                        else if (render_obj->mirrored_state == EEXT_CIRCLE_MIRRORED_ON)
@@ -190,32 +202,35 @@ _eext_circle_surface_render(void *data)
 
                        if (is_mirrored)
                          {
-                            angle1 = (item->draw.angle_offset + item->draw.angle + 90.0) * -1;
-                            angle2 = (item->draw.angle_offset + item->min_angle + 90.0) * -1;
+                            angle1 = (item->draw.angle_offset + item->draw.angle) * -1;
+                            angle2 = (item->draw.angle_offset + item->min_angle) * -1;
                          }
                        else
                          {
-                            angle1 = item->draw.angle_offset + item->min_angle - 90.0;
-                            angle2 = item->draw.angle_offset + item->draw.angle - 90.0;
+                            angle1 = item->draw.angle_offset + item->min_angle;
+                            angle2 = item->draw.angle_offset + item->draw.angle;
                          }
 
-                       _eext_circle_surface_cairo_draw_arc(surface->cairo, item->line_width,
-                                                           surface->center_x, surface->center_y, item->radius,
-                                                           (double)item->draw.color.r / 255,
-                                                           (double)item->draw.color.g / 255,
-                                                           (double)item->draw.color.b / 255,
-                                                           (double)item->draw.color.a / 255,
-                                                           angle1,
+                       if (item->vg == NULL)
+                         item->vg = evas_vg_shape_add(surface->vg_root);
+
+                       _eext_circle_surface_vector_draw_arc(item->vg, item->line_width,
+                                                           surface->w, item->radius,
+                                                           item->draw.color.r,
+                                                           item->draw.color.g,
+                                                           item->draw.color.b,
+                                                           item->draw.color.a,
                                                            angle2,
+                                                           angle1,
                                                            item->round_cap);
-                       cairo_restore(surface->cairo);
                     }
-               }
-             else if (item->font_size)
-               {
-                  // Draw Text
-                  cairo_save(surface->cairo);
-                  _eext_circle_surface_cairo_draw_text(surface->cairo,
+                  /*
+                  //FIXME:: This code should be modified later when the curved text supports is done.
+                  else if (item->font_size)
+                    {
+                       // Draw Text
+                       cairo_save(surface->cairo);
+                       _eext_circle_surface_cairo_draw_text(surface->cairo,
                                                        item->text, item->selected_font, item->font_size,
                                                        CAIRO_FONT_SLANT_NORMAL, CAIRO_FONT_WEIGHT_NORMAL,
                                                        surface->center_x, surface->center_y, item->radius,
@@ -225,13 +240,12 @@ _eext_circle_surface_render(void *data)
                                                        (double)item->draw.color.a / 255,
                                                        item->draw.angle_offset + item->draw.angle - 90.0,
                                                        item->draw.angle_offset + item->draw.angle);
-                  cairo_restore(surface->cairo);
+                       cairo_restore(surface->cairo);
+                    }
+                  */
                }
           }
      }
-
-   evas_object_image_data_update_add(elm_image_object_get(surface->image_widget),
-                                     0, 0, surface->w, surface->h);
 }
 
 static void
@@ -244,44 +258,10 @@ _eext_circle_surface_render_finish(Eext_Circle_Surface *surface)
 }
 
 static void
-_eext_circle_surface_cairo_finish(Eext_Circle_Surface *surface)
+_eext_circle_surface_vector_finish(Eext_Circle_Surface *surface)
 {
-   if (surface->cairo) cairo_destroy(surface->cairo);
-   if (surface->cairo_surface) cairo_surface_destroy(surface->cairo_surface);
-
-   surface->cairo = NULL;
-   surface->cairo_surface = NULL;
-}
-
-static void
-_eext_circle_surface_cairo_init(Eext_Circle_Surface *surface)
-{
-   Evas_Object *image_object;
-   cairo_surface_t *cairo_surface;
-   cairo_t *cairo;
-   unsigned char *buffer;
-   int stride;
-
-   if (surface->cairo_surface || surface->cairo)
-     _eext_circle_surface_cairo_finish(surface);
-
-   if (surface->image_widget == NULL)
-     {
-        ERR("Fail to get buffer from image object!");
-        return;
-     }
-
-   image_object = elm_image_object_get(surface->image_widget);
-
-   buffer = (unsigned char *)evas_object_image_data_get(image_object, 1);
-   stride = evas_object_image_stride_get(image_object);
-   cairo_surface = cairo_image_surface_create_for_data(buffer, CAIRO_FORMAT_ARGB32,
-                                                       surface->w, surface->h, stride);
-   cairo = cairo_create(cairo_surface);
-   cairo_set_antialias(cairo, CAIRO_ANTIALIAS_BEST);
-
-   surface->cairo_surface = cairo_surface;
-   surface->cairo = cairo;
+   evas_object_del(surface->vector_widget);
+   evas_object_del(surface->image_widget);
 }
 
 static void
@@ -300,21 +280,14 @@ _eext_circle_surface_update(Eext_Circle_Surface *surface)
 
    evas_object_image_size_set(image_object, surface->w, surface->h);
    evas_object_image_fill_set(image_object, 0, 0, surface->w, surface->h);
+   evas_object_resize(surface->image_widget, surface->w, surface->h);
+   evas_object_resize(surface->vector_widget, surface->w, surface->h);
 
    if ((surface->w != 0) && (surface->h != 0))
      {
         INF("Surface will be initialized!");
-        _eext_circle_surface_cairo_init(surface);
         _eext_circle_surface_changed(surface);
      }
-   else
-     {
-        if (surface->cairo_surface || surface->cairo)
-          {
-             _eext_circle_surface_cairo_finish(surface);
-             _eext_circle_surface_render_finish(surface);
-          }
-     }
 }
 
 static void
@@ -347,7 +320,7 @@ _eext_circle_surface_hide_cb(void *data, Evas *e, Evas_Object *obj, void *event_
 {
    Eext_Circle_Surface *surface = (Eext_Circle_Surface *)data;
 
-   _eext_circle_surface_cairo_finish(surface);
+   _eext_circle_surface_vector_finish(surface);
    _eext_circle_surface_render_finish(surface);
 }
 
@@ -523,7 +496,7 @@ _eext_circle_surface_del_internal(Eext_Circle_Surface *surface)
         evas_object_event_callback_del(surface->parent, EVAS_CALLBACK_DEL, _eext_circle_surface_parent_del_cb);
      }
 
-   _eext_circle_surface_cairo_finish(surface);
+   _eext_circle_surface_vector_finish(surface);
    _eext_circle_surface_render_finish(surface);
 
    if (surface->image_widget)
@@ -571,6 +544,29 @@ _eext_circle_surface_del_internal(Eext_Circle_Surface *surface)
      }
 
    free(surface);
+  }
+
+static void
+_init_render_object(Eext_Circle_Surface *surface, Evas_Object *image_widget)
+{
+   surface->vector_widget = evas_object_vg_add(evas_object_evas_get(image_widget));
+   Efl_VG *root = evas_object_vg_root_node_get(surface->vector_widget);
+   surface->vg_root = root;
+
+   evas_object_repeat_events_set(surface->vector_widget, EINA_TRUE);
+
+   surface->image_widget = image_widget;
+   evas_object_image_alpha_set(elm_image_object_get(surface->image_widget), EINA_TRUE);
+   elm_image_aspect_fixed_set(surface->image_widget, EINA_FALSE);
+   evas_object_repeat_events_set(surface->image_widget, EINA_TRUE);
+   evas_object_smart_member_add(surface->vector_widget, surface->image_widget);
+
+   evas_object_event_callback_add(surface->image_widget, EVAS_CALLBACK_RESIZE, _eext_circle_surface_resize_cb, surface);
+   evas_object_event_callback_add(surface->image_widget, EVAS_CALLBACK_DEL, _eext_circle_surface_del_cb, surface);
+   evas_object_event_callback_add(surface->image_widget, EVAS_CALLBACK_HIDE, _eext_circle_surface_hide_cb, surface);
+   evas_object_event_callback_add(surface->image_widget, EVAS_CALLBACK_SHOW, _eext_circle_surface_show_cb, surface);
+
+   evas_object_show(surface->vector_widget);
 }
 
 //////////////////////////
@@ -599,24 +595,13 @@ _eext_circle_surface_init(Evas_Object *image_widget, Evas_Object *parent, Eext_C
      }
    else if (type == EEXT_CIRCLE_SURFACE_TYPE_PRIVATE)
      {
-        surface->image_widget = image_widget;
-        evas_object_event_callback_add(surface->image_widget, EVAS_CALLBACK_RESIZE, _eext_circle_surface_resize_cb, surface);
-        evas_object_event_callback_add(surface->image_widget, EVAS_CALLBACK_DEL, _eext_circle_surface_del_cb, surface);
-        evas_object_event_callback_add(surface->image_widget, EVAS_CALLBACK_HIDE, _eext_circle_surface_hide_cb, surface);
-        evas_object_event_callback_add(surface->image_widget, EVAS_CALLBACK_SHOW, _eext_circle_surface_show_cb, surface);
-        evas_object_image_alpha_set(elm_image_object_get(surface->image_widget), EINA_TRUE);
+        _init_render_object(surface, image_widget);
      }
    else
      {
-        surface->image_widget = image_widget;
-        evas_object_event_callback_add(surface->image_widget, EVAS_CALLBACK_RESIZE, _eext_circle_surface_resize_cb, surface);
-        evas_object_event_callback_add(surface->image_widget, EVAS_CALLBACK_DEL, _eext_circle_surface_del_cb, surface);
-        evas_object_event_callback_add(surface->image_widget, EVAS_CALLBACK_HIDE, _eext_circle_surface_hide_cb, surface);
-        evas_object_event_callback_add(surface->image_widget, EVAS_CALLBACK_SHOW, _eext_circle_surface_show_cb, surface);
+        _init_render_object(surface, image_widget);
         evas_object_event_callback_add(surface->parent, EVAS_CALLBACK_DEL, _eext_circle_surface_parent_del_cb, surface);
-        evas_object_image_alpha_set(elm_image_object_get(surface->image_widget), EINA_TRUE);
      }
-
    return surface;
 }
 
@@ -632,6 +617,16 @@ _eext_circle_surface_object_remove(Eext_Circle_Surface *surface, Eext_Circle_Obj
    if (!surface) return;
    if (!obj) return;
 
+   Eina_List *ll;
+   Eext_Circle_Object_Item *item;
+   EINA_LIST_FOREACH(obj->items, ll, item)
+   {
+      if (item->vg)
+        evas_vg_shape_reset(item->vg);
+   }
+
+   _eext_circle_surface_clear(surface);
+
    surface->render_objs = eina_list_remove(surface->render_objs, obj);
    obj->surface = NULL;
    _eext_circle_surface_changed(surface);
@@ -893,6 +888,7 @@ eext_circle_surface_del(Eext_Circle_Surface *surface)
      {
         evas_object_event_callback_del(surface->image_widget, EVAS_CALLBACK_RESIZE, _eext_circle_surface_resize_cb);
         evas_object_event_callback_del(surface->image_widget, EVAS_CALLBACK_DEL, _eext_circle_surface_del_cb);
+        evas_object_del(surface->vector_widget);
         evas_object_del(surface->image_widget);
         surface->image_widget = NULL;
      }