eina: improve Eina_Tiler to be in par with Evas_Tilebuf.
authorCedric Bail <cedric.bail@samsung.com>
Thu, 4 Jul 2013 03:37:51 +0000 (12:37 +0900)
committerCedric Bail <cedric.bail@samsung.com>
Thu, 4 Jul 2013 04:02:48 +0000 (13:02 +0900)
ChangeLog
NEWS
src/lib/eina/eina_rectangle.h
src/lib/eina/eina_tiler.c
src/lib/eina/eina_tiler.h

index 9ea48b0..bf1c398 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,7 @@
+2013-07-04  Cedric Bail
+
+       * Eina: add eina_tiler_area_size_set and eina_tiler_strict_set to make Eina_Tiler in par with Evas_Tilebuf.
+
 2013-07-03  Shinwoo Kim
 
        * Ecore: add atoms - enable, disable - to support accessibility
diff --git a/NEWS b/NEWS
index bd225b2..8539047 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -31,6 +31,7 @@ Additions:
      - Add eina_inlist_last
      - Add eina_str_convert_len() to work around broken eina_str_convert()
      - Add eina_file_dup()
+     - Add eina_tiler_area_size_set(), eina_tiler_strict_set()
     * Eet:
      - Add eet_mmap()
      - Add eet_data_descriptor_name_get()
index 0ad7224..ac51d16 100644 (file)
@@ -195,10 +195,13 @@ EAPI void                 eina_rectangle_pool_release(Eina_Rectangle *rect) EINA
  * width and @p H is its height.
  */
 #define EINA_RECTANGLE_SET(Rectangle, X, Y, W, H) \
-  (Rectangle)->x = X;                             \
-  (Rectangle)->y = Y;                             \
-  (Rectangle)->w = W;                             \
-  (Rectangle)->h = H;
+  if (Rectangle)                                 \
+    {                                            \
+      (Rectangle)->x = X;                        \
+      (Rectangle)->y = Y;                        \
+      (Rectangle)->w = W;                        \
+      (Rectangle)->h = H;                        \
+    }
 
 
 /**
index 51e36e3..fb22bf2 100644 (file)
@@ -111,6 +111,7 @@ struct _Eina_Tiler
    splitter_t splitter;
 
    Eina_Bool rounding : 1;
+   Eina_Bool strict : 1;
 };
 
 #define EINA_MAGIC_CHECK_TILER(d, ...)                                  \
@@ -1013,6 +1014,8 @@ static inline Eina_Bool _splitter_rect_add(Eina_Tiler *t, Eina_Rectangle *rect)
    //printf("ACCOUNTING[1]: add_redraw: %4d,%4d %3dx%3d\n", x, y, w, h);
    if (t->rounding)
      {
+        // FIXME: Seems that this trigger overdraw bug in Evas implementation and
+        // was disable. Need to investigate.
         rect->x >>= 1;
         rect->y >>= 1;
         rect->w += 2;
@@ -1156,6 +1159,16 @@ EAPI void eina_tiler_free(Eina_Tiler *t)
    free(t);
 }
 
+EAPI void eina_tiler_area_size_set(Eina_Tiler *t, int w, int h)
+{
+   EINA_MAGIC_CHECK_TILER(t);
+   if ((w <= 0) || (h <= 0))
+     return;
+
+   t->area.w = w;
+   t->area.h = h;
+}
+
 EAPI void eina_tiler_tile_size_set(Eina_Tiler *t, int w, int h)
 {
    EINA_MAGIC_CHECK_TILER(t);
@@ -1214,6 +1227,12 @@ EAPI void eina_tiler_clear(Eina_Tiler *t)
    _splitter_clear(t);
 }
 
+EAPI void
+eina_tiler_strict_set(Eina_Tiler *t, Eina_Bool strict)
+{
+   EINA_MAGIC_CHECK_TILER(t);
+   t->strict = strict;
+}
 
 EAPI Eina_Iterator *eina_tiler_iterator_new(const Eina_Tiler *t)
 {
@@ -1229,17 +1248,52 @@ EAPI Eina_Iterator *eina_tiler_iterator_new(const Eina_Tiler *t)
 
    if (t->splitter.need_merge == EINA_TRUE)
      {
-        list_t to_merge;
         splitter_t *sp;
+        list_t to_merge;
 
-        sp = (splitter_t *)&(t->splitter);
         to_merge = t->splitter.rects;
+        if (t->strict)
+          {
+             rect_node_t *rn;
+             list_node_t *n;
+
+             // round up rects to tb->tile_size.w and tb->tile_size.h
+             to_merge = list_zeroed;
+             for (n = t->splitter.rects.head; n; n = n->next)
+               {
+                  int x1, x2, y1, y2;
+
+                  x1 = ((rect_node_t *)n)->rect.left;
+                  x2 = x1 + ((rect_node_t *)n)->rect.width;
+                  y1 = ((rect_node_t *)n)->rect.top;
+                  y2 = y1 + ((rect_node_t *)n)->rect.height;
+                  x1 = t->tile.w * (x1 / t->tile.w);
+                  y1 = t->tile.h * (y1 / t->tile.h);
+                  x2 = t->tile.w * ((x2 + t->tile.w - 1) / t->tile.w);
+                  y2 = t->tile.h * ((y2 + t->tile.h - 1) / t->tile.h);
+
+                  rn = (rect_node_t *)rect_list_node_pool_get();
+                  rn->_lst = list_node_zeroed;
+                  rect_init(&rn->rect, x1, y1, x2 - x1, y2 - y1);
+                  rect_list_add_split_fuzzy_and_merge(&to_merge,
+                                                      (list_node_t *)rn,
+                                                      t->tile.w * t->tile.h,
+                                                      t->tile.w * t->tile.h);
+               }
+          }
+
+        sp = (splitter_t *)&(t->splitter);
         sp->rects = list_zeroed;
         rect_list_merge_rects(&sp->rects, &to_merge, t->tile.w * t->tile.h);
         sp->need_merge = 0;
      }
 
    it->curr = it->tiler->splitter.rects.head;
+   if (!it->tiler->splitter.rects.head)
+     {
+        free(it);
+        return NULL;
+     }
 
    it->iterator.version = EINA_ITERATOR_VERSION;
    it->iterator.next = FUNC_ITERATOR_NEXT(_iterator_next);
index 6634a9b..491fc6a 100644 (file)
@@ -205,6 +205,28 @@ EAPI void               eina_tiler_free(Eina_Tiler *t);
  * @warning Tile size is not used!
  */
 EAPI void               eina_tiler_tile_size_set(Eina_Tiler *t, int w, int h);
+
+/**
+ * @brief Change the size of the area covered by the tiler.
+ *
+ * @param t The tiler whose area size will be set.
+ * @param w Width of the area.
+ * @param h Height of the area.
+ *
+ * Better clear the tiler before changing it's size.
+ */
+EAPI void               eina_tiler_area_size_set(Eina_Tiler *t, int w, int h);
+
+/**
+ * @brief Define if we need to follow a strict grid of tile or a loosy one
+ *
+ * @param t The tiler to apply the strict rules to.
+ * @param strict Define if it will be strict or loosy
+ *
+ * By default it will be loosy.
+ */
+EAPI void               eina_tiler_strict_set(Eina_Tiler *t, Eina_Bool strict);
+
 /**
  * @brief Adds a rectangle to a tiler.
  *