[Top][All Lists]
[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
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- [Gnash-commit] gnash ChangeLog server/character.h server/dlist...,
Sandro Santilli <=