function _valToString(val) { if (val === undefined || val === null) return '[' + typeof(val) + ']'; return val.toString() + '[' + typeof(val) + ']'; } var _hex2dec_table = { 0:0, 1:1, 2:2, 3:3, 4:4, 5:5, 6:6, 7:7, 8:8, 9:9, a:10, b:11, c:12, d:13, e:14, f:15, A:10, B:11, C:12, D:13, E:14, F:15 }; function _hex2dec(hex) { return _hex2dec_table[hex.charAt(0)]*16 + _hex2dec_table[hex.charAt(1)]; } var _failed = false; var _asserted = false; function _warn(text) { document.getElementById('d').appendChild(document.createElement('li')).appendChild(document.createTextNode(text)); } function _fail(text) { _warn(text); _failed = true; } function _assert(cond, text) { _asserted = true; if (! cond) _fail('Failed assertion: ' + text); } function _assertSame(a, b, text_a, text_b) { _asserted = true; if (a !== b) _fail('Failed assertion ' + text_a + ' === ' + text_b + ' (got ' + _valToString(a) + ', expected ' + _valToString(b) + ')'); } function _assertDifferent(a, b, text_a, text_b) { _asserted = true; if (a === b) _fail('Failed assertion ' + text_a + ' !== ' + text_b + ' (got ' + _valToString(a) + ', expected not ' + _valToString(b) + ')'); } function _assertEqual(a, b, text_a, text_b) { _asserted = true; if (a != b) _fail('Failed assertion ' + text_a + ' == ' + text_b + ' (got ' + _valToString(a) + ', expected ' + _valToString(b) + ')'); } function _assertMatch(a, b, text_a, text_b) { _asserted = true; if (! a.match(b)) _fail('Failed assertion ' + text_a + ' matches ' + text_b + ' (got ' + _valToString(a) + ')'); } var _manual_check = false; function _requireManualCheck() { _manual_check = true; } function _crash() { _fail('Aborted due to predicted crash'); } var _getImageDataCalibrated = false; var _getImageDataIsPremul, _getImageDataIsBGRA; function _getPixel(canvas, x,y) { var ctx = canvas.getContext('2d'); if (ctx && typeof(ctx.getImageData) != 'undefined') { try { var imgdata = ctx.getImageData(x, y, 1, 1); } catch (e) { // probably a security exception caused by having drawn // data: URLs onto the canvas imgdata = null; } if (imgdata) { // Work around getImageData bugs, since we want the other tests to // carry on working as well as possible if (! _getImageDataCalibrated) { var c2 = document.createElement('canvas'); c2.width = c2.height = 1; var ctx2 = c2.getContext('2d'); ctx2.fillStyle = 'rgba(0, 255, 255, 0.5)'; ctx2.fillRect(0, 0, 1, 1); var data2 = ctx2.getImageData(0, 0, 1, 1).data; // Firefox returns premultiplied alpha if (data2[1] > 100 && data2[1] < 150) _getImageDataIsPremul = true; else _getImageDataIsPremul = false; // Opera Mini 4 Beta returns BGRA instead of RGBA if (data2[0] > 250 && data2[2] < 5) _getImageDataIsBGRA = true; else _getImageDataIsBGRA = false; _getImageDataCalibrated = true; } // Undo the BGRA flipping var rgba = (_getImageDataIsBGRA ? [ imgdata.data[2], imgdata.data[1], imgdata.data[0], imgdata.data[3] ] : [ imgdata.data[0], imgdata.data[1], imgdata.data[2], imgdata.data[3] ]); if (! _getImageDataIsPremul) return rgba; // Undo the premultiplying if (rgba[3] == 0) return [ 0, 0, 0, 0 ]; else { var a = rgba[3] / 255; return [ Math.round(rgba[0]/a), Math.round(rgba[1]/a), Math.round(rgba[2]/a), rgba[3] ]; } } } try { ctx = canvas.getContext('opera-2dgame'); } catch (e) { /* Firefox throws */ } if (ctx && typeof(ctx.getPixel) != 'undefined') { try { var c = ctx.getPixel(x, y); } catch (e) { // probably a security exception caused by having drawn // data: URLs onto the canvas c = null; } if (c) { var matches = /^rgba\((\d+), (\d+), (\d+), ([\d\.]+)\)$/.exec(c); if (matches) return [ matches[1], matches[2], matches[3], Math.round(matches[4]*255) ]; matches = /^#(..)(..)(..)$/.exec(c); if (matches) return [ _hex2dec(matches[1]), _hex2dec(matches[2]), _hex2dec(matches[3]), 255 ]; } } //_warn("(Can't test pixel value)"); _manual_check = true; return undefined; } function _assertPixel(canvas, x,y, r,g,b,a, pos, colour) { _asserted = true; var c = _getPixel(canvas, x,y); if (c && ! (c[0] == r && c[1] == g && c[2] == b && c[3] == a)) _fail('Failed assertion: got pixel [' + c + '] at ('+x+','+y+'), expected ['+r+','+g+','+b+','+a+']'); } function _assertPixelApprox(canvas, x,y, r,g,b,a, pos, colour, tolerance) { _asserted = true; var c = _getPixel(canvas, x,y); if (c) { var diff = Math.max(Math.abs(c[0]-r), Math.abs(c[1]-g), Math.abs(c[2]-b), Math.abs(c[3]-a)); if (diff > tolerance) _fail('Failed assertion: got pixel [' + c + '] at ('+x+','+y+'), expected ['+r+','+g+','+b+','+a+'] +/- '+tolerance); } } function _addTest(test) { var deferred = false; window.deferTest = function () { deferred = true; }; function endTest() { if (_failed) // test failed { document.documentElement.className += ' fail'; window._testStatus = ['fail', document.getElementById('d').innerHTML]; } else if (_manual_check || !_asserted) { // test case explicitly asked for a manual check, or no automatic assertions were performed document.getElementById('d').innerHTML += '