gnash-commit
[Top][All Lists]
Advanced

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

[Gnash-commit] /srv/bzr/gnash/trunk r11416: Do Color class correctly.


From: Benjamin Wolsey
Subject: [Gnash-commit] /srv/bzr/gnash/trunk r11416: Do Color class correctly.
Date: Thu, 13 Aug 2009 14:52:44 +0200
User-agent: Bazaar (1.16.1)

------------------------------------------------------------
revno: 11416 [merge]
committer: Benjamin Wolsey <address@hidden>
branch nick: trunk
timestamp: Thu 2009-08-13 14:52:44 +0200
message:
  Do Color class correctly.
modified:
  libcore/asobj/Color_as.cpp
  libcore/namedStrings.cpp
  libcore/namedStrings.h
  testsuite/actionscript.all/Color.as
=== modified file 'libcore/asobj/Color_as.cpp'
--- a/libcore/asobj/Color_as.cpp        2009-08-07 14:00:50 +0000
+++ b/libcore/asobj/Color_as.cpp        2009-08-13 12:28:02 +0000
@@ -35,8 +35,6 @@
 
 #include <sstream>
 
-// Define this to debug color settings
-//#define GNASH_DEBUG_COLOR 1
 
 namespace gnash {
 
@@ -49,77 +47,13 @@
     as_value color_ctor(const fn_call& fn);
 
     as_object* getColorInterface();
+    inline void parseColorTransProp(as_object& obj, string_table::key key,
+            boost::int16_t& target, bool scale);
+    inline MovieClip* getTarget(as_object* obj, const fn_call& fn);
 }
 
