1 description("Series of tests to ensure correct results on applying different blend modes.");
3 var tmpimg = document.createElement('canvas');
6 ctx = tmpimg.getContext('2d');
8 // Create the image for blending test with images.
9 var img = document.createElement('canvas');
12 var imgCtx = img.getContext('2d');
13 imgCtx.fillStyle = "red";
14 imgCtx.fillRect(0,0,100,100);
15 imgCtx.fillStyle = "yellow";
16 imgCtx.fillRect(100,0,100,100);
17 imgCtx.fillStyle = "green";
18 imgCtx.fillRect(100,100,100,100);
19 imgCtx.fillStyle = "blue";
20 imgCtx.fillRect(0,100,100,100);
22 // Create expected results.
24 // [blendMode, expectations solid on solid, expectations solid on alpha, expectations alpha on solid, expectations alpha on alpha]
27 [[255, 0, 0, 255],[255, 255, 0, 255],[0, 128, 0, 255],[0, 0, 255, 255]],
28 [[128, 0, 127, 255],[128, 128, 127, 255],[0, 64, 127, 255],[0, 0, 255, 255]],
29 [[255, 0, 0, 255],[255, 255, 0, 255],[0, 128, 0, 255],[0, 0, 255, 255]],
30 [[171, 0, 84, 191],[171, 171, 84, 191],[0, 85, 84, 191],[0, 0, 255, 191]]
33 [[0, 0, 0, 255],[0, 0, 0, 255],[0, 0, 0, 255],[0, 0, 255, 255]],
34 [[0, 0, 127, 255],[0, 0, 127, 255],[0, 0, 127, 255],[0, 0, 255, 255]],
35 [[128, 0, 0, 255],[128, 128, 0, 255],[0, 64, 0, 255],[0, 0, 255, 255]],
36 [[85, 0, 84, 191],[85, 85, 84, 191],[0, 43, 84, 191],[0, 0, 255, 191]]
39 [[255, 0, 255, 255],[255, 255, 255, 255],[0, 128, 255, 255],[0, 0, 255, 255]],
40 [[128, 0, 255, 255],[128, 128, 255, 255],[0, 64, 255, 255],[0, 0, 255, 255]],
41 [[255, 0, 127, 255],[255, 255, 127, 255],[0, 128, 127, 255],[0, 0, 255, 255]],
42 [[171, 0, 170, 191],[171, 171, 170, 191],[0, 85, 170, 191],[0, 0, 255, 191]]
45 [[0, 0, 255, 255],[0, 0, 255, 255],[0, 0, 255, 255],[0, 0, 255, 255]],
46 [[0, 0, 255, 255],[0, 0, 255, 255],[0, 0, 255, 255],[0, 0, 255, 255]],
47 [[128, 0, 127, 255],[128, 128, 127, 255],[0, 64, 127, 255],[0, 0, 255, 255]],
48 [[85, 0, 170, 191],[85, 85, 170, 191],[0, 43, 170, 191],[0, 0, 255, 191]]
51 [[0, 0, 0, 255],[0, 0, 0, 255],[0, 0, 0, 255],[0, 0, 255, 255]],
52 [[0, 0, 127, 255],[0, 0, 127, 255],[0, 0, 127, 255],[0, 0, 255, 255]],
53 [[128, 0, 0, 255],[128, 128, 0, 255],[0, 64, 0, 255],[0, 0, 255, 255]],
54 [[85, 0, 84, 191],[85, 85, 84, 191],[0, 43, 84, 191],[0, 0, 255, 191]]
57 [[255, 0, 255, 255],[255, 255, 255, 255],[0, 128, 255, 255],[0, 0, 255, 255]],
58 [[128, 0, 255, 255],[128, 128, 255, 255],[0, 64, 255, 255],[0, 0, 255, 255]],
59 [[255, 0, 127, 255],[255, 255, 127, 255],[0, 128, 127, 255],[0, 0, 255, 255]],
60 [[171, 0, 170, 191],[171, 171, 170, 191],[0, 85, 170, 191],[0, 0, 255, 191]]
63 [[0, 0, 255, 255],[0, 0, 255, 255],[0, 0, 255, 255],[0, 0, 255, 255]],
64 [[0, 0, 255, 255],[0, 0, 255, 255],[0, 0, 255, 255],[0, 0, 255, 255]],
65 [[128, 0, 127, 255],[128, 128, 127, 255],[0, 64, 127, 255],[0, 0, 255, 255]],
66 [[85, 0, 170, 191],[85, 85, 170, 191],[0, 43, 170, 191],[0, 0, 255, 191]]
69 [[0, 0, 255, 255],[0, 0, 255, 255],[0, 0, 255, 255],[0, 0, 255, 255]],
70 [[0, 0, 255, 255],[0, 0, 255, 255],[0, 0, 255, 255],[0, 0, 255, 255]],
71 [[128, 0, 127, 255],[128, 128, 127, 255],[0, 64, 127, 255],[0, 0, 255, 255]],
72 [[85, 0, 170, 191],[85, 85, 170, 191],[0, 42, 170, 191],[0, 0, 255, 191]]
75 [[255, 0, 0, 255],[255, 255, 0, 255],[0, 1, 0, 255],[0, 0, 255, 255]],
76 [[128, 0, 127, 255],[128, 128, 127, 255],[0, 0, 127, 255],[0, 0, 255, 255]],
77 [[255, 0, 0, 255],[255, 255, 0, 255],[0, 65, 0, 255],[0, 0, 255, 255]],
78 [[171, 0, 84, 191],[171, 171, 84, 191],[0, 43, 84, 191],[0, 0, 255, 191]]
81 [[0, 0, 255, 255],[0, 0, 255, 255],[0, 0, 255, 255],[0, 0, 255, 255]],
82 [[0, 0, 255, 255],[0, 0, 255, 255],[0, 0, 255, 255],[0, 0, 255, 255]],
83 [[128, 0, 127, 255],[128, 128, 127, 255],[0, 64, 127, 255],[0, 0, 255, 255]],
84 [[85, 0, 170, 191],[85, 85, 170, 191],[0, 43, 170, 191],[0, 0, 255, 191]]
87 [[255, 0, 255, 255],[255, 255, 255, 255],[0, 128, 255, 255],[0, 0, 0, 255]],
88 [[128, 0, 255, 255],[128, 128, 255, 255],[0, 64, 255, 255],[0, 0, 127, 255]],
89 [[255, 0, 127, 255],[255, 255, 127, 255],[0, 128, 127, 255],[0, 0, 128, 255]],
90 [[171, 0, 170, 191],[171, 171, 170, 191],[0, 85, 170, 191],[0, 0, 171, 191]]
93 [[255, 0, 255, 255],[255, 255, 255, 255],[0, 128, 255, 255],[0, 0, 0, 255]],
94 [[128, 0, 255, 255],[128, 128, 255, 255],[0, 64, 255, 255],[0, 0, 127, 255]],
95 [[255, 0, 127, 255],[255, 255, 127, 255],[0, 128, 127, 255],[0, 0, 128, 255]],
96 [[171, 0, 170, 191],[171, 171, 170, 191],[0, 85, 170, 191],[0, 0, 171, 191]]
99 [[93, 0, 0, 255],[31, 31, 0, 255],[0, 46, 0, 255],[0, 0, 255, 255]],
100 [[49, 0, 127, 255],[16, 16, 127, 255],[0, 25, 127, 255],[0, 0, 255, 255]],
101 [[175, 0, 0, 255],[144, 144, 0, 255],[0, 88, 0, 255],[0, 0, 255, 255]],
102 [[116, 0, 84, 191],[96, 96, 84, 191],[0, 58, 84, 191],[0, 0, 255, 191]]
105 [[0, 0, 255, 255],[0, 0, 255, 255],[14, 14, 142, 255],[0, 0, 255, 255]],
106 [[0, 0, 255, 255],[0, 0, 255, 255],[7, 7, 198, 255],[0, 0, 255, 255]],
107 [[128, 0, 127, 255],[128, 128, 127, 255],[7, 71, 70, 255],[0, 0, 255, 255]],
108 [[85, 0, 167, 191],[85, 85, 167, 191],[0, 48, 130, 191],[0, 0, 255, 191]]
111 [[93, 0, 0, 255],[31, 31, 0, 255],[0, 47, 0, 255],[0, 0, 255, 255]],
112 [[49, 0, 127, 255],[16, 16, 127, 255],[0, 24, 127, 255],[0, 0, 255, 255]],
113 [[175, 0, 0, 255],[144, 144, 0, 255],[0, 88, 0, 255],[0, 0, 255, 255]],
114 [[116, 0, 84, 191],[96, 96, 84, 191],[0, 58, 84, 191],[0, 0, 255, 191]]
117 [[55, 55, 255, 255],[224, 224, 255, 255],[54, 54, 255, 255],[0, 0, 255, 255]],
118 [[28, 28, 255, 255],[112, 112, 255, 255],[27, 27, 255, 255],[0, 0, 255, 255]],
119 [[155, 27, 127, 255],[239, 239, 127, 255],[26, 90, 127, 255],[0, 0, 255, 255]],
120 [[104, 19, 167, 191],[158, 158, 167, 191],[16, 58, 167, 191],[0, 0, 255, 191]]
123 // [Scenario, alpha on background, alpha on foreground]
125 ['solid on solid', 1, 1],
126 ['solid on alpha', 1, 0.5],
127 ['alpha on solid', 0.5, 1],
128 ['alpha on alpha', 0.5, 0.5]
131 testPoints = [{x: 50, y: 50}, {x: 150, y: 50}, {x: 150, y: 150}, {x: 50, y: 150}];
133 function pixelDataAtPoint(i)
135 return ctx.getImageData(testPoints[i].x, testPoints[i].y , 1, 1).data;
138 function checkBlendModeResult(blendMode, testScenario, expectedColors, sigma) {
140 for (var i = 0; i < testPoints.length; i++) {
141 var resultColor = "pixelDataAtPoint(" + i + ")";
142 shouldBeCloseTo(resultColor +"[0]", expectedColors[i][0], sigma);
143 shouldBeCloseTo(resultColor +"[1]", expectedColors[i][1], sigma);
144 shouldBeCloseTo(resultColor +"[2]", expectedColors[i][2], sigma);
145 shouldBeCloseTo(resultColor +"[3]", expectedColors[i][3], sigma);
150 function prepareTestScenario(sigma) {
151 // Check each blend mode individually.
152 for (var i = 0; i < blendModes.length; i++) {
153 debug('Testing blend mode "' + blendModes[i][0] + '"');
154 for (var j = 0; j < testScenario.length; j++) {
155 ctx.clearRect(0,0,200,200);
159 ctx.fillStyle = 'rgba(0, 0, 255, ' + testScenario[j][1] + ')';
160 ctx.fillRect(0,0,200,200);
163 ctx.globalCompositeOperation = blendModes[i][0];
164 ctx.globalAlpha = testScenario[j][2];
165 ctx.drawImage(img, 0, 0);
167 checkBlendModeResult(blendModes[i][0], testScenario[j][0], blendModes[i][j+1], sigma);
174 // Run test and allow variation of results.
175 prepareTestScenario(5);