~ubuntu-branches/ubuntu/maverick/webkit/maverick

« back to all changes in this revision

Viewing changes to WebCore/bindings/js/JSCanvasRenderingContext2DCustom.cpp

  • Committer: Bazaar Package Importer
  • Author(s): Mike Hommey
  • Date: 2007-08-19 15:54:12 UTC
  • Revision ID: james.westby@ubuntu.com-20070819155412-uxxg1h9plpghmtbi
Tags: upstream-0~svn25144
ImportĀ upstreamĀ versionĀ 0~svn25144

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 * Copyright (C) 2006, 2007 Apple Inc. All rights reserved.
 
3
 *
 
4
 * This library is free software; you can redistribute it and/or
 
5
 * modify it under the terms of the GNU Library General Public
 
6
 * License as published by the Free Software Foundation; either
 
7
 * version 2 of the License, or (at your option) any later version.
 
8
 *
 
9
 * This library is distributed in the hope that it will be useful,
 
10
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 
11
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 
12
 * Library General Public License for more details.
 
13
 *
 
14
 * You should have received a copy of the GNU Library General Public License
 
15
 * along with this library; see the file COPYING.LIB.  If not, write to
 
16
 * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
 
17
 * Boston, MA 02111-1307, USA.
 
18
 */
 
19
 
 
20
#include "config.h"
 
21
#include "JSCanvasRenderingContext2D.h"
 
22
 
 
23
#include "CanvasGradient.h"
 
24
#include "CanvasPattern.h"
 
25
#include "CanvasRenderingContext2D.h"
 
26
#include "CanvasStyle.h"
 
27
#include "ExceptionCode.h"
 
28
#include "FloatRect.h"
 
29
#include "HTMLCanvasElement.h"
 
30
#include "HTMLImageElement.h"
 
31
#include "JSCanvasGradient.h"
 
32
#include "JSCanvasPattern.h"
 
33
#include "JSHTMLCanvasElement.h"
 
34
#include "JSHTMLImageElement.h"
 
35
#include "kjs_html.h"
 
36
 
 
37
using namespace KJS;
 
