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