summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorJean-Philippe Andre <jp.andre@samsung.com>2014-02-19 11:02:53 +0900
committerJean-Philippe Andre <jp.andre@samsung.com>2014-02-20 13:27:43 +0900
commit18a7939f414affcbd114e5dc456a7a2d155b93bb (patch)
tree10c4c9417885ab8c6156188ca3f96b08aa8139b8 /src
parente797f7f4c4c54bdb92d2860d3aafd128f139d731 (diff)
Evas filters: Add render test cases with pixel verification
Force render into an Ecore_Evas, and check that the pixels are valid: - Not all transparent (can't really happen) - Not all black (since there's a black rect behind the text) - All valid premultiplied values (A >= R,G,B) Yes, it's a bit slow. But at least it really checks something :)
Diffstat (limited to 'src')
-rw-r--r--src/Makefile_Evas.am3
-rw-r--r--src/tests/evas/evas_test_filters.c214
2 files changed, 166 insertions, 51 deletions
diff --git a/src/Makefile_Evas.am b/src/Makefile_Evas.am
index df99287fff..644391b056 100644
--- a/src/Makefile_Evas.am
+++ b/src/Makefile_Evas.am
@@ -1612,12 +1612,13 @@ tests/evas/evas_tests_helpers.h \
1612tests/evas/evas_suite.h 1612tests/evas/evas_suite.h
1613 1613
1614tests_evas_evas_suite_CPPFLAGS = -I$(top_builddir)/src/lib/efl \ 1614tests_evas_evas_suite_CPPFLAGS = -I$(top_builddir)/src/lib/efl \
1615-I$(top_srcdir)/src/lib/ecore_evas \
1615-DTESTS_SRC_DIR=\"$(top_srcdir)/src/tests/evas\" \ 1616-DTESTS_SRC_DIR=\"$(top_srcdir)/src/tests/evas\" \
1616-DTESTS_BUILD_DIR=\"$(top_builddir)/src/tests/evas\" \ 1617-DTESTS_BUILD_DIR=\"$(top_builddir)/src/tests/evas\" \
1617@CHECK_CFLAGS@ \ 1618@CHECK_CFLAGS@ \
1618@EVAS_CFLAGS@ 1619@EVAS_CFLAGS@
1619 1620
1620tests_evas_evas_suite_LDADD = @CHECK_LIBS@ @USE_EVAS_LIBS@ 1621tests_evas_evas_suite_LDADD = @CHECK_LIBS@ @USE_EVAS_LIBS@ @USE_ECORE_EVAS_LIBS@
1621tests_evas_evas_suite_DEPENDENCIES = @USE_EVAS_INTERNAL_LIBS@ 1622tests_evas_evas_suite_DEPENDENCIES = @USE_EVAS_INTERNAL_LIBS@
1622endif 1623endif
1623 1624
diff --git a/src/tests/evas/evas_test_filters.c b/src/tests/evas/evas_test_filters.c
index 58f682c769..f2f6c08e46 100644
--- a/src/tests/evas/evas_test_filters.c
+++ b/src/tests/evas/evas_test_filters.c
@@ -11,7 +11,7 @@
11 11
12#include "evas_suite.h" 12#include "evas_suite.h"
13#include "Evas.h" 13#include "Evas.h"
14#include "evas_tests_helpers.h" 14#include "Ecore_Evas.h"
15#include "../../lib/evas/include/evas_filter.h" 15#include "../../lib/evas/include/evas_filter.h"
16 16
17#if !defined(EFL_EO_API_SUPPORT) || !defined(EFL_BETA_API_SUPPORT) 17#if !defined(EFL_EO_API_SUPPORT) || !defined(EFL_BETA_API_SUPPORT)
@@ -22,31 +22,48 @@
22 22
23#if BUILD_FILTER_TESTS 23#if BUILD_FILTER_TESTS
24 24
25/* These are the same as in evas_test_text.c */
26
27#define TEST_FONT_NAME "DejaVuSans,UnDotum" 25#define TEST_FONT_NAME "DejaVuSans,UnDotum"
28#define TEST_FONT_SOURCE TESTS_SRC_DIR "/TestFont.eet" 26#define TEST_FONT_SOURCE TESTS_SRC_DIR "/TestFont.eet"
29 27
30#define START_FILTER_TEST() \ 28#define START_FILTER_TEST() \
31 Evas *evas; \ 29 Ecore_Evas *ee; Evas *evas; \
32 Evas_Object *to; \ 30 Evas_Object *to; \
33 evas = EVAS_TEST_INIT_EVAS(); \ 31 evas_init(); \
32 ecore_evas_init(); \
33 ee = ecore_evas_buffer_new(1, 1); \
34 ecore_evas_show(ee); \
35 ecore_evas_manual_render_set(ee, EINA_TRUE); \
36 evas = ecore_evas_get(ee); \
34 evas_font_hinting_set(evas, EVAS_FONT_HINTING_AUTO); \ 37 evas_font_hinting_set(evas, EVAS_FONT_HINTING_AUTO); \
35 to = evas_object_text_add(evas); \ 38 to = evas_object_text_add(evas); \
39 evas_object_text_font_set(to, TEST_FONT_NAME, 20); \
40 evas_object_text_text_set(to, "Tests"); \
41 evas_object_show(to); \
36 evas_object_text_font_source_set(to, TEST_FONT_SOURCE); \ 42 evas_object_text_font_source_set(to, TEST_FONT_SOURCE); \
37do \ 43 do {} while (0)
38{ \
39} \
40while (0)
41 44
42#define END_FILTER_TEST() \ 45#define END_FILTER_TEST() \
43do \
44{ \
45 evas_object_del(to); \ 46 evas_object_del(to); \
46 evas_free(evas); \ 47 ecore_evas_free(ee); \
48 ecore_evas_shutdown(); \
47 evas_shutdown(); \ 49 evas_shutdown(); \
48} \ 50 do {} while (0)
49while (0) 51
52#ifdef LITTLE_ENDIAN
53#define ALPHA 3
54#define RGB0 0
55#define RGB3 3
56#define RED 2
57#define GREEN 1
58#define BLUE 0
59#else
60#define ALPHA 0
61#define RGB0 1
62#define RGB3 4
63#define RED 0
64#define GREEN 1
65#define BLUE 2
66#endif
50 67
51 68
52START_TEST(evas_filter_parser) 69START_TEST(evas_filter_parser)
@@ -210,54 +227,150 @@ START_TEST(evas_filter_parser)
210} 227}
211END_TEST 228END_TEST
212 229
230struct Filter_Test_Case {
231 int l, r, t, b;
232 const char *code;
233};
234
235static struct Filter_Test_Case _test_cases[] = {
236 // Single filters
237 // In some scripts, a first blend is used to make sure all buffers are valid
238 { 0, 0, 0, 0, "blend();" },
239 { 7, 0, 11, 0, "blend(ox = -7, oy = -11);" },
240 { 0, 7, 0, 11, "blend(ox = 7, oy = 11);" },
241 { 5, 5, 7, 7, "blur(rx = 5, ry = 7);" },
242 { 0, 0, 5, 5, "blur(rx = 0, ry = 5);" },
243 { 5, 5, 0, 0, "blur(rx = 5, ry = 0);" },
244 { 0, 15, 7, 0, "blur(rx = 5, ry = 0, ox = 10, oy = -7);" },
245 { 5, 5, 5, 5, "grow(5);" },
246 { 0, 0, 0, 0, "buffer:a(alpha);blend(dst=a);curve(0:0-255:255,src=a,dst=a);blend(a);" },
247 { 0, 0, 0, 0, "buffer:a(alpha);blend(dst=a);curve(0:0-255:255,dst=a);blend(a);" },
248 { 0, 0, 0, 0, "buffer:a(rgba);blend(dst=a);curve(0:0-255:255,src=a,channel=r);" },
249 { 0, 0, 0, 0, "buffer:a(rgba);blend(dst=a);curve(0:128-255:128,src=a,channel=g);" },
250 { 0, 0, 0, 0, "buffer:a(rgba);blend(dst=a);curve(0:255-255:0,src=a,channel=b);" },
251 { 0, 0, 0, 0, "fill(color=red);" },
252 { 0, 0, 0, 0, "buffer:a(rgba);blend(dst=a);mask(a);" },
253 { 0, 0, 0, 0, "buffer:a(alpha);blend(dst=a);bump(a);" },
254 { 7, 7, 7, 7, "buffer:a(rgba);blend(dst=a);displace(a,7);" },
255 { 0, 0, 0, 40, "buffer:a(alpha);transform(a,vflip,oy=20);blend(src=a);" },
256 { 0, 0, 40, 0, "buffer:a(alpha);transform(a,vflip,oy=-20);blend(src=a);" },
257 { 0, 0, 0, 40, "buffer:a(alpha);blend(dst=a);transform(a,vflip,oy=20,src=a);blend(src=a);" },
258
259 // Filter combos. TODO: Add some more tricky cases :)
260 { 3, 5, 7, 11, "blend(ox = -3, oy = 11); blend(ox = 5, oy = -7);" },
261 { 15, 15, 15, 15, "buffer:a(rgba);grow(10,dst=a);blur(5,src=a);" },
262 { 10, 15, 10, 17, "buffer:a(alpha);blend(dst=a,ox=5,oy=7);blur(10,src=a);blend(ox=-6,oy=-9);" },
263 { 5, 5, 5, 5, "buffer:a(alpha);blur(5,dst=a);bump(a,azimuth=45.0,color=yellow);" }
264};
265
266static const int _test_cases_count = sizeof(_test_cases) / sizeof(_test_cases[0]);
267
213START_TEST(evas_filter_text_padding_test) 268START_TEST(evas_filter_text_padding_test)
214{ 269{
215 START_FILTER_TEST(); 270 START_FILTER_TEST();
216 const char *buf = "Tests";
217 const char *font = TEST_FONT_NAME;
218 Evas_Font_Size size = 14;
219 Evas_Coord x, y, w, h, W, H; 271 Evas_Coord x, y, w, h, W, H;
220 int l, r, t, b; 272 int l, r, t, b;
221 273
222 evas_object_move(to, 0, 0);
223 evas_object_text_text_set(to, buf);
224 evas_object_text_font_set(to, font, size);
225 evas_object_geometry_get(to, &x, &y, &w, &h); 274 evas_object_geometry_get(to, &x, &y, &w, &h);
226 printf("Geometry: %dx%d+%d,%d\n", w, h, x, y); 275 printf("Geometry: %dx%d+%d,%d\n", w, h, x, y);
227 276
228#define CHKPAD(_l, _r, _t, _b, _code) \ 277 for (int k = 0; k < _test_cases_count; k++)
229 l = r = t = b = 0; \ 278 {
230 eo_do(to, evas_obj_text_filter_program_set(_code)); \ 279 struct Filter_Test_Case *tc = &(_test_cases[k]);
231 evas_object_text_style_pad_get(to, &l, &r, &t, &b); \ 280 l = r = t = b = 0;
232 evas_object_geometry_get(to, NULL, NULL, &W, &H); \ 281
233 printf("Line %d: %dx%d for padding %d,%d,%d,%d\n", __LINE__, W, H, l, r, t, b); \ 282 eo_do(to, evas_obj_text_filter_program_set(tc->code));
234 fail_if((l != _l) || (r != _r) || (t != _t) || (b != _b)); \ 283 evas_object_text_style_pad_get(to, &l, &r, &t, &b);
235 fail_if((W != (_l + _r + w)) || (H != (_t + _b + h))); 284 evas_object_geometry_get(to, NULL, NULL, &W, &H);
285 printf("Case %d: %dx%d for padding %d,%d,%d,%d\n", k, W, H, l, r, t, b);
286
287 if ((l != tc->l) || (r != tc->r) || (t != tc->t) || (b != tc->b))
288 fail("Failed on invalid padding with '%s'\n", tc->code);
289 if ((W != (tc->l + tc->r + w)) || (H != (tc->t + tc->b + h)))
290 fail("Failed on invalid geometry with '%s'\n", tc->code);
291 }
236 292
237 // Single filters 293 END_FILTER_TEST();
238 // In some scripts, a first blend is used to make sure all buffers are valid 294}
239 CHKPAD(0, 0, 0, 0, "blend();"); 295END_TEST
240 CHKPAD(7, 0, 11, 0, "blend(ox = -7, oy = -11);");
241 CHKPAD(0, 7, 0, 11, "blend(ox = 7, oy = 11);");
242 CHKPAD(5, 5, 7, 7, "blur(rx = 5, ry = 7);");
243 CHKPAD(0, 0, 5, 5, "blur(rx = 0, ry = 5);");
244 CHKPAD(5, 5, 0, 0, "blur(rx = 5, ry = 0);");
245 CHKPAD(0, 15, 7, 0, "blur(rx = 5, ry = 0, ox = 10, oy = -7);");
246 CHKPAD(5, 5, 5, 5, "grow(5);");
247 CHKPAD(0, 0, 0, 0, "buffer:a(alpha);blend(dst=a);curve(0:0-255:255,src=a,dst=a);");
248 CHKPAD(0, 0, 0, 0, "fill();");
249 CHKPAD(0, 0, 0, 0, "buffer:a(rgba);blend(dst=a);mask(a);");
250 CHKPAD(0, 0, 0, 0, "buffer:a(alpha);blend(dst=a);bump(a);");
251 CHKPAD(7, 7, 7, 7, "buffer:a(rgba);blend(dst=a);displace(a,7);");
252 CHKPAD(0, 0, 0, 40, "buffer:a(alpha);blend(dst=a);transform(a,vflip,oy=20);blend(src=a);");
253 296
254 // Filter combos. TODO: Add some more tricky cases :) 297/* This will only check that all pixels are valid premultiplied values
255 CHKPAD(3, 5, 7, 11, "blend(ox = -3, oy = 11); blend(ox = 5, oy = -7);"); 298 * and that they are not all zero.
256 CHKPAD(15, 15, 15, 15, "buffer:a(rgba);grow(10,dst=a);blur(5,src=a);"); 299 */
257 CHKPAD(10, 15, 10, 17, "buffer:a(alpha);blend(dst=a,ox=5,oy=7);blur(10,src=a);blend(ox=-6,oy=-9);"); 300static Eina_Bool
258 CHKPAD(5, 5, 5, 5, "buffer:a(alpha);blur(5,dst=a);bump(a,azimuth=45.0,color=yellow);"); 301_ecore_evas_pixels_check(Ecore_Evas *ee)
302{
303 const DATA32 *pixels;
304 Eina_Bool nonzero = EINA_FALSE;
305 int w = 0, h = 0;
306
307 pixels = ecore_evas_buffer_pixels_get(ee);
308 if (!pixels) return EINA_FALSE;
309
310 ecore_evas_geometry_get(ee, NULL, NULL, &w, &h);
311 if (!w || !h) return EINA_FALSE;
312
313 for (int k = w * h; k; k--, pixels++)
314 {
315 DATA8 *rgba = (DATA8 *) pixels;
316
317 if (*pixels && (*pixels != 0xFF000000)) nonzero = EINA_TRUE;
318 if ((rgba[ALPHA] < rgba[RED])
319 || (rgba[ALPHA] < rgba[GREEN])
320 || (rgba[ALPHA] < rgba[BLUE]))
321 {
322 printf("Invalid RGBA values!\n");
323 return EINA_FALSE;
324 }
325 }
326
327 if (!nonzero) printf("All pixels are empty!\n");
328 return nonzero;
329}
330
331START_TEST(evas_filter_text_render_test)
332{
333 /* FIXME:
334 * START_FILTER_TEST should be here instead of in the for loop
335 * But there seems to be a problem with ecore_evas_buffer as the second
336 * call to pixels_get will return some garbage. Always.
337 */
338
339 for (int k = 0; k < _test_cases_count; k++)
340 {
341 START_FILTER_TEST();
342
343 Evas_Object *rect;
344 Evas_Coord w, h;
345
346 ecore_evas_alpha_set(ee, EINA_TRUE);
347 ecore_evas_transparent_set(ee, EINA_TRUE);
348
349 rect = evas_object_rectangle_add(evas);
350 evas_object_color_set(rect, 0, 0, 0, 0);
351 evas_object_move(rect, 0, 0);
352 evas_object_stack_below(rect, to);
353 evas_object_show(rect);
354
355 struct Filter_Test_Case *tc = &(_test_cases[k]);
356 w = h = 0;
357
358 eo_do(to,
359 evas_obj_color_set(255, 255, 255, 255),
360 evas_obj_text_filter_program_set(tc->code));
361
362 evas_object_geometry_get(to, NULL, NULL, &w, &h);
363 ecore_evas_resize(ee, w, h);
364 evas_object_resize(to, w, h);
365 evas_object_resize(rect, w, h);
366
367 ecore_evas_manual_render(ee);
368 if (!_ecore_evas_pixels_check(ee))
369 fail("Render test failed with: [%dx%d] '%s'", w, h, tc->code);
370
371 END_FILTER_TEST();
372 }
259 373
260 END_FILTER_TEST();
261} 374}
262END_TEST 375END_TEST
263 376
@@ -268,6 +381,7 @@ void evas_test_filters(TCase *tc)
268#if BUILD_FILTER_TESTS 381#if BUILD_FILTER_TESTS
269 tcase_add_test(tc, evas_filter_parser); 382 tcase_add_test(tc, evas_filter_parser);
270 tcase_add_test(tc, evas_filter_text_padding_test); 383 tcase_add_test(tc, evas_filter_text_padding_test);
384 tcase_add_test(tc, evas_filter_text_render_test);
271#else 385#else
272 (void) tc; 386 (void) tc;
273#endif 387#endif