aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMitch Curtis <mitch.curtis@digia.com>2014-08-11 16:41:02 +0200
committerMitch Curtis <mitch.curtis@digia.com>2014-08-14 08:58:28 +0200
commite05ba6967edfe288044d6c397fbb541c67eddead (patch)
tree510db720a01c98428f1689fca788c2a29de92500
parentfb339b21b8a24b835cea7a057c47b7c5ad80dd72 (diff)
Ignore extra arguments passed to Context2D functions.
This is in line with what Chrome, Firefox and IE do. This is also how most JavaScript functions in Qt behave by default (for example, TableView::resizeColumnsToContents()). Task-number: QTBUG-40703 Change-Id: I087221e305dcb5fd6709ad4a99a5163d641faac6 Reviewed-by: Simon Hausmann <simon.hausmann@digia.com>
-rw-r--r--src/quick/items/context2d/qquickcontext2d.cpp94
-rw-r--r--tests/auto/quick/qquickcanvasitem/data/tst_canvas.qml343
2 files changed, 390 insertions, 47 deletions
diff --git a/src/quick/items/context2d/qquickcontext2d.cpp b/src/quick/items/context2d/qquickcontext2d.cpp
index b153fc25b2..1a0d6287aa 100644
--- a/src/quick/items/context2d/qquickcontext2d.cpp
+++ b/src/quick/items/context2d/qquickcontext2d.cpp
@@ -1056,7 +1056,7 @@ QV4::ReturnedValue QQuickJSContext2DPrototype::method_rotate(QV4::CallContext *c
QV4::Scoped<QQuickJSContext2D> r(scope, ctx->d()->callData->thisObject.as<QQuickJSContext2D>());
CHECK_CONTEXT(r)
- if (ctx->d()->callData->argc == 1)
+ if (ctx->d()->callData->argc >= 1)
r->d()->context->rotate(ctx->d()->callData->args[0].toNumber());
return ctx->d()->callData->thisObject.asReturnedValue();
}
@@ -1085,7 +1085,7 @@ QV4::ReturnedValue QQuickJSContext2DPrototype::method_scale(QV4::CallContext *ct
CHECK_CONTEXT(r)
- if (ctx->d()->callData->argc == 2)
+ if (ctx->d()->callData->argc >= 2)
r->d()->context->scale(ctx->d()->callData->args[0].toNumber(), ctx->d()->callData->args[1].toNumber());
return ctx->d()->callData->thisObject.asReturnedValue();
}
@@ -1131,7 +1131,7 @@ QV4::ReturnedValue QQuickJSContext2DPrototype::method_setTransform(QV4::CallCont
CHECK_CONTEXT(r)
- if (ctx->d()->callData->argc == 6)
+ if (ctx->d()->callData->argc >= 6)
r->d()->context->setTransform( ctx->d()->callData->args[0].toNumber()
, ctx->d()->callData->args[1].toNumber()
, ctx->d()->callData->args[2].toNumber()
@@ -1159,7 +1159,7 @@ QV4::ReturnedValue QQuickJSContext2DPrototype::method_transform(QV4::CallContext
QV4::Scoped<QQuickJSContext2D> r(scope, ctx->d()->callData->thisObject.as<QQuickJSContext2D>());
CHECK_CONTEXT(r)
- if (ctx->d()->callData->argc == 6)
+ if (ctx->d()->callData->argc >= 6)
r->d()->context->transform( ctx->d()->callData->args[0].toNumber()
, ctx->d()->callData->args[1].toNumber()
, ctx->d()->callData->args[2].toNumber()
@@ -1185,7 +1185,7 @@ QV4::ReturnedValue QQuickJSContext2DPrototype::method_translate(QV4::CallContext
QV4::Scoped<QQuickJSContext2D> r(scope, ctx->d()->callData->thisObject.as<QQuickJSContext2D>());
CHECK_CONTEXT(r)
- if (ctx->d()->callData->argc == 2)
+ if (ctx->d()->callData->argc >= 2)
r->d()->context->translate(ctx->d()->callData->args[0].toNumber(), ctx->d()->callData->args[1].toNumber());
return ctx->d()->callData->thisObject.asReturnedValue();
}
@@ -1223,7 +1223,7 @@ QV4::ReturnedValue QQuickJSContext2DPrototype::method_shear(QV4::CallContext *ct
QV4::Scoped<QQuickJSContext2D> r(scope, ctx->d()->callData->thisObject.as<QQuickJSContext2D>());
CHECK_CONTEXT(r)
- if (ctx->d()->callData->argc == 2)
+ if (ctx->d()->callData->argc >= 2)
r->d()->context->shear(ctx->d()->callData->args[0].toNumber(), ctx->d()->callData->args[1].toNumber());
return ctx->d()->callData->thisObject.asReturnedValue();
@@ -1538,7 +1538,7 @@ QV4::ReturnedValue QQuickJSContext2DPrototype::method_createLinearGradient(QV4::
QV8Engine *engine = scope.engine->v8Engine;
- if (ctx->d()->callData->argc == 4) {
+ if (ctx->d()->callData->argc >= 4) {
qreal x0 = ctx->d()->callData->args[0].toNumber();
qreal y0 = ctx->d()->callData->args[1].toNumber();
qreal x1 = ctx->d()->callData->args[2].toNumber();
@@ -1584,7 +1584,7 @@ QV4::ReturnedValue QQuickJSContext2DPrototype::method_createRadialGradient(QV4::
QV8Engine *engine = scope.engine->v8Engine;
- if (ctx->d()->callData->argc == 6) {
+ if (ctx->d()->callData->argc >= 6) {
qreal x0 = ctx->d()->callData->args[0].toNumber();
qreal y0 = ctx->d()->callData->args[1].toNumber();
qreal r0 = ctx->d()->callData->args[2].toNumber();
@@ -1638,7 +1638,7 @@ QV4::ReturnedValue QQuickJSContext2DPrototype::method_createConicalGradient(QV4:
QV8Engine *engine = scope.engine->v8Engine;
- if (ctx->d()->callData->argc == 3) {
+ if (ctx->d()->callData->argc >= 3) {
qreal x = ctx->d()->callData->args[0].toNumber();
qreal y = ctx->d()->callData->args[1].toNumber();
qreal angle = DEGREES(ctx->d()->callData->args[2].toNumber());
@@ -1712,7 +1712,7 @@ QV4::ReturnedValue QQuickJSContext2DPrototype::method_createPattern(QV4::CallCon
QV8Engine *engine = scope.engine->v8Engine;
- if (ctx->d()->callData->argc == 2) {
+ if (ctx->d()->callData->argc >= 2) {
QV4::Scoped<QQuickContext2DStyle> pattern(scope, scope.engine->memoryManager->alloc<QQuickContext2DStyle>(scope.engine));
QColor color = engine->toVariant(ctx->d()->callData->args[0], qMetaTypeId<QColor>()).value<QColor>();
@@ -2093,7 +2093,7 @@ QV4::ReturnedValue QQuickJSContext2DPrototype::method_clearRect(QV4::CallContext
CHECK_CONTEXT(r)
- if (ctx->d()->callData->argc == 4)
+ if (ctx->d()->callData->argc >= 4)
r->d()->context->clearRect(ctx->d()->callData->args[0].toNumber(),
ctx->d()->callData->args[1].toNumber(),
ctx->d()->callData->args[2].toNumber(),
@@ -2113,7 +2113,7 @@ QV4::ReturnedValue QQuickJSContext2DPrototype::method_fillRect(QV4::CallContext
QV4::Scoped<QQuickJSContext2D> r(scope, ctx->d()->callData->thisObject);
CHECK_CONTEXT(r)
- if (ctx->d()->callData->argc == 4)
+ if (ctx->d()->callData->argc >= 4)
r->d()->context->fillRect(ctx->d()->callData->args[0].toNumber(), ctx->d()->callData->args[1].toNumber(), ctx->d()->callData->args[2].toNumber(), ctx->d()->callData->args[3].toNumber());
return ctx->d()->callData->thisObject.asReturnedValue();
}
@@ -2134,7 +2134,7 @@ QV4::ReturnedValue QQuickJSContext2DPrototype::method_strokeRect(QV4::CallContex
QV4::Scoped<QQuickJSContext2D> r(scope, ctx->d()->callData->thisObject);
CHECK_CONTEXT(r)
- if (ctx->d()->callData->argc == 4)
+ if (ctx->d()->callData->argc >= 4)
r->d()->context->strokeRect(ctx->d()->callData->args[0].toNumber(), ctx->d()->callData->args[1].toNumber(), ctx->d()->callData->args[2].toNumber(), ctx->d()->callData->args[3].toNumber());
return ctx->d()->callData->thisObject.asReturnedValue();
@@ -2218,7 +2218,7 @@ QV4::ReturnedValue QQuickJSContext2DPrototype::method_arcTo(QV4::CallContext *ct
QV4::Scoped<QQuickJSContext2D> r(scope, ctx->d()->callData->thisObject);
CHECK_CONTEXT(r)
- if (ctx->d()->callData->argc == 5) {
+ if (ctx->d()->callData->argc >= 5) {
qreal radius = ctx->d()->callData->args[4].toNumber();
if (qIsFinite(radius) && radius < 0)
@@ -2276,7 +2276,7 @@ QV4::ReturnedValue QQuickJSContext2DPrototype::method_bezierCurveTo(QV4::CallCon
CHECK_CONTEXT(r)
- if (ctx->d()->callData->argc == 6) {
+ if (ctx->d()->callData->argc >= 6) {
qreal cp1x = ctx->d()->callData->args[0].toNumber();
qreal cp1y = ctx->d()->callData->args[1].toNumber();
qreal cp2x = ctx->d()->callData->args[2].toNumber();
@@ -2376,7 +2376,7 @@ QV4::ReturnedValue QQuickJSContext2DPrototype::method_lineTo(QV4::CallContext *c
CHECK_CONTEXT(r)
- if (ctx->d()->callData->argc == 2) {
+ if (ctx->d()->callData->argc >= 2) {
qreal x = ctx->d()->callData->args[0].toNumber();
qreal y = ctx->d()->callData->args[1].toNumber();
@@ -2400,7 +2400,7 @@ QV4::ReturnedValue QQuickJSContext2DPrototype::method_moveTo(QV4::CallContext *c
QV4::Scoped<QQuickJSContext2D> r(scope, ctx->d()->callData->thisObject);
CHECK_CONTEXT(r)
- if (ctx->d()->callData->argc == 2) {
+ if (ctx->d()->callData->argc >= 2) {
qreal x = ctx->d()->callData->args[0].toNumber();
qreal y = ctx->d()->callData->args[1].toNumber();
@@ -2424,7 +2424,7 @@ QV4::ReturnedValue QQuickJSContext2DPrototype::method_quadraticCurveTo(QV4::Call
QV4::Scoped<QQuickJSContext2D> r(scope, ctx->d()->callData->thisObject);
CHECK_CONTEXT(r)
- if (ctx->d()->callData->argc == 4) {
+ if (ctx->d()->callData->argc >= 4) {
qreal cpx = ctx->d()->callData->args[0].toNumber();
qreal cpy = ctx->d()->callData->args[1].toNumber();
qreal x = ctx->d()->callData->args[2].toNumber();
@@ -2450,7 +2450,7 @@ QV4::ReturnedValue QQuickJSContext2DPrototype::method_rect(QV4::CallContext *ctx
QV4::Scoped<QQuickJSContext2D> r(scope, ctx->d()->callData->thisObject);
CHECK_CONTEXT(r)
- if (ctx->d()->callData->argc == 4)
+ if (ctx->d()->callData->argc >= 4)
r->d()->context->rect(ctx->d()->callData->args[0].toNumber(), ctx->d()->callData->args[1].toNumber(), ctx->d()->callData->args[2].toNumber(), ctx->d()->callData->args[3].toNumber());
return ctx->d()->callData->thisObject.asReturnedValue();
}
@@ -2467,7 +2467,7 @@ QV4::ReturnedValue QQuickJSContext2DPrototype::method_roundedRect(QV4::CallConte
QV4::Scoped<QQuickJSContext2D> r(scope, ctx->d()->callData->thisObject);
CHECK_CONTEXT(r)
- if (ctx->d()->callData->argc == 6)
+ if (ctx->d()->callData->argc >= 6)
r->d()->context->roundedRect(ctx->d()->callData->args[0].toNumber()
, ctx->d()->callData->args[1].toNumber()
, ctx->d()->callData->args[2].toNumber()
@@ -2492,7 +2492,7 @@ QV4::ReturnedValue QQuickJSContext2DPrototype::method_ellipse(QV4::CallContext *
CHECK_CONTEXT(r)
- if (ctx->d()->callData->argc == 4)
+ if (ctx->d()->callData->argc >= 4)
r->d()->context->ellipse(ctx->d()->callData->args[0].toNumber(), ctx->d()->callData->args[1].toNumber(), ctx->d()->callData->args[2].toNumber(), ctx->d()->callData->args[3].toNumber());
return ctx->d()->callData->thisObject.asReturnedValue();
@@ -2510,7 +2510,7 @@ QV4::ReturnedValue QQuickJSContext2DPrototype::method_text(QV4::CallContext *ctx
QV4::Scoped<QQuickJSContext2D> r(scope, ctx->d()->callData->thisObject);
CHECK_CONTEXT(r)
- if (ctx->d()->callData->argc == 3) {
+ if (ctx->d()->callData->argc >= 3) {
qreal x = ctx->d()->callData->args[1].toNumber();
qreal y = ctx->d()->callData->args[2].toNumber();
@@ -2554,7 +2554,7 @@ QV4::ReturnedValue QQuickJSContext2DPrototype::method_isPointInPath(QV4::CallCon
CHECK_CONTEXT(r)
bool pointInPath = false;
- if (ctx->d()->callData->argc == 2)
+ if (ctx->d()->callData->argc >= 2)
pointInPath = r->d()->context->isPointInPath(ctx->d()->callData->args[0].toNumber(), ctx->d()->callData->args[1].toNumber());
return QV4::Primitive::fromBoolean(pointInPath).asReturnedValue();
}
@@ -2776,7 +2776,7 @@ QV4::ReturnedValue QQuickJSContext2DPrototype::method_fillText(QV4::CallContext
QV4::Scoped<QQuickJSContext2D> r(scope, ctx->d()->callData->thisObject);
CHECK_CONTEXT(r)
- if (ctx->d()->callData->argc == 3) {
+ if (ctx->d()->callData->argc >= 3) {
qreal x = ctx->d()->callData->args[1].toNumber();
qreal y = ctx->d()->callData->args[2].toNumber();
if (!qIsFinite(x) || !qIsFinite(y))
@@ -2800,7 +2800,7 @@ QV4::ReturnedValue QQuickJSContext2DPrototype::method_strokeText(QV4::CallContex
QV4::Scoped<QQuickJSContext2D> r(scope, ctx->d()->callData->thisObject);
CHECK_CONTEXT(r)
- if (ctx->d()->callData->argc == 3)
+ if (ctx->d()->callData->argc >= 3)
r->d()->context->drawText(ctx->d()->callData->args[0].toQStringNoThrow(), ctx->d()->callData->args[1].toNumber(), ctx->d()->callData->args[2].toNumber(), false);
return ctx->d()->callData->thisObject.asReturnedValue();
}
@@ -2835,7 +2835,7 @@ QV4::ReturnedValue QQuickJSContext2DPrototype::method_measureText(QV4::CallConte
QV4::Scoped<QQuickJSContext2D> r(scope, ctx->d()->callData->thisObject);
CHECK_CONTEXT(r)
- if (ctx->d()->callData->argc == 1) {
+ if (ctx->d()->callData->argc >= 1) {
QFontMetrics fm(r->d()->context->state.font);
uint width = fm.width(ctx->d()->callData->args[0].toQStringNoThrow());
QV4::Scoped<QV4::Object> tm(scope, scope.engine->newObject());
@@ -2965,25 +2965,7 @@ QV4::ReturnedValue QQuickJSContext2DPrototype::method_drawImage(QV4::CallContext
if (pixmap.isNull() || !pixmap->isValid())
return ctx->d()->callData->thisObject.asReturnedValue();
- if (ctx->d()->callData->argc == 3) {
- dx = ctx->d()->callData->args[1].toNumber();
- dy = ctx->d()->callData->args[2].toNumber();
- sx = 0;
- sy = 0;
- sw = pixmap->width();
- sh = pixmap->height();
- dw = sw;
- dh = sh;
- } else if (ctx->d()->callData->argc == 5) {
- sx = 0;
- sy = 0;
- sw = pixmap->width();
- sh = pixmap->height();
- dx = ctx->d()->callData->args[1].toNumber();
- dy = ctx->d()->callData->args[2].toNumber();
- dw = ctx->d()->callData->args[3].toNumber();
- dh = ctx->d()->callData->args[4].toNumber();
- } else if (ctx->d()->callData->argc == 9) {
+ if (ctx->d()->callData->argc >= 9) {
sx = ctx->d()->callData->args[1].toNumber();
sy = ctx->d()->callData->args[2].toNumber();
sw = ctx->d()->callData->args[3].toNumber();
@@ -2992,6 +2974,24 @@ QV4::ReturnedValue QQuickJSContext2DPrototype::method_drawImage(QV4::CallContext
dy = ctx->d()->callData->args[6].toNumber();
dw = ctx->d()->callData->args[7].toNumber();
dh = ctx->d()->callData->args[8].toNumber();
+ } else if (ctx->d()->callData->argc >= 5) {
+ sx = 0;
+ sy = 0;
+ sw = pixmap->width();
+ sh = pixmap->height();
+ dx = ctx->d()->callData->args[1].toNumber();
+ dy = ctx->d()->callData->args[2].toNumber();
+ dw = ctx->d()->callData->args[3].toNumber();
+ dh = ctx->d()->callData->args[4].toNumber();
+ } else if (ctx->d()->callData->argc >= 3) {
+ dx = ctx->d()->callData->args[1].toNumber();
+ dy = ctx->d()->callData->args[2].toNumber();
+ sx = 0;
+ sy = 0;
+ sw = pixmap->width();
+ sh = pixmap->height();
+ dw = sw;
+ dh = sh;
} else {
return ctx->d()->callData->thisObject.asReturnedValue();
}
@@ -3250,7 +3250,7 @@ QV4::ReturnedValue QQuickJSContext2DPrototype::method_getImageData(QV4::CallCont
CHECK_CONTEXT(r)
QV8Engine *engine = scope.engine->v8Engine;
- if (ctx->d()->callData->argc == 4) {
+ if (ctx->d()->callData->argc >= 4) {
qreal x = ctx->d()->callData->args[0].toNumber();
qreal y = ctx->d()->callData->args[1].toNumber();
qreal w = ctx->d()->callData->args[2].toNumber();
@@ -3276,7 +3276,7 @@ QV4::ReturnedValue QQuickJSContext2DPrototype::method_putImageData(QV4::CallCont
QV4::Scope scope(ctx);
QV4::Scoped<QQuickJSContext2D> r(scope, ctx->d()->callData->thisObject.as<QQuickJSContext2D>());
CHECK_CONTEXT(r)
- if (ctx->d()->callData->argc != 3 && ctx->d()->callData->argc != 7)
+ if (ctx->d()->callData->argc < 7)
return QV4::Encode::undefined();
QV4::ScopedValue arg0(scope, ctx->d()->callData->args[0]);
diff --git a/tests/auto/quick/qquickcanvasitem/data/tst_canvas.qml b/tests/auto/quick/qquickcanvasitem/data/tst_canvas.qml
index d90eb3971e..23fd5192f3 100644
--- a/tests/auto/quick/qquickcanvasitem/data/tst_canvas.qml
+++ b/tests/auto/quick/qquickcanvasitem/data/tst_canvas.qml
@@ -247,5 +247,348 @@ CanvasTestCase {
c.destroy();
}
+
+ Image {
+ id: image
+ source: "anim-gr.png"
+ }
+
+ /*
+ Ensures that extra arguments to functions are ignored,
+ by checking that drawing, clearing, etc. still occurs.
+ */
+ function test_extraArgumentsIgnored_data() {
+ var extra = 0;
+ return [
+ {
+ tag: "arc",
+ test: function(ctx) {
+ ctx.arc(10, 10, 5, 0, Math.PI * 2, true, extra);
+ ctx.fill();
+ comparePixel(ctx, 10, 10, 255, 0, 0, 255);
+ }
+ },
+ {
+ tag: "arcTo",
+ test: function(ctx) {
+ ctx.translate(-50, -25);
+ ctx.moveTo(20,20);
+ ctx.arcTo(150, 20, 100, 70, 50, extra);
+ ctx.fill();
+ comparePixel(ctx, 0, 0, 255, 0, 0, 255);
+ }
+ },
+ {
+ tag: "bezierCurveTo",
+ test: function(ctx) {
+ ctx.beginPath();
+ ctx.moveTo(-20, -20);
+ ctx.bezierCurveTo(20, 100, 100, 100, 100, 20, extra);
+ ctx.fill();
+ comparePixel(ctx, 0, 0, 255, 0, 0, 255);
+ }
+ },
+ {
+ tag: "clearRect",
+ test: function(ctx) {
+ ctx.fillRect(0, 0, ctx.canvas.width, ctx.canvas.height);
+ ctx.clearRect(0, 0, 10, 10, extra);
+ comparePixel(ctx, 0, 0, 0, 0, 0, 0);
+ }
+ },
+ {
+ tag: "createConicalGradient",
+ test: function(ctx) {
+ verify(ctx.createConicalGradient(0, 0, 0, extra) !== ctx);
+ }
+ },
+ {
+ tag: "createLinearGradient",
+ test: function(ctx) {
+ verify(ctx.createLinearGradient(0, 0, 10, 10, extra) !== ctx);
+ }
+ },
+ {
+ tag: "createRadialGradient",
+ test: function(ctx) {
+ verify(ctx.createRadialGradient(0, 0, 10, 20, 20, 10, extra) !== ctx);
+ }
+ },
+ {
+ tag: "createPattern-image",
+ test: function(ctx) {
+ verify(ctx.createPattern(image, "repeat", extra) !== undefined);
+ }
+ },
+ {
+ tag: "createPattern-color",
+ test: function(ctx) {
+ verify(ctx.createPattern("red", Qt.SolidPattern, extra) !== undefined);
+ }
+ },
+ {
+ tag: "drawImage-9-args",
+ test: function(ctx) {
+ ctx.drawImage(image, 0, 0, image.sourceSize.width, image.sourceSize.height,
+ 0, 0, image.sourceSize.width, image.sourceSize.height, extra);
+ comparePixel(ctx, 10, 10, 0, 255, 0, 255);
+ }
+ },
+ {
+ tag: "drawImage-5-args",
+ test: function(ctx) {
+ ctx.drawImage(image, 0, 0, image.sourceSize.width, image.sourceSize.height, extra);
+ comparePixel(ctx, 10, 10, 0, 255, 0, 255);
+ }
+ },
+ {
+ tag: "drawImage-3-args",
+ test: function(ctx) {
+ ctx.drawImage(image, 0, 0, extra);
+ comparePixel(ctx, 10, 10, 0, 255, 0, 255);
+ }
+ },
+ {
+ tag: "ellipse",
+ test: function(ctx) {
+ ctx.ellipse(0, 0, 10, 10);
+ ctx.fill();
+ comparePixel(ctx, 5, 5, 255, 0, 0, 255);
+ }
+ },
+ {
+ tag: "fillRect",
+ test: function(ctx) {
+ ctx.fillRect(0, 0, 10, 10, extra);
+ comparePixel(ctx, 0, 0, 255, 0, 0, 255, 200);
+ }
+ },
+ {
+ tag: "fillText",
+ test: function(ctx) {
+ ctx.font = "100px sans-serif";
+ ctx.fillText("Hello", -10, 10, extra);
+ comparePixel(ctx, 0, 0, 255, 0, 0, 255);
+ }
+ },
+ {
+ tag: "getImageData",
+ test: function(ctx) {
+ verify(ctx.getImageData(0, 0, 1, 1, extra) !== null);
+ }
+ },
+ {
+ tag: "isPointInPath",
+ test: function(ctx) {
+ ctx.moveTo(0, 0);
+ ctx.lineTo(10, 10);
+ verify(ctx.isPointInPath(0, 0, extra));
+ }
+ },
+ {
+ tag: "lineTo",
+ test: function(ctx) {
+ ctx.lineWidth = 5;
+ ctx.moveTo(0, 0);
+ ctx.lineTo(10, 10, extra);
+ ctx.stroke();
+ comparePixel(ctx, 0, 0, 255, 0, 0, 255);
+ }
+ },
+ {
+ tag: "measureText",
+ test: function(ctx) {
+ var textMetrics = ctx.measureText("Hello", extra);
+ verify(textMetrics !== undefined);
+ verify(textMetrics.width > 0);
+ }
+ },
+ {
+ tag: "moveTo",
+ test: function(ctx) {
+ ctx.lineWidth = 5;
+ ctx.moveTo(10, 10, extra);
+ ctx.lineTo(20, 20, extra);
+ ctx.stroke();
+ comparePixel(ctx, 0, 0, 0, 0, 0, 0);
+ comparePixel(ctx, 10, 10, 255, 0, 0, 255);
+ }
+ },
+ {
+ tag: "putImageData",
+ test: function(ctx) {
+ ctx.drawImage(image, 0, 0);
+ comparePixel(ctx, 0, 0, 0, 255, 0, 255);
+ var imageData = ctx.getImageData(0, 0, 1, 1);
+ // Swap green with red.
+ imageData.data[0] = 255;
+ imageData.data[1] = 0;
+ ctx.putImageData(imageData, 0, 0, 0, 0, ctx.canvas.width, ctx.canvas.height, extra);
+ comparePixel(ctx, 0, 0, 255, 0, 0, 255);
+ }
+ },
+ {
+ tag: "quadraticCurveTo",
+ test: function(ctx) {
+ ctx.lineWidth = 5;
+ ctx.moveTo(0, 0);
+ ctx.quadraticCurveTo(20, 100, 100, 20, extra);
+ ctx.stroke();
+ comparePixel(ctx, 0, 0, 255, 0, 0, 255);
+ }
+ },
+ {
+ tag: "rect",
+ test: function(ctx) {
+ ctx.rect(0, 0, 1, 1, extra);
+ ctx.fill();
+ comparePixel(ctx, 0, 0, 255, 0, 0, 255);
+ }
+ },
+ {
+ tag: "rotate",
+ test: function(ctx) {
+ // If we don't rotate, it should be red in the middle.
+ comparePixel(ctx, 50, 50, 0, 0, 0, 0);
+ ctx.fillRect(50, 50, 1, 1);
+ comparePixel(ctx, 50, 50, 255, 0, 0, 255);
+
+ ctx.reset();
+ comparePixel(ctx, 50, 50, 0, 0, 0, 0);
+
+ // If we do rotate, it shouldn't be there.
+ ctx.rotate(Math.PI / 4, extra);
+ ctx.fillRect(50, 50, 1, 1);
+ comparePixel(ctx, 50, 50, 0, 0, 0, 0);
+ }
+ },
+ {
+ tag: "roundedRect",
+ test: function(ctx) {
+ ctx.roundedRect(0, 0, 50, 50, 5, 5, extra);
+ ctx.fill();
+ comparePixel(ctx, 25, 25, 255, 0, 0, 255);
+ }
+ },
+ {
+ tag: "scale",
+ test: function(ctx) {
+ // If we don't scale, it should be red in the middle.
+ comparePixel(ctx, 50, 50, 0, 0, 0, 0);
+ ctx.fillRect(50, 50, 1, 1);
+ comparePixel(ctx, 50, 50, 255, 0, 0, 255);
+
+ ctx.reset();
+ comparePixel(ctx, 50, 50, 0, 0, 0, 0);
+
+ // If we do scale, it shouldn't be there.
+ ctx.scale(1.25, 1.25, extra);
+ ctx.fillRect(50, 50, 1, 1);
+ comparePixel(ctx, 50, 50, 0, 0, 0, 0);
+ }
+ },
+ {
+ tag: "setTransform",
+ test: function(ctx) {
+ // The same as the scale test, except with setTransform.
+ comparePixel(ctx, 50, 50, 0, 0, 0, 0);
+ ctx.fillRect(50, 50, 1, 1);
+ comparePixel(ctx, 50, 50, 255, 0, 0, 255);
+
+ ctx.reset();
+ comparePixel(ctx, 50, 50, 0, 0, 0, 0);
+
+ ctx.setTransform(1.25, 0, 0, 1.25, 0, 0, extra);
+ ctx.fillRect(50, 50, 1, 1);
+ comparePixel(ctx, 50, 50, 0, 0, 0, 0);
+ }
+ },
+ {
+ tag: "shear",
+ test: function(ctx) {
+ comparePixel(ctx, 50, 50, 0, 0, 0, 0);
+ ctx.fillRect(50, 50, 1, 1);
+ comparePixel(ctx, 50, 50, 255, 0, 0, 255);
+
+ ctx.reset();
+ comparePixel(ctx, 50, 50, 0, 0, 0, 0);
+
+ ctx.shear(0.5, 0, extra);
+ ctx.fillRect(50, 50, 1, 1);
+ comparePixel(ctx, 50, 50, 0, 0, 0, 0);
+ }
+ },
+ {
+ tag: "strokeRect",
+ test: function(ctx) {
+ ctx.strokeRect(0, 0, 10, 10, extra);
+ comparePixel(ctx, 0, 0, 255, 0, 0, 255, 200);
+ }
+ },
+ {
+ tag: "strokeText",
+ test: function(ctx) {
+ ctx.font = "10px sans-serif";
+ ctx.strokeText("Hello", -1, 5, extra);
+ comparePixel(ctx, 0, 5, 255, 0, 0, 255, 200);
+ }
+ },
+ {
+ tag: "text",
+ test: function(ctx) {
+ ctx.font = "100px sans-serif";
+ ctx.text(".", -15, 8, extra);
+ ctx.fill();
+ comparePixel(ctx, 0, 0, 255, 0, 0, 255, 200);
+ }
+ },
+ {
+ tag: "transform",
+ test: function(ctx) {
+ comparePixel(ctx, 50, 50, 0, 0, 0, 0);
+ ctx.fillRect(50, 50, 1, 1);
+ comparePixel(ctx, 50, 50, 255, 0, 0, 255);
+
+ ctx.reset();
+ comparePixel(ctx, 50, 50, 0, 0, 0, 0);
+
+ ctx.transform(1.25, 0, 0, 1.25, 0, 0, extra);
+ ctx.fillRect(50, 50, 1, 1);
+ comparePixel(ctx, 50, 50, 0, 0, 0, 0);
+ }
+ },
+ {
+ tag: "translate",
+ test: function(ctx) {
+ comparePixel(ctx, 50, 50, 0, 0, 0, 0);
+ ctx.fillRect(50, 50, 1, 1);
+ comparePixel(ctx, 50, 50, 255, 0, 0, 255);
+
+ ctx.reset();
+ comparePixel(ctx, 50, 50, 0, 0, 0, 0);
+
+ ctx.translate(1, 1, extra);
+ ctx.fillRect(50, 50, 1, 1);
+ comparePixel(ctx, 50, 50, 0, 0, 0, 0);
+ }
+ }
+ ];
+ }
+
+ function test_extraArgumentsIgnored(data) {
+ var canvas = Qt.createQmlObject("import QtQuick 2.3; Canvas { onPaint: {} }", testCase);
+ verify(canvas);
+ canvas.width = 100;
+ canvas.height = 100;
+
+ var ctx = canvas.getContext("2d");
+
+ ctx.beginPath();
+ ctx.fillStyle = "red";
+ ctx.strokeStyle = "red";
+ data.test(ctx);
+
+ canvas.destroy();
+ }
}