gnash-commit
[Top][All Lists]
Advanced

[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!


reply via email to

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