1 #include "evas_common_private.h"
2 #include "evas_private.h"
3 
4 #include "evas_vg_private.h"
5 
6 #include <strings.h>
7 
8 #define MY_CLASS EFL_CANVAS_VG_GRADIENT_LINEAR_CLASS
9 
10 typedef struct _Efl_Canvas_Vg_Gradient_Linear_Data Efl_Canvas_Vg_Gradient_Linear_Data;
11 struct _Efl_Canvas_Vg_Gradient_Linear_Data
12 {
13    struct {
14       double x, y;
15    } start, end;
16 };
17 
18 static void
_efl_canvas_vg_gradient_linear_efl_gfx_gradient_linear_start_set(Eo * obj EINA_UNUSED,Efl_Canvas_Vg_Gradient_Linear_Data * pd,double x,double y)19 _efl_canvas_vg_gradient_linear_efl_gfx_gradient_linear_start_set(Eo *obj EINA_UNUSED,
20                                                           Efl_Canvas_Vg_Gradient_Linear_Data *pd,
21                                                           double x, double y)
22 {
23    pd->start.x = x;
24    pd->start.y = y;
25 
26    efl_canvas_vg_node_change(obj);
27 }
28 
29 static void
_efl_canvas_vg_gradient_linear_efl_gfx_gradient_linear_start_get(const Eo * obj EINA_UNUSED,Efl_Canvas_Vg_Gradient_Linear_Data * pd,double * x,double * y)30 _efl_canvas_vg_gradient_linear_efl_gfx_gradient_linear_start_get(const Eo *obj EINA_UNUSED,
31                                                           Efl_Canvas_Vg_Gradient_Linear_Data *pd,
32                                                           double *x, double *y)
33 {
34    if (x) *x = pd->start.x;
35    if (y) *y = pd->start.y;
36 }
37 
38 static void
_efl_canvas_vg_gradient_linear_efl_gfx_gradient_linear_end_set(Eo * obj EINA_UNUSED,Efl_Canvas_Vg_Gradient_Linear_Data * pd,double x,double y)39 _efl_canvas_vg_gradient_linear_efl_gfx_gradient_linear_end_set(Eo *obj EINA_UNUSED,
40                                                         Efl_Canvas_Vg_Gradient_Linear_Data *pd,
41                                                         double x, double y)
42 {
43    pd->end.x = x;
44    pd->end.y = y;
45 
46    efl_canvas_vg_node_change(obj);
47 }
48 
49 static void
_efl_canvas_vg_gradient_linear_efl_gfx_gradient_linear_end_get(const Eo * obj EINA_UNUSED,Efl_Canvas_Vg_Gradient_Linear_Data * pd,double * x,double * y)50 _efl_canvas_vg_gradient_linear_efl_gfx_gradient_linear_end_get(const Eo *obj EINA_UNUSED,
51                                                         Efl_Canvas_Vg_Gradient_Linear_Data *pd,
52                                                         double *x, double *y)
53 {
54    if (x) *x = pd->end.x;
55    if (y) *y = pd->end.y;
56 }
57 
58 static void
_efl_canvas_vg_gradient_linear_render_pre(Evas_Object_Protected_Data * vg_pd EINA_UNUSED,Efl_VG * obj,Efl_Canvas_Vg_Node_Data * nd,void * engine EINA_UNUSED,void * output EINA_UNUSED,void * context EINA_UNUSED,Ector_Surface * surface,Eina_Matrix3 * ptransform,int p_opacity EINA_UNUSED,Ector_Buffer * comp,Efl_Gfx_Vg_Composite_Method comp_method,void * data)59 _efl_canvas_vg_gradient_linear_render_pre(Evas_Object_Protected_Data *vg_pd EINA_UNUSED,
60                                           Efl_VG *obj,
61                                           Efl_Canvas_Vg_Node_Data *nd,
62                                           void *engine EINA_UNUSED,
63                                           void *output EINA_UNUSED,
64                                           void *context EINA_UNUSED,
65                                           Ector_Surface *surface,
66                                           Eina_Matrix3 *ptransform,
67                                           int p_opacity EINA_UNUSED,
68                                           Ector_Buffer *comp,
69                                           Efl_Gfx_Vg_Composite_Method comp_method,
70                                           void *data)
71 {
72    Efl_Canvas_Vg_Gradient_Linear_Data *pd = data;
73    Efl_Canvas_Vg_Gradient_Data *gd;
74 
75    if (nd->flags == EFL_GFX_CHANGE_FLAG_NONE) return;
76 
77    nd->flags = EFL_GFX_CHANGE_FLAG_NONE;
78 
79    gd = efl_data_scope_get(obj, EFL_CANVAS_VG_GRADIENT_CLASS);
80    EFL_CANVAS_VG_COMPUTE_MATRIX(ctransform, ptransform, nd);
81 
82    if (!nd->renderer)
83      {
84         efl_domain_current_push(EFL_ID_DOMAIN_SHARED);
85         nd->renderer = ector_surface_renderer_factory_new(surface, ECTOR_RENDERER_GRADIENT_LINEAR_MIXIN);
86         efl_domain_current_pop();
87      }
88 
89    ector_renderer_transformation_set(nd->renderer, ctransform);
90    ector_renderer_origin_set(nd->renderer, nd->x, nd->y);
91    ector_renderer_visibility_set(nd->renderer, nd->visibility);
92    efl_gfx_gradient_stop_set(nd->renderer, gd->colors, gd->colors_count);
93    efl_gfx_gradient_spread_set(nd->renderer, gd->spread);
94    efl_gfx_gradient_linear_start_set(nd->renderer, pd->start.x, pd->start.y);
95    efl_gfx_gradient_linear_end_set(nd->renderer, pd->end.x, pd->end.y);
96    ector_renderer_prepare(nd->renderer);
97    ector_renderer_comp_method_set(nd->renderer, comp, comp_method);
98 }
99 
100 static Eo *
_efl_canvas_vg_gradient_linear_efl_object_constructor(Eo * obj,Efl_Canvas_Vg_Gradient_Linear_Data * pd)101 _efl_canvas_vg_gradient_linear_efl_object_constructor(Eo *obj,
102                                             Efl_Canvas_Vg_Gradient_Linear_Data *pd)
103 {
104    Efl_Canvas_Vg_Node_Data *nd;
105 
106    obj = efl_constructor(efl_super(obj, MY_CLASS));
107 
108    nd = efl_data_scope_get(obj, EFL_CANVAS_VG_NODE_CLASS);
109    nd->render_pre = _efl_canvas_vg_gradient_linear_render_pre;
110    nd->data = pd;
111 
112    return obj;
113 }
114 
115 static void
_efl_canvas_vg_gradient_linear_efl_object_destructor(Eo * obj,Efl_Canvas_Vg_Gradient_Linear_Data * pd EINA_UNUSED)116 _efl_canvas_vg_gradient_linear_efl_object_destructor(Eo *obj, Efl_Canvas_Vg_Gradient_Linear_Data *pd EINA_UNUSED)
117 {
118    efl_destructor(efl_super(obj, MY_CLASS));
119 }
120 
121 static void
_efl_canvas_vg_gradient_linear_efl_gfx_path_bounds_get(const Eo * obj,Efl_Canvas_Vg_Gradient_Linear_Data * pd,Eina_Rect * r)122 _efl_canvas_vg_gradient_linear_efl_gfx_path_bounds_get(const Eo *obj, Efl_Canvas_Vg_Gradient_Linear_Data *pd, Eina_Rect *r)
123 {
124    Efl_Canvas_Vg_Node_Data *nd;
125 
126    nd = efl_data_scope_get(obj, EFL_CANVAS_VG_NODE_CLASS);
127    EINA_RECTANGLE_SET(r,
128                       nd->x + pd->start.x, nd->y + pd->start.y,
129                       pd->end.x - pd->start.x, pd->end.y - pd->start.x);
130 }
131 
132 static Eina_Bool
_efl_canvas_vg_gradient_linear_efl_gfx_path_interpolate(Eo * obj,Efl_Canvas_Vg_Gradient_Linear_Data * pd,const Efl_VG * from,const Efl_VG * to,double pos_map)133 _efl_canvas_vg_gradient_linear_efl_gfx_path_interpolate(Eo *obj,
134                                                 Efl_Canvas_Vg_Gradient_Linear_Data *pd,
135                                                 const Efl_VG *from, const Efl_VG *to,
136                                                 double pos_map)
137 {
138    Efl_Canvas_Vg_Gradient_Linear_Data *fromd, *tod;
139    double from_map;
140    Eina_Bool r;
141 
142    r = efl_gfx_path_interpolate(efl_super(obj, EFL_CANVAS_VG_GRADIENT_LINEAR_CLASS), from, to, pos_map);
143 
144    if (!r) return EINA_FALSE;
145 
146    fromd = efl_data_scope_get(from, EFL_CANVAS_VG_GRADIENT_LINEAR_CLASS);
147    tod = efl_data_scope_get(to, EFL_CANVAS_VG_GRADIENT_LINEAR_CLASS);
148    from_map = 1.0 - pos_map;
149 
150 #define INTP(Pd, From, To, Member, From_Map, Pos_Map)   \
151    Pd->Member = From->Member * From_Map + To->Member * Pos_Map
152 
153    INTP(pd, fromd, tod, start.x, from_map, pos_map);
154    INTP(pd, fromd, tod, start.y, from_map, pos_map);
155    INTP(pd, fromd, tod, end.x, from_map, pos_map);
156    INTP(pd, fromd, tod, end.y, from_map, pos_map);
157 
158 #undef INTP
159 
160    return EINA_TRUE;
161 }
162 
163 EOLIAN static Efl_VG *
_efl_canvas_vg_gradient_linear_efl_duplicate_duplicate(const Eo * obj,Efl_Canvas_Vg_Gradient_Linear_Data * pd)164 _efl_canvas_vg_gradient_linear_efl_duplicate_duplicate(const Eo *obj, Efl_Canvas_Vg_Gradient_Linear_Data *pd)
165 {
166    Efl_VG *cn = NULL;
167 
168    cn = efl_duplicate(efl_super(obj, MY_CLASS));
169    efl_gfx_gradient_linear_start_set(cn, pd->start.x, pd->start.y);
170    efl_gfx_gradient_linear_end_set(cn, pd->end.x, pd->end.y);
171    return cn;
172 }
173 
174 EAPI void
evas_vg_gradient_linear_start_set(Evas_Vg_Gradient_Linear * obj,double x,double y)175 evas_vg_gradient_linear_start_set(Evas_Vg_Gradient_Linear *obj, double x, double y)
176 {
177    efl_gfx_gradient_linear_start_set(obj, x, y);
178 }
179 
180 EAPI void
evas_vg_gradient_linear_start_get(Evas_Vg_Gradient_Linear * obj,double * x,double * y)181 evas_vg_gradient_linear_start_get(Evas_Vg_Gradient_Linear *obj, double *x, double *y)
182 {
183    efl_gfx_gradient_linear_start_get(obj, x, y);
184 }
185 
186 EAPI void
evas_vg_gradient_linear_end_set(Evas_Vg_Gradient_Linear * obj,double x,double y)187 evas_vg_gradient_linear_end_set(Evas_Vg_Gradient_Linear *obj, double x, double y)
188 {
189    efl_gfx_gradient_linear_end_set(obj, x, y);
190 }
191 
192 EAPI void
evas_vg_gradient_linear_end_get(Evas_Vg_Gradient_Linear * obj,double * x,double * y)193 evas_vg_gradient_linear_end_get(Evas_Vg_Gradient_Linear *obj, double *x, double *y)
194 {
195    efl_gfx_gradient_linear_end_get(obj, x, y);
196 }
197 
198 EAPI Evas_Vg_Gradient_Linear *
evas_vg_gradient_linear_add(Evas_Vg_Container * parent)199 evas_vg_gradient_linear_add(Evas_Vg_Container *parent)
200 {
201    return efl_add(EFL_CANVAS_VG_GRADIENT_LINEAR_CLASS, parent);
202 }
203 
204 #include "efl_canvas_vg_gradient_linear.eo.c"
205