From 1d7c48e2f58189379d113935efb283b1dd96f6dd Mon Sep 17 00:00:00 2001 From: gastal Date: Thu, 4 Aug 2011 22:05:46 +0000 Subject: [PATCH] Eina: eina tiler example. git-svn-id: svn+ssh://svn.enlightenment.org/var/svn/e/trunk/eina@62113 7cbeb6ba-43b4-40fd-8cce-4c39aea84d33 --- configure.ac | 3 + src/examples/Makefile.am | 9 +- src/examples/eina_tiler_01.c | 316 +++++++++++++++++++++++++++++++++++++++++++ src/include/eina_tiler.h | 75 +++++++++- 4 files changed, 399 insertions(+), 4 deletions(-) create mode 100644 src/examples/eina_tiler_01.c diff --git a/configure.ac b/configure.ac index b5996e5..440cb11 100644 --- a/configure.ac +++ b/configure.ac @@ -346,6 +346,8 @@ if test "x${enable_ememoa}" = "xyes" ; then ) fi +PKG_CHECK_MODULES([ECORE_EVAS], [ecore-evas ecore], [build_tiler_example="yes"], [build_tiler_example="no"]) +AM_CONDITIONAL([BUILD_TILER_EXAMPLE], [test "x${build_tiler_example}" = "xyes"]) ### Checks for header files AC_HEADER_ASSERT @@ -738,6 +740,7 @@ echo " Documentation........: ${build_doc}" echo " Tests................: ${enable_tests}" echo " Coverage.............: ${enable_coverage}" echo " Examples.............: ${enable_build_examples}" +echo " Tiler Example........: ${build_tiler_example}" echo " Examples installed...: ${enable_install_examples}" echo " Benchmark............: ${enable_benchmark}" if test "x${enable_benchmark}" = "xyes" ; then diff --git a/src/examples/Makefile.am b/src/examples/Makefile.am index 9feb138..72a3638 100644 --- a/src/examples/Makefile.am +++ b/src/examples/Makefile.am @@ -36,7 +36,8 @@ SRCS = \ eina_inlist_02.c \ eina_inlist_03.c \ eina_str_01.c \ - eina_strbuf_01.c + eina_strbuf_01.c \ + eina_tiler_01.c pkglib_PROGRAMS = @@ -73,5 +74,11 @@ pkglib_PROGRAMS += \ eina_inlist_03 \ eina_str_01 \ eina_strbuf_01 + +if BUILD_TILER_EXAMPLE +AM_CPPFLAGS += @ECORE_EVAS_CFLAGS@ +pkglib_PROGRAMS += eina_tiler_01 +eina_tiler_01_LDADD = @ECORE_EVAS_LIBS@ endif +endif diff --git a/src/examples/eina_tiler_01.c b/src/examples/eina_tiler_01.c new file mode 100644 index 0000000..b2ff8be --- /dev/null +++ b/src/examples/eina_tiler_01.c @@ -0,0 +1,316 @@ +//Compile with: +//gcc `pkg-config --cflags --libs ecore-evas ecore evas` eina_tiler_01.c -o eina_tiler_01 + +#include +#include +#include +#include + +#define WINDOW_PAD (20) + +static Eina_Tiler *tiler; +static Eina_Rectangle *input_rects; +static unsigned int input_count; +static unsigned int input_idx = 0, input_color_idx = 0, output_color_idx = 0; +static Eina_List *output_objs = NULL; +static Evas_Coord maxw, maxh, winw, winh; +static Evas *evas; + +static const struct color { + unsigned char r, g, b; +} colors[] = { + {255, 0, 0}, + {0, 255, 0}, + {0, 0, 255}, + + {255, 128, 0}, + {0, 255, 128}, + {128, 0, 255}, + + {255, 255, 0}, + {0, 255, 255}, + {255, 0, 255}, + + {255, 0, 128}, + {128, 255, 0}, + {0, 128, 255}, + + {128, 128, 0}, + {0, 128, 128}, + {128, 0, 128}, + + {128, 0, 0}, + {0, 128, 0}, + {0, 0, 128}, + + {255, 128, 0}, + {0, 255, 128}, + {128, 0, 255}, + + {64, 64, 0}, + {0, 64, 64}, + {64, 0, 64}, + + {128, 128, 0}, + {0, 128, 128}, + {128, 0, 128}, + + {255, 0, 128}, + {128, 255, 0}, + {0, 128, 255}, + + {128, 64, 0}, + {0, 128, 64}, + {64, 0, 128}, + + {128, 0, 64}, + {64, 128, 0}, + {0, 64, 128} +}; + +#define MAX_COLORS (sizeof(colors) / sizeof(colors[0])) + +static void +add_text(const char *text, int x, int y, int w) +{ + Evas_Object *o = evas_object_text_add(evas); + evas_object_color_set(o, 0, 0, 0, 255); + evas_object_move(o, x, y); + evas_object_resize(o, w, WINDOW_PAD); + evas_object_text_font_set(o, "Sans", 10); + evas_object_text_text_set(o, text); + evas_object_show(o); +} + +static void +output_rects_reset(void) +{ + Evas_Object *o; + EINA_LIST_FREE(output_objs, o) + evas_object_del(o); + output_color_idx = 0; +} + +static void +add_input_rect(const Eina_Rectangle *r) +{ + Evas_Object *o; + Evas_Coord bx, by; + + bx = WINDOW_PAD; + by = WINDOW_PAD; + + o = evas_object_rectangle_add(evas); +#define C(comp) (((int)colors[input_color_idx].comp * 128) / 255) + evas_object_color_set(o, C(r), C(g), C(b), 128); +#undef C + evas_object_move(o, r->x + bx, r->y + by); + evas_object_resize(o, r->w, r->h); + evas_object_show(o); + + input_color_idx = (input_color_idx + 1) % MAX_COLORS; + + bx += maxw + WINDOW_PAD; + + o = evas_object_rectangle_add(evas); + evas_object_color_set(o, 32, 32, 32, 128); + evas_object_move(o, r->x + bx, r->y + by); + evas_object_resize(o, r->w, 1); + evas_object_layer_set(o, EVAS_LAYER_MAX); + evas_object_show(o); + + o = evas_object_rectangle_add(evas); + evas_object_color_set(o, 32, 32, 32, 128); + evas_object_move(o, r->x + bx, r->y + by); + evas_object_resize(o, 1, r->h); + evas_object_layer_set(o, EVAS_LAYER_MAX); + evas_object_show(o); + + o = evas_object_rectangle_add(evas); + evas_object_color_set(o, 32, 32, 32, 128); + evas_object_move(o, r->x + bx, r->y + by + r->h); + evas_object_resize(o, r->w, 1); + evas_object_layer_set(o, EVAS_LAYER_MAX); + evas_object_show(o); + + o = evas_object_rectangle_add(evas); + evas_object_color_set(o, 32, 32, 32, 128); + evas_object_move(o, r->x + bx + r->w, r->y + by); + evas_object_resize(o, 1, r->h); + evas_object_layer_set(o, EVAS_LAYER_MAX); + evas_object_show(o); +} + +static void +add_output_rect(const Eina_Rectangle *r) +{ + Evas_Object *o = evas_object_rectangle_add(evas); +#define C(comp) (((int)colors[output_color_idx].comp * 128) / 255) + evas_object_color_set(o, C(r), C(g), C(b), 128); +#undef C + evas_object_move(o, r->x + maxw + 2 * WINDOW_PAD, r->y + WINDOW_PAD); + evas_object_resize(o, r->w, r->h); + evas_object_show(o); + + output_color_idx = (output_color_idx + 1) % MAX_COLORS; + + output_objs = eina_list_append(output_objs, o); +} + +static Eina_Bool +process_input(void *data) +{ + Eina_Iterator *itr; + Eina_Rectangle r, *r1; + unsigned int out = 0; + + if (input_idx == input_count) + { + add_text("Done. Close the window to exit", + WINDOW_PAD, winh - WINDOW_PAD, winw - 2 * WINDOW_PAD); + return EINA_FALSE; + } + + output_rects_reset(); + + r = input_rects[input_idx]; + printf("Iteration #%u: %dx%d%+d%+d\n", input_idx, r.w, r.h, r.x, r.y); + input_idx++; + add_input_rect(&r); + + eina_tiler_rect_add(tiler, &r); + itr = eina_tiler_iterator_new(tiler); + EINA_ITERATOR_FOREACH(itr, r1) + { + printf("\tOutput #%u: %dx%d%+d%+d\n", out, r1->w, r1->h, r1->x, r1->y); + add_output_rect(r1); + out++; + } + eina_iterator_free(itr); + + return EINA_TRUE; +} + +static void +usage(const char *progname) +{ + fprintf(stderr, + "Usage:\n\n" + "\t%s ... \n\n" + "with rectangles being in the format:\n" + "\tWIDTHxHEIGHT<+->X<+->Y\n" + "examples:\n" + "\t100x100+10+10 - width=100, height=100 at x=10, y=10\n" + "\t150x50+5+6 - width=150, height=50 at x=5, y=6\n", + progname); +} + +int +main(int argc, char *argv[]) +{ + Ecore_Evas *ee; + Evas_Object *o; + int i; + + if (argc < 2) + { + usage(argv[0]); + return -2; + } + + input_rects = calloc(argc - 1, sizeof(Eina_Rectangle)); + input_count = 0; + maxw = 0; + maxh = 0; + for (i = 1; i < argc; i++) + { + Eina_Rectangle *r = input_rects + input_count; + char sx, sy; + + if (sscanf(argv[i], "%dx%d%c%d%c%d", + &(r->w), &(r->h), &sx, &(r->x), &sy, &(r->y)) == 6) + { + if (sx == '-') r->x *= -1; + if (sy == '-') r->y *= -1; + + if (maxw < r->x + r->w) maxw = r->x + r->w; + if (maxh < r->y + r->h) maxh = r->y + r->h; + input_count++; + } + else + fprintf(stderr, "ERROR: invalid rectangle ignored: %s\n", argv[i]); + } + + if (input_count == 0) + { + fputs("ERROR: Could not find any valid rectangle. Exit!\n", stderr); + usage(argv[0]); + free(input_rects); + return -3; + } + + if ((maxw == 0) || (maxh == 0)) + { + fputs("ERROR: All rectangles with size 0x0. Exit!\n", stderr); + usage(argv[0]); + free(input_rects); + return -3; + } + + ecore_evas_init(); + ecore_init(); + evas_init(); + eina_init(); + + winw = 2 * maxw + 3 * WINDOW_PAD; + winh = maxh + 2 * WINDOW_PAD; + + ee = ecore_evas_new(NULL, 0, 0, winw, winh, NULL); + if (!ee) + { + fputs("ERROR: Could not create window. Check ecore-evas install.\n", + stderr); + goto end; + } + + evas = ecore_evas_get(ee); + + o = evas_object_rectangle_add(evas); + evas_object_color_set(o, 255, 255, 255, 255); + evas_object_resize(o, winw, winh); + evas_object_show(o); + + add_text("Input", WINDOW_PAD, 0, maxw); + o = evas_object_rectangle_add(evas); + evas_object_color_set(o, 200, 200, 200, 255); + evas_object_move(o, WINDOW_PAD, WINDOW_PAD); + evas_object_resize(o, maxw, maxh); + evas_object_show(o); + + add_text("Output", maxw + 2 * WINDOW_PAD, 0, maxw); + o = evas_object_rectangle_add(evas); + evas_object_color_set(o, 200, 200, 200, 255); + evas_object_move(o, maxw + 2 * WINDOW_PAD, WINDOW_PAD); + evas_object_resize(o, maxw, maxh); + evas_object_show(o); + + tiler = eina_tiler_new(maxw, maxh); + ecore_timer_add(2.0, process_input, NULL); + + ecore_evas_show(ee); + ecore_main_loop_begin(); + + eina_list_free(output_objs); + eina_tiler_free(tiler); + ecore_evas_free(ee); + + end: + free(input_rects); + + eina_shutdown(); + evas_shutdown(); + ecore_shutdown(); + ecore_evas_shutdown(); + + return 0; +} diff --git a/src/include/eina_tiler.h b/src/include/eina_tiler.h index cc6af75..5272099 100644 --- a/src/include/eina_tiler.h +++ b/src/include/eina_tiler.h @@ -24,6 +24,60 @@ #include "eina_rectangle.h" /** + * @page eina_tiler_example_01 + * @dontinclude eina_tiler_01.c + * + * This is an example that illustrates how Eina_Tiler works for a given set of + * rectangles. The rectangles must be given in the command line in the form: + * x++ + * The example will show two panels, the first(input) will show the given + * rectangles(in different colors) and in the seconds(output) it will show the + * rectangles given by the tiler. The rectangles will be added one by one every + * two seconds. A lot of the example deals with actually painting the rectangles + * so we'll skip over quite a bit of code, but you can see all of it in @ref + * eina_tiler_01.c "eina_tiler_01.c". + * + * The first thing of note in our example is the creation of the tiler: + * @skipline eina_tiler_new + * @note @p maxw and @p maxh are calculated such that the tiler's size will + * fully encompass all given rectangles. + * + * We'll now look at the function that actually adds rectangles to our tiler. It + * first checks if we added all rectangles already and if so stops right there: + * @dontinclude eina_tiler_01.c + * @skip static Eina_Bool + * @until } + * + * Our function then clears all rectangles given to us by tiler from the last + * execution. It does this because each rectangle we add may change everything + * about the output of eina_tiler: + * @until output_rects_reset + * + * Next we get another rectangle, print it and show it in the input panel: + * @until add_input_rect + * + * We now come to the tiler stuff, we add our new rectangle to it and get a new + * iterator for the tiler: + * @until itr + * + * We now iterate over our tiler printing every rect it gives us and sowing it + * in the output panel: + * @until } + * + * We of course must remember to free our iterator and that's it for this + * function: + * @until } + * + * You should try many different inputs to see how the tiler works, here are a + * few suggestions: + * @li 100x100+0+0 100x100+200+200 + * @li 100x100+0+0 100x100+5+5 100x100+10+10 100x100+15+15 100x100+20+20 + * @li 100x100+0+0 100x100+100+100 100x100+200+0 100x100+0+200 100x100+200+200 + * @li 10x10+0+0 10x10+10+10 10x10+20+0 10x10+0+20 10x10+20+20 + * + * @example eina_tiler_01.c + */ +/** * @addtogroup Eina_Data_Types_Group Data Types * * @{ @@ -44,14 +98,14 @@ * to re-render in the form of a set of non-overlapping rectangles that covers * the whole area that needs re-rendering. * - * The following is a pseudo-code showing some simple use of Eina_Tiler: + * The following is pseudo-code showing some simple use of Eina_Tiler: * @code * tiler = eina_tiler_new(MY_CANVAS_WIDTH, MY_CANVAS_HEIGHT); * EINA_LIST_FOREACH(list_of_areas_that_need_re_rendering, l, rect) - * eina_tiler_add(tiler, rect); + * eina_tiler_add(tiler, rect); * itr = eina_tiler_iterator_new(tiler); * EINA_ITERATOR_FOREACH(itr, rect) - * my_function_that_repaints_areas_of_the_canvas(rect); + * my_function_that_repaints_areas_of_the_canvas(rect); * @endcode * * @see eina_tiler_new() @@ -69,6 +123,21 @@ * the area that will be rendered into tiles. It's customary to, then create one * Eina_Tiler for each tile. * + * The following is pseudo-code showing a very simplified use of grid slicer + * together with Eina_Tiler: + * @code + * itr = eina_tile_grid_slicer_iterator_new(0, 0, MY_CANVAS_WIDTH, MY_CANVAS_HEIGHT, TILE_WIDTH, TILE_HEIGHT); + * EINA_ITERATOR_FOREACH(itr, grid_info) + * { + * tiler = eina_tiler_new(grid_info->rect.w, grid_info->rect.w); + * EINA_LIST_FOREACH(list_of_areas_that_need_re_rendering_in_this_tile, l, rect) + * eina_tiler_add(tiler, rect); + * itr = eina_tiler_iterator_new(tiler); + * EINA_ITERATOR_FOREACH(itr, rect) + * my_function_that_repaints_areas_of_the_canvas(rect); + * } + * @endcode + * * @see eina_tiler_new() * @see eina_tiler_rect_add() * @see eina_tile_grid_slicer_setup() -- 2.7.4