c56f4bceba08d1969435ae5d9776d30e89801723
[WebKit-https.git] / LayoutTests / fast / canvas / canvas-putImageData.js
1 description("This test ensures that putImageData works correctly, the end result should be a 100x100px green square.");
2
3 function fillRect(imageData, x, y, width, height, r, g, b, a)
4 {
5     var bytesPerRow = imageData.width * 4;
6     var data =imageData.data;
7     for (var i = 0; i < height; i++) {
8         var rowOrigin = (y+i) * bytesPerRow;
9         rowOrigin += x * 4;
10         for (var j = 0; j < width; j++) {
11             var position = rowOrigin + j * 4;
12             data[position + 0] = r;
13             data[position + 1] = g;
14             data[position + 2] = b;
15             data[position + 3] = a;
16         }
17     }
18 }
19
20 function dataToArray(data) {
21     var result = new Array(data.length)
22     for (var i = 0; i < data.length; i++)
23         result[i] = data[i];
24     return result;
25 }
26
27 function getPixel(x, y) {
28     var data = context.getImageData(x,y,1,1);
29     if (!data) // getImageData failed, which should never happen
30         return [-1,-1,-1,-1];
31     return dataToArray(data.data);
32 }
33
34 function pixelShouldBe(x, y, colour) {
35     shouldBe("getPixel(" + [x, y] +")", "["+colour+"]");
36 }
37
38 var canvas = document.getElementById("canvas");
39 var context = canvas.getContext("2d");
40
41 if (!context.createImageData)
42     context.createImageData = function(w,h) { 
43         var data = this.getImageData(0, 0, w, h);
44         for (var i = 0; i < data.data.length; i++)
45             data.data[i] = 0;
46     }
47 var buffer = context.createImageData(100,100);
48 // Fill top left corner
49 fillRect(buffer, 0, 0, 50, 50, 0, 128,0,255);
50 context.putImageData(buffer, 0, 0);
51 pixelShouldBe( 0,  0, [0, 128,0,255]);
52 pixelShouldBe(25, 25, [0, 128,0,255]);
53 pixelShouldBe(49,  0, [0, 128,0,255]);
54 pixelShouldBe( 0, 49, [0, 128,0,255]);
55 pixelShouldBe(49, 49, [0, 128,0,255]);
56 pixelShouldBe(50,  0, [0, 0, 0, 0]);
57 pixelShouldBe( 0, 50, [0, 0, 0, 0]);
58 pixelShouldBe(50, 50, [0, 0, 0, 0]);
59
60 // Test positioned drawing -- make bottom right green
61 context.putImageData(buffer, 0, 50);
62 pixelShouldBe( 0, 50, [0, 128,0,255]);
63 pixelShouldBe(25, 75, [0, 128,0,255]);
64 pixelShouldBe(49, 50, [0, 128,0,255]);
65 pixelShouldBe( 0, 99, [0, 128,0,255]);
66 pixelShouldBe(49, 99, [0, 128,0,255]);
67
68 // Test translation doesn't effect putImageData
69 context.translate(50, -50);
70 context.putImageData(buffer, 50, 50);
71 pixelShouldBe(50, 50, [0, 128,0,255]);
72 pixelShouldBe(75, 75, [0, 128,0,255]);
73 pixelShouldBe(99, 99, [0, 128,0,255]);
74 pixelShouldBe(50, 49, [0, 0, 0, 0]);
75 context.translate(-50, 50);
76
77 // Test dirty rect handling
78 buffer = context.createImageData(50,50);
79 fillRect(buffer, 0, 0, 50, 50, 0, 128, 0, 255);
80 context.putImageData(buffer, 50, 0);
81 fillRect(buffer, 0, 0, 50, 50, 255, 0, 0, 255);
82 context.putImageData(buffer, 50, 0, 15, 15, 20, 20);
83 context.fillStyle="rgb(0,128,0)";
84 context.fillRect(65, 15, 20, 20);
85 var points = [0, 5, 15, 25, 35, 45];
86 for (var x = 0; x < points.length; x++)
87     for (var y = 0; y < points.length; y++)
88         pixelShouldBe(points[x] + 50, points[y], [0, 128, 0, 255]);
89
90 // Test drawing outside the canvas border
91 fillRect(buffer, 0, 0, 50, 50, 255, 0, 0, 255);
92 context.putImageData(buffer, -50, 0);
93 pixelShouldBe(0, 25, [0, 128,0,255]);
94 context.putImageData(buffer, 100, 0);
95 pixelShouldBe(99, 25, [0, 128,0,255]);
96 context.putImageData(buffer, 0, -50);
97 pixelShouldBe(25, 0, [0, 128,0,255]);
98 context.putImageData(buffer, 0, 100);
99 pixelShouldBe(25, 99, [0, 128,0,255]);
100
101 // test drawing with non-intersecting dirty rect
102 context.putImageData(buffer, 50, 0,  50, 0, 100, 100);
103 context.putImageData(buffer, 50, 0, -50, 0, 50, 100);
104 context.putImageData(buffer, 50, 0,  0, 50, 100, 100);
105 context.putImageData(buffer, 50, 0,  50, -50, 100, 100);
106 for (var x = 0; x < points.length; x++)
107     for (var y = 0; y < points.length; y++)
108         pixelShouldBe(points[x] + 50, points[y], [0, 128, 0, 255]);
109
110 // Test drawing to region intersect edge of canvas
111 buffer = context.createImageData(100, 100);
112 fillRect(buffer, 0, 0, 100, 100, 0, 128, 0, 255);
113 fillRect(buffer, 10, 10, 80, 80, 255, 0, 0, 255);
114
115 //left edge
116 context.putImageData(buffer, -90, 0);
117 pixelShouldBe(0, 25, [0, 128,0,255]);
118 pixelShouldBe(0, 50, [0, 128,0,255]);
119 pixelShouldBe(0, 75, [0, 128,0,255]);
120 //right edge
121 context.putImageData(buffer, 90, 0);
122 pixelShouldBe(99, 25, [0, 128,0,255]);
123 pixelShouldBe(99, 50, [0, 128,0,255]);
124 pixelShouldBe(99, 75, [0, 128,0,255]);
125 //top edge
126 context.putImageData(buffer, 0, -90);
127 pixelShouldBe(25, 0, [0, 128,0,255]);
128 pixelShouldBe(50, 0, [0, 128,0,255]);
129 pixelShouldBe(75, 0, [0, 128,0,255]);
130 //bottom edge
131 context.putImageData(buffer, 0, 90);
132 pixelShouldBe(25, 99, [0, 128,0,255]);
133 pixelShouldBe(50, 99, [0, 128,0,255]);
134 pixelShouldBe(75, 99, [0, 128,0,255]);
135
136 // Test drawing with only part of the dirty region intersecting the window
137 // left edge
138 context.putImageData(buffer, 0, 0, -90, 0, 100, 100);
139 pixelShouldBe(0, 25, [0, 128,0,255]);
140 pixelShouldBe(0, 50, [0, 128,0,255]);
141 pixelShouldBe(0, 75, [0, 128,0,255]);
142 pixelShouldBe(10, 25, [0, 128,0,255]);
143 pixelShouldBe(10, 50, [0, 128,0,255]);
144 pixelShouldBe(10, 75, [0, 128,0,255]);
145 //right edge
146 context.putImageData(buffer, 0, 0, 90, 0, 100, 100);
147 pixelShouldBe(99, 25, [0, 128,0,255]);
148 pixelShouldBe(99, 50, [0, 128,0,255]);
149 pixelShouldBe(99, 75, [0, 128,0,255]);
150 pixelShouldBe(89, 25, [0, 128,0,255]);
151 pixelShouldBe(89, 50, [0, 128,0,255]);
152 pixelShouldBe(89, 75, [0, 128,0,255]);
153 // top edge
154 context.putImageData(buffer, 0, 0, 0, -90, 100, 100);
155 pixelShouldBe(25, 0, [0, 128,0,255]);
156 pixelShouldBe(50, 0, [0, 128,0,255]);
157 pixelShouldBe(75, 0, [0, 128,0,255]);
158 pixelShouldBe(25, 10, [0, 128,0,255]);
159 pixelShouldBe(50, 10, [0, 128,0,255]);
160 pixelShouldBe(75, 10, [0, 128,0,255]);
161 //bottom edge
162 context.putImageData(buffer, 0, 0, 0, 90, 100, 100);
163 pixelShouldBe(25, 99, [0, 128,0,255]);
164 pixelShouldBe(50, 99, [0, 128,0,255]);
165 pixelShouldBe(75, 99, [0, 128,0,255]);
166 pixelShouldBe(25, 89, [0, 128,0,255]);
167 pixelShouldBe(50, 89, [0, 128,0,255]);
168 pixelShouldBe(75, 89, [0, 128,0,255]);
169
170 // Test clamping of dx/dy
171 var smallbuffer = context.createImageData(10, 10);
172 fillRect(smallbuffer, 0, 0, 10, 10, 255, 0, 0, 255);
173 context.putImageData(smallbuffer, 1.5, 1);
174 pixelShouldBe(11, 11, [0, 128,0,255]);
175 fillRect(smallbuffer, 0, 0, 10, 10, 0, 128, 0, 255);
176 context.putImageData(smallbuffer, 1.5, 1);
177 pixelShouldBe(1, 1, [0, 128,0,255]);
178
179 // test clamping of dirtyX/Y/Width/Height
180 fillRect(smallbuffer, 0, 0, 10, 10, 0, 128, 0, 255);
181 context.fillStyle = "red";
182 context.fillRect(1, 1, 9, 9);
183 context.putImageData(smallbuffer, 1, 1, 0.5, 0.5, 8.5, 8.5);
184 pixelShouldBe(1, 1, [0, 128,0,255]);
185 pixelShouldBe(10, 10, [0, 128,0,255]);
186 context.fillRect(1, 1, 9, 9);
187 context.putImageData(smallbuffer, 1, 1, 0.25, 0.25, 9, 9);
188 pixelShouldBe(1, 1, [0, 128,0,255]);
189 pixelShouldBe(10, 10, [0, 128,0,255]);
190 context.fillRect(1, 1, 8, 8);
191 context.putImageData(smallbuffer, 1, 1, 0.0, 0.0, 8.5, 8.5);
192 pixelShouldBe(1, 1, [0, 128,0,255]);
193 pixelShouldBe(9, 9, [0, 128,0,255]);
194 context.fillRect(1, 1, 8, 8);
195 context.putImageData(smallbuffer, 1, 1, 0.0, 0.0, 8.25, 8.25);
196 pixelShouldBe(1, 1, [0, 128,0,255]);
197 pixelShouldBe(9, 9, [0, 128,0,255]);
198 context.fillRect(1, 1, 7, 7);
199 context.putImageData(smallbuffer, 1, 1, 0.5, 0.5, 7.9, 7.9);
200 pixelShouldBe(1, 1, [0, 128,0,255]);
201 pixelShouldBe(9, 9, [0, 128,0,255]);
202
203
204 shouldThrow("context.putImageData({}, 0, 0)", "'Error: TYPE_MISMATCH_ERR: DOM Exception 17'");
205 shouldThrow("context.putImageData(buffer, NaN, 0, 0, 0, 0, 0)", "'Error: INDEX_SIZE_ERR: DOM Exception 1'");
206 shouldThrow("context.putImageData(buffer, 0, NaN, 0, 0, 0, 0)", "'Error: INDEX_SIZE_ERR: DOM Exception 1'");
207 shouldThrow("context.putImageData(buffer, 0, 0, NaN, 0, 0, 0)", "'Error: INDEX_SIZE_ERR: DOM Exception 1'");
208 shouldThrow("context.putImageData(buffer, 0, 0, 0, NaN, 0, 0)", "'Error: INDEX_SIZE_ERR: DOM Exception 1'");
209 shouldThrow("context.putImageData(buffer, 0, 0, 0, 0, NaN, 0)", "'Error: INDEX_SIZE_ERR: DOM Exception 1'");
210 shouldThrow("context.putImageData(buffer, 0, 0, 0, 0, 0, NaN)", "'Error: INDEX_SIZE_ERR: DOM Exception 1'");
211 shouldThrow("context.putImageData(buffer, Infinity, 0, 0, 0, 0, 0)", "'Error: INDEX_SIZE_ERR: DOM Exception 1'");
212 shouldThrow("context.putImageData(buffer, 0, Infinity, 0, 0, 0, 0)", "'Error: INDEX_SIZE_ERR: DOM Exception 1'");
213 shouldThrow("context.putImageData(buffer, 0, 0, Infinity, 0, 0, 0)", "'Error: INDEX_SIZE_ERR: DOM Exception 1'");
214 shouldThrow("context.putImageData(buffer, 0, 0, 0, Infinity, 0, 0)", "'Error: INDEX_SIZE_ERR: DOM Exception 1'");
215 shouldThrow("context.putImageData(buffer, 0, 0, 0, 0, Infinity, 0)", "'Error: INDEX_SIZE_ERR: DOM Exception 1'");
216 shouldThrow("context.putImageData(buffer, 0, 0, 0, 0, 0, Infinity)", "'Error: INDEX_SIZE_ERR: DOM Exception 1'");
217 shouldThrow("context.putImageData(buffer, undefined, 0, 0, 0, 0, 0)", "'Error: INDEX_SIZE_ERR: DOM Exception 1'");
218 shouldThrow("context.putImageData(buffer, 0, undefined, 0, 0, 0, 0)", "'Error: INDEX_SIZE_ERR: DOM Exception 1'");
219 shouldThrow("context.putImageData(buffer, 0, 0, undefined, 0, 0, 0)", "'Error: INDEX_SIZE_ERR: DOM Exception 1'");
220 shouldThrow("context.putImageData(buffer, 0, 0, 0, undefined, 0, 0)", "'Error: INDEX_SIZE_ERR: DOM Exception 1'");
221 shouldThrow("context.putImageData(buffer, 0, 0, 0, 0, undefined, 0)", "'Error: INDEX_SIZE_ERR: DOM Exception 1'");
222 shouldThrow("context.putImageData(buffer, 0, 0, 0, 0, 0, undefined)", "'Error: INDEX_SIZE_ERR: DOM Exception 1'");
223
224 var successfullyParsed = true;