gnash-commit
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Gnash-commit] gnash ChangeLog server/character.h server/dlist...


From: Sandro Santilli
Subject: [Gnash-commit] gnash ChangeLog server/character.h server/dlist...
Date: Wed, 23 Jan 2008 12:39:37 +0000

CVSROOT:        /sources/gnash
Module name:    gnash
Changes by:     Sandro Santilli <strk>  08/01/23 12:39:37

Modified files:
        .              : ChangeLog 
        server         : character.h dlist.cpp sprite_instance.cpp 
        testsuite/misc-ming.all: masks_test2runner.cpp 

Log message:
        Fix mouse entity and droptarget finders to take mask layers into 
account.

CVSWeb URLs:
http://cvs.savannah.gnu.org/viewcvs/gnash/ChangeLog?cvsroot=gnash&r1=1.5476&r2=1.5477
http://cvs.savannah.gnu.org/viewcvs/gnash/server/character.h?cvsroot=gnash&r1=1.123&r2=1.124
http://cvs.savannah.gnu.org/viewcvs/gnash/server/dlist.cpp?cvsroot=gnash&r1=1.110&r2=1.111
http://cvs.savannah.gnu.org/viewcvs/gnash/server/sprite_instance.cpp?cvsroot=gnash&r1=1.457&r2=1.458
http://cvs.savannah.gnu.org/viewcvs/gnash/testsuite/misc-ming.all/masks_test2runner.cpp?cvsroot=gnash&r1=1.7&r2=1.8

Patches:
Index: ChangeLog
===================================================================
RCS file: /sources/gnash/gnash/ChangeLog,v
retrieving revision 1.5476
retrieving revision 1.5477
diff -u -b -r1.5476 -r1.5477
--- ChangeLog   23 Jan 2008 12:10:21 -0000      1.5476
+++ ChangeLog   23 Jan 2008 12:39:36 -0000      1.5477
@@ -1,3 +1,15 @@
+2008-01-23 Sandro Santilli <address@hidden>
+
+       * testsuite/misc-ming.all/masks_test2runner.cpp: successes.
+       * server/character.h (isMaskLayer): dynamic masks are not mask
+         layers.
+       * server/dlist.cpp (add_invalidated_bounds): use isMaskLayer rather
+         then comparing about the noClipDepthValue.
+       * server/sprite_instance.cpp (get_topmost_mouse_entity,
+         findDropTarget): rewrite mouse entity and drop target finders
+         to take layer (static) masks into account.
+         This fixes bug #21923 and movie in comment #7 of bug #20911.
+
 2008-01-23 Benjamin Wolsey <address@hidden>
 
        * libbase/rc.cpp: Don't increment verbosity automatically when some

Index: server/character.h
===================================================================
RCS file: /sources/gnash/gnash/server/character.h,v
retrieving revision 1.123
retrieving revision 1.124
diff -u -b -r1.123 -r1.124
--- server/character.h  21 Jan 2008 20:55:49 -0000      1.123
+++ server/character.h  23 Jan 2008 12:39:37 -0000      1.124
@@ -15,7 +15,7 @@
 // along with this program; if not, write to the Free Software
 // Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 
-/* $Id: character.h,v 1.123 2008/01/21 20:55:49 rsavoye Exp $ */
+/* $Id: character.h,v 1.124 2008/01/23 12:39:37 strk Exp $ */
 
 #ifndef GNASH_CHARACTER_H
 #define GNASH_CHARACTER_H
@@ -495,7 +495,9 @@
        ///   
        bool isMaskLayer() const
        {
-               return (m_clip_depth!=noClipDepthValue);
+               // TODO: is dynClipDepthValue still needed ?
+               //       since we have a _maskee member now, we may use that 
instead..
+               return (m_clip_depth!=noClipDepthValue && 
m_clip_depth!=dynClipDepthValue);
        }
 
        /// Returns true when the character (and it's childs) is used as a mask

Index: server/dlist.cpp
===================================================================
RCS file: /sources/gnash/gnash/server/dlist.cpp,v
retrieving revision 1.110
retrieving revision 1.111
diff -u -b -r1.110 -r1.111
--- server/dlist.cpp    21 Jan 2008 20:55:50 -0000      1.110
+++ server/dlist.cpp    23 Jan 2008 12:39:37 -0000      1.111
@@ -698,10 +698,10 @@
             render::disable_mask();
         }
 
