[Top][All Lists]
[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
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- [Gnash-commit] /srv/bzr/gnash/trunk r11416: Do Color class correctly.,
Benjamin Wolsey <=