| // 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 '../../pkg/unittest/lib/unittest.dart'; |
| import '../../pkg/unittest/lib/html_config.dart'; |
| import 'dart:html'; |
| import 'dart:math'; |
| |
| // 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)); |
| } |
| |
| main() { |
| useHtmlConfiguration(); |
| |
| group('canvasRenderingContext2d', () { |
| var canvas; |
| var context; |
| var otherCanvas; |
| var otherContext; |
| |
| 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); |
| } |
| |
| setUp(() { |
| canvas = new CanvasElement(); |
| canvas.width = 100; |
| canvas.height = 100; |
| |
| context = canvas.context2d; |
| |
| createOtherCanvas(); |
| }); |
| |
| tearDown(() { |
| canvas = null; |
| context = null; |
| otherCanvas = null; |
| otherContext = 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(int x, int y) { |
| var data = readPixel(x, 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(x,y)}'); |
| } |
| |
| void expectPixelUnfilled(int x, int y) { |
| expectPixelFilled(x, y, false); |
| } |
| |
| |
| 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', () { |
| 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.fillStyle = 'green'; |
| context.fillRect(0, 0, canvas.width, canvas.height); |
| |
| 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('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); |
| }); |
| |
| // Draw an image to the canvas from an image element. |
| test('drawImage from img element with 3 params', () { |
| var dataUrl = otherCanvas.toDataUrl('image/gif'); |
| var img = new ImageElement(); |
| |
| img.onLoad.listen(expectAsync1((_) { |
| 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((_) { |
| guardAsync(() { |
| fail('URL failed to load.'); |
| }); |
| }); |
| img.src = dataUrl; |
| }); |
| |
| // Draw an image to the canvas from an image element and scale it. |
| test('drawImage from img element with 5 params', () { |
| var dataUrl = otherCanvas.toDataUrl('image/gif'); |
| var img = new ImageElement(); |
| |
| img.onLoad.listen(expectAsync1((_) { |
| context.drawImageAtScale(img, new Rect(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((_) { |
| guardAsync(() { |
| fail('URL failed to load.'); |
| }); |
| }); |
| img.src = dataUrl; |
| }); |
| |
| // Draw an image to the canvas from an image element and scale it. |
| test('drawImage from img element 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(expectAsync1((_) { |
| // 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.drawImageAtScale(img, new Rect(50, 50, 20, 20), |
| sourceRect: new Rect(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((_) { |
| guardAsync(() { |
| fail('URL failed to load.'); |
| }); |
| }); |
| img.src = dataUrl; |
| }); |
| |
| // These 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 |
| // python -m base64 -e small.mp4 |
| // avconv -i small.mp4 small.webm |
| // python -m base64 -e small.webm |
| var mp4VideoUrl = |
| 'data:video/mp4;base64,AAAAIGZ0eXBpc29tAAACAGlzb21pc28yYXZjMW1wNDEAAAAIZn' |
| 'JlZQAAAsdtZGF0AAACmwYF//+X3EXpvebZSLeWLNgg2SPu73gyNjQgLSBjb3JlIDEyMCByMj' |
| 'E1MSBhM2Y0NDA3IC0gSC4yNjQvTVBFRy00IEFWQyBjb2RlYyAtIENvcHlsZWZ0IDIwMDMtMj' |
| 'AxMSAtIGh0dHA6Ly93d3cudmlkZW9sYW4ub3JnL3gyNjQuaHRtbCAtIG9wdGlvbnM6IGNhYm' |
| 'FjPTEgcmVmPTMgZGVibG9jaz0xOjA6MCBhbmFseXNlPTB4MToweDExMSBtZT1oZXggc3VibW' |
| 'U9NyBwc3k9MSBwc3lfcmQ9MS4wMDowLjAwIG1peGVkX3JlZj0wIG1lX3JhbmdlPTE2IGNocm' |
| '9tYV9tZT0xIHRyZWxsaXM9MSA4eDhkY3Q9MCBjcW09MCBkZWFkem9uZT0yMSwxMSBmYXN0X3' |
| 'Bza2lwPTEgY2hyb21hX3FwX29mZnNldD0tMiB0aHJlYWRzPTE4IHNsaWNlZF90aHJlYWRzPT' |
| 'AgbnI9MCBkZWNpbWF0ZT0xIGludGVybGFjZWQ9MCBibHVyYXlfY29tcGF0PTAgY29uc3RyYW' |
| 'luZWRfaW50cmE9MCBiZnJhbWVzPTMgYl9weXJhbWlkPTAgYl9hZGFwdD0xIGJfYmlhcz0wIG' |
| 'RpcmVjdD0xIHdlaWdodGI9MCBvcGVuX2dvcD0xIHdlaWdodHA9MiBrZXlpbnQ9MjUwIGtleW' |
| 'ludF9taW49MjUgc2NlbmVjdXQ9NDAgaW50cmFfcmVmcmVzaD0wIHJjX2xvb2thaGVhZD00MC' |
| 'ByYz1jcmYgbWJ0cmVlPTEgY3JmPTUxLjAgcWNvbXA9MC42MCBxcG1pbj0wIHFwbWF4PTY5IH' |
| 'Fwc3RlcD00IGlwX3JhdGlvPTEuMjUgYXE9MToxLjAwAIAAAAARZYiEB//3aoK5/tP9+8yeuI' |
| 'EAAAAHQZoi2P/wgAAAAzxtb292AAAAbG12aGQAAAAAAAAAAAAAAAAAAAPoAAAAUAABAAABAA' |
| 'AAAAAAAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAEAAAAAAAAAAAAAAAAAAEAAAAAAAAAAAAAAAA' |
| 'AAAAAAAAAAAAAAAAAAAAAAAAACAAAAGGlvZHMAAAAAEICAgAcAT/////7/AAACUHRyYWsAAA' |
| 'BcdGtoZAAAAA8AAAAAAAAAAAAAAAEAAAAAAAAAUAAAAAAAAAAAAAAAAAAAAAAAAQAAAAAAAA' |
| 'AAAAAAAAAAAAEAAAAAAAAAAAAAAAAAAEAAAAAACAAAAAgAAAAAACRlZHRzAAAAHGVsc3QAAA' |
| 'AAAAAAAQAAAFAAAAABAAEAAAAAAchtZGlhAAAAIG1kaGQAAAAAAAAAAAAAAAAAAAAZAAAAAl' |
| 'XEAAAAAAAtaGRscgAAAAAAAAAAdmlkZQAAAAAAAAAAAAAAAFZpZGVvSGFuZGxlcgAAAAFzbW' |
| 'luZgAAABR2bWhkAAAAAQAAAAAAAAAAAAAAJGRpbmYAAAAcZHJlZgAAAAAAAAABAAAADHVybC' |
| 'AAAAABAAABM3N0YmwAAACXc3RzZAAAAAAAAAABAAAAh2F2YzEAAAAAAAAAAQAAAAAAAAAAAA' |
| 'AAAAAAAAAACAAIAEgAAABIAAAAAAAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA' |
| 'AAAAAY//8AAAAxYXZjQwFNQAr/4QAYZ01ACuiPyy4C2QAAAwABAAADADIPEiUSAQAGaOvAZS' |
| 'yAAAAAGHN0dHMAAAAAAAAAAQAAAAIAAAABAAAAFHN0c3MAAAAAAAAAAQAAAAEAAAAYY3R0cw' |
| 'AAAAAAAAABAAAAAgAAAAEAAAAcc3RzYwAAAAAAAAABAAAAAQAAAAEAAAABAAAAHHN0c3oAAA' |
| 'AAAAAAAAAAAAIAAAK0AAAACwAAABhzdGNvAAAAAAAAAAIAAAAwAAAC5AAAAGB1ZHRhAAAAWG' |
| '1ldGEAAAAAAAAAIWhkbHIAAAAAAAAAAG1kaXJhcHBsAAAAAAAAAAAAAAAAK2lsc3QAAAAjqX' |
| 'RvbwAAABtkYXRhAAAAAQAAAABMYXZmNTMuMjEuMQ=='; |
| var webmVideoUrl = |
| 'data:video/webm;base64,GkXfowEAAAAAAAAfQoaBAUL3gQFC8oEEQvOBCEKChHdlYm1Ch' |
| '4ECQoWBAhhTgGcBAAAAAAAB/hFNm3RALE27i1OrhBVJqWZTrIHfTbuMU6uEFlSua1OsggEsT' |
| 'buMU6uEHFO7a1OsggHk7AEAAAAAAACkAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA' |
| 'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA' |
| 'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA' |
| 'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAVSalmAQAAAAAAAEEq17GDD0JATYCLTGF2ZjUzL' |
| 'jIxLjFXQYtMYXZmNTMuMjEuMXOkkJatuHwTJ7cvFLSzBSmxbp5EiYhAVAAAAAAAABZUrmsBA' |
| 'AAAAAAAR64BAAAAAAAAPteBAXPFgQGcgQAitZyDdW5khoVWX1ZQOIOBASPjg4QCYloA4AEAA' |
| 'AAAAAASsIEIuoEIVLCBCFS6gQhUsoEDH0O2dQEAAAAAAABZ54EAo72BAACA8AIAnQEqCAAIA' |
| 'ABHCIWFiIWEiAICAnWqA/gD+gINTRgA/v0hRf/kb+PnRv/I4//8WE8DijI//FRAo5WBACgAs' |
| 'QEAARAQABgAGFgv9AAIAAAcU7trAQAAAAAAAA67jLOBALeH94EB8YIBfw=='; |
| |
| // test('drawImage from video element with 3 params', () { |
| // var video = new VideoElement(); |
| // |
| // video.onLoadedData.listen(expectAsync1((_) { |
| // 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((_) { |
| // guardAsync(() { |
| // 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 { |
| // logMessage('Video is not supported on this system.'); |
| // } |
| // }); |
| // |
| // test('drawImage from video element with 5 params', () { |
| // var video = new VideoElement(); |
| // |
| // video.onLoadedData.listen(expectAsync1((_) { |
| // context.drawImageAtScale(video, new Rect(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((_) { |
| // guardAsync(() { |
| // 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? |
| // logMessage('Video is not supported on this system.'); |
| // } |
| // }); |
| // |
| // test('drawImage from video element with 9 params', () { |
| // var video = new VideoElement(); |
| // |
| // video.onLoadedData.listen(expectAsync1((_) { |
| // context.drawImageAtScale(video, new Rect(50, 50, 20, 20), |
| // sourceRect: new Rect(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((_) { |
| // guardAsync(() { |
| // 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? |
| // logMessage('Video is not supported on this system.'); |
| // } |
| // }); |
| |
| test('drawImage from canvas element 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('drawImage from canvas element with 5 params', () { |
| // Draw an image to the canvas from a canvas element. |
| context.drawImageAtScale(otherCanvas, new Rect(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('drawImage from canvas element with 9 params', () { |
| // Draw an image to the canvas from a canvas element. |
| otherContext.fillStyle = "blue"; |
| otherContext.fillRect(5, 5, 5, 5); |
| context.drawImageAtScale(otherCanvas, new Rect(50, 50, 20, 20), |
| sourceRect: new Rect(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); |
| }); |
| }); |
| } |