| Index: test/codegen/lib/html/canvasrenderingcontext2d_test.dart
|
| diff --git a/test/codegen/lib/html/canvasrenderingcontext2d_test.dart b/test/codegen/lib/html/canvasrenderingcontext2d_test.dart
|
| new file mode 100644
|
| index 0000000000000000000000000000000000000000..6d87a648a795490d6756500d46106ce463fb1567
|
| --- /dev/null
|
| +++ b/test/codegen/lib/html/canvasrenderingcontext2d_test.dart
|
| @@ -0,0 +1,740 @@
|
| +// Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file
|
| +// for details. All rights reserved. Use of this source code is governed by a
|
| +// BSD-style license that can be found in the LICENSE file.
|
| +
|
| +library canvas_rendering_context_2d_test;
|
| +
|
| +import 'dart:html';
|
| +import 'dart:math';
|
| +
|
| +import 'package:unittest/html_individual_config.dart';
|
| +import 'package:unittest/unittest.dart';
|
| +
|
| +// Some rounding errors in the browsers.
|
| +checkPixel(List<int> pixel, List<int> expected) {
|
| + expect(pixel[0], closeTo(expected[0], 2));
|
| + expect(pixel[1], closeTo(expected[1], 2));
|
| + expect(pixel[2], closeTo(expected[2], 2));
|
| + expect(pixel[3], closeTo(expected[3], 2));
|
| +}
|
| +
|
| +var canvas;
|
| +var context;
|
| +var otherCanvas;
|
| +var otherContext;
|
| +var video;
|
| +
|
| +void createCanvas() {
|
| + canvas = new CanvasElement();
|
| + canvas.width = 100;
|
| + canvas.height = 100;
|
| +
|
| + context = canvas.context2D;
|
| +}
|
| +
|
| +void createOtherCanvas() {
|
| + otherCanvas = new CanvasElement();
|
| + otherCanvas.width = 10;
|
| + otherCanvas.height = 10;
|
| + otherContext = otherCanvas.context2D;
|
| + otherContext.fillStyle = "red";
|
| + otherContext.fillRect(0, 0, otherCanvas.width, otherCanvas.height);
|
| +}
|
| +
|
| +void setupFunc() {
|
| + createCanvas();
|
| + createOtherCanvas();
|
| + video = new VideoElement();
|
| +}
|
| +
|
| +void tearDownFunc() {
|
| + canvas = null;
|
| + context = null;
|
| + otherCanvas = null;
|
| + otherContext = null;
|
| + video = null;
|
| +}
|
| +
|
| +List<int> readPixel(int x, int y) {
|
| + var imageData = context.getImageData(x, y, 1, 1);
|
| + return imageData.data;
|
| +}
|
| +
|
| +/// Returns true if the pixel has some data in it, false otherwise.
|
| +bool isPixelFilled(int x, int y) => readPixel(x,y).any((p) => p != 0);
|
| +
|
| +String pixelDataToString(List<int> data, int x, int y) {
|
| + return '[${data.join(", ")}]';
|
| +}
|
| +
|
| +String _filled(bool v) => v ? "filled" : "unfilled";
|
| +
|
| +void expectPixelFilled(int x, int y, [bool filled = true]) {
|
| + expect(isPixelFilled(x, y), filled, reason:
|
| + 'Pixel at ($x, $y) was expected to'
|
| + ' be: <${_filled(filled)}> but was: <${_filled(!filled)}> with data: '
|
| + '${pixelDataToString(readPixel(x, y), x, y)}');
|
| +}
|
| +
|
| +void expectPixelUnfilled(int x, int y) {
|
| + expectPixelFilled(x, y, false);
|
| +}
|
| +
|
| +main() {
|
| + useHtmlIndividualConfiguration();
|
| +
|
| + group('pixel_manipulation', () {
|
| + setUp(setupFunc);
|
| + tearDown(tearDownFunc);
|
| +
|
| + test('setFillColorRgb', () {
|
| + context.setFillColorRgb(255, 0, 255, 1);
|
| + context.fillRect(0, 0, canvas.width, canvas.height);
|
| + expect(readPixel(2, 2), [255, 0, 255, 255]);
|
| + });
|
| +
|
| + test('setFillColorHsl hue', () {
|
| + context.setFillColorHsl(0, 100, 50);
|
| + context.fillRect(0, 0, canvas.width, canvas.height);
|
| + checkPixel(readPixel(2, 2), [255, 0, 0, 255]);
|
| + });
|
| +
|
| + test('setFillColorHsl hue 2', () {
|
| + context.setFillColorHsl(240, 100, 50);
|
| + context.fillRect(0, 0, canvas.width, canvas.height);
|
| + checkPixel(readPixel(2, 2), [0, 0, 255, 255]);
|
| + });
|
| +
|
| + test('setFillColorHsl sat', () {
|
| + context.setFillColorHsl(0, 0, 50);
|
| + context.fillRect(0, 0, canvas.width, canvas.height);
|
| + checkPixel(readPixel(2, 2), [127, 127, 127, 255]);
|
| + });
|
| +
|
| + test('setStrokeColorRgb', () {
|
| + context.setStrokeColorRgb(255, 0, 255, 1);
|
| + context.lineWidth = 10;
|
| + context.strokeRect(0, 0, canvas.width, canvas.height);
|
| + expect(readPixel(2, 2), [255, 0, 255, 255]);
|
| + });
|
| +
|
| + test('setStrokeColorHsl hue', () {
|
| + context.setStrokeColorHsl(0, 100, 50);
|
| + context.lineWidth = 10;
|
| + context.strokeRect(0, 0, canvas.width, canvas.height);
|
| + expect(readPixel(2, 2), [255, 0, 0, 255]);
|
| + });
|
| +
|
| + test('setStrokeColorHsl hue 2', () {
|
| + context.setStrokeColorHsl(240, 100, 50);
|
| + context.lineWidth = 10;
|
| + context.strokeRect(0, 0, canvas.width, canvas.height);
|
| + expect(readPixel(2, 2), [0, 0, 255, 255]);
|
| + });
|
| +
|
| + test('setStrokeColorHsl sat', () {
|
| + context.setStrokeColorHsl(0, 0, 50);
|
| + context.lineWidth = 10;
|
| + context.strokeRect(0, 0, canvas.width, canvas.height);
|
| + checkPixel(readPixel(2, 2), [127, 127, 127, 255]);
|
| + });
|
| +
|
| + test('fillStyle', () {
|
| + context.fillStyle = "red";
|
| + context.fillRect(0, 0, canvas.width, canvas.height);
|
| + checkPixel(readPixel(2, 2), [255, 0, 0, 255]);
|
| + });
|
| +
|
| + test('strokeStyle', () {
|
| + context.strokeStyle = "blue";
|
| + context.lineWidth = 10;
|
| + context.strokeRect(0, 0, canvas.width, canvas.height);
|
| + expect(readPixel(2, 2), [0, 0, 255, 255]);
|
| + });
|
| +
|
| + test('fillStyle linearGradient', () {
|
| + var gradient = context.createLinearGradient(0,0,20,20);
|
| + gradient.addColorStop(0,'red');
|
| + gradient.addColorStop(1,'blue');
|
| + context.fillStyle = gradient;
|
| + context.fillRect(0, 0, canvas.width, canvas.height);
|
| + expect(context.fillStyle is CanvasGradient, isTrue);
|
| + });
|
| +
|
| + test('putImageData', () {
|
| + context.fillStyle = 'green';
|
| + context.fillRect(0, 0, canvas.width, canvas.height);
|
| +
|
| + ImageData expectedData = context.getImageData(0, 0, 10, 10);
|
| + expectedData.data[0] = 25;
|
| + expectedData.data[1] = 65;
|
| + expectedData.data[2] = 255;
|
| + // Set alpha to 255 to make the pixels show up.
|
| + expectedData.data[3] = 255;
|
| +
|
| + context.putImageData(expectedData, 0, 0);
|
| +
|
| + var resultingData = context.getImageData(0, 0, 10, 10);
|
| + // Make sure that we read back what we wrote.
|
| + expect(resultingData.data, expectedData.data);
|
| + });
|
| +
|
| + test('putImageData dirty rectangle', () {
|
| + context.fillStyle = 'green';
|
| + context.fillRect(0, 0, canvas.width, canvas.height);
|
| +
|
| + ImageData drawnData = context.getImageData(0, 0, 10, 10);
|
| + drawnData.data[0] = 25;
|
| + drawnData.data[1] = 65;
|
| + drawnData.data[2] = 255;
|
| + drawnData.data[3] = 255;
|
| +
|
| + // Draw these pixels to the 2nd pixel.
|
| + drawnData.data[2 * 4 + 0] = 25;
|
| + drawnData.data[2 * 4 + 1] = 65;
|
| + drawnData.data[2 * 4 + 2] = 255;
|
| + drawnData.data[2 * 4 + 3] = 255;
|
| +
|
| + // Draw these pixels to the 8th pixel.
|
| + drawnData.data[7 * 4 + 0] = 25;
|
| + drawnData.data[7 * 4 + 1] = 65;
|
| + drawnData.data[7 * 4 + 2] = 255;
|
| + drawnData.data[7 * 4 + 3] = 255;
|
| +
|
| + // Use a dirty rectangle to limit what pixels are drawn.
|
| + context.putImageData(drawnData, 0, 0, 1, 0, 5, 5);
|
| +
|
| + // Expect the data to be all green, as we skip all drawn pixels.
|
| + ImageData expectedData = context.createImageData(10, 10);
|
| + for (int i = 0; i < expectedData.data.length; i++) {
|
| + switch (i % 4) {
|
| + case 0:
|
| + expectedData.data[i] = 0;
|
| + break;
|
| + case 1:
|
| + expectedData.data[i] = 128;
|
| + break;
|
| + case 2:
|
| + expectedData.data[i] = 0;
|
| + break;
|
| + case 3:
|
| + expectedData.data[i] = 255;
|
| + break;
|
| + }
|
| + }
|
| + // Third pixel was copied.
|
| + expectedData.data[2 * 4 + 0] = 25;
|
| + expectedData.data[2 * 4 + 1] = 65;
|
| + expectedData.data[2 * 4 + 2] = 255;
|
| + expectedData.data[2 * 4 + 3] = 255;
|
| +
|
| + // Make sure that our data is all green.
|
| + var resultingData = context.getImageData(0, 0, 10, 10);
|
| + expect(resultingData.data, expectedData.data);
|
| + });
|
| +
|
| + test('putImageData throws with wrong number of arguments', () {
|
| + ImageData expectedData = context.getImageData(0, 0, 10, 10);
|
| +
|
| + // TODO(antonm): in Dartium ArgumentError should be thrown too.
|
| + expect(() => context.putImageData(expectedData, 0, 0, 1),
|
| + throws);
|
| + expect(() => context.putImageData(expectedData, 0, 0, 1, 1),
|
| + throws);
|
| + expect(() => context.putImageData(expectedData, 0, 0, 1, 1, 5),
|
| + throws);
|
| + });
|
| + });
|
| +
|
| + group('arc', () {
|
| + setUp(setupFunc);
|
| + tearDown(tearDownFunc);
|
| +
|
| + test('default arc should be clockwise', () {
|
| + context.beginPath();
|
| + final r = 10;
|
| +
|
| + // Center of arc.
|
| + final cx = 20;
|
| + final cy = 20;
|
| + // Arc centered at (20, 20) with radius 10 will go clockwise
|
| + // from (20 + r, 20) to (20, 20 + r), which is 1/4 of a circle.
|
| + context.arc(cx, cy, r, 0, PI/2);
|
| +
|
| + context.strokeStyle = 'green';
|
| + context.lineWidth = 2;
|
| + context.stroke();
|
| +
|
| + // Center should not be filled.
|
| + expectPixelUnfilled(cx, cy);
|
| +
|
| + // (cx + r, cy) should be filled.
|
| + expectPixelFilled(cx + r, cy, true);
|
| + // (cx, cy + r) should be filled.
|
| + expectPixelFilled(cx, cy + r, true);
|
| + // (cx - r, cy) should be empty.
|
| + expectPixelFilled(cx - r, cy, false);
|
| + // (cx, cy - r) should be empty.
|
| + expectPixelFilled(cx, cy - r, false);
|
| +
|
| + // (cx + r/SQRT2, cy + r/SQRT2) should be filled.
|
| + expectPixelFilled((cx + r/SQRT2).toInt(), (cy + r/SQRT2).toInt(), true);
|
| +
|
| + // (cx - r/SQRT2, cy - r/SQRT2) should be empty.
|
| + expectPixelFilled((cx - r/SQRT2).toInt(), (cy + r/SQRT2).toInt(), false);
|
| +
|
| + // (cx + r/SQRT2, cy + r/SQRT2) should be empty.
|
| + expectPixelFilled((cx - r/SQRT2).toInt(), (cy - r/SQRT2).toInt(), false);
|
| +
|
| + // (cx - r/SQRT2, cy - r/SQRT2) should be empty.
|
| + expectPixelFilled((cx + r/SQRT2).toInt(), (cy - r/SQRT2).toInt(), false);
|
| + });
|
| +
|
| + test('arc anticlockwise', () {
|
| + context.beginPath();
|
| + final r = 10;
|
| +
|
| + // Center of arc.
|
| + final cx = 20;
|
| + final cy = 20;
|
| + // Arc centered at (20, 20) with radius 10 will go anticlockwise
|
| + // from (20 + r, 20) to (20, 20 + r), which is 3/4 of a circle.
|
| + // Because of the way arc work, when going anti-clockwise, the end points
|
| + // are not included, so small values are added to radius to make a little
|
| + // more than a 3/4 circle.
|
| + context.arc(cx, cy, r, .1, PI/2 - .1, true);
|
| +
|
| + context.strokeStyle = 'green';
|
| + context.lineWidth = 2;
|
| + context.stroke();
|
| +
|
| + // Center should not be filled.
|
| + expectPixelUnfilled(cx, cy);
|
| +
|
| + // (cx + r, cy) should be filled.
|
| + expectPixelFilled(cx + r, cy, true);
|
| + // (cx, cy + r) should be filled.
|
| + expectPixelFilled(cx, cy + r, true);
|
| + // (cx - r, cy) should be filled.
|
| + expectPixelFilled(cx - r, cy, true);
|
| + // (cx, cy - r) should be filled.
|
| + expectPixelFilled(cx, cy - r, true);
|
| +
|
| + // (cx + r/SQRT2, cy + r/SQRT2) should be empty.
|
| + expectPixelFilled((cx + r/SQRT2).toInt(), (cy + r/SQRT2).toInt(), false);
|
| +
|
| + // (cx - r/SQRT2, cy - r/SQRT2) should be filled.
|
| + expectPixelFilled((cx - r/SQRT2).toInt(), (cy + r/SQRT2).toInt(), true);
|
| +
|
| + // (cx + r/SQRT2, cy + r/SQRT2) should be filled.
|
| + expectPixelFilled((cx - r/SQRT2).toInt(), (cy - r/SQRT2).toInt(), true);
|
| +
|
| + // (cx - r/SQRT2, cy - r/SQRT2) should be filled.
|
| + expectPixelFilled((cx + r/SQRT2).toInt(), (cy - r/SQRT2).toInt(), true);
|
| + });
|
| + });
|
| +
|
| + group('drawImage_image_element', () {
|
| + setUp(setupFunc);
|
| + tearDown(tearDownFunc);
|
| + // Draw an image to the canvas from an image element.
|
| + test('with 3 params', () {
|
| + var dataUrl = otherCanvas.toDataUrl('image/gif');
|
| + var img = new ImageElement();
|
| +
|
| + img.onLoad.listen(expectAsync((_) {
|
| + context.drawImage(img, 50, 50);
|
| +
|
| + expectPixelFilled(50, 50);
|
| + expectPixelFilled(55, 55);
|
| + expectPixelFilled(59, 59);
|
| + expectPixelUnfilled(60, 60);
|
| + expectPixelUnfilled(0, 0);
|
| + expectPixelUnfilled(70, 70);
|
| + }));
|
| + img.onError.listen((_) {
|
| + fail('URL failed to load.');
|
| + });
|
| + img.src = dataUrl;
|
| + });
|
| +
|
| + // Draw an image to the canvas from an image element and scale it.
|
| + test('with 5 params', () {
|
| + var dataUrl = otherCanvas.toDataUrl('image/gif');
|
| + var img = new ImageElement();
|
| +
|
| + img.onLoad.listen(expectAsync((_) {
|
| + context.drawImageToRect(img, new Rectangle(50, 50, 20, 20));
|
| +
|
| + expectPixelFilled(50, 50);
|
| + expectPixelFilled(55, 55);
|
| + expectPixelFilled(59, 59);
|
| + expectPixelFilled(60, 60);
|
| + expectPixelFilled(69, 69);
|
| + expectPixelUnfilled(70, 70);
|
| + expectPixelUnfilled(0, 0);
|
| + expectPixelUnfilled(80, 80);
|
| + }));
|
| + img.onError.listen((_) {
|
| + fail('URL failed to load.');
|
| + });
|
| + img.src = dataUrl;
|
| + });
|
| +
|
| + // Draw an image to the canvas from an image element and scale it.
|
| + test('with 9 params', () {
|
| + otherContext.fillStyle = "blue";
|
| + otherContext.fillRect(5, 5, 5, 5);
|
| + var dataUrl = otherCanvas.toDataUrl('image/gif');
|
| + var img = new ImageElement();
|
| +
|
| + img.onLoad.listen(expectAsync((_) {
|
| + // This will take a 6x6 square from the first canvas from position 2,2
|
| + // and then scale it to a 20x20 square and place it to the second
|
| + // canvas at 50,50.
|
| + context.drawImageToRect(img, new Rectangle(50, 50, 20, 20),
|
| + sourceRect: new Rectangle(2, 2, 6, 6));
|
| +
|
| + checkPixel(readPixel(50, 50), [255, 0, 0, 255]);
|
| + checkPixel(readPixel(55, 55), [255, 0, 0, 255]);
|
| + checkPixel(readPixel(60, 50), [255, 0, 0, 255]);
|
| + checkPixel(readPixel(65, 65), [0, 0, 255, 255]);
|
| + checkPixel(readPixel(69, 69), [0, 0, 255, 255]);
|
| +
|
| + expectPixelFilled(50, 50);
|
| + expectPixelFilled(55, 55);
|
| + expectPixelFilled(59, 59);
|
| + expectPixelFilled(60, 60);
|
| + expectPixelFilled(69, 69);
|
| + expectPixelUnfilled(70, 70);
|
| + expectPixelUnfilled(0, 0);
|
| + expectPixelUnfilled(80, 80);
|
| + }));
|
| + img.onError.listen((_) {
|
| + fail('URL failed to load.');
|
| + });
|
| + img.src = dataUrl;
|
| + });
|
| + });
|
| +
|
| + // These videos and base64 strings are the same video, representing 2
|
| + // frames of 8x8 red pixels.
|
| + // The videos were created with:
|
| + // convert -size 8x8 xc:red blank1.jpg
|
| + // convert -size 8x8 xc:red blank2.jpg
|
| + // avconv -f image2 -i "blank%d.jpg" -c:v libx264 small.mp4
|
| + // avconv -i small.mp4 small.webm
|
| + // python -m base64 -e small.mp4
|
| + // python -m base64 -e small.webm
|
| + var mp4VideoUrl = '/root_dart/tests/html/small.mp4';
|
| + var webmVideoUrl = '/root_dart/tests/html/small.webm';
|
| + var mp4VideoDataUrl =
|
| + 'data:video/mp4;base64,AAAAIGZ0eXBpc29tAAACAGlzb21pc28yYXZjMW1wNDEAAA'
|
| + 'AIZnJlZQAAAsdtZGF0AAACmwYF//+X3EXpvebZSLeWLNgg2SPu73gyNjQgLSBjb3JlID'
|
| + 'EyMCByMjE1MSBhM2Y0NDA3IC0gSC4yNjQvTVBFRy00IEFWQyBjb2RlYyAtIENvcHlsZW'
|
| + 'Z0IDIwMDMtMjAxMSAtIGh0dHA6Ly93d3cudmlkZW9sYW4ub3JnL3gyNjQuaHRtbCAtIG'
|
| + '9wdGlvbnM6IGNhYmFjPTEgcmVmPTMgZGVibG9jaz0xOjA6MCBhbmFseXNlPTB4MToweD'
|
| + 'ExMSBtZT1oZXggc3VibWU9NyBwc3k9MSBwc3lfcmQ9MS4wMDowLjAwIG1peGVkX3JlZj'
|
| + '0wIG1lX3JhbmdlPTE2IGNocm9tYV9tZT0xIHRyZWxsaXM9MSA4eDhkY3Q9MCBjcW09MC'
|
| + 'BkZWFkem9uZT0yMSwxMSBmYXN0X3Bza2lwPTEgY2hyb21hX3FwX29mZnNldD0tMiB0aH'
|
| + 'JlYWRzPTE4IHNsaWNlZF90aHJlYWRzPTAgbnI9MCBkZWNpbWF0ZT0xIGludGVybGFjZW'
|
| + 'Q9MCBibHVyYXlfY29tcGF0PTAgY29uc3RyYWluZWRfaW50cmE9MCBiZnJhbWVzPTMgYl'
|
| + '9weXJhbWlkPTAgYl9hZGFwdD0xIGJfYmlhcz0wIGRpcmVjdD0xIHdlaWdodGI9MCBvcG'
|
| + 'VuX2dvcD0xIHdlaWdodHA9MiBrZXlpbnQ9MjUwIGtleWludF9taW49MjUgc2NlbmVjdX'
|
| + 'Q9NDAgaW50cmFfcmVmcmVzaD0wIHJjX2xvb2thaGVhZD00MCByYz1jcmYgbWJ0cmVlPT'
|
| + 'EgY3JmPTUxLjAgcWNvbXA9MC42MCBxcG1pbj0wIHFwbWF4PTY5IHFwc3RlcD00IGlwX3'
|
| + 'JhdGlvPTEuMjUgYXE9MToxLjAwAIAAAAARZYiEB//3aoK5/tP9+8yeuIEAAAAHQZoi2P'
|
| + '/wgAAAAzxtb292AAAAbG12aGQAAAAAAAAAAAAAAAAAAAPoAAAAUAABAAABAAAAAAAAAA'
|
| + 'AAAAAAAQAAAAAAAAAAAAAAAAAAAAEAAAAAAAAAAAAAAAAAAEAAAAAAAAAAAAAAAAAAAA'
|
| + 'AAAAAAAAAAAAAAAAAAAAACAAAAGGlvZHMAAAAAEICAgAcAT/////7/AAACUHRyYWsAAA'
|
| + 'BcdGtoZAAAAA8AAAAAAAAAAAAAAAEAAAAAAAAAUAAAAAAAAAAAAAAAAAAAAAAAAQAAAA'
|
| + 'AAAAAAAAAAAAAAAAEAAAAAAAAAAAAAAAAAAEAAAAAACAAAAAgAAAAAACRlZHRzAAAAHG'
|
| + 'Vsc3QAAAAAAAAAAQAAAFAAAAABAAEAAAAAAchtZGlhAAAAIG1kaGQAAAAAAAAAAAAAAA'
|
| + 'AAAAAZAAAAAlXEAAAAAAAtaGRscgAAAAAAAAAAdmlkZQAAAAAAAAAAAAAAAFZpZGVvSG'
|
| + 'FuZGxlcgAAAAFzbWluZgAAABR2bWhkAAAAAQAAAAAAAAAAAAAAJGRpbmYAAAAcZHJlZg'
|
| + 'AAAAAAAAABAAAADHVybCAAAAABAAABM3N0YmwAAACXc3RzZAAAAAAAAAABAAAAh2F2Yz'
|
| + 'EAAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAAACAAIAEgAAABIAAAAAAAAAAEAAAAAAAAAAA'
|
| + 'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAY//8AAAAxYXZjQwFNQAr/4QAYZ01ACuiPyy'
|
| + '4C2QAAAwABAAADADIPEiUSAQAGaOvAZSyAAAAAGHN0dHMAAAAAAAAAAQAAAAIAAAABAA'
|
| + 'AAFHN0c3MAAAAAAAAAAQAAAAEAAAAYY3R0cwAAAAAAAAABAAAAAgAAAAEAAAAcc3RzYw'
|
| + 'AAAAAAAAABAAAAAQAAAAEAAAABAAAAHHN0c3oAAAAAAAAAAAAAAAIAAAK0AAAACwAAAB'
|
| + 'hzdGNvAAAAAAAAAAIAAAAwAAAC5AAAAGB1ZHRhAAAAWG1ldGEAAAAAAAAAIWhkbHIAAA'
|
| + 'AAAAAAAG1kaXJhcHBsAAAAAAAAAAAAAAAAK2lsc3QAAAAjqXRvbwAAABtkYXRhAAAAAQ'
|
| + 'AAAABMYXZmNTMuMjEuMQ==';
|
| + var webmVideoDataUrl =
|
| + 'data:video/webm;base64,GkXfowEAAAAAAAAfQoaBAUL3gQFC8oEEQvOBCEKChHdlY'
|
| + 'm1Ch4ECQoWBAhhTgGcBAAAAAAAB/hFNm3RALE27i1OrhBVJqWZTrIHfTbuMU6uEFlSua'
|
| + '1OsggEsTbuMU6uEHFO7a1OsggHk7AEAAAAAAACkAAAAAAAAAAAAAAAAAAAAAAAAAAAAA'
|
| + 'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA'
|
| + 'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA'
|
| + 'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAVSalmAQAAAAAAA'
|
| + 'EEq17GDD0JATYCLTGF2ZjUzLjIxLjFXQYtMYXZmNTMuMjEuMXOkkJatuHwTJ7cvFLSzB'
|
| + 'Smxbp5EiYhAVAAAAAAAABZUrmsBAAAAAAAAR64BAAAAAAAAPteBAXPFgQGcgQAitZyDd'
|
| + 'W5khoVWX1ZQOIOBASPjg4QCYloA4AEAAAAAAAASsIEIuoEIVLCBCFS6gQhUsoEDH0O2d'
|
| + 'QEAAAAAAABZ54EAo72BAACA8AIAnQEqCAAIAABHCIWFiIWEiAICAnWqA/gD+gINTRgA/'
|
| + 'v0hRf/kb+PnRv/I4//8WE8DijI//FRAo5WBACgAsQEAARAQABgAGFgv9AAIAAAcU7trA'
|
| + 'QAAAAAAAA67jLOBALeH94EB8YIBfw==';
|
| + group('drawImage_video_element', () {
|
| + setUp(setupFunc);
|
| + tearDown(tearDownFunc);
|
| +
|
| + test('with 3 params', () {
|
| + video.onCanPlay.listen(expectAsync((_) {
|
| + context.drawImage(video, 50, 50);
|
| +
|
| + expectPixelFilled(50, 50);
|
| + expectPixelFilled(54, 54);
|
| + expectPixelFilled(57, 57);
|
| + expectPixelUnfilled(58, 58);
|
| + expectPixelUnfilled(0, 0);
|
| + expectPixelUnfilled(70, 70);
|
| + }));
|
| +
|
| + video.onError.listen((_) {
|
| + fail('URL failed to load.');
|
| + });
|
| +
|
| + if(video.canPlayType('video/webm; codecs="vp8.0, vorbis"', '') != '') {
|
| + video.src = webmVideoUrl;
|
| + } else if(video.canPlayType('video/mp4; codecs="avc1.4D401E, mp4a.40.2"',
|
| + null) != '') {
|
| + video.src = mp4VideoUrl;
|
| + } else {
|
| + window.console.log('Video is not supported on this system.');
|
| + }
|
| + });
|
| +
|
| + test('with 5 params', () {
|
| + video.onCanPlay.listen(expectAsync((_) {
|
| + context.drawImageToRect(video, new Rectangle(50, 50, 20, 20));
|
| +
|
| + expectPixelFilled(50, 50);
|
| + expectPixelFilled(55, 55);
|
| + expectPixelFilled(59, 59);
|
| + expectPixelFilled(60, 60);
|
| + expectPixelFilled(69, 69);
|
| + expectPixelUnfilled(70, 70);
|
| + expectPixelUnfilled(0, 0);
|
| + expectPixelUnfilled(80, 80);
|
| + }));
|
| + video.onError.listen((_) {
|
| + fail('URL failed to load.');
|
| + });
|
| +
|
| + if(video.canPlayType('video/webm; codecs="vp8.0, vorbis"', '') != '') {
|
| + video.src = webmVideoUrl;
|
| + } else if(video.canPlayType('video/mp4; codecs="avc1.4D401E, mp4a.40.2"',
|
| + null) != '') {
|
| + video.src = mp4VideoUrl;
|
| + } else {
|
| + // TODO(amouravski): Better fallback?
|
| + window.console.log('Video is not supported on this system.');
|
| + }
|
| + });
|
| +
|
| + test('with 9 params', () {
|
| + video.onCanPlay.listen(expectAsync((_) {
|
| + context.drawImageToRect(video, new Rectangle(50, 50, 20, 20),
|
| + sourceRect: new Rectangle(2, 2, 6, 6));
|
| +
|
| + expectPixelFilled(50, 50);
|
| + expectPixelFilled(55, 55);
|
| + expectPixelFilled(59, 59);
|
| + expectPixelFilled(60, 60);
|
| + expectPixelFilled(69, 69);
|
| + expectPixelUnfilled(70, 70);
|
| + expectPixelUnfilled(0, 0);
|
| + expectPixelUnfilled(80, 80);
|
| + }));
|
| + video.onError.listen((_) {
|
| + fail('URL failed to load.');
|
| + });
|
| +
|
| + if(video.canPlayType('video/webm; codecs="vp8.0, vorbis"', '') != '') {
|
| + video.src = webmVideoUrl;
|
| + } else if(video.canPlayType('video/mp4; codecs="avc1.4D401E, mp4a.40.2"',
|
| + null) != '') {
|
| + video.src = mp4VideoUrl;
|
| + } else {
|
| + // TODO(amouravski): Better fallback?
|
| + window.console.log('Video is not supported on this system.');
|
| + }
|
| + });
|
| + });
|
| +
|
| + group('drawImage_video_element_dataUrl', () {
|
| + setUp(setupFunc);
|
| + tearDown(tearDownFunc);
|
| +
|
| + test('with 9 params', () {
|
| + video = new VideoElement();
|
| + canvas = new CanvasElement();
|
| + video.onCanPlay.listen(expectAsync((_) {
|
| + context.drawImageToRect(video, new Rectangle(50, 50, 20, 20),
|
| + sourceRect: new Rectangle(2, 2, 6, 6));
|
| +
|
| + expectPixelFilled(50, 50);
|
| + expectPixelFilled(55, 55);
|
| + expectPixelFilled(59, 59);
|
| + expectPixelFilled(60, 60);
|
| + expectPixelFilled(69, 69);
|
| + expectPixelUnfilled(70, 70);
|
| + expectPixelUnfilled(0, 0);
|
| + expectPixelUnfilled(80, 80);
|
| + }));
|
| + video.onError.listen((_) {
|
| + fail('URL failed to load.');
|
| + });
|
| +
|
| + if(video.canPlayType('video/webm; codecs="vp8.0, vorbis"', '') != '') {
|
| + video.src = webmVideoDataUrl;
|
| + } else if(video.canPlayType('video/mp4; codecs="avc1.4D401E, mp4a.40.2"',
|
| + null) != '') {
|
| + video.src = mp4VideoDataUrl;
|
| + } else {
|
| + // TODO(amouravski): Better fallback?
|
| + window.console.log('Video is not supported on this system.');
|
| + }
|
| + });
|
| + });
|
| +
|
| + group('drawImage_canvas_element', () {
|
| + setUp(setupFunc);
|
| + tearDown(tearDownFunc);
|
| +
|
| + test('with 3 params', () {
|
| + // Draw an image to the canvas from a canvas element.
|
| + context.drawImage(otherCanvas, 50, 50);
|
| +
|
| + expectPixelFilled(50, 50);
|
| + expectPixelFilled(55, 55);
|
| + expectPixelFilled(59, 59);
|
| + expectPixelUnfilled(60, 60);
|
| + expectPixelUnfilled(0, 0);
|
| + expectPixelUnfilled(70, 70);
|
| + });
|
| + test('with 5 params', () {
|
| + // Draw an image to the canvas from a canvas element.
|
| + context.drawImageToRect(otherCanvas, new Rectangle(50, 50, 20, 20));
|
| +
|
| + expectPixelFilled(50, 50);
|
| + expectPixelFilled(55, 55);
|
| + expectPixelFilled(59, 59);
|
| + expectPixelFilled(60, 60);
|
| + expectPixelFilled(69, 69);
|
| + expectPixelUnfilled(70, 70);
|
| + expectPixelUnfilled(0, 0);
|
| + expectPixelUnfilled(80, 80);
|
| + });
|
| + test('with 9 params', () {
|
| + // Draw an image to the canvas from a canvas element.
|
| + otherContext.fillStyle = "blue";
|
| + otherContext.fillRect(5, 5, 5, 5);
|
| + context.drawImageToRect(otherCanvas, new Rectangle(50, 50, 20, 20),
|
| + sourceRect: new Rectangle(2, 2, 6, 6));
|
| +
|
| + checkPixel(readPixel(50, 50), [255, 0, 0, 255]);
|
| + checkPixel(readPixel(55, 55), [255, 0, 0, 255]);
|
| + checkPixel(readPixel(60, 50), [255, 0, 0, 255]);
|
| + checkPixel(readPixel(65, 65), [0, 0, 255, 255]);
|
| + checkPixel(readPixel(69, 69), [0, 0, 255, 255]);
|
| + expectPixelFilled(50, 50);
|
| + expectPixelFilled(55, 55);
|
| + expectPixelFilled(59, 59);
|
| + expectPixelFilled(60, 60);
|
| + expectPixelFilled(69, 69);
|
| + expectPixelUnfilled(70, 70);
|
| + expectPixelUnfilled(0, 0);
|
| + expectPixelUnfilled(80, 80);
|
| + });
|
| +
|
| + test('createImageData', () {
|
| + var imageData = context.createImageData(15, 15);
|
| + expect(imageData.width, 15);
|
| + expect(imageData.height, 15);
|
| +
|
| + var other = context.createImageDataFromImageData(imageData);
|
| + expect(other.width, 15);
|
| + expect(other.height, 15);
|
| + });
|
| +
|
| + test('createPattern', () {
|
| + var pattern = context.createPattern(new CanvasElement(), '');
|
| + //var pattern2 = context.createPatternFromImage(new ImageElement(), '');
|
| + });
|
| + });
|
| +
|
| + group('fillText', () {
|
| + setUp(setupFunc);
|
| + tearDown(tearDownFunc);
|
| +
|
| + final x = 20;
|
| + final y = 20;
|
| +
|
| + test('without maxWidth', () {
|
| + context.font = '40pt Garamond';
|
| + context.fillStyle = 'blue';
|
| +
|
| + // Draw a blue box.
|
| + context.fillText('█', x, y);
|
| +
|
| + var width = context.measureText('█').width.ceil();
|
| +
|
| + checkPixel(readPixel(x, y), [0, 0, 255, 255]);
|
| + checkPixel(readPixel(x + 10, y), [0, 0, 255, 255]);
|
| +
|
| + expectPixelUnfilled(x - 10, y);
|
| + expectPixelFilled(x, y);
|
| + expectPixelFilled(x + 10, y);
|
| +
|
| + // The box does not draw after `width` pixels.
|
| + // Check -2 rather than -1 because this seems
|
| + // to run into a rounding error on Mac bots.
|
| + expectPixelFilled(x + width - 2, y);
|
| + expectPixelUnfilled(x + width + 1, y);
|
| + });
|
| +
|
| + test('with maxWidth null', () {
|
| + context.font = '40pt Garamond';
|
| + context.fillStyle = 'blue';
|
| +
|
| + // Draw a blue box with null maxWidth.
|
| + context.fillText('█', x, y, null);
|
| +
|
| + var width = context.measureText('█').width.ceil();
|
| +
|
| + checkPixel(readPixel(x, y), [0, 0, 255, 255]);
|
| + checkPixel(readPixel(x + 10, y), [0, 0, 255, 255]);
|
| +
|
| + expectPixelUnfilled(x - 10, y);
|
| + expectPixelFilled(x, y);
|
| + expectPixelFilled(x + 10, y);
|
| +
|
| + // The box does not draw after `width` pixels.
|
| + // Check -2 rather than -1 because this seems
|
| + // to run into a rounding error on Mac bots.
|
| + expectPixelFilled(x + width - 2, y);
|
| + expectPixelUnfilled(x + width + 1, y);
|
| + });
|
| +
|
| + test('with maxWidth defined', () {
|
| + context.font = '40pt Garamond';
|
| + context.fillStyle = 'blue';
|
| +
|
| + final maxWidth = 20;
|
| +
|
| + // Draw a blue box that's at most 20 pixels wide.
|
| + context.fillText('█', x, y, maxWidth);
|
| +
|
| + checkPixel(readPixel(x, y), [0, 0, 255, 255]);
|
| + checkPixel(readPixel(x + 10, y), [0, 0, 255, 255]);
|
| +
|
| + // The box does not draw after 20 pixels.
|
| + expectPixelUnfilled(x - 10, y);
|
| + expectPixelUnfilled(x + maxWidth + 1, y);
|
| + expectPixelUnfilled(x + maxWidth + 20, y);
|
| + expectPixelFilled(x, y);
|
| + expectPixelFilled(x + 10, y);
|
| + });
|
| + });
|
| +}
|
|
|