From e05ba6967edfe288044d6c397fbb541c67eddead Mon Sep 17 00:00:00 2001 From: Mitch Curtis Date: Mon, 11 Aug 2014 16:41:02 +0200 Subject: [PATCH] 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 --- src/quick/items/context2d/qquickcontext2d.cpp | 94 +++--- .../quick/qquickcanvasitem/data/tst_canvas.qml | 343 +++++++++++++++++++++ 2 files changed, 390 insertions(+), 47 deletions(-) diff --git a/src/quick/items/context2d/qquickcontext2d.cpp b/src/quick/items/context2d/qquickcontext2d.cpp index b153fc2..1a0d628 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 r(scope, ctx->d()->callData->thisObject.as()); 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 r(scope, ctx->d()->callData->thisObject.as()); 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 r(scope, ctx->d()->callData->thisObject.as()); 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 r(scope, ctx->d()->callData->thisObject.as()); 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 pattern(scope, scope.engine->memoryManager->alloc(scope.engine)); QColor color = engine->toVariant(ctx->d()->callData->args[0], qMetaTypeId()).value(); @@ -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 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 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 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 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 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 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 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 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 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 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 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 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 r(scope, ctx->d()->callData->thisObject.as()); 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 d90eb39..23fd519 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(); + } } -- 2.7.4