1 // Color.cpp: ActionScript class for colors, for Gnash.
3 // Copyright (C) 2005, 2006, 2007, 2008, 2009, 2010 Free Software
6 // This program is free software; you can redistribute it and/or modify
7 // it under the terms of the GNU General Public License as published by
8 // the Free Software Foundation; either version 3 of the License, or
9 // (at your option) any later version.
11 // This program is distributed in the hope that it will be useful,
12 // but WITHOUT ANY WARRANTY; without even the implied warranty of
13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 // GNU General Public License for more details.
16 // You should have received a copy of the GNU General Public License
17 // along with this program; if not, write to the Free Software
18 // Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
25 #include "as_object.h" // for inheritance
28 #include "Global_as.h"
29 #include "smart_ptr.h" // for boost intrusive_ptr
30 #include "builtin_function.h" // need builtin_function
31 #include "NativeFunction.h"
32 #include "SWFCxForm.h" // for composition
34 #include "MovieClip.h"
35 #include "namedStrings.h"
39 // Forward declarations.
41 as_value
color_getrgb(const fn_call
& fn
);
42 as_value
color_gettransform(const fn_call
& fn
);
43 as_value
color_setrgb(const fn_call
& fn
);
44 as_value
color_settransform(const fn_call
& fn
);
45 as_value
color_ctor(const fn_call
& fn
);
47 void attachColorInterface(as_object
& o
);
48 inline void parseColorTransProp(as_object
& obj
, const ObjectURI
& key
,
49 boost::int16_t& target
, bool scale
);
50 inline MovieClip
* getTarget(as_object
* obj
, const fn_call
& fn
);
54 registerColorNative(as_object
& o
)
58 vm
.registerNative(color_setrgb
, 700, 0);
59 vm
.registerNative(color_settransform
, 700, 1);
60 vm
.registerNative(color_getrgb
, 700, 2);
61 vm
.registerNative(color_gettransform
, 700, 3);
64 // extern (used by Global.cpp)
66 color_class_init(as_object
& where
, const ObjectURI
& uri
)
68 as_object
* cl
= registerBuiltinClass(where
, color_ctor
,
69 attachColorInterface
, 0, uri
);
71 as_object
* proto
= toObject(
72 getMember(*cl
, NSV::PROP_PROTOTYPE
), getVM(where
));
76 const int protect
= as_object::DefaultFlags
| PropFlags::readOnly
;
77 proto
->set_member_flags(NSV::PROP_uuPROTOuu
, protect
);
78 proto
->set_member_flags(NSV::PROP_CONSTRUCTOR
, protect
);
86 attachColorInterface(as_object
& o
)
90 const int flags
= PropFlags::dontEnum
|
91 PropFlags::dontDelete
|
94 o
.init_member("setRGB", vm
.getNative(700, 0), flags
);
95 o
.init_member("setTransform", vm
.getNative(700, 1), flags
);
96 o
.init_member("getRGB", vm
.getNative(700, 2), flags
);
97 o
.init_member("getTransform", vm
.getNative(700, 3), flags
);
102 color_getrgb(const fn_call
& fn
)
104 as_object
* obj
= ensure
<ValidThis
>(fn
);
106 MovieClip
* sp
= getTarget(obj
, fn
);
107 if (!sp
) return as_value();
109 const SWFCxForm
& trans
= getCxForm(*sp
);
111 const int r
= trans
.rb
;
112 const int g
= trans
.gb
;
113 const int b
= trans
.bb
;
115 const boost::int32_t rgb
= (r
<<16) | (g
<<8) | b
;
117 return as_value(rgb
);
121 color_gettransform(const fn_call
& fn
)
123 as_object
* obj
= ensure
<ValidThis
>(fn
);
125 MovieClip
* sp
= getTarget(obj
, fn
);
126 if (!sp
) return as_value();
128 const SWFCxForm
& cx
= getCxForm(*sp
);
130 // Convert to as_object
132 Global_as
& gl
= getGlobal(fn
);
133 as_object
* ret
= createObject(gl
);
135 ret
->init_member("ra", double(cx
.ra
/ 2.56));
136 ret
->init_member("ga", double(cx
.ga
/ 2.56));
137 ret
->init_member("ba", double(cx
.ba
/ 2.56));
138 ret
->init_member("aa", double(cx
.aa
/ 2.56));
140 ret
->init_member("rb", int(cx
.rb
));
141 ret
->init_member("gb", int(cx
.gb
));
142 ret
->init_member("bb", int(cx
.bb
));
143 ret
->init_member("ab", int(cx
.ab
));
149 color_setrgb(const fn_call
& fn
)
151 as_object
* obj
= ensure
<ValidThis
>(fn
);
154 IF_VERBOSE_ASCODING_ERRORS(
155 log_aserror(_("Color.setRGB() : missing argument"));
160 MovieClip
* sp
= getTarget(obj
, fn
);
161 if (!sp
) return as_value();
163 boost::int32_t color
= toInt(fn
.arg(0), getVM(fn
));
165 const int r
= (color
& 0xff0000) >> 16;
166 const int g
= (color
& 0x00ff00) >> 8;
167 const int b
= (color
& 0x0000ff);
169 SWFCxForm newTrans
= getCxForm(*sp
);
170 newTrans
.rb
= static_cast<boost::int16_t>(r
);
171 newTrans
.gb
= static_cast<boost::int16_t>(g
);
172 newTrans
.bb
= static_cast<boost::int16_t>(b
);
177 sp
->setCxForm(newTrans
);
182 color_settransform(const fn_call
& fn
)
184 as_object
* obj
= ensure
<ValidThis
>(fn
);
187 IF_VERBOSE_ASCODING_ERRORS(
188 log_aserror(_("Color.setTransform() : missing argument"));
193 as_object
* trans
= toObject(fn
.arg(0), getVM(fn
));
196 IF_VERBOSE_ASCODING_ERRORS(
197 std::ostringstream ss
; fn
.dump_args(ss
);
198 log_aserror(_("Color.setTransform(%s) : first argument doesn't "
199 "cast to an object"), ss
.str());
204 MovieClip
* sp
= getTarget(obj
, fn
);
205 if (!sp
) return as_value();
207 VM
& vm
= getVM(*obj
);
209 SWFCxForm newTrans
= getCxForm(*sp
);
214 parseColorTransProp(*trans
, getURI(vm
, "ra"), newTrans
.ra
, true);
215 parseColorTransProp(*trans
, getURI(vm
, "ga"), newTrans
.ga
, true);
216 parseColorTransProp(*trans
, getURI(vm
, "ba"), newTrans
.ba
, true);
217 parseColorTransProp(*trans
, getURI(vm
, "aa"), newTrans
.aa
, true);
220 parseColorTransProp(*trans
, getURI(vm
, "rb"), newTrans
.rb
, false);
221 parseColorTransProp(*trans
, getURI(vm
, "gb"), newTrans
.gb
, false);
222 parseColorTransProp(*trans
, getURI(vm
, "bb"), newTrans
.bb
, false);
223 parseColorTransProp(*trans
, getURI(vm
, "ab"), newTrans
.ab
, false);
225 sp
->setCxForm(newTrans
);
230 /// The first argument is set as the target property.
232 /// The target property is used to change the MovieClip's color.
233 /// The pp calls ASSetPropFlags on all Color properties during construction,
234 /// adding the readOnly flag. Because Gnash adds the __constructor__ property
235 /// during construction, we have no control over its flags.
237 color_ctor(const fn_call
& fn
)
240 as_object
* obj
= ensure
<ValidThis
>(fn
);
243 if (fn
.nargs
) target
= fn
.arg(0);
245 obj
->set_member(NSV::PROP_TARGET
, target
);
247 Global_as
& gl
= getGlobal(fn
);
249 callMethod(&gl
, NSV::PROP_AS_SET_PROP_FLAGS
, obj
, null
, 7);
255 parseColorTransProp(as_object
& obj
, const ObjectURI
& key
, boost::int16_t&
259 if (!obj
.get_member(key
, &tmp
)) return;
261 const double d
= toNumber(tmp
, getVM(obj
));
263 target
= static_cast<boost::int16_t>(d
* 2.56);
266 target
= static_cast<boost::int16_t>(d
);
270 // First try to convert target to a MovieClip. If that fails, convert to
271 // a string and look up the target.
273 getTarget(as_object
* obj
, const fn_call
& fn
)
275 const as_value
& target
= getMember(*obj
, NSV::PROP_TARGET
);
276 MovieClip
* sp
= target
.toMovieClip();
278 DisplayObject
* o
= findTarget(fn
.env(), target
.to_string());
279 if (o
) return o
->to_movie();
283 } // anonymous namespace
284 } // end of gnash namespace