| OLD | NEW |
| 1 <html> | 1 <html> |
| 2 <head> | 2 <head> |
| 3 <title>A canvas globalCompositeOperation test with alpha blending</title> | 3 <title>A canvas globalCompositeOperation test with alpha compositing on text
</title> |
| 4 <!-- This test was inspired by http://canvex.lazyilluminati.com/misc/composi
tex.html --> | 4 <!-- This test was inspired by http://canvex.lazyilluminati.com/misc/composi
tex.html --> |
| 5 <script type="application/x-javascript"> | 5 <script type="application/x-javascript"> |
| 6 if (window.testRunner) { | 6 if (window.testRunner) { |
| 7 testRunner.dumpAsText(); | 7 testRunner.dumpAsText(); |
| 8 testRunner.waitUntilDone(); | 8 testRunner.waitUntilDone(); |
| 9 } | 9 } |
| 10 | 10 |
| 11 var compositeTypes = [ | 11 var compositeTypes = [ |
| 12 'source-over','source-in','source-out','source-atop', | 12 'source-over','source-in','source-out','source-atop', |
| 13 'destination-over','destination-in','destination-out','destination-ato
p', | 13 'destination-over','destination-in','destination-out','destination-ato
p', |
| (...skipping 292 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 306 trCanvasElement.appendChild(tdElement); | 306 trCanvasElement.appendChild(tdElement); |
| 307 | 307 |
| 308 // Create div element for pass/fail messages. | 308 // Create div element for pass/fail messages. |
| 309 var messageElement = document.createElement("div"); | 309 var messageElement = document.createElement("div"); |
| 310 tdElement = document.createElement("td"); | 310 tdElement = document.createElement("td"); |
| 311 tdElement.setAttribute("colspan", "2"); | 311 tdElement.setAttribute("colspan", "2"); |
| 312 tdElement.appendChild(messageElement); | 312 tdElement.appendChild(messageElement); |
| 313 trMessageElement.appendChild(tdElement); | 313 trMessageElement.appendChild(tdElement); |
| 314 | 314 |
| 315 var ctx = expectedCanvasElement.getContext("2d"); | 315 var ctx = expectedCanvasElement.getContext("2d"); |
| 316 ctx.lineWidth = 10; | 316 ctx.lineWidth = 3; |
| 317 // Draw expected image. | 317 // Draw expected image. |
| 318 ctx.globalCompositeOperation = "copy"; | 318 ctx.globalCompositeOperation = "copy"; |
| 319 ctx.fillStyle = getRGBAString(expectedColor.destination); | 319 ctx.fillStyle = getRGBAString(expectedColor.destination); |
| 320 ctx.strokeStyle = getRGBAString(expectedColor.destination); | 320 ctx.strokeStyle = getRGBAString(expectedColor.destination); |
| 321 drawPolicy.drawDestination(ctx); | 321 drawPolicy.drawDestination(ctx); |
| 322 ctx.fillStyle = getRGBAString(expectedColor.source); | 322 ctx.fillStyle = getRGBAString(expectedColor.source); |
| 323 ctx.strokeStyle = getRGBAString(expectedColor.source); | 323 ctx.strokeStyle = getRGBAString(expectedColor.source); |
| 324 drawPolicy.drawSource(ctx); | 324 drawPolicy.drawSource(ctx); |
| 325 ctx.fillStyle = getRGBAString(expectedColor.composition); | 325 ctx.fillStyle = getRGBAString(expectedColor.composition); |
| 326 ctx.strokeStyle = getRGBAString(expectedColor.composition); | 326 ctx.strokeStyle = getRGBAString(expectedColor.composition); |
| 327 drawPolicy.drawComposition(ctx); | 327 drawPolicy.drawComposition(ctx); |
| 328 | 328 |
| 329 ctx = actualCanvasElement.getContext("2d"); | 329 ctx = actualCanvasElement.getContext("2d"); |
| 330 ctx.lineWidth = 10; | 330 ctx.lineWidth = 3; |
| 331 | 331 |
| 332 // Draw destination rectangle. | 332 // Draw destination rectangle. |
| 333 ctx.globalCompositeOperation = "copy"; | 333 ctx.globalCompositeOperation = "copy"; |
| 334 ctx.fillStyle = getRGBAString(inputColor.destination); | 334 ctx.fillStyle = getRGBAString(inputColor.destination); |
| 335 ctx.strokeStyle = getRGBAString(inputColor.destination); | 335 ctx.strokeStyle = getRGBAString(inputColor.destination); |
| 336 drawPolicy.drawDestination(ctx); | 336 drawPolicy.drawDestination(ctx); |
| 337 | 337 |
| 338 // Draw source rectangle. | 338 // Draw source rectangle. |
| 339 ctx.globalCompositeOperation = type; | 339 ctx.globalCompositeOperation = type; |
| 340 ctx.fillStyle = getRGBAString(inputColor.source); | 340 ctx.fillStyle = getRGBAString(inputColor.source); |
| 341 ctx.strokeStyle = getRGBAString(inputColor.source); | 341 ctx.strokeStyle = getRGBAString(inputColor.source); |
| 342 drawPolicy.drawSource(ctx); | 342 drawPolicy.drawSource(ctx); |
| 343 | 343 |
| 344 // Let's check if the results are expected or not. | 344 // Let's check if the results are expected or not. |
| 345 var errorSuffix = ", composite type: " + type + ", source: " +
inputColor.source + ", destination: " + inputColor.destination + "<br>"; | 345 var errorSuffix = ", composite type: " + type + ", source: " +
inputColor.source + ", destination: " + inputColor.destination + "<br>"; |
| 346 | 346 |
| 347 var results = ""; | 347 var results = ""; |
| 348 // Note that (0, 0) may be affected by anti-alias. | 348 // Note that (2, 3) may be affected by anti-alias. |
| 349 var img = ctx.getImageData(1, 1, 1, 1).data; | 349 var img = ctx.getImageData(3, 4, 1, 1).data; |
| 350 var actualColor = [img[0], img[1], img[2], img[3]]; | 350 var actualColor = [img[0], img[1], img[2], img[3]]; |
| 351 if (isDifferentColor(actualColor, expectedColor.source)) { | 351 if (isDifferentColor(actualColor, expectedColor.source)) { |
| 352 results += "Unexpected source! expected: " + expectedColor
.source + " actual: " + actualColor + errorSuffix; | 352 results += "Unexpected source! expected: " + expectedColor
.source + " actual: " + actualColor + errorSuffix; |
| 353 } | 353 } |
| 354 // Note that (24, 24) may be affected by anti-alias. | 354 // Note that (24, 24) may be affected by anti-alias. |
| 355 img = ctx.getImageData(23, 23, 1, 1).data; | 355 img = ctx.getImageData(23, 23, 1, 1).data; |
| 356 actualColor = [img[0], img[1], img[2], img[3]]; | 356 actualColor = [img[0], img[1], img[2], img[3]]; |
| 357 if (isDifferentColor(actualColor, expectedColor.destination))
{ | 357 if (isDifferentColor(actualColor, expectedColor.destination))
{ |
| 358 results += "Unexpected destination! expected: " + expected
Color.destination + " actual: " + actualColor + errorSuffix; | 358 results += "Unexpected destination! expected: " + expected
Color.destination + " actual: " + actualColor + errorSuffix; |
| 359 } | 359 } |
| 360 img = ctx.getImageData(12, 12, 1, 1).data; | 360 img = ctx.getImageData(11, 12, 1, 1).data; |
| 361 actualColor = [img[0], img[1], img[2], img[3]]; | 361 actualColor = [img[0], img[1], img[2], img[3]]; |
| 362 if (isDifferentColor(actualColor, expectedColor.composition))
{ | 362 if (isDifferentColor(actualColor, expectedColor.composition))
{ |
| 363 results += "Unexpected composition! expected: " + expected
Color.composition + " actual: " + actualColor + errorSuffix; | 363 results += "Unexpected composition! expected: " + expected
Color.composition + " actual: " + actualColor + errorSuffix; |
| 364 } | 364 } |
| 365 | 365 |
| 366 if (results == "") { | 366 if (results == "") { |
| 367 messageElement.style.backgroundColor = "green"; | 367 messageElement.style.backgroundColor = "green"; |
| 368 messageElement.innerHTML = results = "PASS"; | 368 messageElement.innerHTML = results = "PASS"; |
| 369 } else { | 369 } else { |
| 370 messageElement.style.backgroundColor = "red"; | 370 messageElement.style.backgroundColor = "red"; |
| 371 messageElement.innerHTML = results; | 371 messageElement.innerHTML = results; |
| 372 } | 372 } |
| 373 | 373 |
| 374 // Dump colors into text area for debugging purpose. | 374 // Dump colors into text area for debugging purpose. |
| 375 var debugText = document.getElementById("debug"); | 375 var debugText = document.getElementById("debug"); |
| 376 img = ctx.getImageData(0, 0, 1, 1).data; | 376 img = ctx.getImageData(0, 0, 1, 1).data; |
| 377 debugText.value += img[0] + "," + img[1] + "," + img[2] + ","
+ img[3] + "\n"; | 377 debugText.value += img[0] + "," + img[1] + "," + img[2] + ","
+ img[3] + "\n"; |
| 378 img = ctx.getImageData(12, 12, 1, 1).data; | 378 img = ctx.getImageData(12, 12, 1, 1).data; |
| 379 debugText.value += img[0] + "," + img[1] + "," + img[2] + ","
+ img[3] + "\n"; | 379 debugText.value += img[0] + "," + img[1] + "," + img[2] + ","
+ img[3] + "\n"; |
| 380 img = ctx.getImageData(24, 24, 1, 1).data; | 380 img = ctx.getImageData(24, 24, 1, 1).data; |
| 381 debugText.value += img[0] + "," + img[1] + "," + img[2] + ","
+ img[3] + "\n"; | 381 debugText.value += img[0] + "," + img[1] + "," + img[2] + ","
+ img[3] + "\n"; |
| 382 } | 382 } |
| 383 } | 383 } |
| 384 } | 384 } |
| 385 | 385 |
| 386 var useStrokeRect = { | 386 var useFillText = { |
| 387 drawSource: function(ctx) { | 387 drawSource: function(ctx) { |
| 388 ctx.strokeRect(5, 5, 10, 10); | 388 ctx.font="bold 20px arial"; |
| 389 ctx.fillText("B", 0, 18); |
| 389 }, | 390 }, |
| 390 | 391 |
| 391 drawDestination: function(ctx) { | 392 drawDestination: function(ctx) { |
| 392 ctx.fillRect(5, 5, 20, 20); | 393 ctx.fillRect(5, 5, 20, 20); |
| 393 }, | 394 }, |
| 394 | 395 |
| 395 drawComposition: function(ctx) { | 396 drawComposition: function(ctx) { |
| 396 ctx.fillRect(5, 5, 15, 15); | 397 ctx.fillRect(5, 5, 15, 15); |
| 397 }, | 398 }, |
| 398 | 399 |
| 399 name: "stroke rect" | 400 name: "fill text" |
| 400 }; | 401 }; |
| 401 | 402 |
| 402 var usePathAndStroke = { | 403 var useStrokeText = { |
| 403 drawSource: function(ctx) { | 404 drawSource: function(ctx) { |
| 404 ctx.beginPath(); | 405 ctx.font="bold 20px arial"; |
| 405 ctx.moveTo(5, 5); | 406 ctx.strokeText("B", 0, 18); |
| 406 ctx.lineTo(15, 5); | |
| 407 ctx.lineTo(15, 15); | |
| 408 ctx.lineTo(5, 15); | |
| 409 ctx.closePath(); | |
| 410 ctx.stroke(); | |
| 411 }, | 407 }, |
| 412 | 408 |
| 413 drawDestination: function(ctx) { | 409 drawDestination: function(ctx) { |
| 414 ctx.fillRect(5, 5, 20, 20); | 410 ctx.fillRect(5, 5, 20, 20); |
| 415 }, | 411 }, |
| 416 | 412 |
| 417 drawComposition: function(ctx) { | 413 drawComposition: function(ctx) { |
| 418 ctx.fillRect(5, 5, 15, 15); | 414 ctx.fillRect(5, 5, 15, 15); |
| 419 }, | 415 }, |
| 420 | 416 |
| 421 name: "path and stroke" | 417 name: "stroke text" |
| 422 }; | 418 }; |
| 423 | 419 |
| 424 function draw() | 420 function draw() |
| 425 { | 421 { |
| 426 drawTable(useStrokeRect); | 422 drawTable(useFillText); |
| 427 drawTable(usePathAndStroke); | 423 drawTable(useStrokeText); |
| 428 if (window.testRunner) | 424 if (window.testRunner) |
| 429 testRunner.notifyDone(); | 425 testRunner.notifyDone(); |
| 430 } | 426 } |
| 431 </script> | 427 </script> |
| 432 <style type="text/css"> | 428 <style type="text/css"> |
| 433 body { margin: 20px; font-family: arial,verdana,helvetica; background: #ff
f;} | 429 body { margin: 20px; font-family: arial,verdana,helvetica; background: #ff
f;} |
| 434 h1 { font-size: 140%; font-weight:normal; color: #036; border-bottom: 1px
solid #ccc; } | 430 h1 { font-size: 140%; font-weight:normal; color: #036; border-bottom: 1px
solid #ccc; } |
| 435 canvas { border: 2px solid #000; margin-bottom: 5px; } | 431 canvas { border: 2px solid #000; margin-bottom: 5px; } |
| 436 table { background: #00f; } | 432 table { background: #00f; } |
| 437 th { font-size: 70%; padding: 0; } | 433 th { font-size: 70%; padding: 0; } |
| 438 td { font-size: 70%; padding: 0; } | 434 td { font-size: 70%; padding: 0; } |
| 439 pre { float:left; display:block; background: rgb(238,238,238); border: 1px
dashed #666; padding: 15px 20px; margin: 0 0 10px 0; } | 435 pre { float:left; display:block; background: rgb(238,238,238); border: 1px
dashed #666; padding: 15px 20px; margin: 0 0 10px 0; } |
| 440 </style> | 436 </style> |
| 441 </head> | 437 </head> |
| 442 <body onload="draw();"> | 438 <body onload="draw();"> |
| 443 <p>This test exercises a bunch of alpha composition checks with stroking. Th
e top-left rectangles are the source images and bottom-right rectangles are the
destination images.</p> | 439 <p>This test exercises a bunch of alpha composition operations on text. The
top-left rectangles are the source images and bottom-right rectangles are the de
stination images.</p> |
| 444 <div id="results"> | 440 <div id="results"> |
| 445 </div> | 441 </div> |
| 446 <textarea id="debug"></textarea> | 442 <textarea id="debug"></textarea> |
| 447 </body> | 443 </body> |
| 448 </html> | 444 </html> |
| OLD | NEW |