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