~ubuntu-branches/ubuntu/saucy/gnash/saucy-proposed

« back to all changes in this revision

Viewing changes to libcore/asobj/flash/geom/Rectangle_as.cpp

  • Committer: Bazaar Package Importer
  • Author(s): Sindhudweep Narayan Sarkar
  • Date: 2009-10-07 00:06:10 UTC
  • mfrom: (1.1.12 upstream)
  • Revision ID: james.westby@ubuntu.com-20091007000610-mj9rwqe774gizn1j
Tags: 0.8.6-0ubuntu1
new upstream release 0.8.6 (LP: #435897)

Show diffs side-by-side

added added

removed removed

Lines of Context:
22
22
#endif
23
23
 
24
24
#include "Rectangle_as.h"
25
 
#include "Point_as.h"
26
25
#include "as_object.h" // for inheritance
27
26
#include "log.h"
28
27
#include "fn_call.h"
 
28
#include "Global_as.h"
29
29
#include "smart_ptr.h" // for boost intrusive_ptr
30
30
#include "builtin_function.h" // need builtin_function
31
31
#include "GnashException.h" // for ActionException
33
33
#include "VM.h" // for addStatics
34
34
#include "as_value.h"
35
35
#include "namedStrings.h"
36
 
#include "utility.h" // isFinite
 
36
#include "GnashNumeric.h" // isFinite
37
37
 
38
38
#include <sstream>
39
39
 
68
68
static void
69
69
attachRectangleInterface(as_object& o)
70
70
{
71
 
    o.init_member("clone", new builtin_function(Rectangle_clone), 0);
72
 
    o.init_member("contains", new builtin_function(Rectangle_contains), 0);
73
 
    o.init_member("containsPoint", new builtin_function(Rectangle_containsPoint), 0);
74
 
    o.init_member("containsRectangle", new builtin_function(Rectangle_containsRectangle), 0);
75
 
    o.init_member("equals", new builtin_function(Rectangle_equals), 0);
76
 
    o.init_member("inflate", new builtin_function(Rectangle_inflate), 0);
77
 
    o.init_member("inflatePoint", new builtin_function(Rectangle_inflatePoint), 0);
78
 
    o.init_member("intersection", new builtin_function(Rectangle_intersection), 0);
79
 
    o.init_member("intersects", new builtin_function(Rectangle_intersects), 0);
80
 
    o.init_member("isEmpty", new builtin_function(Rectangle_isEmpty), 0);
81
 
    o.init_member("offset", new builtin_function(Rectangle_offset), 0);
82
 
    o.init_member("offsetPoint", new builtin_function(Rectangle_offsetPoint), 0);
83
 
    o.init_member("setEmpty", new builtin_function(Rectangle_setEmpty), 0);
84
 
    o.init_member("toString", new builtin_function(Rectangle_toString), 0);
85
 
    o.init_member("union", new builtin_function(Rectangle_union), 0);
 
71
    Global_as* gl = getGlobal(o);
 
72
    o.init_member("clone", gl->createFunction(Rectangle_clone), 0);
 
73
    o.init_member("contains", gl->createFunction(Rectangle_contains), 0);
 
74
    o.init_member("containsPoint", gl->createFunction(Rectangle_containsPoint), 0);
 
75
    o.init_member("containsRectangle", gl->createFunction(Rectangle_containsRectangle), 0);
 
76
    o.init_member("equals", gl->createFunction(Rectangle_equals), 0);
 
77
    o.init_member("inflate", gl->createFunction(Rectangle_inflate), 0);
 
78
    o.init_member("inflatePoint", gl->createFunction(Rectangle_inflatePoint), 0);
 
79
    o.init_member("intersection", gl->createFunction(Rectangle_intersection), 0);
 
80
    o.init_member("intersects", gl->createFunction(Rectangle_intersects), 0);
 
81
    o.init_member("isEmpty", gl->createFunction(Rectangle_isEmpty), 0);
 
82
    o.init_member("offset", gl->createFunction(Rectangle_offset), 0);
 
83
    o.init_member("offsetPoint", gl->createFunction(Rectangle_offsetPoint), 0);
 
84
    o.init_member("setEmpty", gl->createFunction(Rectangle_setEmpty), 0);
 
85
    o.init_member("toString", gl->createFunction(Rectangle_toString), 0);
 
86
    o.init_member("union", gl->createFunction(Rectangle_union), 0);
86
87
    o.init_property("bottom", Rectangle_bottom_getset, Rectangle_bottom_getset, 0);
87
88
    o.init_property("bottomRight", Rectangle_bottomRight_getset,
88
89
            Rectangle_bottomRight_getset, 0);
102
103
static as_object*
103
104
getRectangleInterface()
104
105
{
105
 
        static boost::intrusive_ptr<as_object> o;
106
 
 
107
 
        if ( ! o )
108
 
        {
109
 
                o = new as_object(getObjectInterface());
110
 
                VM::get().addStatic(o.get());
111
 
 
112
 
                attachRectangleInterface(*o);
113
 
        }
114
 
 
115
 
        return o.get();
 
106
    static boost::intrusive_ptr<as_object> o;
 
107
 
 
108
    if ( ! o )
 
109
    {
 
110
        o = new as_object(getObjectInterface());
 
111
        VM::get().addStatic(o.get());
 
112
 
 
113
        attachRectangleInterface(*o);
 
114
    }
 
115
 
 
116
    return o.get();
116
117
}
117
118
 
118
119
class Rectangle_as: public as_object
120
121
 
121
122
public:
122
123
 
123
 
        Rectangle_as()
124
 
                :
125
 
                as_object(getRectangleInterface())
126
 
        {}
127
 
 
128
 
        // override from as_object ?
129
 
        //std::string get_text_value() const { return "Rectangle"; }
130
 
 
131
 
        // override from as_object ?
132
 
        //double get_numeric_value() const { return 0; }
 
124
    Rectangle_as()
 
125
        :
 
126
        as_object(getRectangleInterface())
 
127
    {}
133
128
};
134
129
 
135
130
 
138
133
{
139
134
    // The object will be interpreted as a rectangle. Any Rectangle
140
135
    // properties that the object has (width, height, x, y) are used.
141
 
        boost::intrusive_ptr<as_object> ptr = ensureType<as_object>(fn.this_ptr);
142
 
 
143
 
        as_value x, y, w, h;
144
 
 
145
 
        ptr->get_member(NSV::PROP_X, &x);
146
 
        ptr->get_member(NSV::PROP_Y, &y);
147
 
        ptr->get_member(NSV::PROP_WIDTH, &w);
148
 
        ptr->get_member(NSV::PROP_HEIGHT, &h);
149
 
 
150
 
        boost::intrusive_ptr<as_object> obj = new Rectangle_as;
151
 
 
152
 
        obj->set_member(NSV::PROP_X, x);
153
 
        obj->set_member(NSV::PROP_Y, y);
154
 
        obj->set_member(NSV::PROP_WIDTH, w);
155
 
        obj->set_member(NSV::PROP_HEIGHT, h);
156
 
 
157
 
        return as_value(obj.get()); // will keep alive
 
136
    boost::intrusive_ptr<as_object> ptr = ensureType<as_object>(fn.this_ptr);
 
137
 
 
138
    as_value x, y, w, h;
 
139
 
 
140
    ptr->get_member(NSV::PROP_X, &x);
 
141
    ptr->get_member(NSV::PROP_Y, &y);
 
142
    ptr->get_member(NSV::PROP_WIDTH, &w);
 
143
    ptr->get_member(NSV::PROP_HEIGHT, &h);
 
144
 
 
145
    boost::intrusive_ptr<as_object> obj = new Rectangle_as;
 
146
 
 
147
    obj->set_member(NSV::PROP_X, x);
 
148
    obj->set_member(NSV::PROP_Y, y);
 
149
    obj->set_member(NSV::PROP_WIDTH, w);
 
150
    obj->set_member(NSV::PROP_HEIGHT, h);
 
151
 
 
152
    return as_value(obj.get()); // will keep alive
158
153
}
159
154
 
160
155
static as_value
161
156
Rectangle_contains(const fn_call& fn)
162
157
{
163
 
        //fn.arg(0) => x coordinate
164
 
        //fn.arg(1) => y coordinate
165
 
 
166
 
        boost::intrusive_ptr<Rectangle_as> ptr = ensureType<Rectangle_as>(fn.this_ptr);
167
 
 
168
 
        as_value rect_x_as, rect_width_as, rect_y_as, rect_height_as;
169
 
 
170
 
        ptr->get_member(NSV::PROP_X, &rect_x_as);
171
 
        ptr->get_member(NSV::PROP_WIDTH, &rect_width_as);
172
 
        ptr->get_member(NSV::PROP_Y, &rect_y_as);
173
 
        ptr->get_member(NSV::PROP_HEIGHT, &rect_height_as);
174
 
 
175
 
        if ( fn.nargs < 2 )
176
 
        {
177
 
                IF_VERBOSE_ASCODING_ERRORS(
178
 
                        std::stringstream ss;
179
 
                        fn.dump_args(ss);
180
 
                        log_aserror("flash.geom.Rectangle(%s): %s", ss.str(), _("missing arguments"));
181
 
                );
182
 
                return as_value();
183
 
        }
184
 
 
185
 
        const as_value& x_as = fn.arg(0);
186
 
        const as_value& y_as = fn.arg(1);
187
 
        if ( x_as.is_null() || x_as.is_undefined() ||
188
 
             y_as.is_null() || y_as.is_undefined() )
189
 
        {
190
 
                IF_VERBOSE_ASCODING_ERRORS(
191
 
                        std::stringstream ss;
192
 
                        fn.dump_args(ss);
193
 
                        log_aserror("flash.geom.Rectangle(%s): %s", ss.str(), _("invalid arguments"));
194
 
                );
195
 
                return as_value();
196
 
        }
197
 
 
198
 
        as_value rect_x1_as = rect_x_as;
199
 
        rect_x1_as.newAdd(rect_width_as);
200
 
 
201
 
        as_value rect_y1_as = rect_y_as;
202
 
        rect_y1_as.newAdd(rect_height_as);
203
 
 
204
 
        if ( rect_x_as.is_null() || rect_x_as.is_undefined() ||
205
 
             rect_y_as.is_null() || rect_y_as.is_undefined() ||
206
 
             rect_x1_as.is_null() || rect_x1_as.is_undefined() ||
207
 
             rect_y1_as.is_null() || rect_y1_as.is_undefined() )
208
 
        {
209
 
                IF_VERBOSE_ASCODING_ERRORS(
210
 
                        std::stringstream ss;
211
 
                        fn.dump_args(ss);
212
 
                        log_aserror("flash.geom.Rectangle(%s): %s", ss.str(), _("invalid rectangle"));
213
 
                );
214
 
                return as_value();
215
 
        }
216
 
 
217
 
        //Points are contained within the Rectangle IFF they lie
218
 
        //on the top or left borders of the rectangle, but not the right or
219
 
        //bottom borders, or they are not on a border but between all.
220
 
        
221
 
        // NOTE: order of tests is important, see actionscript.all/Rectangle.as
222
 
 
223
 
        as_value ret = x_as.newLessThan(rect_x_as);
224
 
        if ( ret.is_undefined() ) return as_value();
225
 
        if ( ret.to_bool() ) return as_value(false); 
226
 
 
227
 
        ret = x_as.newLessThan(rect_x1_as);
228
 
        if ( ret.is_undefined() ) return as_value();
229
 
        if ( ! ret.to_bool() ) return as_value(false); 
230
 
 
231
 
        ret = y_as.newLessThan(rect_y_as);
232
 
        if ( ret.is_undefined() ) return as_value();
233
 
        if ( ret.to_bool() ) return as_value(false); 
234
 
 
235
 
        ret = y_as.newLessThan(rect_y1_as);
236
 
        if ( ret.is_undefined() ) return as_value();
237
 
        if ( ! ret.to_bool() ) return as_value(false); 
238
 
 
239
 
        return as_value(true);
 
158
    //fn.arg(0) => x coordinate
 
159
    //fn.arg(1) => y coordinate
 
160
 
 
161
    boost::intrusive_ptr<Rectangle_as> ptr = ensureType<Rectangle_as>(fn.this_ptr);
 
162
 
 
163
    as_value rect_x_as, rect_width_as, rect_y_as, rect_height_as;
 
164
 
 
165
    ptr->get_member(NSV::PROP_X, &rect_x_as);
 
166
    ptr->get_member(NSV::PROP_WIDTH, &rect_width_as);
 
167
    ptr->get_member(NSV::PROP_Y, &rect_y_as);
 
168
    ptr->get_member(NSV::PROP_HEIGHT, &rect_height_as);
 
169
 
 
170
    if ( fn.nargs < 2 )
 
171
    {
 
172
        IF_VERBOSE_ASCODING_ERRORS(
 
173
            std::stringstream ss;
 
174
            fn.dump_args(ss);
 
175
            log_aserror("flash.geom.Rectangle(%s): %s", ss.str(), 
 
176
                _("missing arguments"));
 
177
        );
 
178
        return as_value();
 
179
    }
 
180
 
 
181
    const as_value& x_as = fn.arg(0);
 
182
    const as_value& y_as = fn.arg(1);
 
183
    if ( x_as.is_null() || x_as.is_undefined() ||
 
184
         y_as.is_null() || y_as.is_undefined() )
 
185
    {
 
186
        IF_VERBOSE_ASCODING_ERRORS(
 
187
            std::stringstream ss;
 
188
            fn.dump_args(ss);
 
189
            log_aserror("flash.geom.Rectangle(%s): %s", ss.str(), _("invalid arguments"));
 
190
        );
 
191
        return as_value();
 
192
    }
 
193
 
 
194
    as_value rect_x1_as = rect_x_as;
 
195
    rect_x1_as.newAdd(rect_width_as);
 
196
 
 
197
    as_value rect_y1_as = rect_y_as;
 
198
    rect_y1_as.newAdd(rect_height_as);
 
199
 
 
200
    if ( rect_x_as.is_null() || rect_x_as.is_undefined() ||
 
201
         rect_y_as.is_null() || rect_y_as.is_undefined() ||
 
202
         rect_x1_as.is_null() || rect_x1_as.is_undefined() ||
 
203
         rect_y1_as.is_null() || rect_y1_as.is_undefined() )
 
204
    {
 
205
        IF_VERBOSE_ASCODING_ERRORS(
 
206
            std::stringstream ss;
 
207
            fn.dump_args(ss);
 
208
            log_aserror("flash.geom.Rectangle(%s): %s", ss.str(), _("invalid rectangle"));
 
209
        );
 
210
        return as_value();
 
211
    }
 
212
 
 
213
    //Points are contained within the Rectangle IFF they lie
 
214
    //on the top or left borders of the rectangle, but not the right or
 
215
    //bottom borders, or they are not on a border but between all.
 
216
    
 
217
    // NOTE: order of tests is important, see actionscript.all/Rectangle.as
 
218
 
 
219
    as_value ret = x_as.newLessThan(rect_x_as);
 
220
    if ( ret.is_undefined() ) return as_value();
 
221
    if ( ret.to_bool() ) return as_value(false); 
 
222
 
 
223
    ret = x_as.newLessThan(rect_x1_as);
 
224
    if ( ret.is_undefined() ) return as_value();
 
225
    if ( ! ret.to_bool() ) return as_value(false); 
 
226
 
 
227
    ret = y_as.newLessThan(rect_y_as);
 
228
    if ( ret.is_undefined() ) return as_value();
 
229
    if ( ret.to_bool() ) return as_value(false); 
 
230
 
 
231
    ret = y_as.newLessThan(rect_y1_as);
 
232
    if ( ret.is_undefined() ) return as_value();
 
233
    if ( ! ret.to_bool() ) return as_value(false); 
 
234
 
 
235
    return as_value(true);
240
236
 
241
237
}
242
238
 
243
239
static as_value
244
240
Rectangle_containsPoint(const fn_call& fn)
245
241
{
246
 
        boost::intrusive_ptr<Rectangle_as> ptr = ensureType<Rectangle_as>(fn.this_ptr);
247
 
        UNUSED(ptr);
248
 
        LOG_ONCE( log_unimpl (__FUNCTION__) );
249
 
        return as_value();
 
242
    boost::intrusive_ptr<Rectangle_as> ptr = ensureType<Rectangle_as>(fn.this_ptr);
 
243
    UNUSED(ptr);
 
244
    LOG_ONCE( log_unimpl (__FUNCTION__) );
 
245
    return as_value();
250
246
}
251
247
 
252
248
static as_value
253
249
Rectangle_containsRectangle(const fn_call& fn)
254
250
{
255
 
        boost::intrusive_ptr<Rectangle_as> ptr = ensureType<Rectangle_as>(fn.this_ptr);
256
 
        UNUSED(ptr);
257
 
        LOG_ONCE( log_unimpl (__FUNCTION__) );
258
 
        return as_value();
 
251
    boost::intrusive_ptr<Rectangle_as> ptr = ensureType<Rectangle_as>(fn.this_ptr);
 
252
    UNUSED(ptr);
 
253
    LOG_ONCE( log_unimpl (__FUNCTION__) );
 
254
    return as_value();
259
255
}
260
256
 
261
257
static as_value
262
258
Rectangle_equals(const fn_call& fn)
263
259
{
264
 
        boost::intrusive_ptr<Rectangle_as> ptr = ensureType<Rectangle_as>(fn.this_ptr);
265
 
        UNUSED(ptr);
266
 
        LOG_ONCE( log_unimpl (__FUNCTION__) );
267
 
        return as_value();
 
260
    boost::intrusive_ptr<Rectangle_as> ptr = ensureType<Rectangle_as>(fn.this_ptr);
 
261
    UNUSED(ptr);
 
262
    LOG_ONCE( log_unimpl (__FUNCTION__) );
 
263
    return as_value();
268
264
}
269
265
 
270
266
static as_value
271
267
Rectangle_inflate(const fn_call& fn)
272
268
{
273
 
        boost::intrusive_ptr<Rectangle_as> ptr = ensureType<Rectangle_as>(fn.this_ptr);
274
 
        UNUSED(ptr);
275
 
        LOG_ONCE( log_unimpl (__FUNCTION__) );
276
 
        return as_value();
 
269
    boost::intrusive_ptr<Rectangle_as> ptr = ensureType<Rectangle_as>(fn.this_ptr);
 
270
    UNUSED(ptr);
 
271
    LOG_ONCE( log_unimpl (__FUNCTION__) );
 
272
    return as_value();
277
273
}
278
274
 
279
275
static as_value
280
276
Rectangle_inflatePoint(const fn_call& fn)
281
277
{
282
 
        boost::intrusive_ptr<Rectangle_as> ptr = ensureType<Rectangle_as>(fn.this_ptr);
283
 
        UNUSED(ptr);
284
 
        LOG_ONCE( log_unimpl (__FUNCTION__) );
285
 
        return as_value();
 
278
    boost::intrusive_ptr<Rectangle_as> ptr = ensureType<Rectangle_as>(fn.this_ptr);
 
279
    UNUSED(ptr);
 
280
    LOG_ONCE( log_unimpl (__FUNCTION__) );
 
281
    return as_value();
286
282
}
287
283
 
288
284
static as_value
289
285
Rectangle_intersection(const fn_call& fn)
290
286
{
291
 
        boost::intrusive_ptr<Rectangle_as> ptr = ensureType<Rectangle_as>(fn.this_ptr);
292
 
        UNUSED(ptr);
293
 
        LOG_ONCE( log_unimpl (__FUNCTION__) );
294
 
        return as_value();
 
287
    boost::intrusive_ptr<Rectangle_as> ptr = ensureType<Rectangle_as>(fn.this_ptr);
 
288
    UNUSED(ptr);
 
289
    LOG_ONCE( log_unimpl (__FUNCTION__) );
 
290
    return as_value();
295
291
}
296
292
 
297
293
static as_value
298
294
Rectangle_intersects(const fn_call& fn)
299
295
{
300
 
        boost::intrusive_ptr<Rectangle_as> ptr = ensureType<Rectangle_as>(fn.this_ptr);
301
 
        UNUSED(ptr);
302
 
        LOG_ONCE( log_unimpl (__FUNCTION__) );
303
 
        return as_value();
 
296
    boost::intrusive_ptr<Rectangle_as> ptr = ensureType<Rectangle_as>(fn.this_ptr);
 
297
    UNUSED(ptr);
 
298
    LOG_ONCE( log_unimpl (__FUNCTION__) );
 
299
    return as_value();
304
300
}
305
301
 
306
302
static as_value
307
303
Rectangle_isEmpty(const fn_call& fn)
308
304
{
309
 
        boost::intrusive_ptr<Rectangle_as> ptr = ensureType<Rectangle_as>(fn.this_ptr);
310
 
 
311
 
        as_value w;
312
 
        ptr->get_member(NSV::PROP_WIDTH, &w);
313
 
        if ( w.is_undefined() || w.is_null() ) return as_value(true);
314
 
 
315
 
        as_value h;
316
 
        ptr->get_member(NSV::PROP_HEIGHT, &h);
317
 
        if ( h.is_undefined() || h.is_null() ) return as_value(true);
318
 
 
319
 
        double wn = w.to_number();
320
 
        if ( ! utility::isFinite(wn) || wn <= 0 ) return as_value(true);
321
 
 
322
 
        double hn = h.to_number();
323
 
        if ( ! utility::isFinite(hn) || hn <= 0 ) return as_value(true);
324
 
 
325
 
        log_debug("Width: %g, Height: %g", wn, hn);
326
 
 
327
 
        return as_value(false);
 
305
    boost::intrusive_ptr<Rectangle_as> ptr = ensureType<Rectangle_as>(fn.this_ptr);
 
306
 
 
307
    as_value w;
 
308
    ptr->get_member(NSV::PROP_WIDTH, &w);
 
309
    if ( w.is_undefined() || w.is_null() ) return as_value(true);
 
310
 
 
311
    as_value h;
 
312
    ptr->get_member(NSV::PROP_HEIGHT, &h);
 
313
    if ( h.is_undefined() || h.is_null() ) return as_value(true);
 
314
 
 
315
    double wn = w.to_number();
 
316
    if (!isFinite(wn) || wn <= 0) return as_value(true);
 
317
 
 
318
    double hn = h.to_number();
 
319
    if (!isFinite(hn) || hn <= 0) return as_value(true);
 
320
 
 
321
    log_debug("Width: %g, Height: %g", wn, hn);
 
322
 
 
323
    return as_value(false);
328
324
}
329
325
 
330
326
static as_value
331
327
Rectangle_offset(const fn_call& fn)
332
328
{
333
 
        boost::intrusive_ptr<Rectangle_as> ptr = ensureType<Rectangle_as>(fn.this_ptr);
334
 
        UNUSED(ptr);
335
 
        LOG_ONCE( log_unimpl (__FUNCTION__) );
336
 
        return as_value();
 
329
    boost::intrusive_ptr<Rectangle_as> ptr = ensureType<Rectangle_as>(fn.this_ptr);
 
330
    UNUSED(ptr);
 
331
    LOG_ONCE( log_unimpl (__FUNCTION__) );
 
332
    return as_value();
337
333
}
338
334
 
339
335
static as_value
340
336
Rectangle_offsetPoint(const fn_call& fn)
341
337
{
342
 
        boost::intrusive_ptr<Rectangle_as> ptr = ensureType<Rectangle_as>(fn.this_ptr);
343
 
        UNUSED(ptr);
344
 
        LOG_ONCE( log_unimpl (__FUNCTION__) );
345
 
        return as_value();
 
338
    boost::intrusive_ptr<Rectangle_as> ptr = ensureType<Rectangle_as>(fn.this_ptr);
 
339
    UNUSED(ptr);
 
340
    LOG_ONCE( log_unimpl (__FUNCTION__) );
 
341
    return as_value();
346
342
}
347
343
 
348
344
static as_value
349
345
Rectangle_setEmpty(const fn_call& fn)
350
346
{
351
 
        boost::intrusive_ptr<Rectangle_as> ptr = ensureType<Rectangle_as>(fn.this_ptr);
352
 
        UNUSED(ptr);
353
 
        LOG_ONCE( log_unimpl (__FUNCTION__) );
354
 
        return as_value();
 
347
    boost::intrusive_ptr<Rectangle_as> ptr = ensureType<Rectangle_as>(fn.this_ptr);
 
348
    UNUSED(ptr);
 
349
    LOG_ONCE( log_unimpl (__FUNCTION__) );
 
350
    return as_value();
355
351
}
356
352
 
357
353
static as_value
358
354
Rectangle_toString(const fn_call& fn)
359
355
{
360
 
        boost::intrusive_ptr<Rectangle_as> ptr = ensureType<Rectangle_as>(fn.this_ptr);
361
 
 
362
 
        as_value x, y, w, h;
363
 
 
364
 
        ptr->get_member(NSV::PROP_X, &x);
365
 
        ptr->get_member(NSV::PROP_Y, &y);
366
 
        ptr->get_member(NSV::PROP_WIDTH, &w);
367
 
        ptr->get_member(NSV::PROP_HEIGHT, &h);
368
 
 
369
 
        std::stringstream ss;
370
 
        ss << "(x=" << x.to_string()
371
 
                << ", y=" << y.to_string()
372
 
                << ", w=" << w.to_string()
373
 
                << ", h=" << h.to_string()
374
 
                 << ")";
375
 
 
376
 
        return as_value(ss.str());
 
356
    boost::intrusive_ptr<Rectangle_as> ptr = ensureType<Rectangle_as>(fn.this_ptr);
 
357
 
 
358
    as_value x, y, w, h;
 
359
 
 
360
    ptr->get_member(NSV::PROP_X, &x);
 
361
    ptr->get_member(NSV::PROP_Y, &y);
 
362
    ptr->get_member(NSV::PROP_WIDTH, &w);
 
363
    ptr->get_member(NSV::PROP_HEIGHT, &h);
 
364
 
 
365
    std::stringstream ss;
 
366
    ss << "(x=" << x.to_string()
 
367
        << ", y=" << y.to_string()
 
368
        << ", w=" << w.to_string()
 
369
        << ", h=" << h.to_string()
 
370
         << ")";
 
371
 
 
372
    return as_value(ss.str());
377
373
}
378
374
 
379
375
static as_value
380
376
Rectangle_union(const fn_call& fn)
381
377
{
382
 
        boost::intrusive_ptr<Rectangle_as> ptr = ensureType<Rectangle_as>(fn.this_ptr);
383
 
        UNUSED(ptr);
384
 
        LOG_ONCE( log_unimpl (__FUNCTION__) );
385
 
        return as_value();
 
378
    boost::intrusive_ptr<Rectangle_as> ptr = ensureType<Rectangle_as>(fn.this_ptr);
 
379
    UNUSED(ptr);
 
380
    LOG_ONCE( log_unimpl (__FUNCTION__) );
 
381
    return as_value();
386
382
}
387
383
 
388
384
static as_value
389
385
Rectangle_bottom_getset(const fn_call& fn)
390
386
{
391
 
        boost::intrusive_ptr<Rectangle_as> ptr = ensureType<Rectangle_as>(fn.this_ptr);
392
 
 
393
 
        as_value ret;
394
 
 
395
 
        if ( ! fn.nargs ) // getter
396
 
        {
397
 
                as_value height;
398
 
                ptr->get_member(NSV::PROP_Y, &ret);
399
 
                ptr->get_member(NSV::PROP_HEIGHT, &height);
400
 
                ret.newAdd(height);
401
 
        }
402
 
        else // setter
403
 
        {
404
 
                as_value y;
405
 
                ptr->get_member(NSV::PROP_Y, &y);
406
 
 
407
 
                as_value bottom = fn.arg(0);
408
 
                as_value newh = bottom.subtract(y);
409
 
                ptr->set_member(NSV::PROP_HEIGHT, newh);
410
 
        }
411
 
 
412
 
        return ret;
 
387
    boost::intrusive_ptr<Rectangle_as> ptr = ensureType<Rectangle_as>(fn.this_ptr);
 
388
 
 
389
    as_value ret;
 
390
 
 
391
    if ( ! fn.nargs ) // getter
 
392
    {
 
393
        as_value height;
 
394
        ptr->get_member(NSV::PROP_Y, &ret);
 
395
        ptr->get_member(NSV::PROP_HEIGHT, &height);
 
396
        ret.newAdd(height);
 
397
    }
 
398
    else // setter
 
399
    {
 
400
        as_value y;
 
401
        ptr->get_member(NSV::PROP_Y, &y);
 
402
 
 
403
        as_value bottom = fn.arg(0);
 
404
        as_value newh = bottom.subtract(y);
 
405
        ptr->set_member(NSV::PROP_HEIGHT, newh);
 
406
    }
 
407
 
 
408
    return ret;
413
409
}
414
410
 
415
411
static as_value
416
412
Rectangle_bottomRight_getset(const fn_call& fn)
417
413
{
418
 
        boost::intrusive_ptr<Rectangle_as> ptr = ensureType<Rectangle_as>(fn.this_ptr);
419
 
 
420
 
        as_value ret;
421
 
 
422
 
        if ( ! fn.nargs ) // getter
423
 
        {
424
 
                as_value x,y,w,h;
425
 
                ptr->get_member(NSV::PROP_X, &x);
426
 
                ptr->get_member(NSV::PROP_Y, &y);
427
 
                ptr->get_member(NSV::PROP_WIDTH, &w);
428
 
                ptr->get_member(NSV::PROP_HEIGHT, &h);
429
 
 
430
 
                as_value right = x.newAdd(w);
431
 
                as_value bottom = y.newAdd(h);
432
 
 
433
 
                as_function* pointCtor = getFlashGeomPointConstructor();
434
 
 
435
 
                as_environment& env = fn.env();
436
 
 
437
 
                std::auto_ptr< std::vector<as_value> > args ( new std::vector<as_value> );
438
 
                args->push_back(right);
439
 
                args->push_back(bottom);
440
 
 
441
 
                ret = pointCtor->constructInstance(env, args);
442
 
        }
443
 
        else // setter
444
 
        {
445
 
                IF_VERBOSE_ASCODING_ERRORS(
446
 
                log_aserror(_("Attempt to set read-only property %s"), "Rectangle.bottomRight");
447
 
                );
448
 
        }
449
 
 
450
 
        return ret;
 
414
    boost::intrusive_ptr<Rectangle_as> ptr = 
 
415
        ensureType<Rectangle_as>(fn.this_ptr);
 
416
 
 
417
    if (!fn.nargs) {
 
418
 
 
419
        as_value x,y,w,h;
 
420
        ptr->get_member(NSV::PROP_X, &x);
 
421
        ptr->get_member(NSV::PROP_Y, &y);
 
422
        ptr->get_member(NSV::PROP_WIDTH, &w);
 
423
        ptr->get_member(NSV::PROP_HEIGHT, &h);
 
424
 
 
425
        as_value right = x.newAdd(w);
 
426
        as_value bottom = y.newAdd(h);
 
427
 
 
428
        as_value point(fn.env().find_object("flash.geom.Point"));
 
429
 
 
430
        boost::intrusive_ptr<as_function> pointCtor = point.to_as_function();
 
431
 
 
432
        if (!pointCtor) {
 
433
            log_error("Failed to construct flash.geom.Point!");
 
434
            return as_value();
 
435
        }
 
436
 
 
437
        fn_call::Args args;
 
438
        args += right, bottom;
 
439
 
 
440
        as_value ret = pointCtor->constructInstance(fn.env(), args);
 
441
        return ret;
 
442
    }
 
443
 
 
444
    IF_VERBOSE_ASCODING_ERRORS(
 
445
    log_aserror(_("Attempt to set read-only property %s"),
 
446
        "Rectangle.bottomRight");
 
447
    );
 
448
    return as_value();
 
449
 
451
450
}
452
451
 
453
452
static as_value
454
453
Rectangle_left_getset(const fn_call& fn)
455
454
{
456
 
        boost::intrusive_ptr<Rectangle_as> ptr = ensureType<Rectangle_as>(fn.this_ptr);
457
 
 
458
 
        as_value ret;
459
 
 
460
 
        if ( ! fn.nargs ) // getter
461
 
        {
462
 
                ptr->get_member(NSV::PROP_X, &ret);
463
 
        }
464
 
        else // setter
465
 
        {
466
 
                as_value oldx;
467
 
                ptr->get_member(NSV::PROP_X, &oldx);
468
 
 
469
 
                as_value newx = fn.arg(0);
470
 
                ptr->set_member(NSV::PROP_X, newx);
471
 
 
472
 
                as_value w;
473
 
                ptr->get_member(NSV::PROP_WIDTH, &w);
474
 
 
475
 
                w.newAdd(oldx.subtract(newx));
476
 
                ptr->set_member(NSV::PROP_WIDTH, w);
477
 
        }
478
 
 
479
 
        return ret;
 
455
    boost::intrusive_ptr<Rectangle_as> ptr = ensureType<Rectangle_as>(fn.this_ptr);
 
456
 
 
457
    as_value ret;
 
458
 
 
459
    if ( ! fn.nargs ) // getter
 
460
    {
 
461
        ptr->get_member(NSV::PROP_X, &ret);
 
462
    }
 
463
    else // setter
 
464
    {
 
465
        as_value oldx;
 
466
        ptr->get_member(NSV::PROP_X, &oldx);
 
467
 
 
468
        as_value newx = fn.arg(0);
 
469
        ptr->set_member(NSV::PROP_X, newx);
 
470
 
 
471
        as_value w;
 
472
        ptr->get_member(NSV::PROP_WIDTH, &w);
 
473
 
 
474
        w.newAdd(oldx.subtract(newx));
 
475
        ptr->set_member(NSV::PROP_WIDTH, w);
 
476
    }
 
477
 
 
478
    return ret;
480
479
}
481
480
 
482
481
static as_value
483
482
Rectangle_right_getset(const fn_call& fn)
484
483
{
485
 
        boost::intrusive_ptr<Rectangle_as> ptr = ensureType<Rectangle_as>(fn.this_ptr);
486
 
 
487
 
        as_value ret;
488
 
 
489
 
        if ( ! fn.nargs ) // getter
490
 
        {
491
 
                as_value width;
492
 
                ptr->get_member(NSV::PROP_X, &ret);
493
 
                ptr->get_member(NSV::PROP_WIDTH, &width);
494
 
                ret.newAdd(width);
495
 
        }
496
 
        else // setter
497
 
        {
498
 
                as_value x;
499
 
                ptr->get_member(NSV::PROP_X, &x);
500
 
 
501
 
                as_value right = fn.arg(0);
502
 
                as_value neww = right.subtract(x);
503
 
                ptr->set_member(NSV::PROP_WIDTH, neww);
504
 
        }
505
 
 
506
 
        return ret;
 
484
    boost::intrusive_ptr<Rectangle_as> ptr = ensureType<Rectangle_as>(fn.this_ptr);
 
485
 
 
486
    as_value ret;
 
487
 
 
488
    if ( ! fn.nargs ) // getter
 
489
    {
 
490
        as_value width;
 
491
        ptr->get_member(NSV::PROP_X, &ret);
 
492
        ptr->get_member(NSV::PROP_WIDTH, &width);
 
493
        ret.newAdd(width);
 
494
    }
 
495
    else // setter
 
496
    {
 
497
        as_value x;
 
498
        ptr->get_member(NSV::PROP_X, &x);
 
499
 
 
500
        as_value right = fn.arg(0);
 
501
        as_value neww = right.subtract(x);
 
502
        ptr->set_member(NSV::PROP_WIDTH, neww);
 
503
    }
 
504
 
 
505
    return ret;
507
506
}
508
507
 
509
508
static as_value
510
509
Rectangle_size_getset(const fn_call& fn)
511
510
{
512
 
        boost::intrusive_ptr<Rectangle_as> ptr = ensureType<Rectangle_as>(fn.this_ptr);
513
 
 
514
 
        as_value ret;
515
 
 
516
 
        if ( ! fn.nargs ) // getter
517
 
        {
518
 
                as_value w,h;
519
 
                ptr->get_member(NSV::PROP_WIDTH, &w);
520
 
                ptr->get_member(NSV::PROP_HEIGHT, &h);
521
 
 
522
 
                as_function* pointCtor = getFlashGeomPointConstructor();
523
 
 
524
 
                as_environment& env = fn.env();
525
 
 
526
 
                std::auto_ptr< std::vector<as_value> > args ( new std::vector<as_value> );
527
 
                args->push_back(w);
528
 
                args->push_back(h);
529
 
 
530
 
                ret = pointCtor->constructInstance(env, args);
531
 
        }
532
 
        else // setter
533
 
        {
534
 
                IF_VERBOSE_ASCODING_ERRORS(
535
 
                log_aserror(_("Attempt to set read-only property %s"), "Rectangle.size");
536
 
                );
537
 
        }
538
 
 
539
 
        return ret;
 
511
    boost::intrusive_ptr<Rectangle_as> ptr = ensureType<Rectangle_as>(fn.this_ptr);
 
512
 
 
513
    as_value ret;
 
514
 
 
515
    if ( ! fn.nargs ) // getter
 
516
    {
 
517
        as_value w,h;
 
518
        ptr->get_member(NSV::PROP_WIDTH, &w);
 
519
        ptr->get_member(NSV::PROP_HEIGHT, &h);
 
520
 
 
521
        as_value point(fn.env().find_object("flash.geom.Point"));
 
522
 
 
523
        boost::intrusive_ptr<as_function> pointCtor = point.to_as_function();
 
524
 
 
525
        if (!pointCtor) {
 
526
            log_error("Failed to construct flash.geom.Point!");
 
527
            return as_value();
 
528
        }
 
529
 
 
530
        fn_call::Args args;
 
531
        args += w, h;
 
532
 
 
533
        ret = pointCtor->constructInstance(fn.env(), args);
 
534
    }
 
535
    else // setter
 
536
    {
 
537
        IF_VERBOSE_ASCODING_ERRORS(
 
538
        log_aserror(_("Attempt to set read-only property %s"), "Rectangle.size");
 
539
        );
 
540
    }
 
541
 
 
542
    return ret;
540
543
}
541
544
 
542
545
static as_value
543
546
Rectangle_top_getset(const fn_call& fn)
544
547
{
545
 
        boost::intrusive_ptr<Rectangle_as> ptr = ensureType<Rectangle_as>(fn.this_ptr);
546
 
 
547
 
        as_value ret;
548
 
 
549
 
        if ( ! fn.nargs ) // getter
550
 
        {
551
 
                ptr->get_member(NSV::PROP_Y, &ret);
552
 
        }
553
 
        else // setter
554
 
        {
555
 
                as_value oldy;
556
 
                ptr->get_member(NSV::PROP_Y, &oldy);
557
 
 
558
 
                as_value newy = fn.arg(0);
559
 
                ptr->set_member(NSV::PROP_Y, newy);
560
 
 
561
 
                as_value h;
562
 
                ptr->get_member(NSV::PROP_HEIGHT, &h);
563
 
 
564
 
                h.newAdd(oldy.subtract(newy));
565
 
                ptr->set_member(NSV::PROP_HEIGHT, h);
566
 
        }
567
 
 
568
 
        return ret;
 
548
    boost::intrusive_ptr<Rectangle_as> ptr = ensureType<Rectangle_as>(fn.this_ptr);
 
549
 
 
550
    as_value ret;
 
551
 
 
552
    if ( ! fn.nargs ) // getter
 
553
    {
 
554
        ptr->get_member(NSV::PROP_Y, &ret);
 
555
    }
 
556
    else // setter
 
557
    {
 
558
        as_value oldy;
 
559
        ptr->get_member(NSV::PROP_Y, &oldy);
 
560
 
 
561
        as_value newy = fn.arg(0);
 
562
        ptr->set_member(NSV::PROP_Y, newy);
 
563
 
 
564
        as_value h;
 
565
        ptr->get_member(NSV::PROP_HEIGHT, &h);
 
566
 
 
567
        h.newAdd(oldy.subtract(newy));
 
568
        ptr->set_member(NSV::PROP_HEIGHT, h);
 
569
    }
 
570
 
 
571
    return ret;
569
572
}
570
573
 
571
574
static as_value
572
575
Rectangle_topLeft_getset(const fn_call& fn)
573
576
{
574
 
        boost::intrusive_ptr<Rectangle_as> ptr = ensureType<Rectangle_as>(fn.this_ptr);
575
 
 
576
 
        as_value ret;
577
 
 
578
 
        if ( ! fn.nargs ) // getter
579
 
        {
580
 
                as_value x,y;
581
 
                ptr->get_member(NSV::PROP_X, &x);
582
 
                ptr->get_member(NSV::PROP_Y, &y);
583
 
 
584
 
                as_function* pointCtor = getFlashGeomPointConstructor();
585
 
 
586
 
                as_environment& env = fn.env();
587
 
 
588
 
                std::auto_ptr< std::vector<as_value> > args ( new std::vector<as_value> );
589
 
                args->push_back(x);
590
 
                args->push_back(y);
591
 
 
592
 
                ret = pointCtor->constructInstance(env, args);
593
 
 
594
 
        }
595
 
        else // setter
596
 
        {
597
 
                IF_VERBOSE_ASCODING_ERRORS(
598
 
                log_aserror(_("Attempt to set read-only property %s"), "Rectangle.topLeft");
599
 
                );
600
 
        }
601
 
 
602
 
        return ret;
 
577
    boost::intrusive_ptr<Rectangle_as> ptr = ensureType<Rectangle_as>(fn.this_ptr);
 
578
 
 
579
    as_value ret;
 
580
 
 
581
    if ( ! fn.nargs ) // getter
 
582
    {
 
583
        as_value x,y;
 
584
        ptr->get_member(NSV::PROP_X, &x);
 
585
        ptr->get_member(NSV::PROP_Y, &y);
 
586
 
 
587
        as_value point(fn.env().find_object("flash.geom.Point"));
 
588
 
 
589
        boost::intrusive_ptr<as_function> pointCtor = point.to_as_function();
 
590
 
 
591
        if (!pointCtor) {
 
592
            log_error("Failed to construct flash.geom.Point!");
 
593
            return as_value();
 
594
        }
 
595
 
 
596
        fn_call::Args args;
 
597
        args += x, y;
 
598
 
 
599
        ret = pointCtor->constructInstance(fn.env(), args);
 
600
 
 
601
    }
 
602
    else // setter
 
603
    {
 
604
        IF_VERBOSE_ASCODING_ERRORS(
 
605
        log_aserror(_("Attempt to set read-only property %s"), "Rectangle.topLeft");
 
606
        );
 
607
    }
 
608
 
 
609
    return ret;
603
610
}
604
611
 
605
612
 
606
613
as_value
607
614
Rectangle_ctor(const fn_call& fn)
608
615
{
609
 
        boost::intrusive_ptr<as_object> obj = new Rectangle_as;
610
 
 
611
 
        as_value x;
612
 
        as_value y;
613
 
        as_value w;
614
 
        as_value h;
615
 
 
616
 
        if ( ! fn.nargs )
617
 
        {
618
 
                x.set_double(0);
619
 
                y.set_double(0);
620
 
                w.set_double(0);
621
 
                h.set_double(0);
622
 
        }
623
 
        else
624
 
        {
625
 
                do {
626
 
                        x = fn.arg(0);
627
 
                        if ( fn.nargs < 2 ) break;
628
 
                        y = fn.arg(1);
629
 
                        if ( fn.nargs < 3 ) break;
630
 
                        w = fn.arg(2);
631
 
                        if ( fn.nargs < 4 ) break;
632
 
                        h = fn.arg(3);
633
 
                        if ( fn.nargs < 5 ) break;
634
 
                        IF_VERBOSE_ASCODING_ERRORS(
635
 
                                std::stringstream ss;
636
 
                                fn.dump_args(ss);
637
 
                                log_aserror("flash.geom.Rectangle(%s): %s", ss.str(), _("arguments after the first four discarded"));
638
 
                        );
639
 
                } while(0);
640
 
        }
641
 
 
642
 
        obj->set_member(NSV::PROP_X, x);
643
 
        obj->set_member(NSV::PROP_Y, y);
644
 
        obj->set_member(NSV::PROP_WIDTH, w);
645
 
        obj->set_member(NSV::PROP_HEIGHT, h);
646
 
 
647
 
        return as_value(obj.get()); // will keep alive
648
 
}
649
 
 
650
 
static as_value get_flash_geom_rectangle_constructor(const fn_call& /*fn*/)
651
 
{
652
 
        log_debug("Loading flash.geom.Rectangle class");
653
 
 
654
 
        builtin_function* cl =
655
 
                new builtin_function(&Rectangle_ctor, getRectangleInterface());
656
 
        return cl;
657
 
}
658
 
 
659
 
boost::intrusive_ptr<as_object> init_Rectangle_instance()
660
 
{
661
 
    return boost::intrusive_ptr<as_object>(new Rectangle_as);
 
616
    boost::intrusive_ptr<as_object> obj = new Rectangle_as;
 
617
 
 
618
    as_value x;
 
619
    as_value y;
 
620
    as_value w;
 
621
    as_value h;
 
622
 
 
623
    if ( ! fn.nargs )
 
624
    {
 
625
        x.set_double(0);
 
626
        y.set_double(0);
 
627
        w.set_double(0);
 
628
        h.set_double(0);
 
629
    }
 
630
    else
 
631
    {
 
632
        do {
 
633
            x = fn.arg(0);
 
634
            if ( fn.nargs < 2 ) break;
 
635
            y = fn.arg(1);
 
636
            if ( fn.nargs < 3 ) break;
 
637
            w = fn.arg(2);
 
638
            if ( fn.nargs < 4 ) break;
 
639
            h = fn.arg(3);
 
640
            if ( fn.nargs < 5 ) break;
 
641
            IF_VERBOSE_ASCODING_ERRORS(
 
642
                std::stringstream ss;
 
643
                fn.dump_args(ss);
 
644
                log_aserror("flash.geom.Rectangle(%s): %s", ss.str(), _("arguments after the first four discarded"));
 
645
            );
 
646
        } while(0);
 
647
    }
 
648
 
 
649
    obj->set_member(NSV::PROP_X, x);
 
650
    obj->set_member(NSV::PROP_Y, y);
 
651
    obj->set_member(NSV::PROP_WIDTH, w);
 
652
    obj->set_member(NSV::PROP_HEIGHT, h);
 
653
 
 
654
    return as_value(obj.get()); // will keep alive
 
655
}
 
656
 
 
657
static as_value
 
658
get_flash_geom_rectangle_constructor(const fn_call& fn)
 
659
{
 
660
    log_debug("Loading flash.geom.Rectangle class");
 
661
 
 
662
    as_object* proto = getRectangleInterface();
 
663
    Global_as* gl = getGlobal(fn);
 
664
    return gl->createClass(&Rectangle_ctor, proto);
662
665
}
663
666
 
664
667
// extern 
665
 
void Rectangle_class_init(as_object& where)
 
668
void
 
669
rectangle_class_init(as_object& where, const ObjectURI& uri)
666
670
{
667
 
        // Register _global.Rectangle
668
 
        string_table& st = where.getVM().getStringTable();
669
 
        where.init_destructive_property(st.find("Rectangle"), get_flash_geom_rectangle_constructor);
 
671
    // TODO: this may not be correct, but it should be enumerable.
 
672
    const int flags = 0;
 
673
    where.init_destructive_property(getName(uri),
 
674
            get_flash_geom_rectangle_constructor, flags, getNamespace(uri));
670
675
}
671
676
 
672
677
} // end of gnash namespace