2
* Copyright (C) 2006, 2007 Apple Inc. All rights reserved.
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.
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.
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.
21
#include "JSCanvasRenderingContext2D.h"
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"
41
static JSValue* toJS(ExecState* exec, CanvasStyle* style)
43
if (style->gradient())
44
return toJS(exec, style->gradient());
46
return toJS(exec, style->pattern());
47
return jsString(style->color());
50
static PassRefPtr<CanvasStyle> toHTMLCanvasStyle(ExecState* exec, JSValue* value)
52
if (value->isString())
53
return new CanvasStyle(value->toString(exec));
54
if (!value->isObject())
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());
64
JSValue* JSCanvasRenderingContext2D::strokeStyle(ExecState* exec) const
66
return toJS(exec, impl()->strokeStyle());
69
void JSCanvasRenderingContext2D::setStrokeStyle(ExecState* exec, JSValue* value)
71
impl()->setStrokeStyle(toHTMLCanvasStyle(exec, value));
74
JSValue* JSCanvasRenderingContext2D::fillStyle(ExecState* exec) const
76
return toJS(exec, impl()->fillStyle());
79
void JSCanvasRenderingContext2D::setFillStyle(ExecState* exec, JSValue* value)
81
impl()->setFillStyle(toHTMLCanvasStyle(exec, value));
84
JSValue* JSCanvasRenderingContext2D::setFillColor(ExecState* exec, const List& args)
86
CanvasRenderingContext2D* context = impl();
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()) {
96
if (args[0]->isString())
97
context->setFillColor(args[0]->toString(exec));
99
context->setFillColor(args[0]->toFloat(exec));
102
if (args[0]->isString())
103
context->setFillColor(args[0]->toString(exec), args[1]->toFloat(exec));
105
context->setFillColor(args[0]->toFloat(exec), args[1]->toFloat(exec));
108
context->setFillColor(args[0]->toFloat(exec), args[1]->toFloat(exec),
109
args[2]->toFloat(exec), args[3]->toFloat(exec));
112
context->setFillColor(args[0]->toFloat(exec), args[1]->toFloat(exec),
113
args[2]->toFloat(exec), args[3]->toFloat(exec), args[4]->toFloat(exec));
116
return throwError(exec, SyntaxError);
118
return jsUndefined();
121
JSValue* JSCanvasRenderingContext2D::setStrokeColor(ExecState* exec, const List& args)
123
CanvasRenderingContext2D* context = impl();
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()) {
133
if (args[0]->isString())
134
context->setStrokeColor(args[0]->toString(exec));
136
context->setStrokeColor(args[0]->toFloat(exec));
139
if (args[0]->isString())
140
context->setStrokeColor(args[0]->toString(exec), args[1]->toFloat(exec));
142
context->setStrokeColor(args[0]->toFloat(exec), args[1]->toFloat(exec));
145
context->setStrokeColor(args[0]->toFloat(exec), args[1]->toFloat(exec),
146
args[2]->toFloat(exec), args[3]->toFloat(exec));
149
context->setStrokeColor(args[0]->toFloat(exec), args[1]->toFloat(exec),
150
args[2]->toFloat(exec), args[3]->toFloat(exec), args[4]->toFloat(exec));
153
return throwError(exec, SyntaxError);
156
return jsUndefined();
159
JSValue* JSCanvasRenderingContext2D::strokeRect(ExecState* exec, const List& args)
161
CanvasRenderingContext2D* context = impl();
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);
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);
172
return jsUndefined();
175
JSValue* JSCanvasRenderingContext2D::drawImage(ExecState* exec, const List& args)
177
CanvasRenderingContext2D* context = impl();
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);
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()) {
195
context->drawImage(imgElt, args[1]->toFloat(exec), args[2]->toFloat(exec));
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);
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);
210
return throwError(exec, SyntaxError);
212
} else if (o->inherits(&JSHTMLCanvasElement::info)) {
213
HTMLCanvasElement* canvas = static_cast<HTMLCanvasElement*>(static_cast<JSHTMLElement*>(args[0])->impl());
214
switch (args.size()) {
216
context->drawImage(canvas, args[1]->toFloat(exec), args[2]->toFloat(exec));
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);
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);
231
return throwError(exec, SyntaxError);
234
setDOMException(exec, TYPE_MISMATCH_ERR);
238
return jsUndefined();
241
JSValue* JSCanvasRenderingContext2D::drawImageFromRect(ExecState* exec, const List& args)
243
CanvasRenderingContext2D* context = impl();
245
JSValue* value = args[0];
246
if (!value->isObject())
247
return throwError(exec, TypeError);
248
JSObject* o = static_cast<JSObject*>(value);
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();
261
JSValue* JSCanvasRenderingContext2D::setShadow(ExecState* exec, const List& args)
263
CanvasRenderingContext2D* context = impl();
265
switch (args.size()) {
267
context->setShadow(args[0]->toFloat(exec), args[1]->toFloat(exec),
268
args[2]->toFloat(exec));
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));
275
context->setShadow(args[0]->toFloat(exec), args[1]->toFloat(exec),
276
args[2]->toFloat(exec), args[3]->toFloat(exec));
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));
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));
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));
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));
301
return throwError(exec, SyntaxError);
304
return jsUndefined();
307
JSValue* JSCanvasRenderingContext2D::createPattern(ExecState* exec, const List& args)
309
CanvasRenderingContext2D* context = impl();
311
JSValue* value = args[0];
312
if (!value->isObject())
313
return throwError(exec, TypeError);
314
JSObject* o = static_cast<JSObject*>(value);
316
if (o->inherits(&JSHTMLImageElement::info)) {
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);
324
if (o->inherits(&JSHTMLCanvasElement::info)) {
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);
332
setDOMException(exec, TYPE_MISMATCH_ERR);
336
} // namespace WebCore