1 <!DOCTYPE HTML PUBLIC
"-//IETF//DTD HTML//EN">
4 <script src=
"../../resources/js-test.js"></script>
9 description("Ensure correct behavior of drawImage with ImageBitmaps.");
10 window
.jsTestIsAsync
= true;
12 function jsWrapperClass(node
)
14 // returns the ClassName of node
17 var string
= Object
.prototype.toString
.apply(node
);
19 // string will be of the form [object ClassName]
20 return string
.substr(8, string
.length
- 9);
23 function shouldBeType(expression
, className
)
25 shouldBe("jsWrapperClass(" + expression
+ ")", "'" + className
+ "'");
28 function shouldNotBeCalled() {
29 testFailed("createImageBitmap promise rejected.");
33 function shouldBeRed(x
, y
) {
34 d
= ctx
.getImageData(x
, y
, 1, 1).data
;
35 shouldBeTrue("d[0] == 255");
36 shouldBeTrue("d[1] == 0");
37 shouldBeTrue("d[2] == 0");
38 shouldBeTrue("d[3] == 255");
41 function shouldBeGreen(x
, y
) {
42 d
= ctx
.getImageData(x
, y
, 1, 1).data
;
43 shouldBeTrue("d[0] == 0");
44 shouldBeTrue("d[1] == 255");
45 shouldBeTrue("d[2] == 0");
46 shouldBeTrue("d[3] == 255");
49 function shouldBeBlue(x
, y
) {
50 d
= ctx
.getImageData(x
, y
, 1, 1).data
;
51 shouldBeTrue("d[0] == 0");
52 shouldBeTrue("d[1] == 0");
53 shouldBeTrue("d[2] == 255");
54 shouldBeTrue("d[3] == 255");
57 function shouldBeBlack(x
, y
) {
58 d
= ctx
.getImageData(x
, y
, 1, 1).data
;
59 shouldBeTrue("d[0] == 0");
60 shouldBeTrue("d[1] == 0");
61 shouldBeTrue("d[2] == 0");
62 shouldBeTrue("d[3] == 255");
65 function shouldBeClear(x
, y
) {
66 // should be transparent black pixels
67 d
= ctx
.getImageData(x
, y
, 1, 1).data
;
68 shouldBeTrue("d[0] == 0");
69 shouldBeTrue("d[1] == 0");
70 shouldBeTrue("d[2] == 0");
71 shouldBeTrue("d[3] == 0");
74 function drawPattern(ctx
) {
75 // Draw a four-color pattern
77 ctx
.fillStyle
= "rgb(255, 0, 0)";
78 ctx
.fillRect(0, 0, 10, 10);
79 ctx
.fillStyle
= "rgb(0, 255, 0)";
80 ctx
.fillRect(10, 0, 10, 10);
81 ctx
.fillStyle
= "rgb(0, 0, 255)";
82 ctx
.fillRect(0, 10, 10, 10);
83 ctx
.fillStyle
= "rgb(0, 0, 0)";
84 ctx
.fillRect(10, 10, 10, 10);
87 function clearContext(context
) {
88 context
.clearRect(0, 0, 50, 50);
93 var testBitmap
; // this is an ImageBitmap that is uncropped. We use this to test createImageBitmap(testBitmap)
94 var d
; // image.imageData
100 // Draw to an auxillary canvas.
101 var aCanvas
= document
.createElement("canvas");
102 aCanvas
.width
= imageWidth
;
103 aCanvas
.height
= imageHeight
;
104 var aCtx
= aCanvas
.getContext("2d");
107 var canvas
= document
.createElement("canvas");
108 canvas
.setAttribute("width", "50");
109 canvas
.setAttribute("height", "50");
110 var ctx
= canvas
.getContext("2d");
113 image
.onload
= imageLoaded
;
114 image
.src
= aCanvas
.toDataURL();
116 var imageLoaded
= false;
117 var imageBitmapLoaded
= false;
118 var blobLoaded
= false;
120 function imageLoaded() {
121 createImageBitmap(image
).then(imageBitmapLoadedCallback
, shouldNotBeCalled
);
122 d
= aCtx
.getImageData(0, 0, 20, 20);
127 function imageBitmapLoadedCallback(imageBitmap
) {
128 testBitmap
= imageBitmap
;
130 shouldBe("testBitmap.width", "imageWidth");
131 shouldBe("testBitmap.height", "imageHeight");
133 // width and height are readonly
134 testBitmap
.width
= 42;
135 testBitmap
.height
= 42;
136 shouldBe("testBitmap.width", "imageWidth");
137 shouldBe("testBitmap.height", "imageHeight");
139 imageBitmapLoaded
= true;
143 var xhr
= new XMLHttpRequest();
144 xhr
.open("GET", 'resources/pattern.png');
145 xhr
.responseType
= 'blob';
147 xhr
.onload = function() {
154 if (imageLoaded
&& imageBitmapLoaded
&& blobLoaded
) {
155 // check all of these elements
156 elements
= [image
, aCanvas
, d
, aCtx
, testBitmap
, blob
];
158 // wait for callback to finish before each check to ensure synchronous behavior
163 function nextCheck(elementIndex
) {
164 if (elementIndex
== elements
.length
) {
168 var element
= elements
[elementIndex
];
170 debug("Checking " + jsWrapperClass(element
) + ".");
171 var p1
= createImageBitmap(element
).then(function (image
) { imageBitmaps
.noCrop
= image
});
172 var p2
= createImageBitmap(element
, 0, 0, 10, 10).then(function (image
) { imageBitmaps
.crop
= image
});
173 var p3
= createImageBitmap(element
, 5, 5, 10, 10).then(function (image
) { imageBitmaps
.cropCenter
= image
});
174 var p4
= createImageBitmap(element
, 10, 10, 10, 10).then(function (image
) { imageBitmaps
.cropRight
= image
});
175 var p5
= createImageBitmap(element
, -10, -10, 60, 60).then(function (image
) { imageBitmaps
.overCrop
= image
});
176 var p6
= createImageBitmap(element
, 10, 10, 50, 50).then(function (image
) { imageBitmaps
.overCropRight
= image
});
177 var p7
= createImageBitmap(element
, 10, 10, -10, -10).then(function (image
) { imageBitmaps
.negativeCrop
= image
});
178 var p8
= createImageBitmap(element
, -30, -30, 30, 30).then(function (image
) { imageBitmaps
.empty
= image
});
179 var p9
= createImageBitmap(element
, 40, 30, 30, 30).then(function (image
) { imageBitmaps
.emptyTwo
= image
});
180 Promise
.all([p1
, p2
, p3
, p4
, p5
, p6
, p7
, p8
, p9
]).then(function() {
181 checkNoCrop(imageBitmaps
.noCrop
);
182 checkCrop(imageBitmaps
.crop
);
183 checkCropCenter(imageBitmaps
.cropCenter
);
184 checkCropRight(imageBitmaps
.cropRight
);
185 checkOverCrop(imageBitmaps
.overCrop
);
186 checkOverCropRight(imageBitmaps
.overCropRight
);
187 checkCrop(imageBitmaps
.negativeCrop
);
188 checkEmpty(imageBitmaps
.empty
);
189 checkEmpty(imageBitmaps
.emptyTwo
);
190 nextCheck(elementIndex
+ 1);
191 }, shouldNotBeCalled
);
194 function checkNoCrop(imageBitmap
) {
195 debug("Check no crop.");
196 bitmap
= imageBitmap
;
197 shouldBeType("bitmap", "ImageBitmap");
198 shouldBe("bitmap.width", "imageWidth");
199 shouldBe("bitmap.height", "imageHeight");
201 // should be drawn to (0, 0), (20, 20)
203 ctx
.drawImage(imageBitmap
, 0, 0);
205 shouldBeGreen(11, 9);
207 shouldBeBlack(11, 11);
208 shouldBeBlack(19, 19);
209 shouldBeClear(1, 21);
210 shouldBeClear(21, 1);
211 shouldBeClear(21, 21);
213 // shrunk to (0, 0), (10, 10)
215 ctx
.drawImage(imageBitmap
, 0, 0, 10, 10);
221 shouldBeClear(1, 11);
222 shouldBeClear(11, 1);
223 shouldBeClear(11, 11);
225 // shrunk to (10, 10), (20, 20)
227 ctx
.drawImage(imageBitmap
, 10, 10, 10, 10);
229 shouldBeGreen(16, 14);
230 shouldBeBlue(14, 16);
231 shouldBeBlack(16, 16);
232 shouldBeBlack(19, 19);
233 shouldBeClear(11, 21);
234 shouldBeClear(21, 11);
235 shouldBeClear(21, 21);
237 // black should be drawn to (10, 10), (20, 20)
239 ctx
.drawImage(imageBitmap
, 10, 10, 10, 10, 10, 10, 10, 10);
241 shouldBeBlack(11, 11);
242 shouldBeBlack(19, 19);
243 shouldBeClear(1, 21);
244 shouldBeClear(21, 1);
245 shouldBeClear(21, 21);
248 function checkCrop(imageBitmap
) {
249 debug("Check crop.");
250 bitmap
= imageBitmap
;
251 shouldBeType("bitmap", "ImageBitmap");
252 shouldBe("bitmap.width", "10");
253 shouldBe("bitmap.height", "10");
255 // red should be drawn to (0, 0), (10, 10)
257 ctx
.drawImage(imageBitmap
, 0, 0);
260 shouldBeClear(12, 12);
261 shouldBeClear(1, 12);
262 shouldBeClear(12, 1);
264 // red should be drawn to (0, 0), (20, 20)
266 ctx
.drawImage(imageBitmap
, 0, 0, 20, 20);
269 shouldBeClear(22, 22);
270 shouldBeClear(1, 22);
271 shouldBeClear(22, 1);
274 function checkCropCenter(imageBitmap
) {
275 debug("Check crop center.");
276 bitmap
= imageBitmap
;
277 shouldBeType("bitmap", "ImageBitmap");
278 shouldBe("bitmap.width", "10");
279 shouldBe("bitmap.height", "10");
281 // should be drawn to (0, 0), (10, 10) with all four colors
283 ctx
.drawImage(imageBitmap
, 0, 0);
289 shouldBeClear(11, 11);
290 shouldBeClear(1, 11);
291 shouldBeClear(11, 1);
293 // should be drawn to (0, 0), (20, 20) with all four colors
295 ctx
.drawImage(imageBitmap
, 0, 0, 20, 20);
297 shouldBeGreen(11, 8);
299 shouldBeBlack(11, 11);
300 shouldBeBlack(18, 18);
301 shouldBeClear(22, 22);
302 shouldBeClear(1, 21);
303 shouldBeClear(21, 1);
306 function checkCropRight(imageBitmap
) {
307 debug("Check crop right.");
308 bitmap
= imageBitmap
;
309 shouldBeType("bitmap", "ImageBitmap");
310 shouldBe("bitmap.width", "10");
311 shouldBe("bitmap.height", "10");
313 // black should be drawn to (0, 0), (10, 10)
315 ctx
.drawImage(imageBitmap
, 0, 0);
318 shouldBeClear(11, 11);
319 shouldBeClear(1, 11);
320 shouldBeClear(11, 1);
323 function checkOverCrop(imageBitmap
) {
324 debug("Check over crop.");
325 bitmap
= imageBitmap
;
326 shouldBeType("bitmap", "ImageBitmap");
327 shouldBe("bitmap.width", "60");
328 shouldBe("bitmap.height", "60");
330 // should be drawn to (10, 10), (30, 30)
332 ctx
.drawImage(imageBitmap
, 0, 0);
337 shouldBeGreen(21, 19);
338 shouldBeBlue(19, 21);
339 shouldBeBlack(21, 21);
340 shouldBeBlack(29, 29);
341 shouldBeClear(32, 1);
342 shouldBeClear(1, 32);
343 shouldBeClear(32, 32);
345 // should be drawn to (5, 5), (15, 15)
347 ctx
.drawImage(imageBitmap
, 0, 0, 30, 30);
352 shouldBeGreen(11, 9);
354 shouldBeBlack(11, 11);
355 shouldBeBlack(14, 14);
356 shouldBeClear(16, 1);
357 shouldBeClear(1, 16);
358 shouldBeClear(16, 16);
361 function checkOverCropRight(imageBitmap
) {
362 debug("Check over crop right.");
363 bitmap
= imageBitmap
;
364 shouldBe("bitmap.width", "50");
365 shouldBe("bitmap.height", "50");
367 // black should be drawn to (0, 0), (10, 10)
369 ctx
.drawImage(imageBitmap
, 0, 0);
372 shouldBeClear(11, 11);
373 shouldBeClear(1, 11);
374 shouldBeClear(11, 1);
376 // black should be drawn to (0, 0), (4, 4)
378 ctx
.drawImage(imageBitmap
, 0, 0, 20, 20);
385 // nothing should be drawn
387 ctx
.drawImage(imageBitmap
, 10, 10, 20, 20, 0, 0, 20, 20);
395 function checkEmpty(imageBitmap
) {
396 debug("Check empty.");
397 bitmap
= imageBitmap
;
398 shouldBeType("bitmap", "ImageBitmap");
399 shouldBe("bitmap.width", "30");
400 shouldBe("bitmap.height", "30");
402 // nothing should be drawn
404 ctx
.drawImage(imageBitmap
, 0, 0);
407 shouldBeClear(11, 11);
408 shouldBeClear(22, 22);