forked from enlightenment/efl
Evas filters: Add transform filter
This is the simplest solution I can come up with for "mirror" effects. Displacement maps are HARD to generate and use properly, since the buffer size is unknown until runtime. Even if we align the map to the text itself (using the padding information), it's still hard to describe properly how to apply the displacement map, and to generate it... So let's just add a simple flip operation.
This commit is contained in:
parent
388a30950a
commit
d9fb0cdc34
|
@ -374,6 +374,7 @@ lib/evas/filters/evas_filter_curve.c \
|
|||
lib/evas/filters/evas_filter_displace.c \
|
||||
lib/evas/filters/evas_filter_mask.c \
|
||||
lib/evas/filters/evas_filter_parser.c \
|
||||
lib/evas/filters/evas_filter_transform.c \
|
||||
lib/evas/filters/evas_filter_utils.c
|
||||
|
||||
|
||||
|
|
|
@ -1047,6 +1047,39 @@ end:
|
|||
return cmdid;
|
||||
}
|
||||
|
||||
int
|
||||
evas_filter_command_transform_add(Evas_Filter_Context *ctx, void *draw_context,
|
||||
int inbuf, int outbuf,
|
||||
Evas_Filter_Transform_Flags flags)
|
||||
{
|
||||
Evas_Filter_Command *cmd;
|
||||
Evas_Filter_Buffer *in, *out;
|
||||
|
||||
EINA_SAFETY_ON_NULL_RETURN_VAL(ctx, -1);
|
||||
|
||||
in = _filter_buffer_get(ctx, inbuf);
|
||||
out = _filter_buffer_get(ctx, outbuf);
|
||||
if (!in || !out)
|
||||
{
|
||||
ERR("Invalid buffer id: input %d [%p], output %d [%p]",
|
||||
inbuf, in, outbuf, out);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (in->alpha_only != out->alpha_only)
|
||||
{
|
||||
CRI("Incompatible buffer formats");
|
||||
return -1;
|
||||
}
|
||||
|
||||
cmd = _command_new(ctx, EVAS_FILTER_MODE_TRANSFORM, in, NULL, out);
|
||||
if (!cmd) return -1;
|
||||
|
||||
cmd->transform.flags = flags;
|
||||
|
||||
return cmd->id;
|
||||
}
|
||||
|
||||
static Eina_Bool
|
||||
_fill_cpu(Evas_Filter_Command *cmd)
|
||||
{
|
||||
|
@ -1248,6 +1281,9 @@ _filter_command_run(Evas_Filter_Command *cmd)
|
|||
case EVAS_FILTER_MODE_BUMP:
|
||||
func = evas_filter_bump_map_cpu_func_get(cmd);
|
||||
break;
|
||||
case EVAS_FILTER_MODE_TRANSFORM:
|
||||
func = evas_filter_transform_cpu_func_get(cmd);
|
||||
break;
|
||||
default:
|
||||
CRI("Invalid filter mode.");
|
||||
break;
|
||||
|
|
|
@ -103,6 +103,11 @@ struct _Evas_Filter_Command
|
|||
Eina_Bool compensate : 1; // Compensate for darkening
|
||||
//Eina_Bool specular : 1; // Use specular light as well (needs specular_factor > 0)
|
||||
} bump;
|
||||
|
||||
struct
|
||||
{
|
||||
Evas_Filter_Transform_Flags flags;
|
||||
} transform;
|
||||
};
|
||||
|
||||
struct {
|
||||
|
@ -158,6 +163,7 @@ Evas_Filter_Apply_Func evas_filter_curve_cpu_func_get(Evas_Filter_Command *cmd
|
|||
Evas_Filter_Apply_Func evas_filter_displace_cpu_func_get(Evas_Filter_Command *cmd);
|
||||
Evas_Filter_Apply_Func evas_filter_fill_cpu_func_get(Evas_Filter_Command *cmd);
|
||||
Evas_Filter_Apply_Func evas_filter_mask_cpu_func_get(Evas_Filter_Command *cmd);
|
||||
Evas_Filter_Apply_Func evas_filter_transform_cpu_func_get(Evas_Filter_Command *cmd);
|
||||
|
||||
/* Utility functions */
|
||||
void _clip_to_target(int *sx, int *sy, int sw, int sh, int ox, int oy, int dw, int dh, int *dx, int *dy, int *rows, int *cols);
|
||||
|
|
|
@ -0,0 +1,65 @@
|
|||
#include "evas_filter_private.h"
|
||||
|
||||
static Eina_Bool
|
||||
_vflip_cpu(Evas_Filter_Command *cmd)
|
||||
{
|
||||
size_t datasize, stride;
|
||||
DATA8 *in, *out, *span;
|
||||
int w, h, sy, dy;
|
||||
|
||||
EINA_SAFETY_ON_NULL_RETURN_VAL(cmd, EINA_FALSE);
|
||||
EINA_SAFETY_ON_NULL_RETURN_VAL(cmd->input, EINA_FALSE);
|
||||
EINA_SAFETY_ON_NULL_RETURN_VAL(cmd->output, EINA_FALSE);
|
||||
EINA_SAFETY_ON_NULL_RETURN_VAL(cmd->input->backing, EINA_FALSE);
|
||||
EINA_SAFETY_ON_NULL_RETURN_VAL(cmd->output->backing, EINA_FALSE);
|
||||
|
||||
w = cmd->input->w;
|
||||
h = cmd->input->h;
|
||||
EINA_SAFETY_ON_FALSE_RETURN_VAL(cmd->output->w == w, EINA_FALSE);
|
||||
EINA_SAFETY_ON_FALSE_RETURN_VAL(cmd->output->h == h, EINA_FALSE);
|
||||
EINA_SAFETY_ON_FALSE_RETURN_VAL(cmd->output->alpha_only == cmd->input->alpha_only, EINA_FALSE);
|
||||
|
||||
in = ((RGBA_Image *) cmd->input->backing)->mask.data;
|
||||
out = ((RGBA_Image *) cmd->output->backing)->mask.data;
|
||||
datasize = cmd->input->alpha_only ? sizeof(DATA8) : sizeof(DATA32);
|
||||
stride = w * datasize;
|
||||
|
||||
if (in == out)
|
||||
{
|
||||
span = malloc(stride);
|
||||
if (!span) return EINA_FALSE;
|
||||
}
|
||||
|
||||
for (sy = 0, dy = h - 1; dy >= 0; sy++, dy--)
|
||||
{
|
||||
DATA8* src = in + stride * sy;
|
||||
DATA8* dst = out + stride * dy;
|
||||
|
||||
if (in == out)
|
||||
{
|
||||
memcpy(span, dst, stride);
|
||||
memcpy(dst, src, stride);
|
||||
memcpy(src, span, stride);
|
||||
if (sy >= (h / 2)) break;
|
||||
}
|
||||
else
|
||||
memcpy(dst, src, stride);
|
||||
}
|
||||
|
||||
return EINA_TRUE;
|
||||
}
|
||||
|
||||
Evas_Filter_Apply_Func
|
||||
evas_filter_transform_cpu_func_get(Evas_Filter_Command *cmd)
|
||||
{
|
||||
EINA_SAFETY_ON_NULL_RETURN_VAL(cmd, NULL);
|
||||
|
||||
switch (cmd->transform.flags)
|
||||
{
|
||||
case EVAS_FILTER_TRANSFORM_VFLIP:
|
||||
return _vflip_cpu;
|
||||
default:
|
||||
CRI("Unknown transform flag %d", (int) cmd->transform.flags);
|
||||
return NULL;
|
||||
}
|
||||
}
|
|
@ -14,6 +14,7 @@ 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 Eina_Bool (* Evas_Filter_Apply_Func) (Evas_Filter_Command *cmd);
|
||||
typedef void (* Evas_Filter_Cb) (Evas_Filter_Context *ctx, void *data);
|
||||
|
@ -30,6 +31,7 @@ enum _Evas_Filter_Mode
|
|||
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_LAST
|
||||
};
|
||||
|
||||
|
@ -79,6 +81,11 @@ enum _Evas_Filter_Fill_Mode
|
|||
EVAS_FILTER_FILL_MODE_STRETCH_XY = EVAS_FILTER_FILL_MODE_STRETCH_X | EVAS_FILTER_FILL_MODE_STRETCH_Y
|
||||
};
|
||||
|
||||
enum _Evas_Filter_Transform_Flags
|
||||
{
|
||||
EVAS_FILTER_TRANSFORM_VFLIP = 1
|
||||
};
|
||||
|
||||
/* Parser stuff (high level API) */
|
||||
Evas_Filter_Program *evas_filter_program_new(const char *name);
|
||||
Eina_Bool evas_filter_program_parse(Evas_Filter_Program *pgm, const char *str);
|
||||
|
@ -213,5 +220,16 @@ int evas_filter_command_mask_add(Evas_Filter_Context *ctx,
|
|||
*/
|
||||
int 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)
|
||||
* @return Filter command ID or -1 in case of error
|
||||
*/
|
||||
int evas_filter_command_transform_add(Evas_Filter_Context *ctx, void *draw_context, int inbuf, int outbuf, Evas_Filter_Transform_Flags flags);
|
||||
|
||||
#endif
|
||||
|
||||
|
|
Loading…
Reference in New Issue