Move parseFontFaceDescriptor to CSSPropertyParser.cpp
[chromium-blink-merge.git] / third_party / WebKit / LayoutTests / fast / canvas / canvas-composite-stroke-alpha.html
blobee1d89e771e5fe1c1f8aa5f3d358628f7e3c2905
1 <html>
2 <head>
3 <title>A canvas globalCompositeOperation test with alpha blending</title>
4 <!-- This test was inspired by http://canvex.lazyilluminati.com/misc/compositex.html -->
5 <script type="application/x-javascript">
6 if (window.testRunner) {
7 testRunner.dumpAsText();
8 testRunner.waitUntilDone();
11 var compositeTypes = [
12 'source-over','source-in','source-out','source-atop',
13 'destination-over','destination-in','destination-out','destination-atop',
14 'lighter','copy','xor'
16 var inputColors = [
17 { source: [255, 0, 0, 255], destination: [0, 255, 0, 255] },
18 { source: [255, 0, 0, 255], destination: [0, 255, 0, 0] },
19 { source: [255, 0, 0, 255], destination: [0, 255, 0, 1] },
20 { source: [0, 255, 0, 0], destination: [255, 0, 0, 255] },
21 { source: [0, 255, 0, 1], destination: [255, 0, 0, 255] },
22 { source: [255, 0, 0, 0], destination: [0, 255, 0, 255] },
23 { source: [255, 0, 0, 127], destination: [0, 255, 0, 127] },
24 { source: [255, 0, 0, 255], destination: [0, 255, 0, 127] },
25 { source: [255, 0, 0, 127], destination: [0, 255, 0, 255] },
26 { source: [127, 0, 0, 255], destination: [0, 127, 0, 127] },
27 { source: [127, 0, 0, 127], destination: [0, 127, 0, 255] },
28 { source: [255, 0, 0, 127], destination: [255, 0, 0, 63] },
29 { source: [255, 127, 0, 32], destination: [255, 63, 0, 63] },
30 { source: [255, 0, 0, 191], destination: [0, 255, 0, 127] },
31 { source: [255, 0, 255, 191], destination: [0, 255, 255, 127] }
33 var expectedColors = [
35 { source: [255, 0, 0, 255], composition: [255, 0, 0, 255], destination: [0, 255, 0, 255] },
36 { source: [255, 0, 0, 255], composition: [255, 0, 0, 255], destination: [0, 0, 0, 0] },
37 { source: [255, 0, 0, 255], composition: [255, 0, 0, 255], destination: [0, 255, 0, 1] },
38 { source: [0, 0, 0, 0], composition: [255, 0, 0, 255], destination: [255, 0, 0, 255] },
39 { source: [0, 255, 0, 1], composition: [254, 1, 0, 255], destination: [255, 0, 0, 255] },
40 { source: [0, 0, 0, 0], composition: [0, 255, 0, 255], destination: [0, 255, 0, 255] },
41 { source: [255, 0, 0, 127], composition: [170, 84, 0, 190], destination: [0, 255, 0, 127] },
42 { source: [255, 0, 0, 255], composition: [255, 0, 0, 255], destination: [0, 255, 0, 127] },
43 { source: [255, 0, 0, 127], composition: [127, 128, 0, 255], destination: [0, 255, 0, 255] },
44 { source: [127, 0, 0, 255], composition: [127, 0, 0, 255], destination: [0, 126, 0, 127] },
45 { source: [126, 0, 0, 127], composition: [63, 63, 0, 255], destination: [0, 127, 0, 255] },
46 { source: [255, 0, 0, 127], composition: [255, 0, 0, 158], destination: [255, 0, 0, 63] },
47 { source: [255, 127, 0, 32], composition: [255, 85, 0, 87], destination: [255, 64, 0, 63] },
48 { source: [255, 0, 0, 191], composition: [219, 35, 0, 222], destination: [0, 255, 0, 127] },
49 { source: [255, 0, 255, 191], composition: [219, 35, 255, 222], destination: [0, 255, 255, 127] }
52 { source: [0, 0, 0, 0], composition: [255, 0, 0, 255], destination: [0, 0, 0, 0] },
53 { source: [0, 0, 0, 0], composition: [0, 0, 0, 0], destination: [0, 0, 0, 0] },
54 { source: [0, 0, 0, 0], composition: [0, 0, 0, 0], destination: [0, 0, 0, 0] },
55 { source: [0, 0, 0, 0], composition: [0, 0, 0, 0], destination: [0, 0, 0, 0] },
56 { source: [0, 0, 0, 0], composition: [0, 0, 0, 0], destination: [0, 0, 0, 0] },
57 { source: [0, 0, 0, 0], composition: [0, 0, 0, 0], destination: [0, 0, 0, 0] },
58 { source: [0, 0, 0, 0], composition: [255, 0, 0, 64], destination: [0, 0, 0, 0] },
59 { source: [0, 0, 0, 0], composition: [255, 0, 0, 127], destination: [0, 0, 0, 0] },
60 { source: [0, 0, 0, 0], composition: [255, 0, 0, 127], destination: [0, 0, 0, 0] },
61 { source: [0, 0, 0, 0], composition: [128, 0, 0, 127], destination: [0, 0, 0, 0] },
62 { source: [0, 0, 0, 0], composition: [126, 0, 0, 127], destination: [0, 0, 0, 0] },
63 { source: [0, 0, 0, 0], composition: [255, 0, 0, 32], destination: [0, 0, 0, 0] },
64 { source: [0, 0, 0, 0], composition: [255, 127, 0, 8], destination: [0, 0, 0, 0] },
65 { source: [0, 0, 0, 0], composition: [255, 0, 0, 96], destination: [0, 0, 0, 0] },
66 { source: [0, 0, 0, 0], composition: [255, 0, 255, 96], destination: [0, 0, 0, 0] }
69 { source: [255, 0, 0, 255], composition: [0, 0, 0, 0], destination: [0, 0, 0, 0] },
70 { source: [255, 0, 0, 255], composition: [255, 0, 0, 255], destination: [0, 0, 0, 0] },
71 { source: [255, 0, 0, 255], composition: [255, 0, 0, 254], destination: [0, 0, 0, 0] },
72 { source: [0, 0, 0, 0], composition: [0, 0, 0, 0], destination: [0, 0, 0, 0] },
73 { source: [0, 255, 0, 1], composition: [0, 0, 0, 0], destination: [0, 0, 0, 0] },
74 { source: [0, 0, 0, 0], composition: [0, 0, 0, 0], destination: [0, 0, 0, 0] },
75 { source: [255, 0, 0, 127], composition: [255, 0, 0, 64], destination: [0, 0, 0, 0] },
76 { source: [255, 0, 0, 255], composition: [255, 0, 0, 128], destination: [0, 0, 0, 0] },
77 { source: [255, 0, 0, 127], composition: [0, 0, 0, 0], destination: [0, 0, 0, 0] },
78 { source: [127, 0, 0, 255], composition: [127, 0, 0, 128], destination: [0, 0, 0, 0] },
79 { source: [126, 0, 0, 127], composition: [0, 0, 0, 0], destination: [0, 0, 0, 0] },
80 { source: [255, 0, 0, 127], composition: [255, 0, 0, 96], destination: [0, 0, 0, 0] },
81 { source: [255, 127, 0, 32], composition: [255, 132, 0, 25], destination: [0, 0, 0, 0] },
82 { source: [255, 0, 0, 191], composition: [255, 0, 0, 96], destination: [0, 0, 0, 0] },
83 { source: [255, 0, 255, 191], composition: [255, 0, 255, 96], destination: [0, 0, 0, 0] }
86 { source: [0, 0, 0, 0], composition: [255, 0, 0, 255], destination: [0, 255, 0, 255] },
87 { source: [0, 0, 0, 0], composition: [0, 0, 0, 0], destination: [0, 0, 0, 0] },
88 { source: [0, 0, 0, 0], composition: [255, 0, 0, 1], destination: [0, 255, 0, 1] },
89 { source: [0, 0, 0, 0], composition: [255, 0, 0, 255], destination: [255, 0, 0, 255] },
90 { source: [0, 0, 0, 0], composition: [254, 1, 0, 255], destination: [255, 0, 0, 255] },
91 { source: [0, 0, 0, 0], composition: [0, 255, 0, 255], destination: [0, 255, 0, 255] },
92 { source: [0, 0, 0, 0], composition: [126, 126, 0, 127], destination: [0, 255, 0, 127] },
93 { source: [0, 0, 0, 0], composition: [255, 0, 0, 127], destination: [0, 255, 0, 127] },
94 { source: [0, 0, 0, 0], composition: [127, 128, 0, 255], destination: [0, 255, 0, 255] },
95 { source: [0, 0, 0, 0], composition: [128, 0, 0, 127], destination: [0, 126, 0, 127] },
96 { source: [0, 0, 0, 0], composition: [63, 63, 0, 255], destination: [0, 127, 0, 255] },
97 { source: [0, 0, 0, 0], composition: [255, 0, 0, 63], destination: [255, 0, 0, 63] },
98 { source: [0, 0, 0, 0], composition: [255, 68, 0, 63], destination: [255, 64, 0, 63] },
99 { source: [0, 0, 0, 0], composition: [190, 62, 0, 127], destination: [0, 255, 0, 127] },
100 { source: [0, 0, 0, 0], composition: [190, 62, 255, 127], destination: [0, 255, 255, 127] }
103 { source: [255, 0, 0, 255], composition: [0, 255, 0, 255], destination: [0, 255, 0, 255] },
104 { source: [255, 0, 0, 255], composition: [255, 0, 0, 255], destination: [0, 0, 0, 0] },
105 { source: [255, 0, 0, 255], composition: [254, 1, 0, 255], destination: [0, 255, 0, 1] },
106 { source: [0, 0, 0, 0], composition: [255, 0, 0, 255], destination: [255, 0, 0, 255] },
107 { source: [0, 255, 0, 1], composition: [255, 0, 0, 255], destination: [255, 0, 0, 255] },
108 { source: [0, 0, 0, 0], composition: [0, 255, 0, 255], destination: [0, 255, 0, 255] },
109 { source: [255, 0, 0, 127], composition: [84, 170, 0, 190], destination: [0, 255, 0, 127] },
110 { source: [255, 0, 0, 255], composition: [128, 127, 0, 255], destination: [0, 255, 0, 127] },
111 { source: [255, 0, 0, 127], composition: [0, 255, 0, 255], destination: [0, 255, 0, 255] },
112 { source: [127, 0, 0, 255], composition: [63, 63, 0, 255], destination: [0, 126, 0, 127] },
113 { source: [126, 0, 0, 127], composition: [0, 127, 0, 255], destination: [0, 127, 0, 255] },
114 { source: [255, 0, 0, 127], composition: [255, 0, 0, 158], destination: [255, 0, 0, 63] },
115 { source: [255, 127, 0, 32], composition: [255, 82, 0, 87], destination: [255, 64, 0, 63] },
116 { source: [255, 0, 0, 191], composition: [109, 145, 0, 222], destination: [0, 255, 0, 127] },
117 { source: [255, 0, 255, 191], composition: [109, 145, 255, 222], destination: [0, 255, 255, 127] }
120 { source: [0, 0, 0, 0], composition: [0, 255, 0, 255], destination: [0, 0, 0, 0] },
121 { source: [0, 0, 0, 0], composition: [0, 0, 0, 0], destination: [0, 0, 0, 0] },
122 { source: [0, 0, 0, 0], composition: [0, 255, 0, 1], destination: [0, 0, 0, 0] },
123 { source: [0, 0, 0, 0], composition: [0, 0, 0, 0], destination: [0, 0, 0, 0] },
124 { source: [0, 0, 0, 0], composition: [255, 0, 0, 1], destination: [0, 0, 0, 0] },
125 { source: [0, 0, 0, 0], composition: [0, 0, 0, 0], destination: [0, 0, 0, 0] },
126 { source: [0, 0, 0, 0], composition: [0, 255, 0, 64], destination: [0, 0, 0, 0] },
127 { source: [0, 0, 0, 0], composition: [0, 255, 0, 127], destination: [0, 0, 0, 0] },
128 { source: [0, 0, 0, 0], composition: [0, 255, 0, 127], destination: [0, 0, 0, 0] },
129 { source: [0, 0, 0, 0], composition: [0, 126, 0, 127], destination: [0, 0, 0, 0] },
130 { source: [0, 0, 0, 0], composition: [0, 128, 0, 127], destination: [0, 0, 0, 0] },
131 { source: [0, 0, 0, 0], composition: [255, 0, 0, 32], destination: [0, 0, 0, 0] },
132 { source: [0, 0, 0, 0], composition: [255, 95, 0, 8], destination: [0, 0, 0, 0] },
133 { source: [0, 0, 0, 0], composition: [0, 255, 0, 96], destination: [0, 0, 0, 0] },
134 { source: [0, 0, 0, 0], composition: [0, 255, 255, 96], destination: [0, 0, 0, 0] }
137 { source: [0, 0, 0, 0], composition: [0, 0, 0, 0], destination: [0, 255, 0, 255] },
138 { source: [0, 0, 0, 0], composition: [0, 0, 0, 0], destination: [0, 0, 0, 0] },
139 { source: [0, 0, 0, 0], composition: [0, 0, 0, 0], destination: [0, 255, 0, 1] },
140 { source: [0, 0, 0, 0], composition: [255, 0, 0, 255], destination: [255, 0, 0, 255] },
141 { source: [0, 0, 0, 0], composition: [255, 0, 0, 254], destination: [255, 0, 0, 255] },
142 { source: [0, 0, 0, 0], composition: [0, 255, 0, 255], destination: [0, 255, 0, 255] },
143 { source: [0, 0, 0, 0], composition: [0, 255, 0, 64], destination: [0, 255, 0, 127] },
144 { source: [0, 0, 0, 0], composition: [0, 0, 0, 0], destination: [0, 255, 0, 127] },
145 { source: [0, 0, 0, 0], composition: [0, 255, 0, 128], destination: [0, 255, 0, 255] },
146 { source: [0, 0, 0, 0], composition: [0, 0, 0, 0], destination: [0, 126, 0, 127] },
147 { source: [0, 0, 0, 0], composition: [0, 127, 0, 128], destination: [0, 127, 0, 255] },
148 { source: [0, 0, 0, 0], composition: [255, 0, 0, 32], destination: [255, 0, 0, 63] },
149 { source: [0, 0, 0, 0], composition: [255, 63, 0, 56], destination: [255, 64, 0, 63] },
150 { source: [0, 0, 0, 0], composition: [0, 255, 0, 32], destination: [0, 255, 0, 127] },
151 { source: [0, 0, 0, 0], composition: [0, 255, 255, 32], destination: [0, 255, 255, 127] }
154 { source: [255, 0, 0, 255], composition: [0, 255, 0, 255], destination: [0,0,0,0] },
155 { source: [255, 0, 0, 255], composition: [255, 0, 0, 255], destination: [0, 0, 0, 0] },
156 { source: [255, 0, 0, 255], composition: [254, 1, 0, 255], destination: [0,0,0,0] },
157 { source: [0, 0, 0, 0], composition: [0, 0, 0, 0], destination: [0,0,0,0] },
158 { source: [0, 255, 0, 1], composition: [255, 0, 0, 1], destination: [0,0,0,0] },
159 { source: [0, 0, 0, 0], composition: [0, 0, 0, 0], destination: [0,0,0,0] },
160 { source: [255, 0, 0, 127], composition: [126, 126, 0, 127], destination: [0,0,0,0] },
161 { source: [255, 0, 0, 255], composition: [128, 127, 0, 255], destination: [0,0,0,0] },
162 { source: [255, 0, 0, 127], composition: [0, 255, 0, 127], destination: [0,0,0,0] },
163 { source: [127, 0, 0, 255], composition: [63, 63, 0, 255], destination: [0,0,0,0] },
164 { source: [126, 0, 0, 127], composition: [0, 126, 0, 127], destination: [0,0,0,0] },
165 { source: [255, 0, 0, 127], composition: [255, 0, 0, 127], destination: [0,0,0,0] },
166 { source: [255, 127, 0, 32], composition: [255, 111, 0, 32], destination: [0,0,0,0] },
167 { source: [255, 0, 0, 191], composition: [126, 126, 0, 191], destination: [0,0,0,0] },
168 { source: [255, 0, 255, 191], composition: [126, 126, 255, 191], destination: [0,0,0,0] }
171 { source: [255, 0, 0, 255], composition: [255, 255, 0, 255], destination: [0, 255, 0, 255] },
172 { source: [255, 0, 0, 255], composition: [255, 0, 0, 255], destination: [0, 0, 0, 0] },
173 { source: [255, 0, 0, 255], composition: [255, 1, 0, 255], destination: [0, 255, 0, 1] },
174 { source: [0, 0, 0, 0], composition: [255, 0, 0, 255], destination: [255, 0, 0, 255] },
175 { source: [0, 255, 0, 1], composition: [255, 1, 0, 255], destination: [255, 0, 0, 255] },
176 { source: [0, 0, 0, 0], composition: [0, 255, 0, 255], destination: [0, 255, 0, 255] },
177 { source: [255, 0, 0, 127], composition: [127, 127, 0, 254], destination: [0, 255, 0, 127] },
178 { source: [255, 0, 0, 255], composition: [255, 127, 0, 255], destination: [0, 255, 0, 127] },
179 { source: [255, 0, 0, 127], composition: [127, 255, 0, 255], destination: [0, 255, 0, 255] },
180 { source: [127, 0, 0, 255], composition: [127, 63, 0, 255], destination: [0, 126, 0, 127] },
181 { source: [126, 0, 0, 127], composition: [63, 127, 0, 255], destination: [0, 127, 0, 255] },
182 { source: [255, 0, 0, 127], composition: [255, 0, 0, 190], destination: [255, 0, 0, 63] },
183 { source: [255, 127, 0, 32], composition: [255, 85, 0, 95], destination: [255, 64, 0, 63] },
184 { source: [255, 0, 0, 191], composition: [191, 127, 0, 255], destination: [0, 255, 0, 127] },
185 { source: [255, 0, 255, 191], composition: [191, 127, 255, 255], destination: [0, 255, 255, 127] }
188 { source: [255, 0, 0, 255], composition: [255, 0, 0, 255], destination: [0, 0, 0, 0] },
189 { source: [255, 0, 0, 255], composition: [255, 0, 0, 255], destination: [0, 0, 0, 0] },
190 { source: [255, 0, 0, 255], composition: [255, 0, 0, 255], destination: [0, 0, 0, 0] },
191 { source: [0, 0, 0, 0], composition: [0, 0, 0, 0], destination: [0, 0, 0, 0] },
192 { source: [0, 255, 0, 1], composition: [0, 255, 0, 1], destination: [0, 0, 0, 0] },
193 { source: [0, 0, 0, 0], composition: [0, 0, 0, 0], destination: [0, 0, 0, 0] },
194 { source: [255, 0, 0, 127], composition: [255, 0, 0, 127], destination: [0, 0, 0, 0] },
195 { source: [255, 0, 0, 255], composition: [255, 0, 0, 255], destination: [0, 0, 0, 0] },
196 { source: [255, 0, 0, 127], composition: [255, 0, 0, 127], destination: [0, 0, 0, 0] },
197 { source: [127, 0, 0, 255], composition: [127, 0, 0, 255], destination: [0, 0, 0, 0] },
198 { source: [126, 0, 0, 127], composition: [126, 0, 0, 127], destination: [0, 0, 0, 0] },
199 { source: [255, 0, 0, 127], composition: [255, 0, 0, 127], destination: [0, 0, 0, 0] },
200 { source: [255, 127, 0, 32], composition: [255, 127, 0, 32], destination: [0, 0, 0, 0] },
201 { source: [255, 0, 0, 191], composition: [255, 0, 0, 191], destination: [0, 0, 0, 0] },
202 { source: [255, 0, 255, 191], composition: [255, 0, 255, 191], destination: [0, 0, 0, 0] }
205 { source: [255, 0, 0, 255], composition: [0, 0, 0, 0], destination: [0, 255, 0, 255] },
206 { source: [255, 0, 0, 255], composition: [255, 0, 0, 255], destination: [0, 0, 0, 0] },
207 { source: [255, 0, 0, 255], composition: [255, 0, 0, 254], destination: [0, 255, 0, 1] },
208 { source: [0, 0, 0, 0], composition: [255, 0, 0, 255], destination: [255, 0, 0, 255] },
209 { source: [0, 255, 0, 1], composition: [255, 0, 0, 254], destination: [255, 0, 0, 255] },
210 { source: [0, 0, 0, 0], composition: [0, 255, 0, 255], destination: [0, 255, 0, 255] },
211 { source: [255, 0, 0, 127], composition: [126, 126, 0, 127], destination: [0, 255, 0, 127] },
212 { source: [255, 0, 0, 255], composition: [255, 0, 0, 128], destination: [0, 255, 0, 127] },
213 { source: [255, 0, 0, 127], composition: [0, 255, 0, 128], destination: [0, 255, 0, 255] },
214 { source: [127, 0, 0, 255], composition: [127, 0, 0, 128], destination: [0, 126, 0, 127] },
215 { source: [126, 0, 0, 127], composition: [0, 125, 0, 128], destination: [0, 127, 0, 255] },
216 { source: [255, 0, 0, 127], composition: [255, 0, 0, 127], destination: [255, 0, 0, 63] },
217 { source: [255, 127, 0, 32], composition: [255, 83, 0, 79], destination: [255, 64, 0, 63] },
218 { source: [255, 0, 0, 191], composition: [190, 62, 0, 127], destination: [0, 255, 0, 127] },
219 { source: [255, 0, 255, 191], composition: [190, 62, 255, 127], destination: [0, 255, 255, 127] }
223 var debugString = "";
225 // Compare two colors with a few margin.
226 function isDifferentColor(actualColor, expectedColor)
228 var actualAlpha = actualColor[3];
229 var expectedAlpha = expectedColor[3];
230 if (Math.abs(actualColor - expectedColor) > 3) return true;
231 // For the value of RGB, we compare the values the users actually see.
232 if (Math.abs(actualColor[0] * actualAlpha / 256 - expectedColor[0] * expectedAlpha / 256) > 3) return true;
233 if (Math.abs(actualColor[1] * actualAlpha / 256 - expectedColor[1] * expectedAlpha / 256) > 3) return true;
234 if (Math.abs(actualColor[2] * actualAlpha / 256 - expectedColor[2] * expectedAlpha / 256) > 3) return true;
235 return false;
238 function getRGBAString(a)
240 return "rgba(" + [a[0], a[1], a[2], a[3] / 255.0].join(",") + ")";
243 function drawTable(drawPolicy)
245 var tableElement = document.createElement("table");
247 // Create a header for source color.
248 var trElement = document.createElement("tr");
249 tableElement.appendChild(trElement);
250 trElement.appendChild(document.createElement("th"));
251 for (var column = 0; column < inputColors.length; column++) {
252 var inputColor = inputColors[column];
253 var thElement = document.createElement("th");
254 thElement.setAttribute("colspan", "2");
255 thElement.textContent = "src " + inputColor.source.join(", ");
256 trElement.appendChild(thElement);
259 // Create a header for destination color.
260 trElement = document.createElement("tr");
261 tableElement.appendChild(trElement);
262 trElement.appendChild(document.createElement("th"));
263 for (var column = 0; column < inputColors.length; column++) {
264 var inputColor = inputColors[column];
265 var thElement = document.createElement("th");
266 thElement.setAttribute("colspan", "2");
267 thElement.textContent = "dst " + inputColor.destination.join(", ");
268 trElement.appendChild(thElement);
271 var resultsElement = document.getElementById("results");
272 var titleElement = document.createElement("h1");
273 titleElement.textContent = "Tests for " + drawPolicy.name;
274 resultsElement.appendChild(titleElement);
275 resultsElement.appendChild(tableElement);
277 for (var row = 0; row < compositeTypes.length; row++){
278 var type = compositeTypes[row];
280 var trCanvasElement = document.createElement("tr");
281 var thElement = document.createElement("th");
282 thElement.setAttribute("rowspan", "2");
283 thElement.textContent = type;
284 trCanvasElement.appendChild(thElement);
285 var trMessageElement = document.createElement("tr");
286 tableElement.appendChild(trCanvasElement);
287 tableElement.appendChild(trMessageElement);
289 for (var column = 0; column < inputColors.length; column++) {
290 var test = type + "-" + column;
291 var inputColor = inputColors[column];
292 var expectedColor = expectedColors[row][column];
294 // Create canvas element for actual color.
295 var actualCanvasElement = document.createElement("canvas");
296 actualCanvasElement.setAttribute("width", "25");
297 actualCanvasElement.setAttribute("height", "25");
298 tdElement = document.createElement("td");
299 tdElement.appendChild(actualCanvasElement);
300 trCanvasElement.appendChild(tdElement);
302 // Create canvas element for expected color.
303 var expectedCanvasElement = document.createElement("canvas");
304 expectedCanvasElement.setAttribute("width", "25");
305 expectedCanvasElement.setAttribute("height", "25");
306 var tdElement = document.createElement("td");
307 tdElement.appendChild(expectedCanvasElement);
308 trCanvasElement.appendChild(tdElement);
310 // Create div element for pass/fail messages.
311 var messageElement = document.createElement("div");
312 tdElement = document.createElement("td");
313 tdElement.setAttribute("colspan", "2");
314 tdElement.appendChild(messageElement);
315 trMessageElement.appendChild(tdElement);
317 var ctx = expectedCanvasElement.getContext("2d");
318 ctx.lineWidth = 10;
319 // Draw expected image.
320 ctx.globalCompositeOperation = "copy";
321 ctx.fillStyle = getRGBAString(expectedColor.destination);
322 ctx.strokeStyle = getRGBAString(expectedColor.destination);
323 drawPolicy.drawDestination(ctx);
324 ctx.fillStyle = getRGBAString(expectedColor.source);
325 ctx.strokeStyle = getRGBAString(expectedColor.source);
326 drawPolicy.drawSource(ctx);
327 ctx.fillStyle = getRGBAString(expectedColor.composition);
328 ctx.strokeStyle = getRGBAString(expectedColor.composition);
329 drawPolicy.drawComposition(ctx);
331 ctx = actualCanvasElement.getContext("2d");
332 ctx.lineWidth = 10;
334 // Draw destination rectangle.
335 ctx.globalCompositeOperation = "copy";
336 ctx.fillStyle = getRGBAString(inputColor.destination);
337 ctx.strokeStyle = getRGBAString(inputColor.destination);
338 drawPolicy.drawDestination(ctx);
340 // Draw source rectangle.
341 ctx.globalCompositeOperation = type;
342 ctx.fillStyle = getRGBAString(inputColor.source);
343 ctx.strokeStyle = getRGBAString(inputColor.source);
344 drawPolicy.drawSource(ctx);
346 // Let's check if the results are expected or not.
347 var errorSuffix = ", composite type: " + type + ", source: " + inputColor.source + ", destination: " + inputColor.destination + "<br>";
349 var results = "";
350 // Note that (0, 0) may be affected by anti-alias.
351 var img = ctx.getImageData(1, 1, 1, 1).data;
352 var actualColor = [img[0], img[1], img[2], img[3]];
353 if (isDifferentColor(actualColor, expectedColor.source)) {
354 results += "Unexpected source! expected: " + expectedColor.source + " actual: " + actualColor + errorSuffix;
356 // Note that (24, 24) may be affected by anti-alias.
357 img = ctx.getImageData(23, 23, 1, 1).data;
358 actualColor = [img[0], img[1], img[2], img[3]];
359 if (isDifferentColor(actualColor, expectedColor.destination)) {
360 results += "Unexpected destination! expected: " + expectedColor.destination + " actual: " + actualColor + errorSuffix;
362 img = ctx.getImageData(12, 12, 1, 1).data;
363 actualColor = [img[0], img[1], img[2], img[3]];
364 if (isDifferentColor(actualColor, expectedColor.composition)) {
365 results += "Unexpected composition! expected: " + expectedColor.composition + " actual: " + actualColor + errorSuffix;
368 if (results == "") {
369 messageElement.style.backgroundColor = "green";
370 messageElement.innerHTML = results = "PASS";
371 } else {
372 messageElement.style.backgroundColor = "red";
373 messageElement.innerHTML = results;
376 img = ctx.getImageData(0, 0, 1, 1).data;
377 debugString += img[0] + "," + img[1] + "," + img[2] + "," + img[3] + "\n";
378 img = ctx.getImageData(12, 12, 1, 1).data;
379 debugString += img[0] + "," + img[1] + "," + img[2] + "," + img[3] + "\n";
380 img = ctx.getImageData(24, 24, 1, 1).data;
381 debugString += img[0] + "," + img[1] + "," + img[2] + "," + img[3] + "\n";
386 var useStrokeRect = {
387 drawSource: function(ctx) {
388 ctx.strokeRect(5, 5, 10, 10);
391 drawDestination: function(ctx) {
392 ctx.fillRect(5, 5, 20, 20);
395 drawComposition: function(ctx) {
396 ctx.fillRect(5, 5, 15, 15);
399 name: "stroke rect"
402 var usePathAndStroke = {
403 drawSource: function(ctx) {
404 ctx.beginPath();
405 ctx.moveTo(5, 5);
406 ctx.lineTo(15, 5);
407 ctx.lineTo(15, 15);
408 ctx.lineTo(5, 15);
409 ctx.closePath();
410 ctx.stroke();
413 drawDestination: function(ctx) {
414 ctx.fillRect(5, 5, 20, 20);
417 drawComposition: function(ctx) {
418 ctx.fillRect(5, 5, 15, 15);
421 name: "path and stroke"
424 function draw()
426 drawTable(useStrokeRect);
427 drawTable(usePathAndStroke);
428 // Dump colors into text area for debugging purpose.
429 document.getElementById("debug").value = debugString;
430 if (window.testRunner)
431 testRunner.notifyDone();
433 </script>
434 <style type="text/css">
435 body { margin: 20px; font-family: arial,verdana,helvetica; background: #fff;}
436 h1 { font-size: 140%; font-weight:normal; color: #036; border-bottom: 1px solid #ccc; }
437 canvas { border: 2px solid #000; margin-bottom: 5px; }
438 table { background: #00f; }
439 th { font-size: 70%; padding: 0; }
440 td { font-size: 70%; padding: 0; }
441 pre { float:left; display:block; background: rgb(238,238,238); border: 1px dashed #666; padding: 15px 20px; margin: 0 0 10px 0; }
442 </style>
443 </head>
444 <body onload="draw();">
445 <p>This test exercises a bunch of alpha composition checks with stroking. The top-left rectangles are the source images and bottom-right rectangles are the destination images.</p>
446 <div id="results">
447 </div>
448 <textarea id="debug"></textarea>
449 </body>
450 </html>