1- name: 2d.text.font.parse.basic
2  testing:
3  - 2d.text.font.parse
4  - 2d.text.font.get
5  code: |
6    ctx.font = '20px serif';
7    @assert ctx.font === '20px serif';
8
9    ctx.font = '20PX   SERIF';
10    @assert ctx.font === '20px serif'; @moz-todo
11
12- name: 2d.text.font.parse.tiny
13  testing:
14  - 2d.text.font.parse
15  - 2d.text.font.get
16  code: |
17    ctx.font = '1px sans-serif';
18    @assert ctx.font === '1px sans-serif';
19
20- name: 2d.text.font.parse.complex
21  testing:
22  - 2d.text.font.parse
23  - 2d.text.font.get
24  - 2d.text.font.lineheight
25  code: |
26    ctx.font = 'small-caps italic 400 12px/2 Unknown Font, sans-serif';
27    @assert ctx.font === 'italic small-caps 12px "Unknown Font", sans-serif'; @moz-todo
28
29  # TODO:
30  #   2d.text.font.parse.size.absolute
31  #     xx-small x-small small medium large x-large xx-large
32  #   2d.text.font.parse.size.relative
33  #     smaller larger
34  #   2d.text.font.parse.size.length.relative
35  #     em ex px
36  #   2d.text.font.parse.size.length.absolute
37  #     in cm mm pt pc
38
39- name: 2d.text.font.parse.size.percentage
40  testing:
41  - 2d.text.font.parse
42  - 2d.text.font.get
43  - 2d.text.font.fontsize
44  - 2d.text.font.size
45  canvas: 'style="font-size: 144px" width="100" height="50"'
46  code: |
47    ctx.font = '50% serif';
48    @assert ctx.font === '72px serif'; @moz-todo
49    canvas.setAttribute('style', 'font-size: 100px');
50    @assert ctx.font === '72px serif'; @moz-todo
51
52- name: 2d.text.font.parse.size.percentage.default
53  testing:
54  - 2d.text.font.undefined
55  code: |
56    var canvas2 = document.createElement('canvas');
57    var ctx2 = canvas2.getContext('2d');
58    ctx2.font = '1000% serif';
59    @assert ctx2.font === '100px serif'; @moz-todo
60
61- name: 2d.text.font.parse.system
62  desc: System fonts must be computed to explicit values
63  testing:
64  - 2d.text.font.parse
65  - 2d.text.font.get
66  - 2d.text.font.systemfonts
67  code: |
68    ctx.font = 'message-box';
69    @assert ctx.font !== 'message-box';
70
71- name: 2d.text.font.parse.invalid
72  testing:
73  - 2d.text.font.invalid
74  code: |
75    ctx.font = '20px serif';
76    @assert ctx.font === '20px serif';
77
78    ctx.font = '20px serif';
79    ctx.font = '';
80    @assert ctx.font === '20px serif';
81
82    ctx.font = '20px serif';
83    ctx.font = 'bogus';
84    @assert ctx.font === '20px serif';
85
86    ctx.font = '20px serif';
87    ctx.font = 'inherit';
88    @assert ctx.font === '20px serif';
89
90    ctx.font = '20px serif';
91    ctx.font = '10px {bogus}';
92    @assert ctx.font === '20px serif';
93
94    ctx.font = '20px serif';
95    ctx.font = '10px initial';
96    @assert ctx.font === '20px serif'; @moz-todo
97
98    ctx.font = '20px serif';
99    ctx.font = '10px default';
100    @assert ctx.font === '20px serif'; @moz-todo
101
102    ctx.font = '20px serif';
103    ctx.font = '10px inherit';
104    @assert ctx.font === '20px serif';
105
106    ctx.font = '20px serif';
107    ctx.font = '10px revert';
108    @assert ctx.font === '20px serif';
109
110    ctx.font = '20px serif';
111    ctx.font = 'var(--x)';
112    @assert ctx.font === '20px serif';
113
114    ctx.font = '20px serif';
115    ctx.font = 'var(--x, 10px serif)';
116    @assert ctx.font === '20px serif';
117
118    ctx.font = '20px serif';
119    ctx.font = '1em serif; background: green; margin: 10px';
120    @assert ctx.font === '20px serif';
121
122- name: 2d.text.font.default
123  testing:
124  - 2d.text.font.default
125  code: |
126    @assert ctx.font === '10px sans-serif';
127
128- name: 2d.text.font.relative_size
129  testing:
130  - 2d.text.font.relative_size
131  code: |
132    var canvas2 = document.createElement('canvas');
133    var ctx2 = canvas2.getContext('2d');
134    ctx2.font = '1em sans-serif';
135    @assert ctx2.font === '10px sans-serif';
136
137- name: 2d.text.align.valid
138  testing:
139  - 2d.text.align.get
140  - 2d.text.align.set
141  code: |
142    ctx.textAlign = 'start';
143    @assert ctx.textAlign === 'start';
144
145    ctx.textAlign = 'end';
146    @assert ctx.textAlign === 'end';
147
148    ctx.textAlign = 'left';
149    @assert ctx.textAlign === 'left';
150
151    ctx.textAlign = 'right';
152    @assert ctx.textAlign === 'right';
153
154    ctx.textAlign = 'center';
155    @assert ctx.textAlign === 'center';
156
157- name: 2d.text.align.invalid
158  testing:
159  - 2d.text.align.invalid
160  code: |
161    ctx.textAlign = 'start';
162    ctx.textAlign = 'bogus';
163    @assert ctx.textAlign === 'start';
164
165    ctx.textAlign = 'start';
166    ctx.textAlign = 'END';
167    @assert ctx.textAlign === 'start';
168
169    ctx.textAlign = 'start';
170    ctx.textAlign = 'end ';
171    @assert ctx.textAlign === 'start';
172
173    ctx.textAlign = 'start';
174    ctx.textAlign = 'end\0';
175    @assert ctx.textAlign === 'start';
176
177- name: 2d.text.align.default
178  testing:
179  - 2d.text.align.default
180  code: |
181    @assert ctx.textAlign === 'start';
182
183
184- name: 2d.text.baseline.valid
185  testing:
186  - 2d.text.baseline.get
187  - 2d.text.baseline.set
188  code: |
189    ctx.textBaseline = 'top';
190    @assert ctx.textBaseline === 'top';
191
192    ctx.textBaseline = 'hanging';
193    @assert ctx.textBaseline === 'hanging';
194
195    ctx.textBaseline = 'middle';
196    @assert ctx.textBaseline === 'middle';
197
198    ctx.textBaseline = 'alphabetic';
199    @assert ctx.textBaseline === 'alphabetic';
200
201    ctx.textBaseline = 'ideographic';
202    @assert ctx.textBaseline === 'ideographic';
203
204    ctx.textBaseline = 'bottom';
205    @assert ctx.textBaseline === 'bottom';
206
207- name: 2d.text.baseline.invalid
208  testing:
209  - 2d.text.baseline.invalid
210  code: |
211    ctx.textBaseline = 'top';
212    ctx.textBaseline = 'bogus';
213    @assert ctx.textBaseline === 'top';
214
215    ctx.textBaseline = 'top';
216    ctx.textBaseline = 'MIDDLE';
217    @assert ctx.textBaseline === 'top';
218
219    ctx.textBaseline = 'top';
220    ctx.textBaseline = 'middle ';
221    @assert ctx.textBaseline === 'top';
222
223    ctx.textBaseline = 'top';
224    ctx.textBaseline = 'middle\0';
225    @assert ctx.textBaseline === 'top';
226
227- name: 2d.text.baseline.default
228  testing:
229  - 2d.text.baseline.default
230  code: |
231    @assert ctx.textBaseline === 'alphabetic';
232
233
234
235
236
237- name: 2d.text.draw.baseline.top
238  desc: textBaseline top is the top of the em square (not the bounding box)
239  testing:
240  - 2d.text.baseline.top
241  fonts:
242  - CanvasTest
243  code: |
244    ctx.font = '50px CanvasTest';
245    deferTest();
246    step_timeout(t.step_func_done(function () {
247        ctx.fillStyle = '#f00';
248        ctx.fillRect(0, 0, 100, 50);
249        ctx.fillStyle = '#0f0';
250        ctx.textBaseline = 'top';
251        ctx.fillText('CC', 0, 0);
252        @assert pixel 5,5 ==~ 0,255,0,255;
253        @assert pixel 95,5 ==~ 0,255,0,255;
254        @assert pixel 25,25 ==~ 0,255,0,255;
255        @assert pixel 75,25 ==~ 0,255,0,255;
256        @assert pixel 5,45 ==~ 0,255,0,255;
257        @assert pixel 95,45 ==~ 0,255,0,255;
258    }), 500);
259  expected: green
260
261- name: 2d.text.draw.baseline.bottom
262  desc: textBaseline bottom is the bottom of the em square (not the bounding box)
263  testing:
264  - 2d.text.baseline.bottom
265  fonts:
266  - CanvasTest
267  code: |
268    ctx.font = '50px CanvasTest';
269    deferTest();
270    step_timeout(t.step_func_done(function () {
271        ctx.fillStyle = '#f00';
272        ctx.fillRect(0, 0, 100, 50);
273        ctx.fillStyle = '#0f0';
274        ctx.textBaseline = 'bottom';
275        ctx.fillText('CC', 0, 50);
276        @assert pixel 5,5 ==~ 0,255,0,255;
277        @assert pixel 95,5 ==~ 0,255,0,255;
278        @assert pixel 25,25 ==~ 0,255,0,255;
279        @assert pixel 75,25 ==~ 0,255,0,255;
280        @assert pixel 5,45 ==~ 0,255,0,255;
281        @assert pixel 95,45 ==~ 0,255,0,255;
282    }), 500);
283  expected: green
284
285- name: 2d.text.draw.baseline.middle
286  desc: textBaseline middle is the middle of the em square (not the bounding box)
287  testing:
288  - 2d.text.baseline.middle
289  fonts:
290  - CanvasTest
291  code: |
292    ctx.font = '50px CanvasTest';
293    deferTest();
294    step_timeout(t.step_func_done(function () {
295        ctx.fillStyle = '#f00';
296        ctx.fillRect(0, 0, 100, 50);
297        ctx.fillStyle = '#0f0';
298        ctx.textBaseline = 'middle';
299        ctx.fillText('CC', 0, 25);
300        @assert pixel 5,5 ==~ 0,255,0,255;
301        @assert pixel 95,5 ==~ 0,255,0,255;
302        @assert pixel 25,25 ==~ 0,255,0,255;
303        @assert pixel 75,25 ==~ 0,255,0,255;
304        @assert pixel 5,45 ==~ 0,255,0,255;
305        @assert pixel 95,45 ==~ 0,255,0,255;
306    }), 500);
307  expected: green
308
309- name: 2d.text.draw.baseline.alphabetic
310  testing:
311  - 2d.text.baseline.alphabetic
312  fonts:
313  - CanvasTest
314  code: |
315    ctx.font = '50px CanvasTest';
316    deferTest();
317    step_timeout(t.step_func_done(function () {
318        ctx.fillStyle = '#f00';
319        ctx.fillRect(0, 0, 100, 50);
320        ctx.fillStyle = '#0f0';
321        ctx.textBaseline = 'alphabetic';
322        ctx.fillText('CC', 0, 37.5);
323        @assert pixel 5,5 ==~ 0,255,0,255;
324        @assert pixel 95,5 ==~ 0,255,0,255;
325        @assert pixel 25,25 ==~ 0,255,0,255;
326        @assert pixel 75,25 ==~ 0,255,0,255;
327        @assert pixel 5,45 ==~ 0,255,0,255;
328        @assert pixel 95,45 ==~ 0,255,0,255;
329    }), 500);
330  expected: green
331
332- name: 2d.text.draw.baseline.ideographic
333  testing:
334  - 2d.text.baseline.ideographic
335  fonts:
336  - CanvasTest
337  code: |
338    ctx.font = '50px CanvasTest';
339    deferTest();
340    step_timeout(t.step_func_done(function () {
341        ctx.fillStyle = '#f00';
342        ctx.fillRect(0, 0, 100, 50);
343        ctx.fillStyle = '#0f0';
344        ctx.textBaseline = 'ideographic';
345        ctx.fillText('CC', 0, 31.25);
346        @assert pixel 5,5 ==~ 0,255,0,255;
347        @assert pixel 95,5 ==~ 0,255,0,255;
348        @assert pixel 25,25 ==~ 0,255,0,255;
349        @assert pixel 75,25 ==~ 0,255,0,255;
350        @assert pixel 5,45 ==~ 0,255,0,255; @moz-todo
351        @assert pixel 95,45 ==~ 0,255,0,255; @moz-todo
352    }), 500);
353  expected: green
354
355- name: 2d.text.draw.baseline.hanging
356  testing:
357  - 2d.text.baseline.hanging
358  fonts:
359  - CanvasTest
360  code: |
361    ctx.font = '50px CanvasTest';
362    deferTest();
363    step_timeout(t.step_func_done(function () {
364        ctx.fillStyle = '#f00';
365        ctx.fillRect(0, 0, 100, 50);
366        ctx.fillStyle = '#0f0';
367        ctx.textBaseline = 'hanging';
368        ctx.fillText('CC', 0, 12.5);
369        @assert pixel 5,5 ==~ 0,255,0,255; @moz-todo
370        @assert pixel 95,5 ==~ 0,255,0,255; @moz-todo
371        @assert pixel 25,25 ==~ 0,255,0,255;
372        @assert pixel 75,25 ==~ 0,255,0,255;
373        @assert pixel 5,45 ==~ 0,255,0,255;
374        @assert pixel 95,45 ==~ 0,255,0,255;
375    }), 500);
376  expected: green
377
378- name: 2d.text.draw.space.collapse.space
379  desc: Space characters are converted to U+0020, and collapsed (per CSS)
380  testing:
381  - 2d.text.draw.spaces
382  fonts:
383  - CanvasTest
384  code: |
385    ctx.font = '50px CanvasTest';
386    deferTest();
387    step_timeout(t.step_func_done(function () {
388        ctx.fillStyle = '#f00';
389        ctx.fillRect(0, 0, 100, 50);
390        ctx.fillStyle = '#0f0';
391        ctx.fillText('E  EE', -100, 37.5);
392        @assert pixel 25,25 ==~ 0,255,0,255; @moz-todo
393        @assert pixel 75,25 ==~ 0,255,0,255;
394    }), 500);
395  expected: green
396
397- name: 2d.text.draw.space.collapse.other
398  desc: Space characters are converted to U+0020, and collapsed (per CSS)
399  testing:
400  - 2d.text.draw.spaces
401  fonts:
402  - CanvasTest
403  code: |
404    ctx.font = '50px CanvasTest';
405    deferTest();
406    step_timeout(t.step_func_done(function () {
407        ctx.fillStyle = '#f00';
408        ctx.fillRect(0, 0, 100, 50);
409        ctx.fillStyle = '#0f0';
410        ctx.fillText('E \x09\x0a\x0c\x0d  \x09\x0a\x0c\x0dEE', -100, 37.5);
411        @assert pixel 25,25 ==~ 0,255,0,255; @moz-todo
412        @assert pixel 75,25 ==~ 0,255,0,255; @moz-todo
413    }), 500);
414  expected: green
415
416- name: 2d.text.draw.space.collapse.start
417  desc: Space characters at the start of a line are collapsed (per CSS)
418  testing:
419  - 2d.text.draw.spaces
420  fonts:
421  - CanvasTest
422  code: |
423    ctx.font = '50px CanvasTest';
424    deferTest();
425    step_timeout(t.step_func_done(function () {
426        ctx.fillStyle = '#f00';
427        ctx.fillRect(0, 0, 100, 50);
428        ctx.fillStyle = '#0f0';
429        ctx.fillText(' EE', 0, 37.5);
430        @assert pixel 25,25 ==~ 0,255,0,255; @moz-todo
431        @assert pixel 75,25 ==~ 0,255,0,255;
432    }), 500);
433  expected: green
434
435- name: 2d.text.draw.space.collapse.end
436  desc: Space characters at the end of a line are collapsed (per CSS)
437  testing:
438  - 2d.text.draw.spaces
439  fonts:
440  - CanvasTest
441  code: |
442    ctx.font = '50px CanvasTest';
443    deferTest();
444    step_timeout(t.step_func_done(function () {
445        ctx.fillStyle = '#f00';
446        ctx.fillRect(0, 0, 100, 50);
447        ctx.fillStyle = '#0f0';
448        ctx.textAlign = 'right';
449        ctx.fillText('EE ', 100, 37.5);
450        @assert pixel 25,25 ==~ 0,255,0,255;
451        @assert pixel 75,25 ==~ 0,255,0,255; @moz-todo
452    }), 500);
453  expected: green
454
455
456- name: 2d.text.measure.width.space
457  desc: Space characters are converted to U+0020 and collapsed (per CSS)
458  testing:
459  - 2d.text.measure.spaces
460  fonts:
461  - CanvasTest
462  code: |
463    deferTest();
464    var f = new FontFace("CanvasTest", "/fonts/CanvasTest.ttf");
465    document.fonts.add(f);
466    document.fonts.ready.then(() => {
467        step_timeout(t.step_func_done(function () {
468            ctx.font = '50px CanvasTest';
469            @assert ctx.measureText('A B').width === 150;
470            @assert ctx.measureText('A  B').width === 200;
471            @assert ctx.measureText('A \x09\x0a\x0c\x0d  \x09\x0a\x0c\x0dB').width === 150; @moz-todo
472            @assert ctx.measureText('A \x0b B').width >= 200;
473
474            @assert ctx.measureText(' AB').width === 100; @moz-todo
475            @assert ctx.measureText('AB ').width === 100; @moz-todo
476        }), 500);
477    });
478
479- name: 2d.text.measure.rtl.text
480  desc: Measurement should follow canvas direction instead text direction
481  testing:
482  - 2d.text.measure.rtl.text
483  fonts:
484  - CanvasTest
485  code: |
486    metrics = ctx.measureText('اَلْعَرَبِيَّةُ');
487    @assert metrics.actualBoundingBoxLeft < metrics.actualBoundingBoxRight;
488
489    metrics = ctx.measureText('hello');
490    @assert metrics.actualBoundingBoxLeft < metrics.actualBoundingBoxRight;
491
492- name: 2d.text.measure.boundingBox.textAlign
493  desc: Measurement should be related to textAlignment
494  testing:
495  - 2d.text.measure.boundingBox.textAlign
496  code: |
497    ctx.textAlign = "right";
498    metrics = ctx.measureText('hello');
499    @assert metrics.actualBoundingBoxLeft > metrics.actualBoundingBoxRight;
500
501    ctx.textAlign = "left"
502    metrics = ctx.measureText('hello');
503    @assert metrics.actualBoundingBoxLeft < metrics.actualBoundingBoxRight;
504
505- name: 2d.text.measure.boundingBox.direction
506  desc: Measurement should follow text direction
507  testing:
508  - 2d.text.measure.boundingBox.direction
509  code: |
510    ctx.direction = "ltr";
511    metrics = ctx.measureText('hello');
512    @assert metrics.actualBoundingBoxLeft < metrics.actualBoundingBoxRight;
513
514    ctx.direction = "rtl";
515    metrics = ctx.measureText('hello');
516    @assert metrics.actualBoundingBoxLeft > metrics.actualBoundingBoxRight;
517