38
 
 
39
namespace WebCore {
 
40
 
 
41
static JSValue* toJS(ExecState* exec, CanvasStyle* style)
 
42
{
 
43
    if (style->gradient())
 
44
        return toJS(exec, style->gradient());
 
45
    if (style->pattern())
 
46
        return toJS(exec, style->pattern());
 
47
    return jsString(style->color());
 
48
}
 
49
 
 
50
static PassRefPtr<CanvasStyle> toHTMLCanvasStyle(ExecState* exec, JSValue* value)
 
51
{
 
52
    if (value->isString())
 
53
        return new CanvasStyle(value->toString(exec));
 
54
    if (!value->isObject())
 
55
        return 0;
 
56
    JSObject* object = static_cast<JSObject*>(value);
 
57
    if (object->inherits(&JSCanvasGradient::info))
 
58
        return new CanvasStyle(static_cast<JSCanvasGradient*>(object)->impl());
 
59
    if (object->inherits(&JSCanvasPattern::info))
 
60
        return new CanvasStyle(static_cast<JSCanvasPattern*>(object)->impl());
 
61
    return 0;
 
62
}
 
63
 
 
64
JSValue* JSCanvasRenderingContext2D::strokeStyle(ExecState* exec) const
 
65
{
 
66
    return toJS(exec, impl()->strokeStyle());        
 
67
}
 
68
 
 
69
void JSCanvasRenderingContext2D::setStrokeStyle(ExecState* exec, JSValue* value)
 
70
{
 
71
    impl()->setStrokeStyle(toHTMLCanvasStyle(exec, value));
 
72
}
 
73
 
 
74
JSValue* JSCanvasRenderingContext2D::fillStyle(ExecState* exec) const
 
75
{
 
76
    return toJS(exec, impl()->fillStyle());
 
77
}
 
78
 
 
79
void JSCanvasRenderingContext2D::setFillStyle(ExecState* exec, JSValue* value)
 
80
{
 
81
    impl()->setFillStyle(toHTMLCanvasStyle(exec, value));
 
82
}
 
83
 
 
84
JSValue* JSCanvasRenderingContext2D::setFillColor(ExecState* exec, const List& args)
 
85
{
 
86
    CanvasRenderingContext2D* context = impl();
 
87
 
 
88
    // string arg = named color
 
89
    // number arg = gray color
 
90
    // string arg, number arg = named color, alpha
 
91
    // number arg, number arg = gray color, alpha
 
92
    // 4 args = r, g, b, a
 
93
    // 5 args = c, m, y, k, a
 
94
    switch (args.size()) {
 
95
        case 1:
 
96
            if (args[0]->isString())
 
97
                context->setFillColor(args[0]->toString(exec));
 
98
            else
 
99
                context->setFillColor(args[0]->toFloat(exec));
 
100
            break;
 
101
        case 2:
 
102
            if (args[0]->isString())
 
103
                context->setFillColor(args[0]->toString(exec), args[1]->toFloat(exec));
 
104
            else
 
105
                context->setFillColor(args[0]->toFloat(exec), args[1]->toFloat(exec));
 
106
            break;
 
107
        case 4:
 
108
            context->setFillColor(args[0]->toFloat(exec), args[1]->toFloat(exec),
 
109
                                  args[2]->toFloat(exec), args[3]->toFloat(exec));
 
110
            break;
 
111
        case 5:
 
112
            context->setFillColor(args[0]->toFloat(exec), args[1]->toFloat(exec),
 
113
                                  args[2]->toFloat(exec), args[3]->toFloat(exec), args[4]->toFloat(exec));
 
114
            break;
 
115
        default:
 
116
            return throwError(exec, SyntaxError);
 
117
    }
 
118
    return jsUndefined();
 
119
}    
 
120
 
 
121
JSValue* JSCanvasRenderingContext2D::setStrokeColor(ExecState* exec, const List& args)
 
122
 
123
    CanvasRenderingContext2D* context = impl();
 
124
 
 
125
    // string arg = named color
 
126
    // number arg = gray color
 
127
    // string arg, number arg = named color, alpha
 
128
    // number arg, number arg = gray color, alpha
 
129
    // 4 args = r, g, b, a
 
130
    // 5 args = c, m, y, k, a
 
131
    switch (args.size()) {
 
132
        case 1:
 
133
            if (args[0]->isString())
 
134
                context->setStrokeColor(args[0]->toString(exec));
 
135
            else
 
136
                context->setStrokeColor(args[0]->toFloat(exec));
 
137
            break;
 
138
        case 2:
 
139
            if (args[0]->isString())
 
140
                context->setStrokeColor(args[0]->toString(exec), args[1]->toFloat(exec));
 
141
            else
 
142
                context->setStrokeColor(args[0]->toFloat(exec), args[1]->toFloat(exec));
 
143
            break;
 
144
        case 4:
 
145
            context->setStrokeColor(args[0]->toFloat(exec), args[1]->toFloat(exec),
 
146
                                    args[2]->toFloat(exec), args[3]->toFloat(exec));
 
147
            break;
 
148
        case 5:
 
149
            context->setStrokeColor(args[0]->toFloat(exec), args[1]->toFloat(exec),
 
150
                                    args[2]->toFloat(exec), args[3]->toFloat(exec), args[4]->toFloat(exec));
 
151
            break;
 
152
        default:
 
153
            return throwError(exec, SyntaxError);
 
154
    }
 
155
    
 
156
    return jsUndefined();
 
157
}
 
158
 
 
159
JSValue* JSCanvasRenderingContext2D::strokeRect(ExecState* exec, const List& args)
 
160
 
161
    CanvasRenderingContext2D* context = impl();    
 
162
    ExceptionCode ec;
 
163
    
 
164
    if (args.size() <= 4)
 
165
        context->strokeRect(args[0]->toFloat(exec), args[1]->toFloat(exec),
 
166
                            args[2]->toFloat(exec), args[3]->toFloat(exec), ec);
 
167
    else
 
168
        context->strokeRect(args[0]->toFloat(exec), args[1]->toFloat(exec),
 
169
                            args[2]->toFloat(exec), args[3]->toFloat(exec), args[4]->toFloat(exec), ec);
 
170
    setDOMException(exec, ec);
 
171
    
 
172
    return jsUndefined();    
 
173
}
 
174
 
 
175
JSValue* JSCanvasRenderingContext2D::drawImage(ExecState* exec, const List& args)
 
176
 
