Index: tests/html/canvasrenderingcontext2d_test.dart |
diff --git a/tests/html/canvasrenderingcontext2d_test.dart b/tests/html/canvasrenderingcontext2d_test.dart |
index 22f02ebd724d6cc209b5c4bef8ca1f7fa74a950c..8dfbff234d72a4a281233de9729c0231225d458b 100644 |
--- a/tests/html/canvasrenderingcontext2d_test.dart |
+++ b/tests/html/canvasrenderingcontext2d_test.dart |
@@ -2,7 +2,7 @@ |
// 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 url_test; |
+library canvas_rendering_context_2d_test; |
import '../../pkg/unittest/lib/unittest.dart'; |
import '../../pkg/unittest/lib/html_config.dart'; |
import 'dart:html'; |
@@ -22,6 +22,17 @@ main() { |
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(); |
@@ -29,11 +40,15 @@ main() { |
canvas.height = 100; |
context = canvas.context2d; |
+ |
+ createOtherCanvas(); |
}); |
tearDown(() { |
canvas = null; |
context = null; |
+ otherCanvas = null; |
+ otherContext = null; |
}); |
List<int> readPixel(int x, int y) { |
@@ -237,5 +252,283 @@ main() { |
// (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); |
+ }); |
}); |
} |