-        int clipDepth = ch->get_clip_depth();
         // Push a new mask to the masks stack
-        if(clipDepth != character::noClipDepthValue)
+       if ( ch->isMaskLayer() ) // clipDepth != character::noClipDepthValue
         {
+            int clipDepth = ch->get_clip_depth();
             clipDepthStack.push(clipDepth);
             render::begin_submit_mask();
         }
@@ -800,10 +800,10 @@
       
     }
     
-    int clipDepth = dobj->get_clip_depth();
     // Push a new mask to the masks stack
-    if (clipDepth != character::noClipDepthValue) 
+    if ( dobj->isMaskLayer() ) // clipDepth != character::noClipDepthValue
     {
+      int clipDepth = dobj->get_clip_depth();
       clipDepthStack.push(clipDepth);
       
       drawing_mask = true; // begin_submit_mask equivalent

Index: server/sprite_instance.cpp
===================================================================
RCS file: /sources/gnash/gnash/server/sprite_instance.cpp,v
retrieving revision 1.457
retrieving revision 1.458
diff -u -b -r1.457 -r1.458
--- server/sprite_instance.cpp  23 Jan 2008 09:35:21 -0000      1.457
+++ server/sprite_instance.cpp  23 Jan 2008 12:39:37 -0000      1.458
@@ -83,6 +83,11 @@
 // easily re-compilable to obtain a smaller testcase
 //#define DEBUG_DRAWING_API 1
 
+// Define this to make mouse entity finding verbose
+// This includes get_topmost_mouse_entity and findDropTarget
+//
+//#define DEBUG_MOUSE_ENTITY_FINDING 1
+
 // Forward declarations
 static as_object* getMovieClipInterface();
 static void attachMovieClipInterface(as_object& o);
@@ -1721,18 +1726,6 @@
   boost::intrusive_ptr<sprite_instance> ptr = 
ensureType<sprite_instance>(fn.this_ptr);
 
   return ptr->getDropTarget();
-  UNUSED(ptr);
-
-  static bool warned = false;
-  if ( ! warned )
-  {
-    log_unimpl("MovieClip._droptarget");
-    warned=true;
-  }
-
-  //VM& vm = VM::get();
-  // NOTE: _droptarget should be set after startDrag() and stopDrag() calls
-  return as_value("");
 }
 
 static as_value
@@ -3240,38 +3233,126 @@
 }
 
 /// Find a character hit by the given coordinates.