177
    CanvasRenderingContext2D* context = impl();
 
178
 
 
179
    // DrawImage has three variants:
 
180
    //     drawImage(img, dx, dy)
 
181
    //     drawImage(img, dx, dy, dw, dh)
 
182
    //     drawImage(img, sx, sy, sw, sh, dx, dy, dw, dh)
 
183
    // Composite operation is specified with globalCompositeOperation.
 
184
    // The img parameter can be a <img> or <canvas> element.
 
185
    JSValue* value = args[0];
 
186
    if (!value->isObject())
 
187
        return throwError(exec, TypeError);
 
188
    JSObject* o = static_cast<JSObject*>(value);
 
189
    
 
190
    ExceptionCode ec = 0;
 
191
    if (o->inherits(&JSHTMLImageElement::info)) {
 
192
        HTMLImageElement* imgElt = static_cast<HTMLImageElement*>(static_cast<JSHTMLElement*>(args[0])->impl());
 
193
        switch (args.size()) {
 
194
            case 3:
 
195
                context->drawImage(imgElt, args[1]->toFloat(exec), args[2]->toFloat(exec));
 
196
                break;
 
197
            case 5:
 
198
                context->drawImage(imgElt, args[1]->toFloat(exec), args[2]->toFloat(exec),
 
199
                                   args[3]->toFloat(exec), args[4]->toFloat(exec), ec);
 
200
                setDOMException(exec, ec);
 
201
                break;
 
202
            case 9:
 
203
                context->drawImage(imgElt, FloatRect(args[1]->toFloat(exec), args[2]->toFloat(exec),
 
204
                                   args[3]->toFloat(exec), args[4]->toFloat(exec)),
 
205
                                   FloatRect(args[5]->toFloat(exec), args[6]->toFloat(exec),
 
206
                                   args[7]->toFloat(exec), args[8]->toFloat(exec)), ec);
 
207
                setDOMException(exec, ec);
 
208
                break;
 
209
            default:
 
210
                return throwError(exec, SyntaxError);
 
211
        }
 
212
    } else if (o->inherits(&JSHTMLCanvasElement::info)) {
 
213
        HTMLCanvasElement* canvas = static_cast<HTMLCanvasElement*>(static_cast<JSHTMLElement*>(args[0])->impl());
 
214
        switch (args.size()) {
 
215
            case 3:
 
216
                context->drawImage(canvas, args[1]->toFloat(exec), args[2]->toFloat(exec));
 
217
                break;
 
218
            case 5:
 
219
                context->drawImage(canvas, args[1]->toFloat(exec), args[2]->toFloat(exec),
 
220
                                   args[3]->toFloat(exec), args[4]->toFloat(exec), ec);
 
221
                setDOMException(exec, ec);
 
222
                break;
 
223
            case 9:
 
224
                context->drawImage(canvas, FloatRect(args[1]->toFloat(exec), args[2]->toFloat(exec),
 
225
                                   args[3]->toFloat(exec), args[4]->toFloat(exec)),
 
226
                                   FloatRect(args[5]->toFloat(exec), args[6]->toFloat(exec),
 
227
                                   args[7]->toFloat(exec), args[8]->toFloat(exec)), ec);
 
228
                setDOMException(exec, ec);
 
229
                break;
 
230
            default:
 
231
                return throwError(exec, SyntaxError);
 
232
        }
 
233
    } else {
 
234
        setDOMException(exec, TYPE_MISMATCH_ERR);
 
235
        return 0;
 
236
    }
 
237
    
 
238
    return jsUndefined();    
 
239
}
 
240
 
 
241
JSValue* JSCanvasRenderingContext2D::drawImageFromRect(ExecState* exec, const List& args)
 
242
 
243
    CanvasRenderingContext2D* context = impl();
 
244
    
 
245
    JSValue* value = args[0];
 
246
    if (!value->isObject())
 
247
        return throwError(exec, TypeError);
 
248
    JSObject* o = static_cast<JSObject*>(value);
 
249
    
 
250
    if (!o->inherits(&JSHTMLImageElement::info))
 
251
        return throwError(exec, TypeError);
 
