1 #ifndef _EVAS_FILTER_H
2 #define _EVAS_FILTER_H
3 
4 #include "evas_common_private.h"
5 #include "evas_private.h"
6 
7 
8 #ifdef EAPI
9 # undef EAPI
10 #endif
11 
12 #ifdef _WIN32
13 # ifdef EFL_BUILD
14 #  ifdef DLL_EXPORT
15 #   define EAPI __declspec(dllexport)
16 #  else
17 #   define EAPI
18 #  endif
19 # else
20 #  define EAPI __declspec(dllimport)
21 # endif
22 #else
23 # ifdef __GNUC__
24 #  if __GNUC__ >= 4
25 #   define EAPI __attribute__ ((visibility("default")))
26 #  else
27 #   define EAPI
28 #  endif
29 # else
30 #  define EAPI
31 # endif
32 #endif
33 
34 #include "efl_canvas_filter_internal.eo.h"
35 
36 #ifdef DEBUG
37 # define FILTERS_DEBUG
38 #endif
39 
40 typedef struct _Evas_Filter_Instruction Evas_Filter_Instruction;
41 typedef struct _Evas_Filter_Buffer Evas_Filter_Buffer;
42 typedef struct _Evas_Filter_Proxy_Binding Evas_Filter_Proxy_Binding;
43 typedef struct _Evas_Filter_Padding Evas_Filter_Padding;
44 typedef enum _Evas_Filter_Mode Evas_Filter_Mode;
45 typedef enum _Evas_Filter_Blur_Type Evas_Filter_Blur_Type;
46 typedef enum _Evas_Filter_Channel Evas_Filter_Channel;
47 typedef enum _Evas_Filter_Displacement_Flags Evas_Filter_Displacement_Flags;
48 typedef enum _Evas_Filter_Bump_Flags Evas_Filter_Bump_Flags;
49 typedef enum _Evas_Filter_Fill_Mode Evas_Filter_Fill_Mode;
50 typedef enum _Evas_Filter_Transform_Flags Evas_Filter_Transform_Flags;
51 
52 typedef void (* Evas_Filter_Cb) (Evas_Filter_Context *ctx, void *data, Eina_Bool success);
53 
54 #define EVAS_FILTER_BUFFER_RGBA  EINA_FALSE
55 #define EVAS_FILTER_BUFFER_ALPHA EINA_TRUE
56 
57 #define EVAS_FILTER_BUFFER_INPUT_ID  1
58 #define EVAS_FILTER_BUFFER_OUTPUT_ID 2
59 
60 /** @internal */
61 enum _Evas_Filter_Mode
62 {
63    EVAS_FILTER_MODE_SKIP,         /**< No operation */
64    EVAS_FILTER_MODE_BLEND,        /**< Blend with current context render_op */
65    EVAS_FILTER_MODE_BLUR,         /**< @see Evas_Filter_Blur_Type */
66    EVAS_FILTER_MODE_CURVE,        /**< Apply color curve */
67    EVAS_FILTER_MODE_DISPLACE,     /**< Apply XY displacement based on RG mask */
68    EVAS_FILTER_MODE_FILL,         /**< Fill a buffer with a solid color */
69    EVAS_FILTER_MODE_MASK,         /**< Apply Alpha or RGBA texture on image */
70    EVAS_FILTER_MODE_BUMP,         /**< Apply bump mapping (light effect) */
71    EVAS_FILTER_MODE_TRANSFORM,    /**< Apply a simple geometrical transformation */
72    EVAS_FILTER_MODE_PADDING_SET,  /**< Special padding_set instruction to force a specific padding value */
73    EVAS_FILTER_MODE_GRAYSCALE,    /**< Leave only grayscale information */
74    EVAS_FILTER_MODE_INVERSE_COLOR,/**< Apply inverse color */
75    EVAS_FILTER_MODE_LAST
76 };
77 
78 /** @internal */
79 enum _Evas_Filter_Blur_Type
80 {
81    EVAS_FILTER_BLUR_DEFAULT  = 0x0, // Default blur (GAUSSIAN or series of BOX)
82    EVAS_FILTER_BLUR_BOX      = 0x1, // Optimizable on CPU. But, UGLY. O(n)
83    EVAS_FILTER_BLUR_GAUSSIAN = 0x2, // Gaussian blur (using sine curve)
84    EVAS_FILTER_BLUR_LAST,
85 };
86 
87 /** @internal */
88 enum _Evas_Filter_Channel
89 {
90    EVAS_FILTER_CHANNEL_ALPHA = 0,
91    EVAS_FILTER_CHANNEL_RED   = 1,
92    EVAS_FILTER_CHANNEL_GREEN = 2,
93    EVAS_FILTER_CHANNEL_BLUE  = 3,
94    EVAS_FILTER_CHANNEL_RGB   = 4
95 };
96 
97 /** @internal */
98 enum _Evas_Filter_Displacement_Flags
99 {
100    EVAS_FILTER_DISPLACE_NEAREST  = 0x0,   /**< Interpolate between pixels (linear interpolation) */
101    EVAS_FILTER_DISPLACE_LINEAR   = 0x1,   /**< Interpolate between pixels (linear interpolation) */
102    EVAS_FILTER_DISPLACE_BLACK    = 0x0,   /**< Use black (or transparent) when going out of bounds) */
103    EVAS_FILTER_DISPLACE_STRETCH  = 0x2,   /**< Stretch border pixels when going out of bounds */
104    EVAS_FILTER_DISPLACE_BITMASK  = 0x3
105 };
106 
107 /** @internal */
108 enum _Evas_Filter_Bump_Flags
109 {
110    EVAS_FILTER_BUMP_NORMAL       = 0x0,
111    EVAS_FILTER_BUMP_COMPENSATE   = 0x1    /**< Compensate for darkening (diffuse light) or brightening (specular light) of zero gradient surfaces */
112 };
113 
114 /** @internal */
115 enum _Evas_Filter_Fill_Mode
116 {
117    EVAS_FILTER_FILL_MODE_NONE               = 0x0,
118    EVAS_FILTER_FILL_MODE_STRETCH_X          = 0x1,
119    EVAS_FILTER_FILL_MODE_STRETCH_Y          = 0x2,
120    EVAS_FILTER_FILL_MODE_REPEAT_X           = 0x4,
121    EVAS_FILTER_FILL_MODE_REPEAT_Y           = 0x8,
122    EVAS_FILTER_FILL_MODE_REPEAT_X_STRETCH_Y = EVAS_FILTER_FILL_MODE_REPEAT_X | EVAS_FILTER_FILL_MODE_STRETCH_Y,
123    EVAS_FILTER_FILL_MODE_REPEAT_Y_STRETCH_X = EVAS_FILTER_FILL_MODE_REPEAT_Y | EVAS_FILTER_FILL_MODE_STRETCH_X,
124    EVAS_FILTER_FILL_MODE_REPEAT_XY          = EVAS_FILTER_FILL_MODE_REPEAT_X | EVAS_FILTER_FILL_MODE_REPEAT_Y,
125    EVAS_FILTER_FILL_MODE_STRETCH_XY         = EVAS_FILTER_FILL_MODE_STRETCH_X | EVAS_FILTER_FILL_MODE_STRETCH_Y
126 };
127 
128 /** @internal */
129 enum _Evas_Filter_Transform_Flags
130 {
131    EVAS_FILTER_TRANSFORM_VFLIP = 1
132 };
133 
134 /** @internal */
135 struct _Evas_Filter_Padding
136 {
137    int l, r, t, b;
138 };
139 
140 #define EFL_CANVAS_FILTER_STATE_DEFAULT { {}, { 255, 255, 255, 255 }, { "default", 0.0 }, {}, 0, 0, 1.0, 0.0 }
141 
142 /* Parser stuff (high level API) */
143 EAPI Evas_Filter_Program *evas_filter_program_new(const char *name, Eina_Bool input_alpha);
144 EAPI Eina_Bool           evas_filter_program_state_set(Evas_Filter_Program *pgm, const Efl_Canvas_Filter_State *state);
145 EAPI Eina_Bool           evas_filter_program_parse(Evas_Filter_Program *pgm, const char *str);
146 EAPI void                evas_filter_program_del(Evas_Filter_Program *pgm);
147 EAPI Eina_Bool           evas_filter_program_padding_get(Evas_Filter_Program *pgm, Evas_Filter_Padding *final, Evas_Filter_Padding *calc);
148 EAPI void                evas_filter_program_source_set_all(Evas_Filter_Program *pgm, Eina_Hash *sources);
149 void                     evas_filter_program_data_set_all(Evas_Filter_Program *pgm, Eina_Inlist *data);
150 
151 /* Filter context (low level) */
152 Evas_Filter_Context     *evas_filter_context_new(Evas_Public_Data *evas, Eina_Bool async, void *user_data);
153 void                    *evas_filter_context_data_get(Evas_Filter_Context *ctx);
154 Eina_Bool                evas_filter_context_async_get(Evas_Filter_Context *ctx);
155 void                     evas_filter_context_size_get(Evas_Filter_Context *ctx, int *w, int *H);
156 int                      evas_filter_context_ref(Evas_Filter_Context *ctx);
157 void                     evas_filter_context_unref(Evas_Filter_Context *ctx);
158 Eina_Bool                evas_filter_context_program_use(void *engine, void *output, Evas_Filter_Context *ctx, Evas_Filter_Program *pgm, Eina_Bool reuse, int object_x, int object_y);
159 void                     evas_filter_context_proxy_render_all(Evas_Filter_Context *ctx, Eo *eo_obj, void *output, Eina_Bool do_async);
160 void                     evas_filter_context_post_run_callback_set(Evas_Filter_Context *ctx, Evas_Filter_Cb cb, void *data);
161 Eina_Bool                evas_filter_context_buffers_allocate_all(Evas_Filter_Context *ctx);
162 void                     evas_filter_context_obscured_region_set(Evas_Filter_Context *ctx, Eina_Rectangle rect);
163 
164 int                      evas_filter_buffer_empty_new(Evas_Filter_Context *ctx, int w, int h, Eina_Bool alpha_only);
165 int                      evas_filter_buffer_proxy_new(Evas_Filter_Context *ctx, Evas_Filter_Proxy_Binding *pb, int *w, int *h);
166 void                    *evas_filter_buffer_backing_get(Evas_Filter_Context *ctx, int bufid, Eina_Bool render);
167 Eina_Bool                evas_filter_buffer_backing_set(Evas_Filter_Context *ctx, int bufid, void *engine_buffer);
168 
169 Eina_Bool                evas_filter_context_run(void *engine, void *output, Evas_Filter_Context *ctx);
170 
171 Eina_Bool                evas_filter_font_draw(Evas_Filter_Context *ctx, void *engine, void *output, void *draw_context, int bufid, Evas_Font_Set *font, int x, int y, Evas_Text_Props *text_props, Eina_Bool do_async);
172 Eina_Bool                evas_filter_target_set(Evas_Filter_Context *ctx, void *draw_context, void *surface, int x, int y, const RGBA_Map *map);
173 
174 // utility function
175 void                     _evas_filter_source_hash_free_cb(void *data);
176 
177 /**
178  * @brief Blend a source buffer into a destination buffer, allowing X,Y offsets, Alpha to RGBA conversion with color
179  * @param ctx            Current filter chain
180  * @param draw_context   Current Evas draw context. Current color is used when inbuf is ALPHA and outbuf is RGBA.
181  * @param inbuf          Source buffer: ALPHA or RGBA
182  * @param outbuf         Destination buffer: ALPHA or RGBA (note: must be RGBA if inbuf is RGBA)
183  * @param ox             X offset in the destination buffer
184  * @param oy             Y offset in the destination buffer
185  * @param fillmode       Specifies whether to repeat or stretch the input onto its destination, and on which axes
186  * @param alphaonly      If true, discard RGB during RGBA -> Alpha conversions.
187  * @return               Filter command ID or -1 in case of error
188  * @internal
189  */
190 Evas_Filter_Command     *evas_filter_command_blend_add(Evas_Filter_Context *ctx, void *draw_context, int inbuf, int outbuf, int ox, int oy, Evas_Filter_Fill_Mode fillmode, Eina_Bool alphaonly);
191 
192 /**
193  * @brief Apply a blur effect on a buffer
194  * @param ctx            Current filter chain
195  * @param draw_context   Current Evas draw context. Current color is used when inbuf is ALPHA and outbuf is RGBA.
196  * @param inbuf          Source buffer: ALPHA or RGBA
197  * @param outbuf         Destination buffer: ALPHA or RGBA (note: must be RGBA if inbuf is RGBA)
198  * @param type           Type of blur: BOX, GAUSSIAN or MOTION
199  * @param dx             X radius of blur. Can be negative ONLY for MOTION blur
200  * @param dy             Y radius of blur. Can be negative ONLY for MOTION blur
201  * @param ox             X offset in the destination buffer
202  * @param oy             Y offset in the destination buffer
203  * @param count          Number of times to repeat the operation (used for smooth fast blurs with box blur)
204  * @param alphaonly      If true, discard RGB during RGBA -> Alpha conversions.
205  * @return               Filter command ID or -1 in case of error
206  * @internal
207  */
208 Evas_Filter_Command     *evas_filter_command_blur_add(Evas_Filter_Context *ctx, void *draw_context, int inbuf, int outbuf, Evas_Filter_Blur_Type type, int dx, int dy, int ox, int oy, int count, Eina_Bool alphaonly);
209 
210 /**
211  * @brief Fill a buffer with the current color
212  * @param ctx            Current filter chain
213  * @param draw_context   Current Evas draw context. Current color is used when buf is RGBA, and clip is used to specify the fill area.
214  * @param buf            Buffer: ALPHA or RGBA
215  * @return               Filter command ID or -1 in case of error
216  * @note The current draw context's render operation is ignored (always uses COPY mode).
217  * @internal
218  */
219 Evas_Filter_Command     *evas_filter_command_fill_add(Evas_Filter_Context *ctx, void *draw_context, int buf);
220 
221 /**
222  * @brief evas_filter_command_curve_add
223  * @param ctx            Current filter chain
224  * @param draw_context   Current Evas draw context. Current color is used when buf is RGBA, and clip is used to specify the fill area.
225  * @param inbuf          Input buffer, ALPHA or RGBA.
226  * @param outbuf         Output buffer, must have same colorspace as inbuf.
227  * @param curve          The data points to use, must contain 256 values.
228  * @param channel        Which channel to apply the curve (red, green, blue, alpha or RGB)
229  * @return               Filter command ID or -1 in case of error
230  * @internal
231  */
232 Evas_Filter_Command     *evas_filter_command_curve_add(Evas_Filter_Context *ctx, void *draw_context, int inbuf, int outbuf, DATA8 *curve /* 256 elements */, Evas_Filter_Channel channel);
233 
234 /**
235  * @brief Grow/Shrink an image, as defined in image processing (this is not a scale algorithm!)
236  * @param ctx            Current filter chain
237  * @param draw_context   Current Evas draw context. Current color is used when inbuf is ALPHA and outbuf is RGBA.
238  * @param inbuf          Source buffer: ALPHA or RGBA
239  * @param outbuf         Destination buffer: ALPHA or RGBA (note: must be RGBA if inbuf is RGBA)
240  * @param radius         Number of pixels to grow by. If negative, shrink instead of grow
241  * @param smooth         Use smooth blur and curve for grow (default: true)
242  * @param alphaonly      If true, discard RGB during RGBA -> Alpha conversions.
243  * @return               Filter command ID or -1 in case of error
244  * @internal
245  */
246 Evas_Filter_Command     *evas_filter_command_grow_add(Evas_Filter_Context *ctx, void *draw_context, int inbuf, int outbuf, int radius, Eina_Bool smooth, Eina_Bool alphaonly);
247 
248 /**
249  * @brief Apply a displacement map to a buffer. This will move pixels from the source to the destination based on pixel per pixel offset, as defined in the displacement map
250  * @param ctx            Current filter chain
251  * @param draw_context   Current Evas draw context (ignored)
252  * @param inbuf          Input buffer (Alpha or RGBA)
253  * @param outbuf         Output buffer (Alpha or RGBA), same size as inbuf
254  * @param dispbuf        Displacement map. Should be an RGBA buffer, where the Red and Green channels are the displacement maps for X and Y. Can be also ALPHA buffer, in which case only one dimension can be specified (X or Y).
255  * @param flags          Alters how the map is interpreted, @see Evas_Filter_Displacement_Flags
256  * @param intensity      Maximum offset possible, if the map's value is maximal at this point (ie. 0 or 255)
257  * @param fillmode       Specifies how to repeat and stretch the map to fit the target size
258  * @return               Filter command ID or -1 in case of error
259  * @internal
260  */
261 Evas_Filter_Command     *evas_filter_command_displacement_map_add(Evas_Filter_Context *ctx, void *draw_context, int inbuf, int outbuf, int dispbuf, Evas_Filter_Displacement_Flags flags, int intensity, Evas_Filter_Fill_Mode fillmode);
262 
263 /**
264  * @brief Apply a texture to a buffer
265  * @param ctx            Current filter chain
266  * @param draw_context   Current Evas draw context (ignored)
267  * @param inbuf          Input buffer (Alpha or RGBA)
268  * @param maskbuf        Texture buffer (Alpha or RGBA)
269  * @param outbuf         Output buffer (Alpha or RGBA)
270  * @param fillmode       Specifies how to repeat and stretch the mask to fit the target size
271  * @return               Filter command ID or -1 in case of error
272  * @note For the moment, inbuf can only be ALPHA, and output must be RGBA if mask is RGBA as well
273  * @internal
274  */
275 Evas_Filter_Command     *evas_filter_command_mask_add(Evas_Filter_Context *ctx, void *draw_context, int inbuf, int maskbuf, int outbuf, Evas_Filter_Fill_Mode fillmode);
276 
277 /**
278  * @brief Apply a relief effect based on a bump map (Z map)
279  * @param ctx              Current filter chain
280  * @param draw_context     Current Evas draw context (ignored)
281  * @param inbuf            Input buffer (Alpha or RGBA)
282  * @param bumpbuf          Bump map (Alpha only), same size as inbuf. By definition, lows are black (alpha 0) and highs are white (alpha 255).
283  * @param outbuf           Output buffer (Alpha or RGBA), same size as inbuf
284  * @param azimuth          CCW angle in degrees from the X axis of the light direction. 0 is light from the right, 90 from the top, 180 from the left, 270 from the bottom. All values are valid.
285  * @param elevation        Angle in degrees between the XY plane and the light. Only values from 0 (light is perfectly horizontal) to 90 (light comes from the viewer herself) are acceptable.
286  * @param depth            Max depth in the bump map. Default value is 10.
287  * @param specular_factor  Factor for the specular light effect (shininess). Ranges from 1.0 to 1000+ with logarithmic effects
288  * @param black            Darkest color, defines the ambiant light
289  * @param color            Light's normal color
290  * @param white            Brightest color, used in the shininess effect
291  * @param flags            Optional flags: compensation for darkening
292  * @param fillmode         Specifies how to repeat and stretch the map to fit the target size
293  * @return                 Filter command ID or -1 in case of error
294  * @internal
295  */
296 Evas_Filter_Command     *evas_filter_command_bump_map_add(Evas_Filter_Context *ctx, void *draw_context, int inbuf, int bumpbuf, int outbuf, float azimuth, float elevation, float depth, float specular_factor, DATA32 black, DATA32 color, DATA32 white, Evas_Filter_Bump_Flags flags, Evas_Filter_Fill_Mode fillmode);
297 
298 /**
299  * @brief Apply a geometrical transformation to the buffer
300  * @param ctx            Current filter chain
301  * @param draw_context   Current Evas draw context (ignored)
302  * @param inbuf          Input buffer (Alpha or RGBA)
303  * @param outbuf         Output buffer (Alpha or RGBA), same size as inbuf
304  * @param flags          Specifies the operation to apply (eg. vflip)
305  * @param ox             X offset
306  * @param oy             Y offset
307  * @return               Filter command ID or -1 in case of error
308  * @internal
309  */
310 Evas_Filter_Command     *evas_filter_command_transform_add(Evas_Filter_Context *ctx, void *draw_context, int inbuf, int outbuf, Evas_Filter_Transform_Flags flags, int ox, int oy);
311 
312 /**
313  * @brief Remove color information from the buffer
314  * @param ctx            Current filter chain
315  * @param draw_context   Current Evas draw context (ignored)
316  * @param inbuf          Input buffer (Alpha or RGBA)
317  * @param outbuf         Output buffer (Alpha or RGBA), same size as inbuf
318  * @return               Filter command or NULL in case of error
319  * @internal
320  */
321 Evas_Filter_Command     *evas_filter_command_grayscale_add(Evas_Filter_Context *ctx, void *draw_context, int inbuf, int outbuf);
322 
323 /**
324  * @brief Apply inverse color of the buffer
325  * @param ctx            Current filter chain
326  * @param draw_context   Current Evas draw context (ignored)
327  * @param inbuf          Input buffer (Alpha or RGBA)
328  * @param outbuf         Output buffer (Alpha or RGBA), same size as inbuf
329  * @return               Filter command or NULL in case of error
330  * @internal
331  */
332 Evas_Filter_Command     *evas_filter_command_inverse_color_add(Evas_Filter_Context *ctx, void *draw_context, int inbuf, int outbuf);
333 
334 /* Simple binding between a filter object and its sources */
335 struct _Evas_Filter_Proxy_Binding
336 {
337    Evas_Object *eo_proxy;
338    Evas_Object *eo_source;
339    Eina_Stringshare *name;
340 };
341 
342 struct _Evas_Filter_Data_Binding
343 {
344    EINA_INLIST;
345    Eina_Stringshare *name;
346    Eina_Stringshare *value;
347    Eina_Bool execute : 1;
348 };
349 
350 #undef EAPI
351 #define EAPI
352 
353 #endif
354