summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJean-Philippe Andre <jp.andre@samsung.com>2014-01-07 16:44:10 +0900
committerJean-Philippe Andre <jp.andre@samsung.com>2014-02-07 17:33:17 +0900
commitd9fb0cdc34dd13dade8378842988863c1156cf1f (patch)
treebcb0bed12d87c2409ad0a5a7964d5c477b9362aa
parent388a30950a64352be96f0d99c8c849a0f307d4b8 (diff)
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.
-rw-r--r--src/Makefile_Evas.am1
-rw-r--r--src/lib/evas/filters/evas_filter.c36
-rw-r--r--src/lib/evas/filters/evas_filter_private.h6
-rw-r--r--src/lib/evas/filters/evas_filter_transform.c65
-rw-r--r--src/lib/evas/include/evas_filter.h18
5 files changed, 126 insertions, 0 deletions
diff --git a/src/Makefile_Evas.am b/src/Makefile_Evas.am
index 746da4b582..f983f03c29 100644
--- a/src/Makefile_Evas.am
+++ b/src/Makefile_Evas.am
@@ -374,6 +374,7 @@ lib/evas/filters/evas_filter_curve.c \
374lib/evas/filters/evas_filter_displace.c \ 374lib/evas/filters/evas_filter_displace.c \
375lib/evas/filters/evas_filter_mask.c \ 375lib/evas/filters/evas_filter_mask.c \
376lib/evas/filters/evas_filter_parser.c \ 376lib/evas/filters/evas_filter_parser.c \
377lib/evas/filters/evas_filter_transform.c \
377lib/evas/filters/evas_filter_utils.c 378lib/evas/filters/evas_filter_utils.c
378 379
379 380
diff --git a/src/lib/evas/filters/evas_filter.c b/src/lib/evas/filters/evas_filter.c
index 5480a41863..c4ec46b21c 100644
--- a/src/lib/evas/filters/evas_filter.c
+++ b/src/lib/evas/filters/evas_filter.c
@@ -1047,6 +1047,39 @@ end:
1047 return cmdid; 1047 return cmdid;
1048} 1048}
1049 1049
1050int
1051evas_filter_command_transform_add(Evas_Filter_Context *ctx, void *draw_context,
1052 int inbuf, int outbuf,
1053 Evas_Filter_Transform_Flags flags)
1054{
1055 Evas_Filter_Command *cmd;
1056 Evas_Filter_Buffer *in, *out;
1057
1058 EINA_SAFETY_ON_NULL_RETURN_VAL(ctx, -1);
1059
1060 in = _filter_buffer_get(ctx, inbuf);
1061 out = _filter_buffer_get(ctx, outbuf);
1062 if (!in || !out)
1063 {
1064 ERR("Invalid buffer id: input %d [%p], output %d [%p]",
1065 inbuf, in, outbuf, out);
1066 return -1;
1067 }
1068
1069 if (in->alpha_only != out->alpha_only)
1070 {
1071 CRI("Incompatible buffer formats");
1072 return -1;
1073 }
1074
1075 cmd = _command_new(ctx, EVAS_FILTER_MODE_TRANSFORM, in, NULL, out);
1076 if (!cmd) return -1;
1077
1078 cmd->transform.flags = flags;
1079
1080 return cmd->id;
1081}
1082
1050static Eina_Bool 1083static Eina_Bool
1051_fill_cpu(Evas_Filter_Command *cmd) 1084_fill_cpu(Evas_Filter_Command *cmd)
1052{ 1085{
@@ -1248,6 +1281,9 @@ _filter_command_run(Evas_Filter_Command *cmd)
1248 case EVAS_FILTER_MODE_BUMP: 1281 case EVAS_FILTER_MODE_BUMP:
1249 func = evas_filter_bump_map_cpu_func_get(cmd); 1282 func = evas_filter_bump_map_cpu_func_get(cmd);
1250 break; 1283 break;
1284 case EVAS_FILTER_MODE_TRANSFORM:
1285 func = evas_filter_transform_cpu_func_get(cmd);
1286 break;
1251 default: 1287 default:
1252 CRI("Invalid filter mode."); 1288 CRI("Invalid filter mode.");
1253 break; 1289 break;
diff --git a/src/lib/evas/filters/evas_filter_private.h b/src/lib/evas/filters/evas_filter_private.h
index 5dd0c71143..6c417e3cb9 100644
--- a/src/lib/evas/filters/evas_filter_private.h
+++ b/src/lib/evas/filters/evas_filter_private.h
@@ -103,6 +103,11 @@ struct _Evas_Filter_Command
103 Eina_Bool compensate : 1; // Compensate for darkening 103 Eina_Bool compensate : 1; // Compensate for darkening
104 //Eina_Bool specular : 1; // Use specular light as well (needs specular_factor > 0) 104 //Eina_Bool specular : 1; // Use specular light as well (needs specular_factor > 0)
105 } bump; 105 } bump;
106
107 struct
108 {
109 Evas_Filter_Transform_Flags flags;
110 } transform;
106 }; 111 };
107 112
108 struct { 113 struct {
@@ -158,6 +163,7 @@ Evas_Filter_Apply_Func evas_filter_curve_cpu_func_get(Evas_Filter_Command *cmd
158Evas_Filter_Apply_Func evas_filter_displace_cpu_func_get(Evas_Filter_Command *cmd); 163Evas_Filter_Apply_Func evas_filter_displace_cpu_func_get(Evas_Filter_Command *cmd);
159Evas_Filter_Apply_Func evas_filter_fill_cpu_func_get(Evas_Filter_Command *cmd); 164Evas_Filter_Apply_Func evas_filter_fill_cpu_func_get(Evas_Filter_Command *cmd);
160Evas_Filter_Apply_Func evas_filter_mask_cpu_func_get(Evas_Filter_Command *cmd); 165Evas_Filter_Apply_Func evas_filter_mask_cpu_func_get(Evas_Filter_Command *cmd);
166Evas_Filter_Apply_Func evas_filter_transform_cpu_func_get(Evas_Filter_Command *cmd);
161 167
162/* Utility functions */ 168/* Utility functions */
163void _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); 169void _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);
diff --git a/src/lib/evas/filters/evas_filter_transform.c b/src/lib/evas/filters/evas_filter_transform.c
new file mode 100644
index 0000000000..7ae81d6c12
--- /dev/null
+++ b/src/lib/evas/filters/evas_filter_transform.c
@@ -0,0 +1,65 @@
1#include "evas_filter_private.h"
2
3static Eina_Bool
4_vflip_cpu(Evas_Filter_Command *cmd)
5{
6 size_t datasize, stride;
7 DATA8 *in, *out, *span;
8 int w, h, sy, dy;
9
10 EINA_SAFETY_ON_NULL_RETURN_VAL(cmd, EINA_FALSE);
11 EINA_SAFETY_ON_NULL_RETURN_VAL(cmd->input, EINA_FALSE);
12 EINA_SAFETY_ON_NULL_RETURN_VAL(cmd->output, EINA_FALSE);
13 EINA_SAFETY_ON_NULL_RETURN_VAL(cmd->input->backing, EINA_FALSE);
14 EINA_SAFETY_ON_NULL_RETURN_VAL(cmd->output->backing, EINA_FALSE);
15
16 w = cmd->input->w;
17 h = cmd->input->h;
18 EINA_SAFETY_ON_FALSE_RETURN_VAL(cmd->output->w == w, EINA_FALSE);
19 EINA_SAFETY_ON_FALSE_RETURN_VAL(cmd->output->h == h, EINA_FALSE);
20 EINA_SAFETY_ON_FALSE_RETURN_VAL(cmd->output->alpha_only == cmd->input->alpha_only, EINA_FALSE);
21
22 in = ((RGBA_Image *) cmd->input->backing)->mask.data;
23 out = ((RGBA_Image *) cmd->output->backing)->mask.data;
24 datasize = cmd->input->alpha_only ? sizeof(DATA8) : sizeof(DATA32);
25 stride = w * datasize;
26
27 if (in == out)
28 {
29 span = malloc(stride);
30 if (!span) return EINA_FALSE;
31 }
32
33 for (sy = 0, dy = h - 1; dy >= 0; sy++, dy--)
34 {
35 DATA8* src = in + stride * sy;
36 DATA8* dst = out + stride * dy;
37
38 if (in == out)
39 {
40 memcpy(span, dst, stride);
41 memcpy(dst, src, stride);
42 memcpy(src, span, stride);
43 if (sy >= (h / 2)) break;
44 }
45 else
46 memcpy(dst, src, stride);
47 }
48
49 return EINA_TRUE;
50}
51
52Evas_Filter_Apply_Func
53evas_filter_transform_cpu_func_get(Evas_Filter_Command *cmd)
54{
55 EINA_SAFETY_ON_NULL_RETURN_VAL(cmd, NULL);
56
57 switch (cmd->transform.flags)
58 {
59 case EVAS_FILTER_TRANSFORM_VFLIP:
60 return _vflip_cpu;
61 default:
62 CRI("Unknown transform flag %d", (int) cmd->transform.flags);
63 return NULL;
64 }
65}
diff --git a/src/lib/evas/include/evas_filter.h b/src/lib/evas/include/evas_filter.h
index 7496673789..1d1a171399 100644
--- a/src/lib/evas/include/evas_filter.h
+++ b/src/lib/evas/include/evas_filter.h
@@ -14,6 +14,7 @@ typedef enum _Evas_Filter_Channel Evas_Filter_Channel;
14typedef enum _Evas_Filter_Displacement_Flags Evas_Filter_Displacement_Flags; 14typedef enum _Evas_Filter_Displacement_Flags Evas_Filter_Displacement_Flags;
15typedef enum _Evas_Filter_Bump_Flags Evas_Filter_Bump_Flags; 15typedef enum _Evas_Filter_Bump_Flags Evas_Filter_Bump_Flags;
16typedef enum _Evas_Filter_Fill_Mode Evas_Filter_Fill_Mode; 16typedef enum _Evas_Filter_Fill_Mode Evas_Filter_Fill_Mode;
17typedef enum _Evas_Filter_Transform_Flags Evas_Filter_Transform_Flags;
17 18
18typedef Eina_Bool (* Evas_Filter_Apply_Func) (Evas_Filter_Command *cmd); 19typedef Eina_Bool (* Evas_Filter_Apply_Func) (Evas_Filter_Command *cmd);
19typedef void (* Evas_Filter_Cb) (Evas_Filter_Context *ctx, void *data); 20typedef void (* Evas_Filter_Cb) (Evas_Filter_Context *ctx, void *data);
@@ -30,6 +31,7 @@ enum _Evas_Filter_Mode
30 EVAS_FILTER_MODE_FILL, /**< Fill a buffer with a solid color */ 31 EVAS_FILTER_MODE_FILL, /**< Fill a buffer with a solid color */
31 EVAS_FILTER_MODE_MASK, /**< Apply Alpha or RGBA texture on image */ 32 EVAS_FILTER_MODE_MASK, /**< Apply Alpha or RGBA texture on image */
32 EVAS_FILTER_MODE_BUMP, /**< Apply bump mapping (light effect) */ 33 EVAS_FILTER_MODE_BUMP, /**< Apply bump mapping (light effect) */
34 EVAS_FILTER_MODE_TRANSFORM, /**< Apply a simple geometrical transformation */
33 EVAS_FILTER_MODE_LAST 35 EVAS_FILTER_MODE_LAST
34}; 36};
35 37
@@ -79,6 +81,11 @@ enum _Evas_Filter_Fill_Mode
79 EVAS_FILTER_FILL_MODE_STRETCH_XY = EVAS_FILTER_FILL_MODE_STRETCH_X | EVAS_FILTER_FILL_MODE_STRETCH_Y 81 EVAS_FILTER_FILL_MODE_STRETCH_XY = EVAS_FILTER_FILL_MODE_STRETCH_X | EVAS_FILTER_FILL_MODE_STRETCH_Y
80}; 82};
81 83
84enum _Evas_Filter_Transform_Flags
85{
86 EVAS_FILTER_TRANSFORM_VFLIP = 1
87};
88
82/* Parser stuff (high level API) */ 89/* Parser stuff (high level API) */
83Evas_Filter_Program *evas_filter_program_new(const char *name); 90Evas_Filter_Program *evas_filter_program_new(const char *name);
84Eina_Bool evas_filter_program_parse(Evas_Filter_Program *pgm, const char *str); 91Eina_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,
213 */ 220 */
214int 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); 221int 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);
215 222
223/**
224 * @brief Apply a geometrical transformation to the buffer
225 * @param ctx Current filter chain
226 * @param draw_context Current Evas draw context (ignored)
227 * @param inbuf Input buffer (Alpha or RGBA)
228 * @param outbuf Output buffer (Alpha or RGBA), same size as inbuf
229 * @param flags Specifies the operation to apply (eg. vflip)
230 * @return Filter command ID or -1 in case of error
231 */
232int evas_filter_command_transform_add(Evas_Filter_Context *ctx, void *draw_context, int inbuf, int outbuf, Evas_Filter_Transform_Flags flags);
233
216#endif 234#endif
217 235