-
-
-class Color_as: public as_object
-{
-
-public:
-
-       Color_as(MovieClip* sp)
-               :
-               as_object(getColorInterface()),
-               _sprite(sp)
-       {}
-
-       /// Mark associated sprite as reachable
-       //
-       /// Drop sprite instance reference if sprite
-       /// was unloaded.
-       ///
-       void markReachableResources() const
-       {
-               if ( checkSprite() )
-               {
-                       assert ( ! _sprite->unloaded() );
-                       _sprite->setReachable();
-               }
-               markAsObjectReachable();
-       }
-
-       MovieClip* getSprite() const
-       {
-               checkSprite();
-               return _sprite;
-       }
-
-       cxform getTransform() const
-       {
-               cxform ret;
-               if ( checkSprite() ) ret = _sprite->get_user_cxform();
-               return ret;
-       }
-
-       void setTransform(const cxform& newTrans) 
-       {
-               if (!checkSprite()) return;
-               _sprite->set_user_cxform(newTrans);
-       }
-
-private:
-
-       /// Drop reference to sprite if unloaded
-       //
-       /// Return true if we have a non-unloaded sprite
-       ///
-       bool checkSprite() const
-       {
-               if ( ! _sprite ) return false;
-               if ( _sprite->unloaded() )
-               {
-                       _sprite = 0;
-                       return false;
-               }
-               return true;
-       }
-
-       mutable MovieClip* _sprite;
-
-};
-
-void registerColorNative(as_object& o)
+void
+registerColorNative(as_object& o)
 {
        VM& vm = getVM(o);
 
@@ -137,6 +71,12 @@
     as_object* proto = getColorInterface();
     as_object* cl = gl->createClass(&color_ctor, proto);
 
+    // This has to be done after createClass is called, as that modifies
+    // proto.
+    const int protect = as_object::DefaultFlags | PropFlags::readOnly;
+    proto->set_member_flags(NSV::PROP_uuPROTOuu, protect); 
+    proto->set_member_flags(NSV::PROP_CONSTRUCTOR, protect); 
+
        // Register _global.Color
        global.init_member(getName(uri), cl, as_object::DefaultFlags,
             getNamespace(uri));
@@ -168,7 +108,9 @@
        static boost::intrusive_ptr<as_object> o;
        if ( ! o )
        {
-               o = new as_object(getObjectInterface());
+        as_object* proto = getObjectInterface();
+               o = new as_object(proto);
+
                attachColorInterface(*o);
        }
        return o.get();
@@ -178,18 +120,18 @@
 as_value
 color_getrgb(const fn_call& fn)
 {
-       boost::intrusive_ptr<Color_as> obj = ensureType<Color_as>(fn.this_ptr);
-
-       MovieClip* sp = obj->getSprite();
-       if ( ! sp ) return as_value();
-
-       const cxform& trans = obj->getTransform();
-
-       int r = (int)trans.rb;
-       int g = (int)trans.gb;
-       int b = (int)trans.bb;
-
-       boost::int32_t rgb = (r<<16) | (g<<8) | b;
+       boost::intrusive_ptr<as_object> obj = 
ensureType<as_object>(fn.this_ptr);
+
+    MovieClip* sp = getTarget(obj.get(), fn);
+    if (!sp) return as_value();
+
+       const cxform& trans = sp->get_user_cxform();
+
+    const int r = trans.rb;
+    const int g = trans.gb;
+    const int b = trans.bb;
+
+    const boost::int32_t rgb = (r<<16) | (g<<8) | b;
 
        return as_value(rgb);
 }
@@ -197,23 +139,18 @@
 as_value
 color_gettransform(const fn_call& fn)
 {
-       boost::intrusive_ptr<Color_as> obj = ensureType<Color_as>(fn.this_ptr);
-
-       MovieClip* sp = obj->getSprite();
-       if ( ! sp )
-       {
-               IF_VERBOSE_ASCODING_ERRORS(
-               std::stringstream ss; fn.dump_args(ss);
-               log_aserror(_("Color.getTransform(%s) : no or unloaded sprite 
associated with the Color object"), ss.str());
-               );
-               return as_value();
-       }
-
-       const cxform& cx = obj->getTransform();
+       boost::intrusive_ptr<as_object> obj = 
ensureType<as_object>(fn.this_ptr);
+
+    MovieClip* sp = getTarget(obj.get(), fn);
+    if (!sp) return as_value();
+
+       const cxform& cx = sp->get_user_cxform();
 
        // Convert to as_object
 
-       as_object* ret = new as_object(getObjectInterface());
+    Global_as* gl = getGlobal(fn);
+    as_object* proto = getObjectInterface();
+       as_object* ret = gl->createObject(proto);
 
        ret->init_member("ra", double(cx.ra / 2.56));
        ret->init_member("ga", double(cx.ga / 2.56));
@@ -231,62 +168,42 @@
 as_value
 color_setrgb(const fn_call& fn)
 {
-       boost::intrusive_ptr<Color_as> obj = ensureType<Color_as>(fn.this_ptr);
-
-       if ( fn.nargs < 1 )
-       {
+       boost::intrusive_ptr<as_object> obj = 
ensureType<as_object>(fn.this_ptr);
+       
+    if (!fn.nargs) {
                IF_VERBOSE_ASCODING_ERRORS(
                log_aserror(_("Color.setRGB() : missing argument"));
                );
                return as_value();
        }
 
+    MovieClip* sp = getTarget(obj.get(), fn);
+    if (!sp) return as_value();
+
        boost::int32_t color = fn.arg(0).to_int();
 
-       int r = (color&0xFF0000) >> 16;
-       int g = (color&0x00FF00) >> 8;
-       int b = (color&0x0000FF);
+       const int r = (color & 0xff0000) >> 16;
+       const int g = (color & 0x00ff00) >> 8;
+       const int b = (color & 0x0000ff);
 
-       cxform newTrans = obj->getTransform();
-       newTrans.rb = (boost::int16_t)r;
-       newTrans.gb = (boost::int16_t)g;
-       newTrans.bb = (boost::int16_t)b;
+       cxform newTrans = sp->get_user_cxform();
+       newTrans.rb = static_cast<boost::int16_t>(r);
+       newTrans.gb = static_cast<boost::int16_t>(g);
+       newTrans.bb = static_cast<boost::int16_t>(b);
        newTrans.ra = 0;
        newTrans.ga = 0;
        newTrans.ba = 0;
 
-       obj->setTransform(newTrans);
+    sp->set_user_cxform(newTrans);
 
        return as_value();
 }
-
-inline void
-parseColorTransProp (as_object& obj, string_table::key key,
-        boost::int16_t *target, bool scale)
-{
-       as_value tmp;
-       double d;
-
-       if ( ! obj.get_member(key, &tmp) ) {
-        return;
-    }
-    
-       d = tmp.to_number();
-       if ( scale ) {   
-        *target = (boost::int16_t)(d * 2.56);
-    }
-       else {
-        *target = (boost::int16_t)d;
-    }
-}
-
 as_value
 color_settransform(const fn_call& fn)
 {
-       boost::intrusive_ptr<Color_as> obj = ensureType<Color_as>(fn.this_ptr);
+       boost::intrusive_ptr<as_object> obj = 
ensureType<as_object>(fn.this_ptr);
 
-       if ( fn.nargs < 1 )
-       {
+       if (!fn.nargs) {
                IF_VERBOSE_ASCODING_ERRORS(
                log_aserror(_("Color.setTransform() : missing argument"));
                );
@@ -294,107 +211,91 @@
        }
 
        boost::intrusive_ptr<as_object> trans = 
fn.arg(0).to_object(*getGlobal(fn));
-       if ( ! trans )
-       {
-               IF_VERBOSE_ASCODING_ERRORS(
-               std::stringstream ss; fn.dump_args(ss);
-               log_aserror(_("Color.setTransform(%s) : first argument doesn't "
-                            "cast to an object"), ss.str());
-               );
-               return as_value();
-       }
-
-       MovieClip* sp = obj->getSprite();
-       if ( ! sp )
-       {
-               IF_VERBOSE_ASCODING_ERRORS(
-               std::stringstream ss; fn.dump_args(ss);
-               log_aserror(_("Color.setTransform(%s) : no or unloaded sprite "
-                        "associated with the Color object"), ss.str());
-               );
-               return as_value();
-       }
+
+    if (!trans) {
+               IF_VERBOSE_ASCODING_ERRORS(
+            std::ostringstream ss; fn.dump_args(ss);
+            log_aserror(_("Color.setTransform(%s) : first argument doesn't "
+                                "cast to an object"), ss.str());
+               );
+               return as_value();
+       }
+
+    MovieClip* sp = getTarget(obj.get(), fn);
+    if (!sp) return as_value();
 
        string_table& st = getStringTable(*obj);
 
-       cxform newTrans = obj->getTransform();
+       cxform newTrans = sp->get_user_cxform();
 
        // multipliers
-       parseColorTransProp(*trans, st.find("ra"), &newTrans.ra, true);
-       parseColorTransProp(*trans, st.find("ga"), &newTrans.ga, true);
-       parseColorTransProp(*trans, st.find("ba"), &newTrans.ba, true);
-       parseColorTransProp(*trans, st.find("aa"), &newTrans.aa, true);
+       parseColorTransProp(*trans, st.find("ra"), newTrans.ra, true);
+       parseColorTransProp(*trans, st.find("ga"), newTrans.ga, true);
+       parseColorTransProp(*trans, st.find("ba"), newTrans.ba, true);
+       parseColorTransProp(*trans, st.find("aa"), newTrans.aa, true);
 
        // offsets
-       parseColorTransProp(*trans, st.find("rb"), &newTrans.rb, false);
-       parseColorTransProp(*trans, st.find("gb"), &newTrans.gb, false);
-       parseColorTransProp(*trans, st.find("bb"), &newTrans.bb, false);
-       parseColorTransProp(*trans, st.find("ab"), &newTrans.ab, false);
-
-       obj->setTransform(newTrans);
-
-#ifdef GNASH_DEBUG_COLOR 
-       std::stringstream ss; 
-       as_value tmp;
-       if (trans->get_member(st.find("ra"), &tmp)) ss << " ra:" << 
tmp.to_number();
-       if (trans->get_member(st.find("ga"), &tmp)) ss << " ga:" << 
tmp.to_number();
-       if (trans->get_member(st.find("ba"), &tmp)) ss << " ba:" << 
tmp.to_number();
-       if (trans->get_member(st.find("aa"), &tmp)) ss << " aa:" << 
tmp.to_number();
-       if (trans->get_member(st.find("rb"), &tmp)) ss << " rb:" << 
tmp.to_number();
-       if (trans->get_member(st.find("gb"), &tmp)) ss << " gb:" << 
tmp.to_number();
-       if (trans->get_member(st.find("bb"), &tmp)) ss << " bb:" << 
tmp.to_number();
-       if (trans->get_member(st.find("ab"), &tmp)) ss << " ab:" << 
tmp.to_number();
-       log_debug("Color.setTransform(%s) : TESTING", ss.str());
-#endif
+       parseColorTransProp(*trans, st.find("rb"), newTrans.rb, false);
+       parseColorTransProp(*trans, st.find("gb"), newTrans.gb, false);
+       parseColorTransProp(*trans, st.find("bb"), newTrans.bb, false);
+       parseColorTransProp(*trans, st.find("ab"), newTrans.ab, false);
+
+       sp->set_user_cxform(newTrans);
 
        return as_value();
 }
 
+/// The first argument is set as the target property.
+//
+/// The target property is used to change the MovieClip's color.
+/// The pp calls ASSetPropFlags on all Color properties during construction,
+/// adding the readOnly flag. Because Gnash adds the __constructor__ property
+/// during construction, we have no control over its flags.
 as_value
 color_ctor(const fn_call& fn)
 {
-       MovieClip* sp=0;
-       if ( fn.nargs )
-       {
-               const as_value& arg = fn.arg(0);
-
-               // TODO: check what should happen if the argument is
-               //       a not-unloaded sprite but another exist with same
-               //       target at lower depth (always looking up would return
-               //       the lowest depth)
-               sp = arg.to_sprite();
-               if ( ! sp )
-               {
-                       // must be a target..
-                       DisplayObject* ch = 
fn.env().find_target(arg.to_string());
-                       if ( ch )
-                       {
-                               sp = ch->to_movie();
-                               IF_VERBOSE_ASCODING_ERRORS(
-                               if ( ! sp )
-                               {
-                               std::stringstream ss; fn.dump_args(ss);
-                               log_aserror(_("new Color(%s) : first argument 
evaluates "
-                                "to DisplayObject %s which is a %s (not a 
sprite)"),
-                                                   ss.str(), ch->getTarget(), 
typeName(*ch));
-                               }
-                               );
-                       }
-                       else
-                       {
-                               IF_VERBOSE_ASCODING_ERRORS(
-                               std::stringstream ss; fn.dump_args(ss);
-                               log_aserror(_("new Color(%s) : first argument 
doesn't evaluate or point to a DisplayObject"),
-                                       ss.str());
-                               )
-                       }
-               }
-       }
-
-       boost::intrusive_ptr<as_object> obj = new Color_as(sp);
        
+    as_object* proto = getColorInterface();
+    boost::intrusive_ptr<as_object> obj = new as_object(proto);
+    
+    as_value target;
+    if (fn.nargs) target = fn.arg(0);
+
+    const int flags = as_object::DefaultFlags | PropFlags::readOnly;
+
+    obj->init_member(NSV::PROP_TARGET, target, flags); 
+
        return as_value(obj.get()); // will keep alive
 }
 
+inline void
+parseColorTransProp (as_object& obj, string_table::key key, boost::int16_t&
+        target, bool scale)
+{
+       as_value tmp;
+       if (!obj.get_member(key, &tmp)) return;
+    
+       const double d = tmp.to_number();
+       if ( scale ) {   
+        target = static_cast<boost::int16_t>(d * 2.56);
+    }
+       else {
+        target = static_cast<boost::int16_t>(d);
+    }
+}
+
+// First try to convert target to a MovieClip. If that fails, convert to 
+// a string and look up the target.
+inline MovieClip*
+getTarget(as_object* obj, const fn_call& fn)
+{
+    const as_value& target = obj->getMember(NSV::PROP_TARGET);
+    MovieClip* sp = target.to_sprite();
+    if (sp) return sp;
+    DisplayObject* d = fn.env().find_target(target.to_string());
+    if (d) return d->to_movie();
+    return 0;
+}
+
 } // anonymous namespace 
 } // end of gnash namespace

=== modified file 'libcore/namedStrings.cpp'
--- a/libcore/namedStrings.cpp  2009-08-12 14:05:36 +0000
+++ b/libcore/namedStrings.cpp  2009-08-13 11:17:20 +0000
@@ -134,6 +134,7 @@
        string_table::svt( "Stage", NSV::PROP_iSTAGE ),
        string_table::svt( "status", NSV::PROP_STATUS ),
        string_table::svt( "super", NSV::PROP_SUPER ),
+       string_table::svt( "target", NSV::PROP_TARGET ),
        string_table::svt( "_target", NSV::PROP_uTARGET ),
        string_table::svt( "text", NSV::PROP_TEXT ),
        string_table::svt( "textColor", NSV::PROP_TEXT_COLOR ),

=== modified file 'libcore/namedStrings.h'
--- a/libcore/namedStrings.h    2009-08-12 14:05:36 +0000
+++ b/libcore/namedStrings.h    2009-08-13 11:17:20 +0000
@@ -207,6 +207,7 @@
         PROP_SPLICE,
         PROP_STATUS,
         PROP_SUPER,
+        PROP_TARGET,
         PROP_TEXT,
         PROP_TEXT_COLOR,
         PROP_TEXT_HEIGHT,

=== modified file 'testsuite/actionscript.all/Color.as'
--- a/testsuite/actionscript.all/Color.as       2009-02-25 22:33:03 +0000
+++ b/testsuite/actionscript.all/Color.as       2009-08-13 12:28:02 +0000
@@ -28,6 +28,9 @@
 //--------------------------------
 // Color was introduced in SWF5
 //--------------------------------
+#if OUTPUT_VERSION < 6
+Color.prototype.hasOwnProperty = ASnative(101, 5);
+#endif
 
 check_equals ( typeof(Color), 'function')
 check_equals ( typeof(Color.prototype), 'object')
@@ -40,12 +43,10 @@
 check_equals ( typeof(Color.getTransform), 'undefined')
 check_equals ( typeof(Color.setTransform), 'undefined')
 
-#if OUTPUT_VERSION > 5
 check ( Color.prototype.hasOwnProperty('getRGB') );
 check ( Color.prototype.hasOwnProperty('setRGB') );
 check ( Color.prototype.hasOwnProperty('getTransform') );
 check ( Color.prototype.hasOwnProperty('setTransform') );
-#endif
 
 //-----------------------------------------------------------
 // test the Color constuctor
@@ -58,15 +59,53 @@
 check_equals ( typeof(colorObj.getRGB()), 'undefined' );
 check_equals ( typeof(colorObj.getTransform()), 'undefined' );
 
+check(colorObj.hasOwnProperty("target"));
+check_equals(colorObj.target, undefined);
+
 colorObj = new Color(__shared_assets);
 check_equals ( typeof(colorObj), 'object')
 check ( colorObj instanceof Color );
 check ( colorObj instanceof Object );
+check(colorObj.hasOwnProperty("target"));
+check_equals(colorObj.target.toString(), "[object Object]");
 
 invalidColorObj = new Color(4);
 check_equals ( typeof(colorObj), 'object')
 check ( colorObj instanceof Color );
 check ( colorObj instanceof Object );
+check(invalidColorObj.hasOwnProperty("target"));
+check_equals(invalidColorObj.target.toString(), "4");
+
+called = "";
+o = {};
+o.toString = function() { called += "."; return "_root"; };
+
+// Check that target.toString() is called on each method, but not on
+// construction
+
+f = new Color(o);
+check_equals(called, "");
+
+rgb = f.getRGB();
+check_equals(called, ".");
+
+f.setRGB(rgb);
+check_equals(called, "..");
+
+// If o is a MovieClip, toString is not called.
+called = "";
+o = _root;
+o.toString = function() { called += ":"; return "mc"; };
+f = new Color(o);
+check_equals(called, "");
+
+rgb = f.getRGB();
+check_equals(called, "");
+
+f.setRGB(rgb);
+check_equals(called, "");
+
+
 
 //-----------------------------------------------------------
 // test the Color::getRGB method


reply via email to

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