[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Gnash-commit] /srv/bzr/gnash/trunk r10391: Implement AS side of MovieCl
From: |
Benjamin Wolsey |
Subject: |
[Gnash-commit] /srv/bzr/gnash/trunk r10391: Implement AS side of MovieClip.blendMode. As Button and allegedly TextField |
Date: |
Thu, 04 Dec 2008 16:15:27 +0100 |
User-agent: |
Bazaar (1.5) |
------------------------------------------------------------
revno: 10391
committer: Benjamin Wolsey <address@hidden>
branch nick: trunk
timestamp: Thu 2008-12-04 16:15:27 +0100
message:
Implement AS side of MovieClip.blendMode. As Button and allegedly TextField
can also use blendModes, the implementation may be moved to the character
class.
modified:
libcore/MovieClip.cpp
libcore/MovieClip.h
testsuite/actionscript.all/MovieClip.as
------------------------------------------------------------
revno: 10390.1.1
committer: Benjamin Wolsey <address@hidden>
branch nick: work
timestamp: Thu 2008-12-04 15:58:12 +0100
message:
Test and implement AS MovieClip.blendMode setting.
modified:
libcore/MovieClip.cpp
libcore/MovieClip.h
testsuite/actionscript.all/MovieClip.as
=== modified file 'libcore/MovieClip.cpp'
--- a/libcore/MovieClip.cpp 2008-12-03 14:04:11 +0000
+++ b/libcore/MovieClip.cpp 2008-12-04 14:58:12 +0000
@@ -66,6 +66,8 @@
#include <algorithm> // for std::swap
#include <boost/algorithm/string/case_conv.hpp>
#include <boost/lexical_cast.hpp>
+#include <boost/assign/list_of.hpp>
+#include <boost/bind.hpp>
namespace gnash {
@@ -151,6 +153,12 @@
as_value movieclip_loadVariables(const fn_call& fn);
as_value movieclip_(const fn_call& fn);
+ /// Match blend modes.
+ typedef std::map<MovieClip::BlendMode, std::string> BlendModeMap;
+ const BlendModeMap& getBlendModeMap();
+ bool blendModeMatches(const BlendModeMap::value_type& val,
+ const std::string& mode);
+
}
/// Anonymous namespace for module-private definitions
@@ -267,6 +275,7 @@
_drawable(new DynamicShape()),
_drawable_inst(_drawable->create_character_instance(this, 0)),
m_play_state(PLAY),
+ _blendMode(BLENDMODE_NORMAL),
m_current_frame(0),
m_has_looped(false),
_callingFrameActions(false),
@@ -3091,9 +3100,60 @@
{
boost::intrusive_ptr<MovieClip> movieclip =
ensureType<MovieClip>(fn.this_ptr);
- UNUSED(movieclip);
+
+ // This is AS-correct, but doesn't do anything.
+ // TODO: implement in the renderers!
LOG_ONCE(log_unimpl(_("MovieClip.blendMode()")));
+
+ if (!fn.nargs)
+ {
+ // Getter
+ MovieClip::BlendMode bm = movieclip->getBlendMode();
+
+ /// If the blend mode is undefined, it doesn't return a string.
+ if (bm == MovieClip::BLENDMODE_UNDEFINED) return as_value();
+
+ std::ostringstream blendMode;
+ blendMode << bm;
+ return as_value(blendMode.str());
+ }
+
+ //
+ // Setter
+ //
+
+ // Numeric argument.
+ const as_value& bm = fn.arg(0);
+ if (bm.is_number()) {
+ double mode = bm.to_number();
+
+ // hardlight is the last known value
+ if (mode < 0 || mode > MovieClip::BLENDMODE_HARDLIGHT) {
+
+ // An invalid string argument becomes undefined.
+ movieclip->setBlendMode(MovieClip::BLENDMODE_UNDEFINED);
+ }
+ else {
+ movieclip->setBlendMode(static_cast<MovieClip::BlendMode>(mode));
+ }
+ return as_value();
+ }
+
+ // Other arguments use toString method.
+ const std::string& mode = bm.to_string();
+
+ const BlendModeMap& bmm = getBlendModeMap();
+ BlendModeMap::const_iterator it = std::find_if(bmm.begin(), bmm.end(),
+ boost::bind(blendModeMatches, _1, mode));
+
+ if (it != bmm.end()) {
+ movieclip->setBlendMode(it->first);
+ }
+
+ // An invalid string argument has no effect.
+
return as_value();
+
}
@@ -5404,6 +5464,49 @@
return proto.get();
}
+const BlendModeMap&
+getBlendModeMap()
+{
+ /// BLENDMODE_UNDEFINED has no matching string in AS. It is included
+ /// here for logging purposes.
+ static const BlendModeMap bm = boost::assign::map_list_of
+ (MovieClip::BLENDMODE_UNDEFINED, "undefined")
+ (MovieClip::BLENDMODE_NORMAL, "normal")
+ (MovieClip::BLENDMODE_LAYER, "layer")
+ (MovieClip::BLENDMODE_MULTIPLY, "multiply")
+ (MovieClip::BLENDMODE_SCREEN, "screen")
+ (MovieClip::BLENDMODE_LIGHTEN, "lighten")
+ (MovieClip::BLENDMODE_DARKEN, "darken")
+ (MovieClip::BLENDMODE_DIFFERENCE, "difference")
+ (MovieClip::BLENDMODE_ADD, "add")
+ (MovieClip::BLENDMODE_SUBTRACT, "subtract")
+ (MovieClip::BLENDMODE_INVERT, "invert")
+ (MovieClip::BLENDMODE_ALPHA, "alpha")
+ (MovieClip::BLENDMODE_ERASE, "erase")
+ (MovieClip::BLENDMODE_OVERLAY, "overlay")
+ (MovieClip::BLENDMODE_HARDLIGHT, "hardlight");
+
+ return bm;
+}
+
+// Match a blend mode to its string.
+bool
+blendModeMatches(const BlendModeMap::value_type& val, const std::string& mode)
+{
+ /// The match must be case-sensitive.
+ if (mode.empty()) return false;
+ return (val.second == mode);
+}
+
} // anonymous namespace
+
+std::ostream&
+operator<<(std::ostream& o, MovieClip::BlendMode bm)
+{
+ const BlendModeMap& bmm = getBlendModeMap();
+ return (o << bmm.find(bm)->second);
+}
+
+
} // namespace gnash
=== modified file 'libcore/MovieClip.h'
--- a/libcore/MovieClip.h 2008-12-03 08:22:34 +0000
+++ b/libcore/MovieClip.h 2008-12-04 14:58:12 +0000
@@ -76,7 +76,6 @@
typedef std::vector<swf_event*> SWFEventsVector;
-
/// Construct a MovieClip instance
//
/// @param def
@@ -112,6 +111,25 @@
STOP
};
+ enum BlendMode
+ {
+ BLENDMODE_UNDEFINED = 0,
+ BLENDMODE_NORMAL = 1,
+ BLENDMODE_LAYER,
+ BLENDMODE_MULTIPLY,
+ BLENDMODE_SCREEN,
+ BLENDMODE_LIGHTEN,
+ BLENDMODE_DARKEN,
+ BLENDMODE_DIFFERENCE,
+ BLENDMODE_ADD,
+ BLENDMODE_SUBTRACT,
+ BLENDMODE_INVERT,
+ BLENDMODE_ALPHA,
+ BLENDMODE_ERASE,
+ BLENDMODE_OVERLAY,
+ BLENDMODE_HARDLIGHT = 14
+ };
+
/// Type of execute tags
//
/// TODO: move to ControlTag.h ?
@@ -217,6 +235,14 @@
play_state get_play_state() const { return m_play_state; }
+ BlendMode getBlendMode() const {
+ return _blendMode;
+ }
+
+ void setBlendMode(BlendMode bm) {
+ _blendMode = bm;
+ }
+
character* get_character(int character_id);
// delegates to movie_root (possibly wrong)
@@ -912,6 +938,8 @@
play_state m_play_state;
+ BlendMode _blendMode;
+
// 0-based index to current frame
size_t m_current_frame;
@@ -1029,6 +1057,9 @@
/// Initialize the global MovieClip class
void movieclip_class_init(as_object& global);
+/// Stream operator for MovieClip blend mode.
+std::ostream&
+operator<<(std::ostream& o, MovieClip::BlendMode bm);
} // end of namespace gnash
=== modified file 'testsuite/actionscript.all/MovieClip.as'
--- a/testsuite/actionscript.all/MovieClip.as 2008-12-01 13:46:15 +0000
+++ b/testsuite/actionscript.all/MovieClip.as 2008-12-04 14:58:12 +0000
@@ -123,7 +123,7 @@
#endif
#if OUTPUT_VERSION >= 8
- check_totals(920); // SWF8+
+ check_totals(935); // SWF8+
#endif
play();
@@ -2172,6 +2172,40 @@
_root.focusEnabled = "hello";
check_equals(_root.focusEnabled, "hello");
+#if OUTPUT_VERSION > 7
+check_equals(_root.blendMode, "normal");
+check_equals(typeof(_root.blendMode), "string");
+_root.blendMode = 2;
+check_equals(_root.blendMode, "layer");
+_root.blendMode = "multiply";
+check_equals(_root.blendMode, "multiply");
+_root.blendMode = 0;
+check_equals(_root.blendMode, undefined);
+_root.blendMode = 14;
+check_equals(_root.blendMode, "hardlight");
+_root.blendMode = 15;
+check_equals(_root.blendMode, undefined);
+_root.blendMode = "scre";
+check_equals(_root.blendMode, undefined);
+_root.blendMode = "daRkEn";
+check_equals(_root.blendMode, undefined);
+_root.blendMode = "darken";
+check_equals(_root.blendMode, "darken");
+_root.blendMode = "Some rubbish";
+check_equals(_root.blendMode, "darken");
+_root.blendMode = -1;
+check_equals(_root.blendMode, undefined);
+_root.blendMode = 5.5;
+check_equals(_root.blendMode, "lighten");
+_root.blendMode = "NORMAL";
+check_equals(_root.blendMode, "lighten");
+
+// Set back to normal so we can see the results...
+_root.blendMode = "normal";
+check_equals(_root.blendMode, "normal");
+
+#endif
+
//_root.loadVariables(MEDIA(vars.txt), "GET");
// Can't rely on this to call onData!
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- [Gnash-commit] /srv/bzr/gnash/trunk r10391: Implement AS side of MovieClip.blendMode. As Button and allegedly TextField,
Benjamin Wolsey <=