aaaaaaaaaaaaaaargh! where's me rum! :(
authorraster <raster@7cbeb6ba-43b4-40fd-8cce-4c39aea84d33>
Tue, 31 Aug 2010 22:16:08 +0000 (22:16 +0000)
committerraster <raster@7cbeb6ba-43b4-40fd-8cce-4c39aea84d33>
Tue, 31 Aug 2010 22:16:08 +0000 (22:16 +0000)
git-svn-id: svn+ssh://svn.enlightenment.org/var/svn/e/trunk/evas@51788 7cbeb6ba-43b4-40fd-8cce-4c39aea84d33

src/lib/canvas/evas_clip.c
src/lib/canvas/evas_map.c
src/lib/include/evas_inline.x
src/lib/include/evas_private.h

index 6623aa7..1de20bc 100644 (file)
@@ -38,6 +38,77 @@ evas_object_clippers_was_visible(Evas_Object *obj)
    return 0;
 }
 
+/* aaaaargh (pirate voice) ... notes!
+ * 
+ * we have a big problem until now that's gone undetected... until yesterday.
+ * that problem involves clips and maps and smart objects. hooray! 3 of the
+ * more complex bits of evas - and maps and smart objects  being one of the
+ * nastiest ones.
+ * 
+ * what is the problem? when a clip crosses a map boundary. that is to say
+ * that when the clipper and clippee are not within the child tree of the
+ * mapped object. in this case "bad stuff" happens. basically as clips are
+ * then used to render objects, but they no longer apply as you'd expect as
+ * the map transfomr the objects to-be-clipped separately from the objects
+ * that clip them and this whole relationship is broken by maps. it somehow
+ * managed to not break with the advent of smart objects. lucky me... but
+ * maps killed it. now... what do we do? that is a good question. detect
+ * such a broken link and "turn off clipping" in that event - sure. but this
+ * isn't going to be cheap as ANY addition or deletion of a map to an object
+ * or any change in clipper of an object or any change in smart object
+ * membership needs to walk the obj tree both up and down from the changed
+ * object and probably walk entire object trees to find these and mark them.
+ * thats silly-expensive and i was about to fix it that way but it has since
+ * dawned on me that that is just going to kill performance in some critical
+ * areas like during object setup and manipulation, as well as teardown.
+ * 
+ * aaaaagh! best for now is to document this as a "don't do it damnit!" thing
+ * and have the apps avoid it. but even then - how to do this? this is not
+ * easy. everywhere i turn so far i come up to either expensive operations,
+ * breaks in logic, or nasty re-work of apps or4 the whole concept of clipping,
+ * smart objects and maps... and that will have to wait for evas 2.0
+ * 
+ */
+
+static void
+evas_object_child_map_across_mark(Evas_Object *obj, Eina_List *clippers, 
+                                  Eina_Bool map)
+{
+#if 0
+   if (map)
+     {
+        // if obj->cur.clipper is in clippers list, then set 
+        // obj->cur.clip_across_map to 1
+     }
+   else
+     {
+     }
+#endif   
+}
+
+void
+evas_object_mapped_clip_across_mark(Evas_Object *obj)
+{
+   return;
+#if 0
+   Eina_Bool map = 0;
+   
+   if ((obj->cur.map) && (obj->cur.usemap)) map = 1;
+   if (map)
+     {
+        Eina_List *list = NULL;
+        
+        // FIXME: list = build list of all clippers that are children of obj
+        // up until any obj that has map applied to it. if map is applied
+        // tghen we must assume this has been run before o9n that obj and
+        // its children etc.
+        evas_object_child_map_across_mark(obj, list, map);
+     }
+   else
+      evas_object_child_map_across_mark(obj, NULL, map);
+#endif   
+}
+
 /* public functions */
 
 /**
index 9d9634a..df41477 100644 (file)
@@ -295,6 +295,7 @@ evas_object_map_enable_set(Evas_Object *obj, Eina_Bool enabled)
      {
         if (!obj->cur.map)
           obj->cur.map = _evas_map_new(4);
+        evas_object_mapped_clip_across_mark(obj);
 //        obj->cur.map->normal_geometry = obj->cur.geometry;
      }
    else
@@ -302,6 +303,7 @@ evas_object_map_enable_set(Evas_Object *obj, Eina_Bool enabled)
         if (obj->cur.map)
           {
              _evas_map_calc_geom_change(obj);
+             evas_object_mapped_clip_across_mark(obj);
           }
      }
    _evas_map_calc_map_geometry(obj);
@@ -433,6 +435,8 @@ evas_object_map_set(Evas_Object *obj, const Evas_Map *map)
              obj->cur.map = NULL;
              if (!obj->cur.usemap) _evas_map_calc_geom_change(obj);
              else _evas_map_calc_map_geometry(obj);
+             if (obj->cur.usemap)
+                evas_object_mapped_clip_across_mark(obj);
           }
         return;
      }
@@ -440,6 +444,8 @@ evas_object_map_set(Evas_Object *obj, const Evas_Map *map)
      {
         obj->cur.map = _evas_map_dup(map);
         obj->prev.map = NULL;
+        if (obj->cur.usemap)
+           evas_object_mapped_clip_across_mark(obj);
      }
    else
      {
index 19aa7f6..5db783a 100644 (file)
@@ -175,8 +175,9 @@ evas_object_clip_recalc(Evas_Object *obj)
    int cx, cy, cw, ch, cvis, cr, cg, cb, ca;
    int nx, ny, nw, nh, nvis, nr, ng, nb, na;
 
-   if (!obj->cur.cache.clip.dirty &&
-       !(!obj->cur.clipper || obj->cur.clipper->cur.cache.clip.dirty))
+   if ((!obj->cur.cache.clip.dirty &&
+        !(!obj->cur.clipper || obj->cur.clipper->cur.cache.clip.dirty)) ||
+       (obj->cur.clip_across_map))
      return;
    if (obj->layer->evas->events_frozen > 0) return;
    evas_object_coords_recalc(obj);
@@ -200,7 +201,7 @@ evas_object_clip_recalc(Evas_Object *obj)
    else cvis = obj->cur.visible;
    cr = obj->cur.color.r; cg = obj->cur.color.g;
    cb = obj->cur.color.b; ca = obj->cur.color.a;
-   if (obj->cur.clipper)
+   if ((obj->cur.clipper) && (!obj->cur.clip_across_map))
      {
 // this causes problems... hmmm
        if (obj->cur.clipper->cur.cache.clip.dirty)
index 728243c..ae2a667 100644 (file)
@@ -435,6 +435,7 @@ struct _Evas_Object
       Eina_Bool         visible : 1;
       Eina_Bool         have_clipees : 1;
       Eina_Bool         anti_alias : 1;
+      Eina_Bool         clip_across_map : 1;
       Evas_Render_Op    render_op : 4;
    } cur, prev;
 
@@ -733,6 +734,7 @@ int evas_object_was_opaque(Evas_Object *obj);
 int evas_object_is_inside(Evas_Object *obj, Evas_Coord x, Evas_Coord y);
 int evas_object_was_inside(Evas_Object *obj, Evas_Coord x, Evas_Coord y);
 int evas_object_clippers_was_visible(Evas_Object *obj);
+void evas_object_mapped_clip_across_mark(Evas_Object *obj);
 void evas_event_callback_call(Evas *e, Evas_Callback_Type type, void *event_info);
 void evas_object_event_callback_call(Evas_Object *obj, Evas_Callback_Type type, void *event_info);
 Eina_List *evas_event_objects_event_list(Evas *e, Evas_Object *stop, int x, int y);