+//
+/// This class takes care about taking masks layers into
+/// account, but nested masks aren't properly tested yet.
+///
 class MouseEntityFinder {
 
+  /// Highest depth hidden by a mask
+  //
+  /// This will be -1 initially, and set
+  /// the the depth of a mask when the mask
+  /// doesn't contain the query point, while
+  /// scanning a DisplayList bottom-up
+  ///
+  int _highestHiddenDepth;
+
   character* _m;
 
-  float _x;
+  typedef std::vector<character*> Candidates;
+  Candidates _candidates;
 
-  float _y;
+  /// Query point in world coordinate space
+  point _wp;
+
+  /// Query point in parent coordinate space
+  point _pp;
+
+  bool _checked;
 
 public:
 
-  MouseEntityFinder(float x, float y)
+  /// @param wp
+  ///   Query point in world coordinate space
+  ///
+  /// @param pp
+  ///   Query point in parent coordinate space
+  ///
+  MouseEntityFinder(point wp, point pp)
     :
+    _highestHiddenDepth(std::numeric_limits<int>::min()),
     _m(NULL),
-    _x(x),
-    _y(y)
+    _candidates(),
+    _wp(wp),
+    _pp(pp),
+    _checked(false)
   {}
 
-  bool operator() (character* ch)
+  void operator() (character* ch)
+  {
+    assert(!_checked);
+    if ( ch->get_depth() <= _highestHiddenDepth )
+    {
+      if ( ch->isMaskLayer() )
+      {
+        log_debug("CHECKME: nested mask in MouseEntityFinder. This mask is %s 
at depth %d outer mask masked up to depth %d.",
+          ch->getTarget().c_str(), ch->get_depth(), _highestHiddenDepth);
+        // Hiding mask still in effect...
+      }
+      return;
+    }
+
+    if ( ch->isMaskLayer() )
+    {
+      if ( ! ch->get_visible() )
+      {
+        log_debug("FIXME: invisible mask in MouseEntityFinder.");
+      }
+      if ( ! ch->pointInShape(_wp.x, _wp.y) )
+      {
+#ifdef DEBUG_MOUSE_ENTITY_FINDING
+        log_debug("Character %s at depth %d is a mask not hitting the query 
point %g,%g and masking up to depth %d",
+          ch->getTarget().c_str(), ch->get_depth(), _wp.x, _wp.y, 
ch->get_clip_depth());
+#endif // DEBUG_MOUSE_ENTITY_FINDING
+        _highestHiddenDepth = ch->get_clip_depth();
+      }
+      else
   {
-    if ( ! ch->get_visible() ) return true;
+#ifdef DEBUG_MOUSE_ENTITY_FINDING
+        log_debug("Character %s at depth %d is a mask hitting the query point 
%g,%g",
+          ch->getTarget().c_str(), ch->get_depth(), _wp.x, _wp.y);
+#endif // DEBUG_MOUSE_ENTITY_FINDING
+      }
+
+      return;
+    }
 
-    character* te = ch->get_topmost_mouse_entity(_x, _y);
+    if ( ! ch->get_visible() ) return;
+
+    _candidates.push_back(ch);
+
+  }
+
+  void checkCandidates()
+  {
+    if ( _checked ) return;
+    for (Candidates::reverse_iterator i=_candidates.rbegin(),
+            e=_candidates.rend(); i!=e; ++i)
+    {
+      character* ch = *i;
+      character* te = ch->get_topmost_mouse_entity(_pp.x, _pp.y);
     if ( te )
     {
       _m = te;
-      return false; // done
+        break;
     }
-
-    return true; // haven't found it yet
+    }
+    _checked = true;
   }
 
-  character* getEntity() { return _m; }
+  character* getEntity()
+  {
+    checkCandidates();
+#ifdef DEBUG_MOUSE_ENTITY_FINDING
+    if ( _m ) 
+    {
+      log_debug("MouseEntityFinder found character %s (depth %d) hitting point 
%g,%g",
+        _m->getTarget().c_str(), _m->get_depth(), _wp.x, _wp.y);
+    }
+#endif // DEBUG_MOUSE_ENTITY_FINDING
+    return _m;
+  }
     
 };
 
@@ -3382,35 +3463,36 @@
     return NULL;
   }
 
