hermet pushed a commit to branch master.

http://git.enlightenment.org/core/efl.git/commit/?id=442fae5c5621636bf52c3467d6d4c7147fd53a5a

commit 442fae5c5621636bf52c3467d6d4c7147fd53a5a
Author: JunsuChoi <jsuya.c...@samsung.com>
Date:   Wed Jun 3 11:37:23 2020 +0900

    Efl.Canvas.Vg.Object: Optimize Ector Surface Size
    
    Summary:
    The ector surface size was determined by the size of the vg object.
    vg object is usually sized by the size of the container.
    So, the ector surface is set unnecessarily large.
    This patch sets the ector surface size to the path boundary.
    And the path boundary refers to the stroke width and miterlimit.
    
    Test Plan:
    vector sample
    {F3887634}
    {F3887632}
    
    [grey area is ector surface size]
    {F3887633}
    
    Reviewers: Hermet, kimcinoo, smohanty, herb
    
    Reviewed By: Hermet
    
    Subscribers: cedric, #reviewers, #committers
    
    Tags: #efl
    
    Differential Revision: https://phab.enlightenment.org/D11865
---
 .../ector/software/ector_renderer_software_shape.c |  4 +-
 src/lib/edje/edje_calc.c                           |  6 +++
 src/lib/evas/canvas/efl_canvas_vg_container.c      | 35 ++++++++++++-
 src/lib/evas/canvas/efl_canvas_vg_object.c         | 57 +++++++++++++++++-----
 src/lib/evas/canvas/evas_vg_private.h              |  1 +
 5 files changed, 87 insertions(+), 16 deletions(-)

