aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorsubhransu mohanty <sub.mohanty@samsung.com>2017-10-25 20:16:17 +0900
committerJean-Philippe Andre <jp.andre@samsung.com>2017-10-25 20:17:20 +0900
commit57ba3318dca35f51a5e2a89367677100bf7b9e49 (patch)
tree6ba6df373ba34e64f44cd559b9d8da21a8b67e87
parenteolian: enable duplicate validation but only warn for now (diff)
downloadefl-57ba3318dca35f51a5e2a89367677100bf7b9e49.tar.gz
evas/vg: Added align, viewbox and fill_mode property to the vg canvas
Summary: viewbox, fill_mode and align property required to scale the vg tree that we get from the svg file or manually created depending on the vg canvas size. Reviewers: jpeg, cedric Subscribers: jenkins, cedric Differential Revision: https://phab.enlightenment.org/D5358
-rw-r--r--src/lib/evas/canvas/efl_canvas_vg.c152
-rw-r--r--src/lib/evas/canvas/efl_canvas_vg.eo53
-rw-r--r--src/lib/evas/canvas/evas_vg_private.h21
3 files changed, 178 insertions, 48 deletions
diff --git a/src/lib/evas/canvas/efl_canvas_vg.c b/src/lib/evas/canvas/efl_canvas_vg.c
index 55ad5d3b8d..e54875642d 100644
--- a/src/lib/evas/canvas/efl_canvas_vg.c
+++ b/src/lib/evas/canvas/efl_canvas_vg.c
@@ -73,6 +73,52 @@ _evas_vg_tree_changed(void *data, const Efl_Event *event EINA_UNUSED)
evas_object_change(obj->object, obj);
}
+static void
+_update_vgtree_viewport(Eo *obj, Efl_Canvas_Vg_Data *pd)
+{
+ double vb_w, vb_h, vp_w, vp_h, scale_w, scale_h, scale;
+ Eina_Size2D sz = efl_gfx_size_get(obj);
+ Eina_Matrix3 m;
+
+ eina_matrix3_identity(&m);
+
+ vb_w = pd->viewbox.w;
+ vb_h = pd->viewbox.h;
+ vp_w = sz.w;
+ vp_h = sz.h;
+
+ scale_w = vp_w / vb_w;
+ scale_h = vp_h / vb_h;
+
+ if (pd->fill_mode == EFL_CANVAS_VG_FILL_MODE_STRETCH)
+ { // Fill the viewport and ignore the aspect ratio
+ eina_matrix3_scale(&m, scale_w, scale_h);
+ eina_matrix3_translate(&m, -pd->viewbox.x, -pd->viewbox.y);
+ }
+ else
+ {
+ if (pd->fill_mode == EFL_CANVAS_VG_FILL_MODE_MEET)
+ scale = scale_w < scale_h ? scale_w : scale_h;
+ else // slice
+ scale = scale_w > scale_h ? scale_w : scale_h;
+ eina_matrix3_translate(&m, (vp_w - vb_w * scale) * pd->align_x, (vp_h - vb_h * scale) * pd->align_y);
+ eina_matrix3_scale(&m, scale, scale);
+ eina_matrix3_translate(&m, -pd->viewbox.x, -pd->viewbox.y);
+ }
+
+ efl_vg_transformation_set(pd->root, &m);
+}
+
+static void
+_evas_vg_resize(void *data, const Efl_Event *ev)
+{
+ Efl_Canvas_Vg_Data *pd = data;
+
+ if (eina_rectangle_is_empty(&pd->viewbox.rect))
+ return;
+ _update_vgtree_viewport(ev->object, pd);
+}
+
/* the actual api call to add a vector graphic object */
EAPI Evas_Object *
evas_object_vg_add(Evas *e)
@@ -84,13 +130,13 @@ evas_object_vg_add(Evas *e)
return efl_add(MY_CLASS, e, efl_canvas_object_legacy_ctor(efl_added));
}
-Efl_VG *
+EOLIAN static Efl_VG *
_efl_canvas_vg_root_node_get(Eo *obj EINA_UNUSED, Efl_Canvas_Vg_Data *pd)
{
return pd->vg_tree;
}
-void
+EOLIAN static void
_efl_canvas_vg_root_node_set(Eo *obj EINA_UNUSED, Efl_Canvas_Vg_Data *pd, Efl_VG *root_node)
{
// if the same root is already set
@@ -102,19 +148,84 @@ _efl_canvas_vg_root_node_set(Eo *obj EINA_UNUSED, Efl_Canvas_Vg_Data *pd, Efl_VG
efl_parent_set(pd->vg_tree, NULL);
pd->vg_tree = root_node;
-
+
if (pd->vg_tree)
{
// set the parent so that vg canvas can render it.
efl_parent_set(pd->vg_tree, pd->root);
}
-
+
// force a redraw
pd->changed = EINA_TRUE;
-
+
evas_object_change(obj, efl_data_scope_get(obj, EFL_CANVAS_OBJECT_CLASS));
}
+EOLIAN static void
+_efl_canvas_vg_fill_mode_set(Eo *obj EINA_UNUSED, Efl_Canvas_Vg_Data *pd, Efl_Canvas_Vg_Fill_Mode fill_mode)
+{
+ pd->fill_mode = fill_mode;
+}
+
+EOLIAN static Efl_Canvas_Vg_Fill_Mode
+_efl_canvas_vg_fill_mode_get(Eo *obj EINA_UNUSED, Efl_Canvas_Vg_Data *pd)
+{
+ return pd->fill_mode;
+}
+
+EOLIAN static void
+_efl_canvas_vg_viewbox_set(Eo *obj, Efl_Canvas_Vg_Data *pd, Eina_Rect viewbox)
+{
+ // viewbox should be a valid rectangle
+ if (eina_rectangle_is_empty(&viewbox.rect))
+ {
+ // reset the old viewbox if any
+ if (!eina_rectangle_is_empty(&pd->viewbox.rect))
+ {
+ Eina_Matrix3 m;
+
+ pd->viewbox = EINA_RECT_EMPTY();
+ eina_matrix3_identity(&m);
+ efl_vg_transformation_set(pd->root, &m);
+ // un register the resize callback
+ efl_event_callback_del(obj, EFL_GFX_EVENT_RESIZE, _evas_vg_resize, pd);
+ }
+ return;
+ }
+ // register for resize callback if not done yet
+ if (eina_rectangle_is_empty(&pd->viewbox.rect))
+ efl_event_callback_add(obj, EFL_GFX_EVENT_RESIZE, _evas_vg_resize, pd);
+
+ pd->viewbox = viewbox;
+ _update_vgtree_viewport(obj, pd);
+}
+
+EOLIAN static Eina_Rect
+_efl_canvas_vg_viewbox_get(Eo *obj EINA_UNUSED, Efl_Canvas_Vg_Data *pd)
+{
+ return pd->viewbox;
+}
+
+EOLIAN static void
+_efl_canvas_vg_viewbox_align_set(Eo *obj EINA_UNUSED, Efl_Canvas_Vg_Data *pd, double align_x, double align_y)
+{
+ align_x = align_x < 0 ? 0 : align_x;
+ align_x = align_x > 1 ? 1 : align_x;
+
+ align_y = align_y < 0 ? 0 : align_y;
+ align_y = align_y > 1 ? 1 : align_y;
+
+ pd->align_x = align_x;
+ pd->align_y = align_y;
+}
+
+EOLIAN static void
+_efl_canvas_vg_viewbox_align_get(Eo *obj EINA_UNUSED, Efl_Canvas_Vg_Data *pd, double *align_x, double *align_y)
+{
+ if (align_x) *align_x = pd->align_x;
+ if (align_y) *align_y = pd->align_y;
+}
+
static void
_cleanup_reference(void *data, const Efl_Event *event EINA_UNUSED)
{
@@ -126,7 +237,7 @@ _cleanup_reference(void *data, const Efl_Event *event EINA_UNUSED)
efl_unref(renderer);
}
-void
+EOLIAN static void
_efl_canvas_vg_efl_object_destructor(Eo *eo_obj, Efl_Canvas_Vg_Data *pd)
{
Evas_Object_Protected_Data *obj;
@@ -143,7 +254,7 @@ _efl_canvas_vg_efl_object_destructor(Eo *eo_obj, Efl_Canvas_Vg_Data *pd)
efl_destructor(efl_super(eo_obj, MY_CLASS));
}
-Eo *
+EOLIAN static Eo *
_efl_canvas_vg_efl_object_constructor(Eo *eo_obj, Efl_Canvas_Vg_Data *pd)
{
Evas_Object_Protected_Data *obj = efl_data_scope_get(eo_obj, EFL_CANVAS_OBJECT_CLASS);
@@ -157,7 +268,7 @@ _efl_canvas_vg_efl_object_constructor(Eo *eo_obj, Efl_Canvas_Vg_Data *pd)
/* root node */
pd->root = efl_add(EFL_VG_CONTAINER_CLASS, NULL);
-
+
eina_array_step_set(&pd->cleanup, sizeof(pd->cleanup), 8);
efl_event_callback_add(pd->root, EFL_GFX_EVENT_CHANGED, _evas_vg_tree_changed, obj);
@@ -428,29 +539,4 @@ _efl_canvas_vg_was_opaque(Evas_Object *eo_obj EINA_UNUSED,
return 0;
}
-EOLIAN static Eina_Size2D
-_efl_canvas_vg_efl_gfx_view_view_size_get(Eo *obj EINA_UNUSED, Efl_Canvas_Vg_Data *pd)
-{
- return EINA_SIZE2D(pd->width, pd->height);
-}
-
-EOLIAN static void
-_efl_canvas_vg_efl_gfx_view_view_size_set(Eo *obj EINA_UNUSED, Efl_Canvas_Vg_Data *pd, Eina_Size2D sz)
-{
- pd->width = sz.w;
- pd->height = sz.h;
-}
-
-void
-_efl_canvas_vg_efl_gfx_fill_fill_set(Eo *obj EINA_UNUSED, Efl_Canvas_Vg_Data *pd, Eina_Rect fill)
-{
- pd->fill = fill;
-}
-
-Eina_Rect
-_efl_canvas_vg_efl_gfx_fill_fill_get(Eo *obj EINA_UNUSED, Efl_Canvas_Vg_Data *pd)
-{
- return pd->fill;
-}
-
#include "efl_canvas_vg.eo.c"
diff --git a/src/lib/evas/canvas/efl_canvas_vg.eo b/src/lib/evas/canvas/efl_canvas_vg.eo
index 3f4becd056..27826af620 100644
--- a/src/lib/evas/canvas/efl_canvas_vg.eo
+++ b/src/lib/evas/canvas/efl_canvas_vg.eo
@@ -1,9 +1,56 @@
-class Efl.Canvas.Vg (Efl.Canvas.Object, Efl.Gfx.Fill, Efl.Gfx.View)
+enum Efl.Canvas.Vg.Fill_Mode
+{
+ [[Enumeration that defines how viewbox will be filled int the vg canvs's viewport.
+ default Fill_Mode is $none]]
+ none, [[Don't scale the viewbox. Placed it inside viewport taking
+ align property into account]]
+ stretch, [[Scale the viewbox so that it matches
+ the canvas viewport.
+ Aaspect ratio might be changed.]]
+ meet, [[Scale the viewbox
+ so that it fits inside canvas viewport
+ while maintaining the aspect ratio.
+ At least one of the dimensions of the viewbox
+ should be equal to the corresponding dimension
+ of the viewport.]]
+ slice [[Scale the viewbox
+ so that it covers the entire canvas viewport
+ while maintaining the aspect ratio.
+ At least one of the dimensions of the viewbox
+ should be equal to the corresponding
+ dimension of the viewport.]]
+}
+
+class Efl.Canvas.Vg (Efl.Canvas.Object)
{
[[Efl vector graphics class]]
legacy_prefix: evas_object_vg;
- eo_prefix: evas_obj_vg;
methods {
+ @property fill_mode {
+ [[Control how the viewbox is mapped to the vg canvas's viewport.]]
+ values {
+ fill_mode: Efl.Canvas.Vg.Fill_Mode; [[Fill mode type]]
+ }
+ }
+ @property viewbox {
+ get {
+ [[Get the current viewbox from the evas_object_vg]]
+ }
+ set {
+ [[Sets the viewbox for the evas vg canvas.
+ viewbox if set should be mapped to the canvas geometry when rendering the vg tree.]]
+ }
+ values {
+ viewbox: Eina.Rect; [[viewbox for the vg canvas]]
+ }
+ }
+ @property viewbox_align {
+ [[Control how the viewbox is positioned inside the viewport.]]
+ values {
+ align_x: double(0); [[Alignment in the horizontal axis (0 <= align_x <= 1).]]
+ align_y: double(0); [[Alignment in the vertical axis (0 <= align_y <= 1).]]
+ }
+ }
@property root_node {
get {
[[Get the root node of the evas_object_vg.
@@ -26,7 +73,5 @@ class Efl.Canvas.Vg (Efl.Canvas.Object, Efl.Gfx.Fill, Efl.Gfx.View)
Efl.Object.constructor;
Efl.Object.finalize;
Efl.Object.destructor;
- Efl.Gfx.Fill.fill { get; set; }
- Efl.Gfx.View.view_size { get; set; }
}
}
diff --git a/src/lib/evas/canvas/evas_vg_private.h b/src/lib/evas/canvas/evas_vg_private.h
index f45ba0a3ac..d3e151aba1 100644
--- a/src/lib/evas/canvas/evas_vg_private.h
+++ b/src/lib/evas/canvas/evas_vg_private.h
@@ -12,17 +12,16 @@ typedef struct _Efl_Canvas_Vg_Data Efl_Canvas_Vg_Data;
struct _Efl_Canvas_Vg_Data
{
- void *engine_data;
- Efl_VG *root;
- Efl_VG *vg_tree;
-
- Eina_Rect fill;
-
- unsigned int width, height;
-
- Eina_Array cleanup;
-
- Eina_Bool changed;
+ void *engine_data;
+ Efl_VG *root;
+ Efl_VG *vg_tree;
+ Eina_Rect fill;
+ Eina_Rect viewbox;
+ unsigned int width, height;
+ Eina_Array cleanup;
+ double align_x, align_y;
+ Efl_Canvas_Vg_Fill_Mode fill_mode;
+ Eina_Bool changed;
};
struct _Efl_VG_Data