-  if ( can_handle_mouse_event() )
-  {
     // point is in parent's space,
     // we need to convert it in world space
+  point wp(x,y);
     character* parent = get_parent();
+  if ( parent ) parent->get_world_matrix().transform(wp);
     // WARNING: if we have NO parent, our parent it the Stage (movie_root)
     //          so, in case we'll add a "stage" matrix, we'll need to take
     //          it into account here.
     // TODO: actually, why are we insisting in using parent's coordinates for
     //       this method at all ?
     //
-    matrix parent_world_matrix = parent ? parent->get_world_matrix() : 
matrix::identity;
-    point wp(x,y);
-    parent_world_matrix.transform(wp);
+
+  if ( can_handle_mouse_event() )
+  {
     if ( pointInVisibleShape(wp.x, wp.y) ) return this;
     else return NULL;
   }
 
 
   matrix  m = get_matrix();
-  point p;
-  m.transform_by_inverse(&p, point(x, y));
+  point pp;
+  m.transform_by_inverse(&pp, point(x, y));
 
-  MouseEntityFinder finder(p.x, p.y);
-  m_display_list.visitBackward(finder);
+  MouseEntityFinder finder(wp, pp);
+  //m_display_list.visitBackward(finder);
+  m_display_list.visitAll(finder);
   character* ch = finder.getEntity();
   if ( ! ch ) 
   {
-    ch = _drawable_inst->get_topmost_mouse_entity(p.x, p.y);
+    ch = _drawable_inst->get_topmost_mouse_entity(pp.x, pp.y);
   }
 
   return ch; // might be NULL
@@ -3423,33 +3505,103 @@
 ///
 class DropTargetFinder {
 
+  /// Highest depth hidden by a mask
+  //
+  /// This will be -1 initially, and set
+  /// the the depth of a mask when the mask
+  /// doesn't contain the query point, while
+  /// scanning a DisplayList bottom-up
+  ///
+  int _highestHiddenDepth;
+
   float _x;
   float _y;
   character* _dragging;
-  const character* _dropch;
+  mutable const character* _dropch;
+
+  typedef std::vector<const character*> Candidates;
+  Candidates _candidates;
+
+  mutable bool _checked;
 
 public:
 
   DropTargetFinder(float x, float y, character* dragging)
     :
+    _highestHiddenDepth(std::numeric_limits<int>::min()),
     _x(x),
     _y(y),
     _dragging(dragging),
-    _dropch(0)
+    _dropch(0),
+               _candidates(),
+               _checked(false)
   {}
 
-  bool operator() (const character* ch)
+  void operator() (const character* ch)
+  {
+               assert(!_checked);
+    if ( ch->get_depth() <= _highestHiddenDepth )
+    {
+      if ( ch->isMaskLayer() )
+      {
+        log_debug("CHECKME: nested mask in DropTargetFinder. This mask is %s 
at depth %d outer mask masked up to depth %d.",
+          ch->getTarget().c_str(), ch->get_depth(), _highestHiddenDepth);
+        // Hiding mask still in effect...
+      }
+      return;
+    }
+
+    if ( ch->isMaskLayer() )
+    {
+      if ( ! ch->get_visible() )
+      {
+        log_debug("FIXME: invisible mask in MouseEntityFinder.");
+      }
+      if ( ! ch->pointInShape(_x, _y) )
+      {
+#ifdef DEBUG_MOUSE_ENTITY_FINDING
+        log_debug("Character %s at depth %d is a mask not hitting the query 
point %g,%g and masking up to depth %d",
+          ch->getTarget().c_str(), ch->get_depth(), _x, _y, 
ch->get_clip_depth());
+#endif // DEBUG_MOUSE_ENTITY_FINDING
+        _highestHiddenDepth = ch->get_clip_depth();
+      }
+      else
+      {
+#ifdef DEBUG_MOUSE_ENTITY_FINDING
+        log_debug("Character %s at depth %d is a mask hitting the query point 
%g,%g",
+          ch->getTarget().c_str(), ch->get_depth(), _x, _y);
+#endif // DEBUG_MOUSE_ENTITY_FINDING
+      }
+
+      return;
+    }
+
+    _candidates.push_back(ch);
+
+  }
+
+  void checkCandidates() const
+  {
+    if ( _checked ) return;
+    for (Candidates::const_reverse_iterator i=_candidates.rbegin(),
+            e=_candidates.rend(); i!=e; ++i)
   {
+      const character* ch = *i;
     const character* dropChar = ch->findDropTarget(_x, _y, _dragging);
     if ( dropChar )
     {
       _dropch = dropChar;
-      return false;
+                               break;
     }
-    else return true;
+    }
+    _checked = true;
   }
 
-  const character* getDropChar() const { return _dropch; }
+  const character* getDropChar() const
+       {
+               checkCandidates();
+               return _dropch;
+       }
 };
 
 const character*
@@ -3462,7 +3614,7 @@
   if ( ! get_visible() ) return 0; // isn't me !
 
   DropTargetFinder finder(x, y, dragging);
-  m_display_list.visitBackward(finder);
+  m_display_list.visitAll(finder);
 
   // does it hit any child ?
   const character* ch = finder.getDropChar();

Index: testsuite/misc-ming.all/masks_test2runner.cpp
===================================================================
RCS file: /sources/gnash/gnash/testsuite/misc-ming.all/masks_test2runner.cpp,v
retrieving revision 1.7
retrieving revision 1.8
diff -u -b -r1.7 -r1.8
--- testsuite/misc-ming.all/masks_test2runner.cpp       23 Jan 2008 09:46:37 
-0000      1.7
+++ testsuite/misc-ming.all/masks_test2runner.cpp       23 Jan 2008 12:39:37 
-0000      1.8
@@ -61,9 +61,9 @@
   xcheck_pixel(40, 40, 10, white, 3); 
 
   tester.movePointerTo(118, 118);
-  xcheck( ! tester.isMouseOverMouseEntity() ); // not visible in its mask
+  check( ! tester.isMouseOverMouseEntity() ); // not visible in its mask
   tester.movePointerTo(50, 50);
-  xcheck( ! tester.isMouseOverMouseEntity() ); // hits mc2 mask, but not mc1 
mask 
+  check( ! tester.isMouseOverMouseEntity() ); // hits mc2 mask, but not mc1 
mask 
   tester.movePointerTo(10, 10);
   check( tester.isMouseOverMouseEntity() ); // hits both mc2 and mc1 mask, and 
mc4 mouse entity
   




reply via email to

[Prev in Thread] Current Thread [Next in Thread]