1 #ifndef EVAS_VG_PRIVATE_H_
2 # define EVAS_VG_PRIVATE_H_
3 
4 #include <Ector.h>
5 
6 typedef struct _Efl_Canvas_Vg_Node_Data             Efl_Canvas_Vg_Node_Data;
7 typedef struct _Efl_Canvas_Vg_Container_Data        Efl_Canvas_Vg_Container_Data;
8 typedef struct _Efl_Canvas_Vg_Gradient_Data         Efl_Canvas_Vg_Gradient_Data;
9 typedef struct _Efl_Canvas_Vg_Interpolation         Efl_Canvas_Vg_Interpolation;
10 typedef struct _Efl_Canvas_Vg_Object_Data           Efl_Canvas_Vg_Object_Data;
11 
12 typedef struct _Vg_Cache
13 {
14    Eina_Hash             *vfd_hash;
15    Eina_Hash             *vg_entry_hash;
16    Eina_List             *vg_surface_keys;
17    int                    ref;
18 } Vg_Cache;
19 
20 typedef struct _Vg_Cache_Entry
21 {
22    Evas                 *evas;
23    char                 *hash_key;
24    const Eina_File      *file;
25    Eina_Stringshare     *key;
26    int                   w;
27    int                   h;
28    Efl_VG               *root;
29    int                   ref;
30    Vg_File_Data         *vfd;
31 } Vg_Cache_Entry;
32 
33 // holds the vg tree info set by the user
34 typedef struct _Vg_User_Entry
35 {
36    int                   w; // current surface width
37    int                   h; // current surface height
38    Eina_Rect             path_bounds;
39    Efl_VG               *root;
40 } Vg_User_Entry;
41 
42 struct _Efl_Canvas_Vg_Object_Data
43 {
44    Efl_VG                    *root;
45    Vg_Cache_Entry            *vg_entry;
46    Vg_User_Entry             *user_entry; //holds the user set vg tree
47    Evas_Object_Protected_Data *obj;
48    Eina_Rect                  fill;
49    Eina_Rect                  viewbox;
50    unsigned int               width, height;
51    Eina_Array                 cleanup;
52    double                     align_x, align_y;
53    Efl_Canvas_Vg_Fill_Mode    fill_mode;
54    int                        frame_idx;
55    void                      *ckeys[2];  //cache keys for first, last frames if animation
56 
57    Eina_Bool                  changed : 1;
58    Eina_Bool                  sync_render : 1;
59 };
60 
61 struct _Efl_Canvas_Vg_Node_Data
62 {
63    Eina_Matrix3 *m;
64    Efl_Canvas_Vg_Interpolation *intp;
65 
66    Ector_Renderer *renderer;
67 
68    Efl_VG *vg_obj;
69    Efl_Canvas_Vg_Object_Data *vd;
70 
71    void (*render_pre)(Evas_Object_Protected_Data *vg_pd, Efl_VG *node,
72          Efl_Canvas_Vg_Node_Data *nd,
73          void *engine, void *output, void *contenxt, Ector_Surface *surface,
74          Eina_Matrix3 *ptransform, int opacity, Ector_Buffer *comp, Efl_Gfx_Vg_Composite_Method comp_method, void *data);
75    void *data;
76 
77    double x, y;
78    int r, g, b, a;
79    Efl_Gfx_Change_Flag flags;
80 
81    Eina_Bool visibility : 1;
82    Eina_Bool changed : 1;
83 };
84 
85 typedef struct _Vg_Composite
86 {
87    Evas_Object_Protected_Data *vg_pd;      //Vector Object (for accessing backend engine)
88    Ector_Buffer *buffer;                   //Composite Ector Buffer
89    void *pixels;                           //Composite pixel buffer (actual data)
90    unsigned int length;                    //pixel buffer data size
91    unsigned int stride;                    //pixel buffer stride
92    Eina_Size2D size;                       //Composite boundary
93    Eina_List *src;                         //Composite Sources
94    Efl_Gfx_Vg_Composite_Method method;     //Composite Method
95 } Vg_Comp;
96 
97 struct _Efl_Canvas_Vg_Container_Data
98 {
99    Eina_List *children;
100    Eina_Hash *names;
101 
102    //Composite feature.
103    Efl_Canvas_Vg_Node *comp_target; //Composite target
104    Vg_Comp comp;                    //Composite target data
105 
106    /* Layer transparency feature.
107       This buffer is only valid when the layer has transparency. */
108    struct {
109         Ector_Buffer *buffer;
110         void *pixels;
111         unsigned int length;                //blend buffer data size
112         unsigned int stride;                //blend buffer stride
113    } blend;
114 };
115 
116 struct _Efl_Canvas_Vg_Gradient_Data
117 {
118    // FIXME: Later on we should deduplicate it somehow (Using Ector ?).
119    Efl_Gfx_Gradient_Stop *colors;
120    unsigned int colors_count;
121 
122    Efl_Gfx_Gradient_Spread spread;
123 };
124 
125 struct _Efl_Canvas_Vg_Interpolation
126 {
127    Eina_Quaternion rotation;
128    Eina_Quaternion perspective;
129    Eina_Point_3D translation;
130    Eina_Point_3D scale;
131    Eina_Point_3D skew;
132 };
133 
134 void                        evas_cache_vg_init(void);
135 void                        evas_cache_vg_shutdown(void);
136 Vg_Cache_Entry*             evas_cache_vg_entry_resize(Vg_Cache_Entry *entry, int w, int h);
137 Vg_Cache_Entry*             evas_cache_vg_entry_create(Evas *evas, const Eina_File *file, const char *key, int w, int h, Eina_List *vp_list);
138 Efl_VG*                     evas_cache_vg_tree_get(Vg_Cache_Entry *vg_entry, unsigned int frame_num);
139 void                        evas_cache_vg_entry_value_provider_update(Vg_Cache_Entry *vg_entry, Eina_List *vp_list);
140 void                        evas_cache_vg_entry_del(Vg_Cache_Entry *vg_entry);
141 Vg_File_Data *              evas_cache_vg_file_open(const Eina_File *file, const char *key, Evas *e, Eina_Bool shareable);
142 Eina_Bool                   evas_cache_vg_file_save(Efl_VG *root, int w, int h, const char *file, const char *key, const Efl_File_Save_Info *info);
143 Eina_Bool                   evas_cache_vg_entry_file_save(Vg_Cache_Entry *vg_entry, const char *file, const char *key, const Efl_File_Save_Info *info);
144 double                      evas_cache_vg_anim_duration_get(const Vg_Cache_Entry *vg_entry);
145 Eina_Bool                   evas_cache_vg_anim_sector_set(const Vg_Cache_Entry* vg_entry, const char *name, int startframe, int endframe);
146 Eina_Bool                   evas_cache_vg_anim_sector_get(const Vg_Cache_Entry* vg_entry, const char *name, int* startframe, int* endframe);
147 unsigned int                evas_cache_vg_anim_frame_count_get(const Vg_Cache_Entry *vg_entry);
148 Eina_Size2D                 evas_cache_vg_entry_default_size_get(const Vg_Cache_Entry *vg_entry);
149 void *                      evas_cache_vg_surface_key_get(Efl_Canvas_Vg_Node *root, int w, int h, int frame_idx);
150 void                        efl_canvas_vg_node_vg_obj_set(Efl_VG *node, Efl_VG *vg_obj, Efl_Canvas_Vg_Object_Data *vd);
151 void                        efl_canvas_vg_node_change(Efl_VG *node);
152 void                        efl_canvas_vg_container_vg_obj_update(Efl_VG *obj, Efl_Canvas_Vg_Node_Data *nd);
153 void                        efl_canvas_vg_container_blend_buffer_clear(Efl_VG *obj, Efl_Canvas_Vg_Container_Data *cd);
154 
155 static inline void
efl_canvas_vg_object_change(Efl_Canvas_Vg_Object_Data * vd)156 efl_canvas_vg_object_change(Efl_Canvas_Vg_Object_Data *vd)
157 {
158    if (!vd || (vd->changed && vd->obj->changed)) return;
159    vd->changed = EINA_TRUE;
160    evas_object_change(vd->obj->object, vd->obj);
161 }
162 
163 static inline Efl_Canvas_Vg_Node_Data *
_evas_vg_render_pre(Evas_Object_Protected_Data * vg_pd,Efl_VG * child,void * engine,void * output,void * context,Ector_Surface * surface,Eina_Matrix3 * transform,int opacity,Ector_Buffer * comp,Efl_Gfx_Vg_Composite_Method comp_method)164 _evas_vg_render_pre(Evas_Object_Protected_Data *vg_pd, Efl_VG *child,
165                     void *engine, void *output, void *context,
166                     Ector_Surface *surface,
167                     Eina_Matrix3 *transform,
168                     int opacity,
169                     Ector_Buffer *comp, Efl_Gfx_Vg_Composite_Method comp_method)
170 {
171    if (!child) return NULL;
172    Efl_Canvas_Vg_Node_Data *nd = efl_data_scope_get(child, EFL_CANVAS_VG_NODE_CLASS);
173    if (nd) nd->render_pre(vg_pd, child, nd,
174                           engine, output, context, surface,
175                           transform, opacity, comp, comp_method, nd->data);
176    return nd;
177 }
178 
179 #define EFL_CANVAS_VG_COMPUTE_MATRIX(Current, Parent, Nd)                      \
180   Eina_Matrix3 *Current = Nd->m;                                        \
181   Eina_Matrix3 _matrix_tmp;                                             \
182                                                                         \
183   if (Parent)                                                           \
184     {                                                                   \
185        if (Current)                                                     \
186          {                                                              \
187             eina_matrix3_compose(Parent, Current, &_matrix_tmp);        \
188             Current = &_matrix_tmp;                                     \
189          }                                                              \
190        else                                                             \
191          {                                                              \
192             eina_matrix3_identity(&_matrix_tmp);                        \
193             eina_matrix3_translate(&_matrix_tmp, -(Nd->x), -(Nd->y));   \
194             eina_matrix3_compose(Parent, &_matrix_tmp, &_matrix_tmp);   \
195             eina_matrix3_translate(&_matrix_tmp, (Nd->x), (Nd->y));     \
196             Current = &_matrix_tmp;                                     \
197          }                                                              \
198     }
199 
200 #define EFL_CANVAS_VG_COMPUTE_ALPHA(Current_r, Current_g, Current_b, Current_a, Parent_Opacity, Nd)   \
201   int Current_r = Nd->r;                                                \
202   int Current_g = Nd->g;                                                \
203   int Current_b = Nd->b;                                                \
204   int Current_a = Nd->a;                                                \
205                                                                         \
206   if (Parent_Opacity < 255)                                             \
207     {                                                                   \
208        double pa = (double)Parent_Opacity / 255.0;                      \
209        Current_r = (double)Current_r * pa;                              \
210        Current_g = (double)Current_g * pa;                              \
211        Current_b = (double)Current_b * pa;                              \
212        Current_a = (double)Current_a * pa;                              \
213     }
214 
215 #endif
216