252
    context->drawImageFromRect(static_cast<HTMLImageElement*>(static_cast<JSHTMLElement*>(args[0])->impl()),
 
253
                               args[1]->toFloat(exec), args[2]->toFloat(exec),
 
254
                               args[3]->toFloat(exec), args[4]->toFloat(exec),
 
255
                               args[5]->toFloat(exec), args[6]->toFloat(exec),
 
256
                               args[7]->toFloat(exec), args[8]->toFloat(exec),
 
257
                               args[9]->toString(exec));    
 
258
    return jsUndefined();    
 
259
}
 
260
 
 
261
JSValue* JSCanvasRenderingContext2D::setShadow(ExecState* exec, const List& args)
 
262
 
263
    CanvasRenderingContext2D* context = impl();
 
264
 
 
265
    switch (args.size()) {
 
266
        case 3:
 
267
            context->setShadow(args[0]->toFloat(exec), args[1]->toFloat(exec),
 
268
                               args[2]->toFloat(exec));
 
269
            break;
 
270
        case 4:
 
271
            if (args[3]->isString())
 
272
                context->setShadow(args[0]->toFloat(exec), args[1]->toFloat(exec),
 
273
                                   args[2]->toFloat(exec), args[3]->toString(exec));
 
274
            else
 
275
                context->setShadow(args[0]->toFloat(exec), args[1]->toFloat(exec),
 
276
                                   args[2]->toFloat(exec), args[3]->toFloat(exec));
 
277
            break;
 
278
        case 5:
 
279
            if (args[3]->isString())
 
280
                context->setShadow(args[0]->toFloat(exec), args[1]->toFloat(exec),
 
281
                                   args[2]->toFloat(exec), args[3]->toString(exec),
 
282
                                   args[4]->toFloat(exec));
 
283
            else
 
284
                context->setShadow(args[0]->toFloat(exec), args[1]->toFloat(exec),
 
285
                                   args[2]->toFloat(exec), args[3]->toFloat(exec),
 
286
                                   args[4]->toFloat(exec));
 
287
            break;
 
288
        case 7:
 
289
            context->setShadow(args[0]->toFloat(exec), args[1]->toFloat(exec),
 
290
                               args[2]->toFloat(exec), args[3]->toFloat(exec),
 
291
                               args[4]->toFloat(exec), args[5]->toFloat(exec),
 
292
                               args[6]->toFloat(exec));
 
293
            break;
 
294
        case 8:
 
295
            context->setShadow(args[0]->toFloat(exec), args[1]->toFloat(exec),
 
296
                               args[2]->toFloat(exec), args[3]->toFloat(exec),
 
297
                               args[4]->toFloat(exec), args[5]->toFloat(exec),
 
298
                               args[6]->toFloat(exec), args[7]->toFloat(exec));
 
299
            break;
 
300
        default:
 
301
            return throwError(exec, SyntaxError);
 
302
    }
 
303
    
 
304
    return jsUndefined();    
 
305
}
 
306
 
 
307
JSValue* JSCanvasRenderingContext2D::createPattern(ExecState* exec, const List& args)
 
308
 
309
    CanvasRenderingContext2D* context = impl();
 
310
 
 
311
    JSValue* value = args[0];
 
312
    if (!value->isObject())
 
313
        return throwError(exec, TypeError);
 
314
    JSObject* o = static_cast<JSObject*>(value);
 
315
    
 
316
    if (o->inherits(&JSHTMLImageElement::info)) {
 
317
        ExceptionCode ec;
 
318
        JSValue* pattern = toJS(exec,
 
319
            context->createPattern(static_cast<HTMLImageElement*>(static_cast<JSHTMLElement*>(args[0])->impl()),
 
320
                args[1]->toString(exec), ec).get());
 
321
        setDOMException(exec, ec);
 
322
        return pattern;
 
323
    }
 
324
    if (o->inherits(&JSHTMLCanvasElement::info)) {
 
325
        ExceptionCode ec;
 
326
        JSValue* pattern = toJS(exec,
 
327
            context->createPattern(static_cast<HTMLCanvasElement*>(static_cast<JSHTMLElement*>(args[0])->impl()),
 
328
                args[1]->toString(exec), ec).get());
 
329
        setDOMException(exec, ec);
 
330
        return pattern;
 
331
    }
 
332
    setDOMException(exec, TYPE_MISMATCH_ERR);
 
333
    return 0;
 
334
}
 
335
 
 
336
} // namespace WebCore