OLD | NEW |
| (Empty) |
1 <!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//EN"> | |
2 <html> | |
3 <head> | |
4 <script src="../../resources/js-test.js"></script> | |
5 </head> | |
6 <body> | |
7 <script> | |
8 | |
9 description("Ensure correct behavior of drawImage with ImageBitmaps along with f
lipY option."); | |
10 window.jsTestIsAsync = true; | |
11 | |
12 function jsWrapperClass(node) | |
13 { | |
14 // returns the ClassName of node | |
15 if (!node) | |
16 return "[null]"; | |
17 var string = Object.prototype.toString.apply(node); | |
18 | |
19 // string will be of the form [object ClassName] | |
20 return string.substr(8, string.length - 9); | |
21 } | |
22 | |
23 function shouldBeType(expression, className) | |
24 { | |
25 shouldBe("jsWrapperClass(" + expression + ")", "'" + className + "'"); | |
26 } | |
27 | |
28 function shouldNotBeCalled() { | |
29 testFailed("createImageBitmap promise rejected."); | |
30 finishJSTest(); | |
31 } | |
32 | |
33 function shouldBeRed(x, y) { | |
34 d = ctx.getImageData(x, y, 1, 1).data; | |
35 if (d[0] == 255 && d[1] == 0 && d[2] == 0 && d[3] == 255) { | |
36 testPassed("This pixel is red."); | |
37 return; | |
38 } | |
39 testFailed("This pixel is expected to be red, but it is actually " + d); | |
40 } | |
41 | |
42 function shouldBeGreen(x, y) { | |
43 d = ctx.getImageData(x, y, 1, 1).data; | |
44 if (d[0] == 0 && d[1] == 255 && d[2] == 0 && d[3] == 255) { | |
45 testPassed("This pixel is green."); | |
46 return; | |
47 } | |
48 testFailed("This pixel is expected to be green, but it is actually " + d); | |
49 } | |
50 | |
51 function shouldBeBlue(x, y) { | |
52 d = ctx.getImageData(x, y, 1, 1).data; | |
53 if (d[0] == 0 && d[1] == 0 && d[2] == 255 && d[3] == 255) { | |
54 testPassed("This pixel is blue."); | |
55 return; | |
56 } | |
57 testFailed("This pixel is expected to be blue, but it is actually " + d); | |
58 } | |
59 | |
60 function shouldBeBlack(x, y) { | |
61 d = ctx.getImageData(x, y, 1, 1).data; | |
62 if (d[0] == 0 && d[1] == 0 && d[2] == 0 && d[3] == 255) { | |
63 testPassed("This pixel is black."); | |
64 return; | |
65 } | |
66 testFailed("This pixel is expected to be black, but it is actually " + d); | |
67 } | |
68 | |
69 function shouldBeClear(x, y) { | |
70 // should be transparent black pixels | |
71 d = ctx.getImageData(x, y, 1, 1).data; | |
72 if (d[0] == 0 && d[1] == 0 && d[2] == 0 && d[3] == 0) { | |
73 testPassed("This pixel is transparent black."); | |
74 return; | |
75 } | |
76 testFailed("This pixel is expected to be transparent black, but it is actual
ly " + d); | |
77 } | |
78 | |
79 function drawPattern(ctx) { | |
80 // Draw a four-color pattern | |
81 ctx.beginPath(); | |
82 ctx.fillStyle = "rgb(255, 0, 0)"; | |
83 ctx.fillRect(0, 0, 10, 10); | |
84 ctx.fillStyle = "rgb(0, 255, 0)"; | |
85 ctx.fillRect(10, 0, 10, 10); | |
86 ctx.fillStyle = "rgb(0, 0, 255)"; | |
87 ctx.fillRect(0, 10, 10, 10); | |
88 ctx.fillStyle = "rgb(0, 0, 0)"; | |
89 ctx.fillRect(10, 10, 10, 10); | |
90 } | |
91 | |
92 function clearContext(context) { | |
93 context.clearRect(0, 0, 50, 50); | |
94 } | |
95 | |
96 var bitmap; | |
97 var image; | |
98 var testBitmap; // this is an ImageBitmap that is uncropped. We use this to test
createImageBitmap(testBitmap) | |
99 var d; // image.imageData | |
100 var elements; | |
101 var options; | |
102 | |
103 var imageWidth = 20; | |
104 var imageHeight = 20; | |
105 | |
106 // Draw to an auxillary canvas. | |
107 var aCanvas = document.createElement("canvas"); | |
108 aCanvas.width = imageWidth; | |
109 aCanvas.height = imageHeight; | |
110 var aCtx = aCanvas.getContext("2d"); | |
111 drawPattern(aCtx); | |
112 | |
113 var canvas = document.createElement("canvas"); | |
114 canvas.setAttribute("width", "50"); | |
115 canvas.setAttribute("height", "50"); | |
116 var ctx = canvas.getContext("2d"); | |
117 | |
118 image = new Image(); | |
119 image.onload = imageLoaded; | |
120 image.src = aCanvas.toDataURL(); | |
121 | |
122 var imageLoaded = false; | |
123 var imageBitmapLoaded = false; | |
124 var blobLoaded = false; | |
125 | |
126 function imageLoaded() { | |
127 createImageBitmap(image).then(imageBitmapLoadedCallback, shouldNotBeCalled); | |
128 d = aCtx.getImageData(0, 0, 20, 20); | |
129 imageLoaded = true; | |
130 loaded(); | |
131 } | |
132 | |
133 function imageBitmapLoadedCallback(imageBitmap) { | |
134 testBitmap = imageBitmap; | |
135 | |
136 shouldBe("testBitmap.width", "imageWidth"); | |
137 shouldBe("testBitmap.height", "imageHeight"); | |
138 | |
139 // width and height are readonly | |
140 testBitmap.width = 42; | |
141 testBitmap.height = 42; | |
142 shouldBe("testBitmap.width", "imageWidth"); | |
143 shouldBe("testBitmap.height", "imageHeight"); | |
144 | |
145 imageBitmapLoaded = true; | |
146 loaded(); | |
147 } | |
148 | |
149 var xhr = new XMLHttpRequest(); | |
150 xhr.open("GET", 'resources/pattern.png'); | |
151 xhr.responseType = 'blob'; | |
152 xhr.send(); | |
153 xhr.onload = function() { | |
154 blob = xhr.response; | |
155 blobLoaded = true; | |
156 loaded(); | |
157 } | |
158 | |
159 function loaded() { | |
160 if (imageLoaded && imageBitmapLoaded && blobLoaded) { | |
161 // check all elements and all options | |
162 elements = [image, aCanvas, d, testBitmap, blob]; | |
163 options = ["none", "flipY"]; | |
164 // elements = [image, aCanvas, d, testBitmap, blob]; | |
165 // wait for callback to finish before each check to ensure synchronous b
ehavior | |
166 nextCheck(0, 0); | |
167 } | |
168 } | |
169 | |
170 function nextCheck(elementIndex, optionIndex) { | |
171 if (elementIndex == elements.length) { | |
172 finishJSTest(); | |
173 return; | |
174 } | |
175 var element = elements[elementIndex]; | |
176 imageBitmaps = {}; | |
177 debug("Checking " + jsWrapperClass(element) + " with imageOrientation: " + o
ptions[optionIndex] + "."); | |
178 var p1 = createImageBitmap(element, {imageOrientation: options[optionIndex]}
).then(function (image) { imageBitmaps.noCrop = image }); | |
179 var p2 = createImageBitmap(element, 0, 0, 10, 10, {imageOrientation: options
[optionIndex]}).then(function (image) { imageBitmaps.crop = image }); | |
180 var p3 = createImageBitmap(element, 5, 5, 10, 10, {imageOrientation: options
[optionIndex]}).then(function (image) { imageBitmaps.cropCenter = image }); | |
181 var p4 = createImageBitmap(element, 10, 10, 10, 10, {imageOrientation: optio
ns[optionIndex]}).then(function (image) { imageBitmaps.cropRight = image }); | |
182 var p5 = createImageBitmap(element, -10, -10, 60, 60, {imageOrientation: opt
ions[optionIndex]}).then(function (image) { imageBitmaps.overCrop = image }); | |
183 var p6 = createImageBitmap(element, 10, 10, 50, 50, {imageOrientation: optio
ns[optionIndex]}).then(function (image) { imageBitmaps.overCropRight = image }); | |
184 var p7 = createImageBitmap(element, 10, 10, -10, -10, {imageOrientation: opt
ions[optionIndex]}).then(function (image) { imageBitmaps.negativeCrop = image })
; | |
185 var p8 = createImageBitmap(element, -30, -30, 30, 30, {imageOrientation: opt
ions[optionIndex]}).then(function (image) { imageBitmaps.empty = image }); | |
186 var p9 = createImageBitmap(element, 40, 30, 30, 30, {imageOrientation: optio
ns[optionIndex]}).then(function (image) { imageBitmaps.emptyTwo = image }); | |
187 Promise.all([p1, p2, p3, p4, p5, p6, p7, p8, p9]).then(function() { | |
188 checkNoCrop(imageBitmaps.noCrop, options[optionIndex]); | |
189 checkCrop(imageBitmaps.crop, options[optionIndex]); | |
190 checkCropCenter(imageBitmaps.cropCenter, options[optionIndex]); | |
191 checkCropRight(imageBitmaps.cropRight, options[optionIndex]); | |
192 checkOverCrop(imageBitmaps.overCrop, options[optionIndex]); | |
193 checkOverCropRight(imageBitmaps.overCropRight, options[optionIndex]); | |
194 checkCrop(imageBitmaps.negativeCrop, options[optionIndex]); | |
195 checkEmpty(imageBitmaps.empty, options[optionIndex]); | |
196 checkEmpty(imageBitmaps.emptyTwo, options[optionIndex]); | |
197 if (optionIndex == 3) | |
198 nextCheck(elementIndex + 1, 0); | |
199 else | |
200 nextCheck(elementIndex, optionIndex + 1); | |
201 }, shouldNotBeCalled); | |
202 } | |
203 | |
204 function checkNoCrop(imageBitmap, option) { | |
205 debug("Check no crop."); | |
206 bitmap = imageBitmap; | |
207 shouldBeType("bitmap", "ImageBitmap"); | |
208 shouldBe("bitmap.width", "imageWidth"); | |
209 shouldBe("bitmap.height", "imageHeight"); | |
210 | |
211 clearContext(ctx); | |
212 ctx.drawImage(imageBitmap, 0, 0); | |
213 if (option == "flipY" || option == "bottomLeft") { | |
214 shouldBeBlue(9, 9); | |
215 shouldBeBlack(11, 9); | |
216 shouldBeRed(9, 11); | |
217 shouldBeGreen(11, 11); | |
218 shouldBeGreen(19, 19); | |
219 shouldBeClear(1, 21); | |
220 shouldBeClear(21, 1); | |
221 shouldBeClear(21, 21); | |
222 } else { | |
223 shouldBeRed(9, 9); | |
224 shouldBeGreen(11, 9); | |
225 shouldBeBlue(9, 11); | |
226 shouldBeBlack(11, 11); | |
227 shouldBeBlack(19, 19); | |
228 shouldBeClear(1, 21); | |
229 shouldBeClear(21, 1); | |
230 shouldBeClear(21, 21); | |
231 } | |
232 | |
233 clearContext(ctx); | |
234 ctx.drawImage(imageBitmap, 0, 0, 10, 10); | |
235 if (option == "flipY" || option == "bottomLeft") { | |
236 shouldBeBlue(4, 4); | |
237 shouldBeBlack(6, 4); | |
238 shouldBeRed(4, 6); | |
239 shouldBeGreen(6, 6); | |
240 shouldBeGreen(9, 9); | |
241 shouldBeClear(1, 11); | |
242 shouldBeClear(11, 1); | |
243 shouldBeClear(11, 11); | |
244 } else { | |
245 shouldBeRed(4, 4); | |
246 shouldBeGreen(6, 4); | |
247 shouldBeBlue(4, 6); | |
248 shouldBeBlack(6, 6); | |
249 shouldBeBlack(9, 9); | |
250 shouldBeClear(1, 11); | |
251 shouldBeClear(11, 1); | |
252 shouldBeClear(11, 11); | |
253 } | |
254 | |
255 clearContext(ctx); | |
256 ctx.drawImage(imageBitmap, 10, 10, 10, 10); | |
257 if (option == "flipY" || option == "bottomLeft") { | |
258 shouldBeBlue(14, 14); | |
259 shouldBeBlack(16, 14); | |
260 shouldBeRed(14, 16); | |
261 shouldBeGreen(16, 16); | |
262 shouldBeGreen(19, 19); | |
263 shouldBeClear(11, 21); | |
264 shouldBeClear(21, 11); | |
265 shouldBeClear(21, 21); | |
266 } else { | |
267 shouldBeRed(14, 14); | |
268 shouldBeGreen(16, 14); | |
269 shouldBeBlue(14, 16); | |
270 shouldBeBlack(16, 16); | |
271 shouldBeBlack(19, 19); | |
272 shouldBeClear(11, 21); | |
273 shouldBeClear(21, 11); | |
274 shouldBeClear(21, 21); | |
275 } | |
276 | |
277 clearContext(ctx); | |
278 ctx.drawImage(imageBitmap, 10, 10, 10, 10, 10, 10, 10, 10); | |
279 if (option == "flipY" || option == "bottomLeft") { | |
280 shouldBeClear(9, 9); | |
281 shouldBeGreen(11, 11); | |
282 shouldBeGreen(19, 19); | |
283 shouldBeClear(1, 21); | |
284 shouldBeClear(21, 1); | |
285 shouldBeClear(21, 21); | |
286 } else { | |
287 shouldBeClear(9, 9); | |
288 shouldBeBlack(11, 11); | |
289 shouldBeBlack(19, 19); | |
290 shouldBeClear(1, 21); | |
291 shouldBeClear(21, 1); | |
292 shouldBeClear(21, 21); | |
293 } | |
294 } | |
295 | |
296 function checkCrop(imageBitmap, option) { | |
297 debug("Check crop."); | |
298 bitmap = imageBitmap; | |
299 shouldBeType("bitmap", "ImageBitmap"); | |
300 shouldBe("bitmap.width", "10"); | |
301 shouldBe("bitmap.height", "10"); | |
302 | |
303 clearContext(ctx); | |
304 ctx.drawImage(imageBitmap, 0, 0); | |
305 if (option == "flipY" || option == "bottomLeft") { | |
306 shouldBeRed(1, 1); | |
307 shouldBeRed(9, 9); | |
308 shouldBeClear(12, 12); | |
309 shouldBeClear(1, 12); | |
310 shouldBeClear(12, 1); | |
311 } else { | |
312 shouldBeRed(1, 1); | |
313 shouldBeRed(9, 9); | |
314 shouldBeClear(12, 12); | |
315 shouldBeClear(1, 12); | |
316 shouldBeClear(12, 1); | |
317 } | |
318 | |
319 clearContext(ctx); | |
320 ctx.drawImage(imageBitmap, 0, 0, 20, 20); | |
321 if (option == "flipY" || option == "bottomLeft") { | |
322 shouldBeRed(1, 1); | |
323 shouldBeRed(18, 18); | |
324 shouldBeClear(22, 22); | |
325 shouldBeClear(1, 22); | |
326 shouldBeClear(22, 1); | |
327 } else { | |
328 shouldBeRed(1, 1); | |
329 shouldBeRed(18, 18); | |
330 shouldBeClear(22, 22); | |
331 shouldBeClear(1, 22); | |
332 shouldBeClear(22, 1); | |
333 } | |
334 } | |
335 | |
336 function checkCropCenter(imageBitmap, option) { | |
337 debug("Check crop center."); | |
338 bitmap = imageBitmap; | |
339 shouldBeType("bitmap", "ImageBitmap"); | |
340 shouldBe("bitmap.width", "10"); | |
341 shouldBe("bitmap.height", "10"); | |
342 | |
343 clearContext(ctx); | |
344 ctx.drawImage(imageBitmap, 0, 0); | |
345 if (option == "flipY" || option == "bottomLeft") { | |
346 shouldBeBlue(4, 4); | |
347 shouldBeBlack(6, 4); | |
348 shouldBeRed(4, 6); | |
349 shouldBeGreen(6, 6); | |
350 shouldBeGreen(9, 9); | |
351 shouldBeClear(11, 11); | |
352 shouldBeClear(1, 11); | |
353 shouldBeClear(11, 1); | |
354 } else { | |
355 shouldBeRed(4, 4); | |
356 shouldBeGreen(6, 4); | |
357 shouldBeBlue(4, 6); | |
358 shouldBeBlack(6, 6); | |
359 shouldBeBlack(9, 9); | |
360 shouldBeClear(11, 11); | |
361 shouldBeClear(1, 11); | |
362 shouldBeClear(11, 1); | |
363 } | |
364 | |
365 clearContext(ctx); | |
366 ctx.drawImage(imageBitmap, 0, 0, 20, 20); | |
367 if (option == "flipY" || option == "bottomLeft") { | |
368 shouldBeBlue(8, 8); | |
369 shouldBeBlack(11, 8); | |
370 shouldBeRed(8, 11); | |
371 shouldBeGreen(11, 11); | |
372 shouldBeGreen(18, 18); | |
373 shouldBeClear(22, 22); | |
374 shouldBeClear(1, 21); | |
375 shouldBeClear(21, 1); | |
376 } else { | |
377 shouldBeRed(8, 8); | |
378 shouldBeGreen(11, 8); | |
379 shouldBeBlue(8, 11); | |
380 shouldBeBlack(11, 11); | |
381 shouldBeBlack(18, 18); | |
382 shouldBeClear(22, 22); | |
383 shouldBeClear(1, 21); | |
384 shouldBeClear(21, 1); | |
385 } | |
386 } | |
387 | |
388 function checkCropRight(imageBitmap, option) { | |
389 debug("Check crop right."); | |
390 bitmap = imageBitmap; | |
391 shouldBeType("bitmap", "ImageBitmap"); | |
392 shouldBe("bitmap.width", "10"); | |
393 shouldBe("bitmap.height", "10"); | |
394 | |
395 clearContext(ctx); | |
396 ctx.drawImage(imageBitmap, 0, 0); | |
397 if (option == "flipY" || option == "bottomLeft") { | |
398 shouldBeBlack(1, 1); | |
399 shouldBeBlack(9, 9); | |
400 shouldBeClear(11, 11); | |
401 shouldBeClear(1, 11); | |
402 shouldBeClear(11, 1); | |
403 } else { | |
404 shouldBeBlack(1, 1); | |
405 shouldBeBlack(9, 9); | |
406 shouldBeClear(11, 11); | |
407 shouldBeClear(1, 11); | |
408 shouldBeClear(11, 1); | |
409 } | |
410 } | |
411 | |
412 function checkOverCrop(imageBitmap, option) { | |
413 debug("Check over crop."); | |
414 bitmap = imageBitmap; | |
415 shouldBeType("bitmap", "ImageBitmap"); | |
416 shouldBe("bitmap.width", "60"); | |
417 shouldBe("bitmap.height", "60"); | |
418 | |
419 clearContext(ctx); | |
420 ctx.drawImage(imageBitmap, 0, 0); | |
421 if (option == "flipY" || option == "bottomLeft") { | |
422 shouldBeClear(1, 59); | |
423 shouldBeClear(9, 51); | |
424 shouldBeBlue(10, 30); | |
425 shouldBeBlue(19, 39); | |
426 shouldBeBlack(20, 30); | |
427 shouldBeBlack(29, 39); | |
428 shouldBeRed(10, 40); | |
429 shouldBeRed(19, 49); | |
430 shouldBeGreen(20, 40); | |
431 shouldBeGreen(29, 49); | |
432 shouldBeClear(31, 59); | |
433 shouldBeClear(1, 29); | |
434 shouldBeClear(30, 30); | |
435 } else { | |
436 shouldBeClear(1, 1); | |
437 shouldBeClear(9, 9); | |
438 shouldBeRed(11, 11); | |
439 shouldBeRed(19, 19); | |
440 shouldBeGreen(21, 19); | |
441 shouldBeBlue(19, 21); | |
442 shouldBeBlack(21, 21); | |
443 shouldBeBlack(29, 29); | |
444 shouldBeClear(32, 1); | |
445 shouldBeClear(1, 32); | |
446 shouldBeClear(32, 32); | |
447 } | |
448 | |
449 clearContext(ctx); | |
450 ctx.drawImage(imageBitmap, 0, 0, 30, 30); | |
451 if (option == "flipY" || option == "bottomLeft") { | |
452 shouldBeClear(1, 29); | |
453 shouldBeClear(4, 25); | |
454 shouldBeBlue(5, 15); | |
455 shouldBeBlue(9, 19); | |
456 shouldBeBlack(10, 15); | |
457 shouldBeBlack(14, 19); | |
458 shouldBeRed(5, 21); | |
459 shouldBeRed(9, 24); | |
460 shouldBeGreen(11, 21); | |
461 shouldBeGreen(14, 24); | |
462 shouldBeClear(16, 29); | |
463 shouldBeClear(1, 14); | |
464 shouldBeClear(15, 15); | |
465 } else { | |
466 shouldBeClear(1, 1); | |
467 shouldBeClear(4, 4); | |
468 shouldBeRed(6, 6); | |
469 shouldBeRed(9, 9); | |
470 shouldBeGreen(11, 9); | |
471 shouldBeBlue(9, 11); | |
472 shouldBeBlack(11, 11); | |
473 shouldBeBlack(14, 14); | |
474 shouldBeClear(16, 1); | |
475 shouldBeClear(1, 16); | |
476 shouldBeClear(16, 16); | |
477 } | |
478 } | |
479 | |
480 function checkOverCropRight(imageBitmap, option) { | |
481 debug("Check over crop right."); | |
482 bitmap = imageBitmap; | |
483 shouldBe("bitmap.width", "50"); | |
484 shouldBe("bitmap.height", "50"); | |
485 | |
486 clearContext(ctx); | |
487 ctx.drawImage(imageBitmap, 0, 0); | |
488 if (option == "flipY" || option == "bottomLeft") { | |
489 shouldBeBlack(1, 40); | |
490 shouldBeBlack(9, 49); | |
491 shouldBeClear(10, 49); | |
492 shouldBeClear(1, 39); | |
493 shouldBeClear(10, 40); | |
494 } else { | |
495 shouldBeBlack(1, 1); | |
496 shouldBeBlack(9, 9); | |
497 shouldBeClear(11, 11); | |
498 shouldBeClear(1, 11); | |
499 shouldBeClear(11, 1); | |
500 } | |
501 | |
502 clearContext(ctx); | |
503 ctx.drawImage(imageBitmap, 0, 0, 20, 20); | |
504 if (option == "flipY" || option == "bottomLeft") { | |
505 shouldBeBlack(0, 16); | |
506 shouldBeBlack(3, 19); | |
507 shouldBeClear(4, 19); | |
508 shouldBeClear(0, 15); | |
509 shouldBeClear(4, 15); | |
510 } else { | |
511 shouldBeBlack(1, 1); | |
512 shouldBeBlack(3, 3); | |
513 shouldBeClear(5, 5); | |
514 shouldBeClear(1, 5); | |
515 shouldBeClear(5, 1); | |
516 } | |
517 | |
518 clearContext(ctx); | |
519 ctx.drawImage(imageBitmap, 10, 10, 20, 20, 0, 0, 20, 20); | |
520 if (option == "flipY" || option == "bottomLeft") { | |
521 shouldBeClear(1, 1); | |
522 shouldBeClear(3, 3); | |
523 shouldBeClear(5, 5); | |
524 shouldBeClear(1, 5); | |
525 shouldBeClear(5, 1); | |
526 } else { | |
527 shouldBeClear(1, 1); | |
528 shouldBeClear(3, 3); | |
529 shouldBeClear(5, 5); | |
530 shouldBeClear(1, 5); | |
531 shouldBeClear(5, 1); | |
532 } | |
533 } | |
534 | |
535 // For an empty image, the orientation doesn't matter | |
536 function checkEmpty(imageBitmap, option) { | |
537 debug("Check empty."); | |
538 bitmap = imageBitmap; | |
539 shouldBeType("bitmap", "ImageBitmap"); | |
540 shouldBe("bitmap.width", "30"); | |
541 shouldBe("bitmap.height", "30"); | |
542 | |
543 // nothing should be drawn | |
544 clearContext(ctx); | |
545 ctx.drawImage(imageBitmap, 0, 0); | |
546 shouldBeClear(1, 1); | |
547 shouldBeClear(9, 9); | |
548 shouldBeClear(11, 11); | |
549 shouldBeClear(22, 22); | |
550 } | |
551 </script> | |
552 </body> | |
553 </html> | |
OLD | NEW |