JSValue* JSCanvasRenderingContext2D::createPattern(ExecState* exec, const ArgList& args)
{ 
    CanvasRenderingContext2D* context = impl();

    JSValue* value = args[0];
    if (!value->isObject())
        return throwError(exec, TypeError);
    JSObject* o = static_cast<JSObject*>(value);

    if (o->inherits(&JSHTMLImageElement::s_info)) {
        ExceptionCode ec;
        JSValue* pattern = toJS(exec,
            context->createPattern(static_cast<HTMLImageElement*>(static_cast<JSHTMLElement*>(args[0])->impl()),
                                   valueToStringWithNullCheck(exec, args[1]), ec).get());
        setDOMException(exec, ec);
        return pattern;
    }
    if (o->inherits(&JSHTMLCanvasElement::s_info)) {
        ExceptionCode ec;
        JSValue* pattern = toJS(exec,
            context->createPattern(static_cast<HTMLCanvasElement*>(static_cast<JSHTMLElement*>(args[0])->impl()),
                valueToStringWithNullCheck(exec, args[1]), ec).get());
        setDOMException(exec, ec);
        return pattern;
    }
    setDOMException(exec, TYPE_MISMATCH_ERR);
    return 0;
}
v8::Handle<v8::Value> V8CanvasRenderingContext2D::createPatternCallback(const v8::Arguments& args)
{
    INC_STATS("DOM.CanvasRenderingContext2D.createPattern()");
    CanvasRenderingContext2D* context = V8CanvasRenderingContext2D::toNative(args.Holder());

    v8::Handle<v8::Value> arg = args[0];

    if (V8HTMLImageElement::HasInstance(arg)) {
        HTMLImageElement* imageElement = V8HTMLImageElement::toNative(v8::Handle<v8::Object>::Cast(arg));
        ExceptionCode ec = 0;
        RefPtr<CanvasPattern> pattern = context->createPattern(imageElement, toWebCoreStringWithNullCheck(args[1]), ec);
        if (ec != 0) {
            V8Proxy::setDOMException(ec);
            return notHandledByInterceptor();
        }
        return toV8(pattern.release());
    }

    if (V8HTMLCanvasElement::HasInstance(arg)) {
        HTMLCanvasElement* canvasElement = V8HTMLCanvasElement::toNative(v8::Handle<v8::Object>::Cast(arg));
        ExceptionCode ec = 0;
        RefPtr<CanvasPattern> pattern = context->createPattern(canvasElement, toWebCoreStringWithNullCheck(args[1]), ec);
        if (ec != 0) {
            V8Proxy::setDOMException(ec);
            return notHandledByInterceptor();
        }
        return toV8(pattern.release());
    }

    V8Proxy::setDOMException(TYPE_MISMATCH_ERR);
    return notHandledByInterceptor();
}
v8::Handle<v8::Value> V8CanvasRenderingContext2D::strokeTextCallback(const v8::Arguments& args)
{
    INC_STATS("DOM.CanvasRenderingContext2D.strokeText()");
    CanvasRenderingContext2D* context = V8CanvasRenderingContext2D::toNative(args.Holder());

    // Two forms:
    // * strokeText(text, x, y)
    // * strokeText(text, x, y, maxWidth)
    if (args.Length() < 3 || args.Length() > 4) {
        V8Proxy::setDOMException(SYNTAX_ERR);
        return notHandledByInterceptor();
    }

    String text = toWebCoreString(args[0]);
    float x = toFloat(args[1]);
    float y = toFloat(args[2]);

    if (args.Length() == 4) {
        float maxWidth = toFloat(args[3]);
        context->strokeText(text, x, y, maxWidth);
    } else
        context->strokeText(text, x, y);

    return v8::Undefined();
}
void BoardDrawer::drawEmpty(int row, int col, int number) {
	m_ctx->fillRect(col * 10, row * 10, 10, 10);
	m_ctx->clearRect(col * 10 + 1, row * 10 + 1, 8, 8);
	if (number > 0) {
		sprintf(buffer, "%u", number);
		m_ctx->fillText(std::string(buffer), col * 10 + 2, row * 10 + 8.5);
	}
}
void V8CanvasRenderingContext2D::fillStyleAttrSetterCustom(v8::Local<v8::String> name, v8::Local<v8::Value> value, const v8::AccessorInfo& info)
{
    CanvasRenderingContext2D* impl = V8CanvasRenderingContext2D::toNative(info.Holder());
    if (value->IsString())
        impl->setFillColor(toWebCoreString(value));
    else
        impl->setFillStyle(toCanvasStyle(value, info.GetIsolate()));
}
void HTMLCanvasElement::attach()
{
    HTMLElement::attach();

    if (m_context && m_context->is2d()) {
        CanvasRenderingContext2D* ctx = static_cast<CanvasRenderingContext2D*>(m_context.get());
        ctx->updateFont();
    }
}
void JSCanvasRenderingContext2D::setFillStyle(ExecState* exec, JSValue value)
{
    CanvasRenderingContext2D* context = static_cast<CanvasRenderingContext2D*>(impl());
    if (value.isString()) {
        context->setFillColor(asString(value)->value(exec));
        return;
    }
    context->setFillStyle(toHTMLCanvasStyle(exec, value));
}
void V8CanvasRenderingContext2D::fillStyleAttributeSetterCustom(v8::Local<v8::Value> value, const v8::PropertyCallbackInfo<void>& info)
{
    CanvasRenderingContext2D* impl = V8CanvasRenderingContext2D::toNative(info.Holder());
    if (RefPtr<CanvasStyle> canvasStyle = toCanvasStyle(value, info.GetIsolate())) {
        impl->setFillStyle(canvasStyle);
    } else {
        TOSTRING_VOID(V8StringResource<>, colorString, value);
        impl->setFillColor(colorString);
    }
}
JSValue* jsCanvasRenderingContext2DPrototypeFunctionClearShadow(ExecState* exec, JSObject*, JSValue* thisValue, const ArgList& args)
{
    if (!thisValue->isObject(&JSCanvasRenderingContext2D::s_info))
        return throwError(exec, TypeError);
    JSCanvasRenderingContext2D* castedThisObj = static_cast<JSCanvasRenderingContext2D*>(thisValue);
    CanvasRenderingContext2D* imp = static_cast<CanvasRenderingContext2D*>(castedThisObj->impl());

    imp->clearShadow();
    return jsUndefined();
}
void HTMLCanvasElement::recalcStyle(StyleChange change)
{
    HTMLElement::recalcStyle(change);

    // Update font if needed.
    if (change == Force && m_context && m_context->is2d()) {
        CanvasRenderingContext2D* ctx = static_cast<CanvasRenderingContext2D*>(m_context.get());
        ctx->updateFont();
    }
}
JSValue* jsCanvasRenderingContext2DPrototypeFunctionSetLineJoin(ExecState* exec, JSObject*, JSValue* thisValue, const ArgList& args)
{
    if (!thisValue->isObject(&JSCanvasRenderingContext2D::s_info))
        return throwError(exec, TypeError);
    JSCanvasRenderingContext2D* castedThisObj = static_cast<JSCanvasRenderingContext2D*>(thisValue);
    CanvasRenderingContext2D* imp = static_cast<CanvasRenderingContext2D*>(castedThisObj->impl());
    const UString& join = args[0]->toString(exec);

    imp->setLineJoin(join);
    return jsUndefined();
}
JSValue* jsCanvasRenderingContext2DPrototypeFunctionSetMiterLimit(ExecState* exec, JSObject*, JSValue* thisValue, const ArgList& args)
{
    if (!thisValue->isObject(&JSCanvasRenderingContext2D::s_info))
        return throwError(exec, TypeError);
    JSCanvasRenderingContext2D* castedThisObj = static_cast<JSCanvasRenderingContext2D*>(thisValue);
    CanvasRenderingContext2D* imp = static_cast<CanvasRenderingContext2D*>(castedThisObj->impl());
    float limit = args[0]->toFloat(exec);

    imp->setMiterLimit(limit);
    return jsUndefined();
}
JSValue JSCanvasRenderingContext2D::webkitLineDash(ExecState* exec) const
{
    CanvasRenderingContext2D* context = static_cast<CanvasRenderingContext2D*>(impl());
    const Vector<float>& dash = context->getLineDash();

    MarkedArgumentBuffer list;
    Vector<float>::const_iterator end = dash.end();
    for (Vector<float>::const_iterator it = dash.begin(); it != end; ++it)
        list.append(JSValue(*it));
    return constructArray(exec, 0, globalObject(), list);
}
JSValue* JSCanvasRenderingContext2D::strokeRect(ExecState* exec, const ArgList& args)
{ 
    CanvasRenderingContext2D* context = impl();
    
    if (args.size() <= 4)
        context->strokeRect(args[0]->toFloat(exec), args[1]->toFloat(exec),
                            args[2]->toFloat(exec), args[3]->toFloat(exec));
    else
        context->strokeRect(args[0]->toFloat(exec), args[1]->toFloat(exec),
                            args[2]->toFloat(exec), args[3]->toFloat(exec), args[4]->toFloat(exec));

    return jsUndefined();    
}
JSValue JSCanvasRenderingContext2D::strokeRect(ExecState* exec, const ArgList& args)
{ 
    CanvasRenderingContext2D* context = impl();
    
    if (args.size() <= 4)
        context->strokeRect(args.at(0).toFloat(exec), args.at(1).toFloat(exec),
                            args.at(2).toFloat(exec), args.at(3).toFloat(exec));
    else
        context->strokeRect(args.at(0).toFloat(exec), args.at(1).toFloat(exec),
                            args.at(2).toFloat(exec), args.at(3).toFloat(exec), args.at(4).toFloat(exec));

    return jsUndefined();    
}
JSValue* jsCanvasRenderingContext2DPrototypeFunctionCreateImageData(ExecState* exec, JSObject*, JSValue* thisValue, const ArgList& args)
{
    if (!thisValue->isObject(&JSCanvasRenderingContext2D::s_info))
        return throwError(exec, TypeError);
    JSCanvasRenderingContext2D* castedThisObj = static_cast<JSCanvasRenderingContext2D*>(thisValue);
    CanvasRenderingContext2D* imp = static_cast<CanvasRenderingContext2D*>(castedThisObj->impl());
    float sw = args[0]->toFloat(exec);
    float sh = args[1]->toFloat(exec);


    KJS::JSValue* result = toJS(exec, WTF::getPtr(imp->createImageData(sw, sh)));
    return result;
}
JSValue* jsCanvasRenderingContext2DPrototypeFunctionIsPointInPath(ExecState* exec, JSObject*, JSValue* thisValue, const ArgList& args)
{
    if (!thisValue->isObject(&JSCanvasRenderingContext2D::s_info))
        return throwError(exec, TypeError);
    JSCanvasRenderingContext2D* castedThisObj = static_cast<JSCanvasRenderingContext2D*>(thisValue);
    CanvasRenderingContext2D* imp = static_cast<CanvasRenderingContext2D*>(castedThisObj->impl());
    float x = args[0]->toFloat(exec);
    float y = args[1]->toFloat(exec);


    KJS::JSValue* result = jsBoolean(imp->isPointInPath(x, y));
    return result;
}
v8::Handle<v8::Value> V8CanvasRenderingContext2D::strokeRectCallback(const v8::Arguments& args)
{
    INC_STATS("DOM.CanvasRenderingContext2D.strokeRect()");
    CanvasRenderingContext2D* context = V8CanvasRenderingContext2D::toNative(args.Holder());
    if (args.Length() == 5)
        context->strokeRect(toFloat(args[0]), toFloat(args[1]), toFloat(args[2]), toFloat(args[3]), toFloat(args[4]));
    else if (args.Length() == 4)
        context->strokeRect(toFloat(args[0]), toFloat(args[1]), toFloat(args[2]), toFloat(args[3]));
    else {
        V8Proxy::setDOMException(INDEX_SIZE_ERR);
        return notHandledByInterceptor();
    }
    return v8::Undefined();
}
v8::Handle<v8::Value> V8CanvasRenderingContext2D::setShadowCallback(const v8::Arguments& args)
{
    INC_STATS("DOM.CanvasRenderingContext2D.setShadow()");
    CanvasRenderingContext2D* context = V8CanvasRenderingContext2D::toNative(args.Holder());

    switch (args.Length()) {
    case 3:
        context->setShadow(toFloat(args[0]), toFloat(args[1]), toFloat(args[2]));
        break;
    case 4:
        if (args[3]->IsString())
            context->setShadow(toFloat(args[0]), toFloat(args[1]), toFloat(args[2]), toWebCoreString(args[3]));
        else
            context->setShadow(toFloat(args[0]), toFloat(args[1]), toFloat(args[2]), toFloat(args[3]));
        break;
    case 5:
        if (args[3]->IsString())
            context->setShadow(toFloat(args[0]), toFloat(args[1]), toFloat(args[2]), toWebCoreString(args[3]), toFloat(args[4]));
        else
            context->setShadow(toFloat(args[0]), toFloat(args[1]), toFloat(args[2]), toFloat(args[3]), toFloat(args[4]));
        break;
    case 7:
        context->setShadow(toFloat(args[0]), toFloat(args[1]), toFloat(args[2]), toFloat(args[3]), toFloat(args[4]), toFloat(args[5]), toFloat(args[6]));
        break;
    case 8:
        context->setShadow(toFloat(args[0]), toFloat(args[1]), toFloat(args[2]), toFloat(args[3]), toFloat(args[4]), toFloat(args[5]), toFloat(args[6]), toFloat(args[7]));
        break;
    default:
        V8Proxy::throwError(V8Proxy::SyntaxError, "setShadow: Invalid number of arguments");
        break;
    }

    return v8::Undefined();
}
JSValue* jsCanvasRenderingContext2DPrototypeFunctionRect(ExecState* exec, JSObject*, JSValue* thisValue, const ArgList& args)
{
    if (!thisValue->isObject(&JSCanvasRenderingContext2D::s_info))
        return throwError(exec, TypeError);
    JSCanvasRenderingContext2D* castedThisObj = static_cast<JSCanvasRenderingContext2D*>(thisValue);
    CanvasRenderingContext2D* imp = static_cast<CanvasRenderingContext2D*>(castedThisObj->impl());
    float x = args[0]->toFloat(exec);
    float y = args[1]->toFloat(exec);
    float width = args[2]->toFloat(exec);
    float height = args[3]->toFloat(exec);

    imp->rect(x, y, width, height);
    return jsUndefined();
}
JSValue* jsCanvasRenderingContext2DPrototypeFunctionQuadraticCurveTo(ExecState* exec, JSObject*, JSValue* thisValue, const ArgList& args)
{
    if (!thisValue->isObject(&JSCanvasRenderingContext2D::s_info))
        return throwError(exec, TypeError);
    JSCanvasRenderingContext2D* castedThisObj = static_cast<JSCanvasRenderingContext2D*>(thisValue);
    CanvasRenderingContext2D* imp = static_cast<CanvasRenderingContext2D*>(castedThisObj->impl());
    float cpx = args[0]->toFloat(exec);
    float cpy = args[1]->toFloat(exec);
    float x = args[2]->toFloat(exec);
    float y = args[3]->toFloat(exec);

    imp->quadraticCurveTo(cpx, cpy, x, y);
    return jsUndefined();
}
v8::Handle<v8::Value> V8CanvasRenderingContext2D::drawImageFromRectCallback(const v8::Arguments& args)
{
    INC_STATS("DOM.CanvasRenderingContext2D.drawImageFromRect()");
    CanvasRenderingContext2D* context = V8CanvasRenderingContext2D::toNative(args.Holder());

    v8::Handle<v8::Value> arg = args[0];

    if (V8HTMLImageElement::HasInstance(arg)) {
        HTMLImageElement* imageElement = V8HTMLImageElement::toNative(v8::Handle<v8::Object>::Cast(arg));
        context->drawImageFromRect(imageElement,  toFloat(args[1]), toFloat(args[2]), toFloat(args[3]), toFloat(args[4]), toFloat(args[5]), toFloat(args[6]), toFloat(args[7]), toFloat(args[8]), toWebCoreString(args[9]));
    } else
        V8Proxy::throwError(V8Proxy::TypeError, "drawImageFromRect: Invalid type of arguments");

    return v8::Undefined();
}
JSValue* jsCanvasRenderingContext2DPrototypeFunctionCreateLinearGradient(ExecState* exec, JSObject*, JSValue* thisValue, const ArgList& args)
{
    if (!thisValue->isObject(&JSCanvasRenderingContext2D::s_info))
        return throwError(exec, TypeError);
    JSCanvasRenderingContext2D* castedThisObj = static_cast<JSCanvasRenderingContext2D*>(thisValue);
    CanvasRenderingContext2D* imp = static_cast<CanvasRenderingContext2D*>(castedThisObj->impl());
    float x0 = args[0]->toFloat(exec);
    float y0 = args[1]->toFloat(exec);
    float x1 = args[2]->toFloat(exec);
    float y1 = args[3]->toFloat(exec);


    KJS::JSValue* result = toJS(exec, WTF::getPtr(imp->createLinearGradient(x0, y0, x1, y1)));
    return result;
}
JSValue* jsCanvasRenderingContext2DPrototypeFunctionTransform(ExecState* exec, JSObject*, JSValue* thisValue, const ArgList& args)
{
    if (!thisValue->isObject(&JSCanvasRenderingContext2D::s_info))
        return throwError(exec, TypeError);
    JSCanvasRenderingContext2D* castedThisObj = static_cast<JSCanvasRenderingContext2D*>(thisValue);
    CanvasRenderingContext2D* imp = static_cast<CanvasRenderingContext2D*>(castedThisObj->impl());
    float m11 = args[0]->toFloat(exec);
    float m12 = args[1]->toFloat(exec);
    float m21 = args[2]->toFloat(exec);
    float m22 = args[3]->toFloat(exec);
    float dx = args[4]->toFloat(exec);
    float dy = args[5]->toFloat(exec);

    imp->transform(m11, m12, m21, m22, dx, dy);
    return jsUndefined();
}
JSValue JSCanvasRenderingContext2D::strokeText(ExecState* exec, const ArgList& args)
{ 
    CanvasRenderingContext2D* context = impl();

    // string arg = text to draw
    // number arg = x
    // number arg = y
    // optional number arg = maxWidth
    if (args.size() < 3 || args.size() > 4)
        return throwError(exec, SyntaxError);
    
    if (args.size() == 4)
        context->strokeText(args.at(0).toString(exec), args.at(1).toFloat(exec), args.at(2).toFloat(exec), args.at(3).toFloat(exec));
    else
        context->strokeText(args.at(0).toString(exec), args.at(1).toFloat(exec), args.at(2).toFloat(exec));
    return jsUndefined();
}
JSValue* jsCanvasRenderingContext2DPrototypeFunctionArcTo(ExecState* exec, JSObject*, JSValue* thisValue, const ArgList& args)
{
    if (!thisValue->isObject(&JSCanvasRenderingContext2D::s_info))
        return throwError(exec, TypeError);
    JSCanvasRenderingContext2D* castedThisObj = static_cast<JSCanvasRenderingContext2D*>(thisValue);
    CanvasRenderingContext2D* imp = static_cast<CanvasRenderingContext2D*>(castedThisObj->impl());
    ExceptionCode ec = 0;
    float x1 = args[0]->toFloat(exec);
    float y1 = args[1]->toFloat(exec);
    float x2 = args[2]->toFloat(exec);
    float y2 = args[3]->toFloat(exec);
    float radius = args[4]->toFloat(exec);

    imp->arcTo(x1, y1, x2, y2, radius, ec);
    setDOMException(exec, ec);
    return jsUndefined();
}
JSValue* JSCanvasRenderingContext2D::putImageData(ExecState* exec, const ArgList& args)
{
    // putImageData has two variants
    // putImageData(ImageData, x, y)
    // putImageData(ImageData, x, y, dirtyX, dirtyY, dirtyWidth, dirtyHeight)
    CanvasRenderingContext2D* context = impl();

    ExceptionCode ec = 0;
    if (args.size() >= 7)
        context->putImageData(toImageData(args[0]), args[1]->toFloat(exec), args[2]->toFloat(exec), 
                              args[3]->toFloat(exec), args[4]->toFloat(exec), args[5]->toFloat(exec), args[6]->toFloat(exec), ec);
    else
        context->putImageData(toImageData(args[0]), args[1]->toFloat(exec), args[2]->toFloat(exec), ec);

    setDOMException(exec, ec);
    return jsUndefined();
}
JSValue* jsCanvasRenderingContext2DPrototypeFunctionArc(ExecState* exec, JSObject*, JSValue* thisValue, const ArgList& args)
{
    if (!thisValue->isObject(&JSCanvasRenderingContext2D::s_info))
        return throwError(exec, TypeError);
    JSCanvasRenderingContext2D* castedThisObj = static_cast<JSCanvasRenderingContext2D*>(thisValue);
    CanvasRenderingContext2D* imp = static_cast<CanvasRenderingContext2D*>(castedThisObj->impl());
    ExceptionCode ec = 0;
    float x = args[0]->toFloat(exec);
    float y = args[1]->toFloat(exec);
    float radius = args[2]->toFloat(exec);
    float startAngle = args[3]->toFloat(exec);
    float endAngle = args[4]->toFloat(exec);
    bool anticlockwise = args[5]->toBoolean(exec);

    imp->arc(x, y, radius, startAngle, endAngle, anticlockwise, ec);
    setDOMException(exec, ec);
    return jsUndefined();
}
void JSCanvasRenderingContext2D::setWebkitLineDash(ExecState* exec, JSValue value)
{
    if (!isJSArray(value))
        return;

    Vector<float> dash;
    JSArray* valueArray = asArray(value);
    for (unsigned i = 0; i < valueArray->length(); ++i) {
        float elem = valueArray->getIndex(exec, i).toFloat(exec);
        if (elem <= 0 || !std::isfinite(elem))
            return;

        dash.append(elem);
    }

    CanvasRenderingContext2D* context = static_cast<CanvasRenderingContext2D*>(impl());
    context->setWebkitLineDash(dash);
}
JSValue* JSCanvasRenderingContext2D::drawImageFromRect(ExecState* exec, const ArgList& args)
{ 
    CanvasRenderingContext2D* context = impl();
    
    JSValue* value = args[0];
    if (!value->isObject())
        return throwError(exec, TypeError);
    JSObject* o = static_cast<JSObject*>(value);
    
    if (!o->inherits(&JSHTMLImageElement::s_info))
        return throwError(exec, TypeError);
    context->drawImageFromRect(static_cast<HTMLImageElement*>(static_cast<JSHTMLElement*>(args[0])->impl()),
                               args[1]->toFloat(exec), args[2]->toFloat(exec),
                               args[3]->toFloat(exec), args[4]->toFloat(exec),
                               args[5]->toFloat(exec), args[6]->toFloat(exec),
                               args[7]->toFloat(exec), args[8]->toFloat(exec),
                               args[9]->toString(exec));    
    return jsUndefined();    
}