diff --git a/src/lib/ector/software/ector_renderer_software_shape.c 
b/src/lib/ector/software/ector_renderer_software_shape.c
index d8d804db22..be024ff5d1 100644
--- a/src/lib/ector/software/ector_renderer_software_shape.c
+++ b/src/lib/ector/software/ector_renderer_software_shape.c
@@ -654,8 +654,8 @@ _ector_renderer_software_shape_ector_renderer_draw(Eo *obj 
EINA_UNUSED,
    if (task) ector_software_wait(_update_rle, _done_rle, task);
 
    // adjust the offset
-   x = pd->surface->x + (int)pd->base->origin.x;
-   y = pd->surface->y + (int)pd->base->origin.y;
+   x = (int)pd->base->origin.x - pd->surface->x;
+   y = (int)pd->base->origin.y - pd->surface->y;
 
    ector_software_rasterizer_clip_rect_set(pd->surface->rasterizer, clips);
    ector_software_rasterizer_transform_set(pd->surface->rasterizer, 
pd->base->m);
diff --git a/src/lib/edje/edje_calc.c b/src/lib/edje/edje_calc.c
index 93a99254bf..5d3f42344b 100644
--- a/src/lib/edje/edje_calc.c
+++ b/src/lib/edje/edje_calc.c
@@ -3319,17 +3319,23 @@ _edje_vector_recalc_apply(Edje *ed, Edje_Real_Part *ep, 
Edje_Calc_Params *p3 EIN
      }
    else
      {
+        Eina_Rect viewbox;
+
         snprintf(dest_key, sizeof(dest_key), "edje/vectors/%i", new_id);
 
         efl_file_simple_load(ep->object, ed->file->path, src_key);
         src_root = efl_canvas_vg_object_root_node_get(ep->object);
         efl_ref(src_root);
 
+        // Note: Assume that the viewboxes of two interpolation objects are 
the same.
+        viewbox = efl_canvas_vg_object_viewbox_get(ep->object);
+
         efl_file_simple_load(ep->object, ed->file->path, dest_key);
         dest_root = efl_canvas_vg_object_root_node_get(ep->object);
         efl_ref(dest_root);
 
         root = efl_duplicate(src_root);
+        efl_canvas_vg_object_viewbox_set(ep->object, viewbox);
 
         if (!efl_gfx_path_interpolate(root, src_root, dest_root, pos))
           ERR("Can't interpolate check the svg file");
diff --git a/src/lib/evas/canvas/efl_canvas_vg_container.c 
b/src/lib/evas/canvas/efl_canvas_vg_container.c
index 61bd74e7c3..4516b34ba0 100644
--- a/src/lib/evas/canvas/efl_canvas_vg_container.c
+++ b/src/lib/evas/canvas/efl_canvas_vg_container.c
@@ -280,15 +280,46 @@ _efl_canvas_vg_container_efl_gfx_path_bounds_get(const Eo 
*obj EINA_UNUSED,
 
    EINA_LIST_FOREACH(pd->children, l, child)
      {
+        Eina_Position2D pos = efl_gfx_entity_position_get(child);
+        double miterlimit = 0.0, stroke_gap = 0.0;
+        if (efl_isa(child, EFL_CANVAS_VG_SHAPE_CLASS))
+          {
+             miterlimit = efl_gfx_shape_stroke_miterlimit_get(child);
+             stroke_gap = efl_gfx_shape_stroke_width_get(child) * (miterlimit 
<= 0 ? 1 : miterlimit);
+          }
         if (first)
           {
              efl_gfx_path_bounds_get(child, r);
-             first = EINA_FALSE;
+             if (r->size.w != 0 && r->size.h != 0)
+               {
+                  r->pos.x += pos.x;
+                  r->pos.y += pos.y;
+                  if (stroke_gap > 1.0)
+                    {
+                       r->pos.x -= (int)(stroke_gap/2.0);
+                       r->pos.y -= (int)(stroke_gap/2.0);
+                       r->size.w += (int)(stroke_gap);
+                       r->size.h += (int)(stroke_gap);
+                    }
+                  first = EINA_FALSE;
+               }
           }
         else
           {
              efl_gfx_path_bounds_get(child, &s);
-             eina_rectangle_union(&r->rect, &s.rect);
+             if (s.size.w != 0 && s.size.h != 0)
+               {
+                  s.pos.x += pos.x;
+                  s.pos.y += pos.y;
+                  if (stroke_gap > 1.0)
+                    {
+                       s.pos.x -= (int)(stroke_gap/2.0);
+                       s.pos.y -= (int)(stroke_gap/2.0);
+                       s.size.w += (int)(stroke_gap);
+                       s.size.h += (int)(stroke_gap);
+                    }
+                  eina_rectangle_union(&r->rect, &s.rect);
+               }
           }
      }
 }
diff --git a/src/lib/evas/canvas/efl_canvas_vg_object.c 
b/src/lib/evas/canvas/efl_canvas_vg_object.c
index 3a3ba1c346..d05bfc551d 100644
--- a/src/lib/evas/canvas/efl_canvas_vg_object.c
+++ b/src/lib/evas/canvas/efl_canvas_vg_object.c
@@ -293,6 +293,11 @@ _efl_canvas_vg_object_efl_file_load(Eo *eo_obj, 
Efl_Canvas_Vg_Object_Data *pd)
                                              file, key,
                                              obj->cur->geometry.w,
                                              obj->cur->geometry.h, NULL);
+
+   // NOTE: Update object's viewbox. In this case, there is no need to update
+   //       the root of tree. That's why We don't use viewbox_set.
+   pd->viewbox.rect = pd->vg_entry->vfd->view_box;
+
    evas_object_change(eo_obj, obj);
    pd->changed = EINA_TRUE;
 
@@ -504,7 +509,7 @@ _evas_vg_render(Evas_Object_Protected_Data *obj, 
Efl_Canvas_Vg_Object_Data *pd,
 //renders a vg_tree to an offscreen buffer and push it to the cache.
 static void *
 _render_to_buffer(Evas_Object_Protected_Data *obj, Efl_Canvas_Vg_Object_Data 
*pd,
-                  void *engine, Efl_VG *root, int w, int h, void *buffer, void 
*ckey,
+                  void *engine, Efl_VG *root, int x, int y, int w, int h, void 
*buffer, void *ckey,
                   Eina_Bool do_async)
 {
    Ector_Surface *ector;
@@ -532,7 +537,7 @@ _render_to_buffer(Evas_Object_Protected_Data *obj, 
Efl_Canvas_Vg_Object_Data *pd
    _evas_vg_render_pre(obj, root, engine, buffer, context, ector, NULL, 255, 
NULL, 0);
 
    //Actual content drawing
-   if (!ENFN->ector_begin(engine, buffer, context, ector, 0, 0, do_async))
+   if (!ENFN->ector_begin(engine, buffer, context, ector, x, y, do_async))
      {
         ERR("Failed ector begin!");
         return NULL;
@@ -688,7 +693,7 @@ _cache_vg_entry_render(Evas_Object_Protected_Data *obj,
 
    if (!buffer)
      {
-        buffer = _render_to_buffer(obj, pd, engine, root, w, h, NULL, key, 
do_async);
+        buffer = _render_to_buffer(obj, pd, engine, root, 0, 0, w, h, NULL, 
key, do_async);
      }
    else
      {
@@ -710,26 +715,52 @@ _user_vg_entry_render(Evas_Object_Protected_Data *obj,
                       int x, int y, int w, int h, Eina_Bool do_async)
 {
    Vg_User_Entry *user_entry = pd->user_entry;
+   Eina_Rect render_rect = EINA_RECT(x, y, w, h);
+
+   // Get changed boundary and fit the size.
+   Eina_Rect r;
+   if (pd->changed)
+     efl_gfx_path_bounds_get(user_entry->root, &user_entry->path_bounds);
+   EINA_RECTANGLE_SET(&r, user_entry->path_bounds.x,
+                      user_entry->path_bounds.y,
+                      user_entry->path_bounds.w,
+                      user_entry->path_bounds.h);
+
+   if (pd->viewbox.w != 0 || pd->viewbox.h !=0)
+     {
+        double sx = 0, sy= 0;
+        sx = (double)render_rect.w / (double)pd->viewbox.w;
+        sy = (double)render_rect.h / (double)pd->viewbox.h;
+        r.pos.x = (r.pos.x - pd->viewbox.x) * sx;
+        r.pos.y = (r.pos.y - pd->viewbox.y) * sy;
+        r.size.w *= sx;
+        r.size.h *= sy;
+     }
+
+   if (render_rect.x < r.pos.x) render_rect.x = r.pos.x;
+   if (render_rect.y < r.pos.y) render_rect.y = r.pos.y;
+   if (render_rect.w > r.size.w) render_rect.w = r.size.w;
+   if (render_rect.h > r.size.h) render_rect.h = r.size.h;
 
    //if the size doesn't match, drop previous cache surface.
-   if ((user_entry->w != w ) ||
-       (user_entry->h != h))
+   if ((user_entry->w != render_rect.w ) ||
+       (user_entry->h != render_rect.h))
      {
-         ENFN->ector_surface_cache_drop(engine, user_entry->root);
-         user_entry->w = w;
-         user_entry->h = h;
+        ENFN->ector_surface_cache_drop(engine, user_entry->root);
+        user_entry->w = w;
+        user_entry->h = h;
      }
 
    //if the buffer is not created yet
    void *buffer = NULL;
 
-     buffer = ENFN->ector_surface_cache_get(engine, user_entry->root);
+   buffer = ENFN->ector_surface_cache_get(engine, user_entry->root);
 
    if (!buffer)
      {
         // render to the buffer
         buffer = _render_to_buffer(obj, pd, engine, user_entry->root,
-                                   w, h, buffer, user_entry->root, do_async);
+                                   render_rect.x, render_rect.y, 
render_rect.w, render_rect.h, buffer, user_entry->root, do_async);
      }
    else
      {
@@ -737,7 +768,7 @@ _user_vg_entry_render(Evas_Object_Protected_Data *obj,
         if (pd->changed)
           buffer = _render_to_buffer(obj, pd, engine,
                                      user_entry->root,
-                                     w, h, buffer, NULL,
+                                     render_rect.x, render_rect.y, 
render_rect.w, render_rect.h, buffer, NULL,
                                      do_async);
         //cache reference was increased when we get the cache.
         ENFN->ector_surface_cache_drop(engine, user_entry->root);
@@ -746,7 +777,9 @@ _user_vg_entry_render(Evas_Object_Protected_Data *obj,
    _render_buffer_to_screen(obj,
                             engine, output, context, surface,
                             buffer,
-                            x, y, w, h,
+                            x + r.pos.x,
+                            y + r.pos.y,
+                            render_rect.w, render_rect.h,
                             do_async, EINA_TRUE);
 }
 
diff --git a/src/lib/evas/canvas/evas_vg_private.h 
b/src/lib/evas/canvas/evas_vg_private.h
index dcd5cb0356..c20ed2a1eb 100644
--- a/src/lib/evas/canvas/evas_vg_private.h
+++ b/src/lib/evas/canvas/evas_vg_private.h
@@ -35,6 +35,7 @@ typedef struct _Vg_User_Entry
 {
    int                   w; // current surface width
    int                   h; // current surface height
+   Eina_Rect             path_bounds;
    Efl_VG               *root;
 } Vg_User_Entry;
 

-- 


Reply via email to