summaryrefslogtreecommitdiff
path: root/doc/context/sources/general/manuals/fonts/fonts-extensions.tex
blob: afe6fd82386187945bd09de49c89dff588bc9c62 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220
1221
1222
1223
1224
1225
1226
1227
1228
1229
1230
1231
1232
1233
1234
1235
1236
1237
1238
1239
1240
1241
1242
1243
1244
1245
1246
1247
1248
1249
1250
1251
1252
1253
1254
1255
1256
1257
1258
1259
1260
1261
1262
1263
1264
1265
1266
1267
1268
1269
1270
1271
1272
1273
1274
1275
1276
1277
1278
1279
1280
1281
1282
1283
1284
1285
1286
1287
1288
1289
1290
1291
1292
1293
1294
1295
1296
1297
1298
1299
1300
1301
1302
1303
1304
1305
1306
1307
1308
1309
1310
1311
1312
1313
1314
1315
1316
1317
1318
1319
1320
1321
1322
1323
1324
1325
1326
1327
1328
1329
1330
1331
1332
1333
1334
1335
1336
1337
1338
1339
1340
1341
1342
1343
1344
1345
1346
1347
1348
1349
1350
1351
1352
1353
1354
1355
1356
1357
1358
1359
1360
1361
1362
1363
1364
1365
1366
1367
1368
1369
1370
1371
1372
1373
1374
1375
1376
1377
1378
1379
1380
1381
1382
1383
1384
1385
1386
1387
1388
1389
1390
1391
1392
1393
1394
1395
1396
1397
1398
1399
1400
1401
1402
1403
1404
1405
1406
1407
1408
1409
1410
1411
1412
1413
1414
1415
1416
1417
1418
1419
1420
1421
1422
1423
1424
1425
1426
1427
1428
1429
1430
1431
1432
1433
1434
1435
1436
1437
1438
1439
1440
1441
1442
1443
1444
1445
1446
1447
1448
1449
1450
1451
1452
1453
1454
1455
1456
1457
1458
1459
1460
1461
1462
1463
1464
1465
1466
1467
1468
1469
1470
1471
1472
1473
1474
1475
1476
1477
1478
1479
1480
1481
1482
1483
1484
1485
1486
1487
1488
1489
1490
1491
1492
1493
1494
1495
1496
1497
1498
1499
1500
1501
1502
1503
1504
1505
1506
1507
1508
1509
1510
1511
1512
1513
1514
1515
1516
1517
1518
1519
1520
1521
1522
1523
1524
1525
1526
1527
1528
1529
1530
1531
1532
1533
1534
1535
1536
1537
1538
1539
1540
1541
1542
1543
1544
1545
1546
1547
1548
1549
1550
1551
1552
1553
1554
1555
1556
1557
1558
1559
1560
1561
1562
1563
1564
1565
1566
1567
1568
1569
1570
1571
1572
1573
1574
1575
1576
1577
1578
1579
1580
1581
1582
1583
1584
1585
1586
1587
1588
1589
1590
1591
1592
1593
1594
1595
1596
1597
1598
1599
1600
1601
1602
1603
1604
1605
1606
1607
1608
1609
1610
1611
1612
1613
1614
1615
1616
1617
1618
1619
1620
1621
1622
1623
1624
1625
1626
1627
1628
1629
1630
1631
1632
1633
1634
1635
1636
1637
1638
1639
1640
1641
1642
1643
1644
1645
1646
1647
1648
1649
1650
1651
1652
1653
1654
1655
1656
1657
1658
1659
1660
1661
1662
1663
1664
1665
1666
1667
1668
1669
1670
1671
1672
1673
1674
1675
1676
1677
1678
1679
1680
1681
1682
1683
1684
1685
1686
1687
1688
1689
1690
1691
1692
1693
1694
1695
1696
1697
1698
1699
1700
1701
1702
1703
1704
1705
1706
1707
1708
1709
1710
1711
1712
1713
1714
1715
1716
1717
1718
1719
1720
1721
1722
1723
1724
1725
1726
1727
1728
1729
1730
1731
1732
1733
1734
1735
1736
1737
1738
1739
1740
1741
1742
1743
1744
1745
1746
1747
1748
1749
1750
1751
1752
1753
1754
1755
1756
1757
1758
1759
1760
1761
1762
1763
1764
1765
1766
1767
1768
1769
1770
1771
1772
1773
1774
1775
1776
1777
1778
1779
1780
1781
1782
1783
1784
1785
1786
1787
1788
1789
1790
1791
1792
1793
1794
1795
1796
1797
1798
1799
1800
1801
1802
1803
1804
1805
1806
1807
1808
1809
1810
1811
1812
1813
1814
1815
1816
1817
1818
1819
1820
1821
1822
1823
1824
1825
1826
1827
1828
1829
1830
1831
1832
1833
1834
1835
1836
1837
1838
1839
1840
1841
1842
1843
1844
1845
1846
1847
1848
1849
1850
1851
1852
1853
1854
1855
1856
1857
1858
1859
1860
1861
1862
1863
1864
1865
1866
1867
1868
1869
1870
1871
1872
1873
1874
1875
1876
1877
1878
1879
1880
1881
1882
1883
1884
1885
1886
1887
1888
1889
1890
1891
1892
1893
1894
1895
1896
1897
1898
1899
1900
1901
1902
1903
1904
1905
1906
1907
1908
1909
1910
1911
1912
1913
1914
1915
1916
1917
1918
1919
1920
1921
1922
1923
1924
1925
1926
1927
1928
1929
1930
1931
1932
1933
1934
1935
1936
1937
1938
1939
1940
1941
1942
1943
1944
1945
1946
1947
1948
1949
1950
1951
1952
1953
1954
1955
1956
1957
1958
1959
1960
1961
1962
1963
1964
1965
1966
1967
1968
1969
1970
1971
1972
1973
1974
1975
1976
1977
1978
1979
1980
1981
1982
1983
1984
1985
1986
1987
1988
1989
1990
1991
1992
1993
1994
1995
1996
1997
1998
1999
2000
2001
2002
2003
2004
2005
2006
2007
2008
2009
2010
2011
2012
2013
2014
2015
2016
2017
2018
2019
2020
2021
2022
2023
2024
2025
2026
2027
2028
2029
2030
2031
2032
2033
2034
2035
2036
2037
2038
2039
2040
2041
2042
2043
2044
2045
2046
2047
2048
2049
2050
2051
2052
2053
2054
2055
2056
2057
2058
2059
2060
2061
2062
2063
2064
2065
2066
2067
2068
2069
2070
2071
2072
2073
2074
2075
2076
2077
2078
2079
2080
2081
2082
2083
2084
2085
2086
2087
2088
2089
2090
2091
2092
2093
2094
2095
2096
2097
2098
2099
2100
2101
2102
2103
2104
2105
2106
2107
2108
2109
2110
2111
2112
2113
2114
2115
2116
2117
2118
2119
2120
2121
2122
2123
2124
2125
2126
2127
2128
2129
2130
2131
2132
2133
2134
2135
2136
2137
2138
2139
2140
2141
2142
2143
2144
2145
2146
2147
2148
2149
2150
2151
2152
2153
2154
2155
2156
2157
2158
2159
2160
2161
2162
2163
2164
2165
2166
2167
2168
2169
2170
2171
2172
2173
2174
2175
2176
2177
2178
2179
2180
2181
2182
2183
2184
2185
2186
2187
2188
2189
2190
2191
2192
2193
2194
2195
2196
2197
2198
2199
2200
2201
2202
2203
2204
2205
2206
2207
2208
2209
2210
2211
2212
2213
2214
2215
2216
2217
2218
2219
2220
2221
2222
2223
2224
2225
2226
2227
2228
2229
2230
2231
2232
2233
2234
2235
2236
2237
2238
2239
2240
2241
2242
2243
2244
2245
2246
2247
2248
2249
2250
2251
2252
2253
2254
2255
2256
2257
2258
2259
2260
2261
2262
2263
2264
2265
2266
2267
2268
2269
2270
2271
2272
2273
2274
2275
2276
2277
2278
2279
2280
2281
2282
2283
2284
2285
2286
2287
2288
2289
2290
2291
2292
2293
2294
2295
2296
2297
2298
2299
2300
2301
2302
2303
2304
2305
2306
2307
2308
2309
2310
2311
2312
2313
2314
2315
2316
2317
2318
2319
2320
2321
2322
2323
2324
2325
2326
2327
2328
2329
2330
2331
2332
2333
2334
2335
2336
2337
2338
2339
2340
2341
2342
2343
2344
2345
2346
2347
2348
2349
2350
2351
2352
2353
2354
2355
2356
2357
2358
2359
2360
2361
2362
2363
2364
2365
2366
2367
2368
2369
2370
2371
2372
2373
2374
2375
2376
2377
2378
2379
2380
2381
2382
2383
2384
2385
2386
2387
2388
2389
2390
2391
2392
2393
2394
2395
2396
2397
2398
2399
2400
2401
2402
2403
2404
2405
2406
2407
2408
2409
2410
2411
2412
2413
2414
2415
2416
2417
2418
2419
2420
2421
2422
2423
2424
2425
2426
2427
2428
2429
2430
2431
2432
2433
2434
2435
2436
2437
2438
2439
2440
2441
2442
2443
2444
2445
2446
2447
2448
2449
2450
2451
2452
2453
2454
2455
2456
2457
2458
2459
2460
2461
2462
2463
2464
2465
2466
2467
2468
2469
2470
2471
2472
2473
2474
2475
2476
2477
2478
2479
2480
2481
2482
2483
2484
2485
2486
2487
2488
2489
2490
2491
2492
2493
2494
2495
2496
2497
2498
2499
2500
2501
2502
2503
2504
2505
2506
2507
2508
2509
2510
2511
2512
2513
2514
2515
2516
2517
2518
2519
2520
2521
2522
2523
2524
2525
2526
2527
2528
2529
2530
2531
2532
2533
2534
2535
2536
2537
2538
2539
2540
2541
2542
2543
2544
2545
2546
2547
2548
2549
2550
2551
2552
2553
2554
2555
2556
2557
2558
2559
2560
2561
2562
2563
2564
2565
2566
2567
2568
2569
2570
2571
2572
2573
2574
2575
2576
2577
2578
2579
2580
2581
2582
2583
2584
2585
2586
2587
2588
2589
2590
2591
2592
2593
2594
2595
2596
2597
2598
2599
2600
2601
2602
2603
2604
2605
2606
2607
2608
2609
2610
2611
2612
2613
2614
2615
2616
2617
2618
2619
2620
2621
2622
2623
2624
2625
2626
2627
2628
2629
2630
2631
2632
2633
2634
2635
2636
2637
2638
2639
2640
2641
2642
2643
2644
2645
2646
2647
2648
2649
2650
2651
2652
2653
2654
2655
2656
2657
2658
2659
2660
2661
2662
2663
2664
2665
2666
2667
2668
2669
2670
2671
2672
2673
2674
2675
2676
2677
2678
2679
2680
2681
2682
2683
2684
2685
2686
2687
2688
2689
2690
2691
2692
2693
2694
2695
2696
2697
2698
2699
2700
2701
2702
2703
2704
2705
2706
2707
2708
2709
2710
2711
2712
2713
2714
2715
2716
2717
2718
2719
2720
2721
2722
2723
2724
2725
2726
2727
2728
2729
% language=uk

\startcomponent fonts-extensions

\environment fonts-environment

\startchapter[title=Extensions][color=darkorange]

\startsection[title=Introduction]

One of the benefits of using \TEX\ is that you can add your own features and try
to optimize the look and feel. Of course this can also go wrong and output can
look pretty awful when you don't know what you're doing, but on the average it
works out well. In many aspects the move to an \UNICODE\ data path and \OPENTYPE\
fonts is a good one and solves a lot of problems with traditional \TEX\ engines
and helps us to avoid complex and ugly hacks. But, if you look into the source
code of \CONTEXT\ you will notice that there's still quite some complex coding
needed. This is because we want to control mechanisms, even if it's only for
dealing with some border cases. It's also the reason why \LUATEX\ is what it is:
an extensible engine, building on tradition.

As always with \TEX, fonts are an area where many tuning happens and this is also
true in \CONTEXT. In this chapter some of the extensions will be discussed. Some
extensions run on top of the (rather generic) feature mechanism and some are
using dedicated code.

\stopsection

\startsection[title=Italics]

Although \OPENTYPE\ fonts are more rich in features than traditional \TEX\ and
\TYPEONE\ fonts, one important feature is missing: italic correction. This might
sound strange but you need to keep in mind that in practice it's a feature that
needs to be applied manually.

\starttyping
test {\it test\/} test
\stoptyping

It is possible to automate this mechanism and this is what the \type {\em} command
does in \MKII:

\starttyping
test {\em test} test
\stoptyping

This command knows that it switches to italic (or slanted) and when used nested it
knows to switch back. It also knows if a bold italic or slanted font is used. Therefore
it can add italic correction between an italic and upright shape.

An italic correction is bound to a glyph and bound to a font. In \in {figure}
[latinmodern-italic] we see how an italic shape extends out of the bounding box.
This is not the case in Dejavu: watch \in {figure} [dejavu-italic].

\startplacefigure[reference=latinmodern-italic,title={Italic overshoot in Latin Modern.}]
    \startcombination
        \startcontent
            \backgroundline[gray]{\color[maincolor]{\definedfont[lmroman10-regular*default sa 8]test}}
        \stopcontent
        \startcaption
            Latin Modern Roman Regular
        \stopcaption
        \startcontent
            \backgroundline[gray]{\color[maincolor]{\definedfont[lmroman10-italic*default sa 8]test}}
        \stopcontent
        \startcaption
            Latin Modern Roman Italic
        \stopcaption
    \stopcombination
\stopplacefigure

\startplacefigure[reference=dejavu-italic,title={Italic overshoot in Dejavu Serif.}]
    \startcombination
        \startcontent
            \backgroundline[gray]{\color[maincolor]{\definedfont[dejavuserif*default sa 8]test}}
        \stopcontent
        \startcaption
            Dejavu Regular
        \stopcaption
        \startcontent
            \backgroundline[gray]{\color[maincolor]{\definedfont[dejavuserifitalic*default sa 8]test}}
        \stopcontent
        \startcaption
            Dejavu Italic
        \stopcaption
    \stopcombination
\stopplacefigure

This means that the application of italic correction should never been applied without
knowing the font. In  \in {figure} [italic-upright] we see an upright word following
an italic. The space is determined by the upright one.

\startplacefigure[reference=italic-upright,title={Italic followed by upright.}]
    \startcombination
        \startcontent
            \backgroundline
                [gray]
                {\color[maincolor]{\definedfont[lmroman10-italic*default  sa 4]test}
                 \color[maincolor]{\definedfont[lmroman10-regular*default sa 4]\space test}}
        \stopcontent
        \startcaption
            Latin Modern
        \stopcaption
        \startcontent
            \backgroundline
                [gray]
                {\color[maincolor]{\definedfont[dejavuserifitalic*default sa 4]test}%
                 \color[maincolor]{\definedfont[dejavuserif*default       sa 4]\space test}}
        \stopcontent
        \startcaption
            Dejavu
        \stopcaption
    \stopcombination
\stopplacefigure

Because it is to be used with care you need to enable this feature per font, You
also need to explicitly enable the application of this correction. in \in {figure}
[italic-one] we see italic correction in action.

\startbuffer
\definefontfeature
  [italic]
  [default]
  [itlc=yes]
\stopbuffer

\typebuffer

\getbuffer

\startplacefigure[reference=italic-one,title={Italic correction.}]
    \startcombination
        \startcontent
            \backgroundline
                [maincolor]
                {\color[white]{\definedfont[lmroman10-italic*default  sa 4]test}
                 \color[white]{\definedfont[lmroman10-regular*default sa 4]\space test}}
        \stopcontent
        \startcaption
            \backgroundline
                [maincolor]
                {\setupitaliccorrection[text]%
                 \color[white]{\definedfont[lmroman10-italic*italic   sa 4]test}
                 \color[white]{\definedfont[lmroman10-regular*default sa 4]\space test}}
        \stopcaption
        \startcontent
            \backgroundline
                [maincolor]
                {\color[white]{\definedfont[dejavuserifitalic*default sa 4]test}
                 \color[white]{\definedfont[dejavuserif*default       sa 4]\space test}}
        \stopcontent
        \startcaption
            \backgroundline
                [maincolor]
                {\setupitaliccorrection[text]%
                 \color[white]{\definedfont[dejavuserifitalic*italic sa 4]test}
                 \color[white]{\definedfont[dejavuserif*default      sa 4]\space test}}
        \stopcaption
    \stopcombination
\stopplacefigure

This only signals the font constructor that additional italic information has
to be added to the font metrics. As we already mentioned, the application of
correction is driven by the \type {\/} primitive and that one consults the
font metrics. Because the correction is not part of the original font
metrics it is calculated automatically by adding a small value to the
width. This value is calculated as follows:

\starttyping
factor * (parameters.uwidth or 40) / 2
\stoptyping

The \type {uwidth} parameter is sometimes part of the specification but if not, we
take a reasonable default.  The factor is under user control:

\startbuffer
\definefontfeature
  [moreitalic]
  [default]
  [itlc=5]
\stopbuffer

\typebuffer

\getbuffer

This is demonstrated in \in {figure} [italic-two]. You will notice that for Latin
Modern (any) correction makes sense, but for Dejavu it probably makes things look
worse. This is why italic correction is disabled by default. When enabled there
are several variants:

\starttabulate[|Bl|l|]
\NC global \NC always apply correction \NC \NR
\NC text   \NC only apply correction to text \NC \NR
\NC always \NC apply correction between text and boxes \NC \NR
\NC none   \NC forget about correction \NC \NR
\stoptabulate

We keep track of the state using attributes but that comes at a (small) price in terms
of extra memory and runtime. The \type {global} option simply assumes that we always
need to check for correction (of course only for fonts that have this feature enables).
In the given example we used:

\starttyping
\setupitaliccorrection
  [text]
\stoptyping

You can combine keys:

\starttyping
\setupitaliccorrection
  [global,always]
\stoptyping

\startplacefigure[reference=italic-two,title={Italic correction (factor 5).}]
    \startcombination
        \startcontent
            \backgroundline
                [maincolor]
                {\color[white]{\definedfont[lmroman10-italic*default  sa 4]test}
                 \color[white]{\definedfont[lmroman10-regular*default sa 4]\space test}}
        \stopcontent
        \startcaption
            \backgroundline
                [maincolor]
                {\setupitaliccorrection[text]%
                 \color[white]{\definedfont[lmroman10-italic*italic   sa 4]test}
                 \color[white]{\definedfont[lmroman10-regular*default sa 4]\space test}}
        \stopcaption
        \startcontent
            \backgroundline
                [maincolor]
                {\color[white]{\definedfont[dejavuserifitalic*default sa 4]test}
                 \color[white]{\definedfont[dejavuserif*default       sa 4]\space test}}
        \stopcontent
        \startcaption
            \backgroundline
                [maincolor]
                {\setupitaliccorrection[text]%
                 \color[white]{\definedfont[dejavuserifitalic*italic  sa 4]test}
                 \color[white]{\definedfont[dejavuserif*default       sa 4]\space test}}
        \stopcaption
    \stopcombination
\stopplacefigure

The \type {itlc} feature controls if a font gets italic correction applied. In
principle this is all that the user needs to do, given that the mechanism is
enabled. These is an extra feature that controls the implementation:

\starttabulate[|T|T|p|]
\NC itlc        \NC no    \NC don't apply italic correction (default) \NC \NR
\NC             \NC yes   \NC apply italic correction \NC \NR
\NC textitalics \NC no    \NC precalculate italic corrections (permit engine usage) \NC \NR
\NC             \NC yes   \NC precalculate italic corrections (inhibit engine) \NC \NR
\NC             \NC delay \NC delay calculation of corrections \NC \NR
\stoptabulate

When \type {textitalics} is set to \type {yes} or \type {delay} the mechanism
built into the engine is completely disabled. When set to \type {no} the engine
can kick in but normally the alternative method takes precedence so that the
engine sees no reason for further action. You can trace italic corrections with:

\starttyping
\enabletrackers[typesetters.italics]
\stoptyping

\stopsection

\startsection[title=Bounding boxes]

\startbuffer
\definefontfeature
  [withbbox]
  [boundingbox=yes]

\definefont
  [FontWithBB]
  [Normal*withbbox]
\stopbuffer

\start \getbuffer \FontWithBB

There are some features that are rather useless and only make sense when figuring out
issues. An example of such a feature is the following:

\typebuffer

This feature adds a background to each character in a font. In some fonts a glyph
has a tight bounding box, while on other fonts some extra space is put on the left
and right. Keep in mind that this feature blocks colored text.

\par \stop

\stopsection

\startsection[title=Math italics]

In the traditional \TEX\ fonts the width of a glyph was not the real width because
one had to add the italic correction to it. The engine then juggles a bit with
these properties. If you run into fonts that are designed this way, you can do this:

\starttyping
\definefontfeature[mathextra][italicwidths=yes] % fix latin modern
\stoptyping

This might make \type {$\left|V\right| = \left|W\right|$} look better for such
fonts. Of course there can be side effects because these fonts assume a
traditional engine.

\stopsection

\startsection[title=Slanting]

This features (as well as the one described in the next section) are seldom used
but provided because they were introduced in \PDFTEX.

\startbuffer[define]
\definefontfeature
  [abitslanted]
  [default]
  [slant=.1]

\definefontfeature
  [abitmoreslanted]
  [default]
  [slant=.2]
\stopbuffer

\startbuffer[sample]
\definedfont[Normal*abitslanted]This is a bit slanted.
\definedfont[Normal*abitmoreslanted]And this is a bit more slanted.
\stopbuffer

\typebuffer[define,sample]

The result is:

\getbuffer[define]

\startlines
\getbuffer[sample]
\stoplines

\stopsection

\startsection[title=Extending]

The second manipulation is extending the shapes horizontally:

\startbuffer[define]
\definefontfeature
  [abitbolder]
  [default]
  [extend=1.3]

\definefontfeature
  [abitnarrower]
  [default]
  [extend=0.7]
\stopbuffer

\startbuffer[sample]
\definedfont[Normal*abitbolder]This looks a bit bolder.
\definedfont[Normal*abitnarrower]And this is a bit narrower.
\stopbuffer

\typebuffer[define,sample]

The result is:

\getbuffer[define]

\startlines
\getbuffer[sample]
\stoplines

We can also combine slanting and extending:

\startbuffer[define]
\definefontfeature
  [abitofboth]
  [default]
  [extend=1.3,
   slant=.1]
\stopbuffer

\startbuffer[sample]
\definedfont[Normal*abitofboth]This is a bit bolder but also slanted.
\stopbuffer

\typebuffer[define,sample]

If you remember those first needle matrix printers you might recognize the
next rendering:

\getbuffer[define]

\startlines
\getbuffer[sample]
\stoplines

\stopsection

\startsection[title=Fixing] % dimensions

This is a rather special one. First we show a couple of definitions:

\startbuffer
\definefontfeature
  [dimensions-a]
  [default]
  [dimensions={1,1,1}]

\definefontfeature
  [dimensions-b]
  [default]
  [dimensions={1,2,3}]

\definefontfeature
  [dimensions-c]
  [default]
  [dimensions={1,3,2}]

\definefontfeature
  [dimensions-d]
  [default]
  [dimensions={3,3,3}]
\stopbuffer

\typebuffer \getbuffer

When you don't want a dimension to change you leave an entry empty, so
valid entries are for instance: \type {,3,} and \type {1,,}.

As usual you apply such a feature as follows:

\starttyping
\definefont[MyFont][Serif*dimensions-a sa 2]
\stoptyping

Alternatively you can use such a feature on its own:

\starttyping
\definefontfeature
  [dimensions-333]
  [dimensions={3,3,3}]
\definefont[MyFont][Serif*default,dimensions-333 sa 2]
\stoptyping

In \in {figure} [dimensions-side-by-side] you see these four definitions in
action. The leftmost rendering is the default rendering. The three numbers in the
definitions represent the width (in em), height and depth (in ex).

\startplacefigure[reference={dimensions-side-by-side},title={Freezing dimensions of glyphs.}]
    \startcombination[5*1]
        \startcontent \hbox to 7em {\hss\ruledhbox{\definedfont[Serif*default      sa 2]g}\hss}\stopcontent \startcaption default     \stopcaption
        \startcontent \hbox to 7em {\hss\ruledhbox{\definedfont[Serif*dimensions-a sa 2]g}\hss}\stopcontent \startcaption \hbox{1em 1ex 1ex} \stopcaption
        \startcontent \hbox to 7em {\hss\ruledhbox{\definedfont[Serif*dimensions-b sa 2]g}\hss}\stopcontent \startcaption \hbox{1em 2ex 3ex} \stopcaption
        \startcontent \hbox to 7em {\hss\ruledhbox{\definedfont[Serif*dimensions-c sa 2]g}\hss}\stopcontent \startcaption \hbox{1em 3ex 2ex} \stopcaption
        \startcontent \hbox to 7em {\hss\ruledhbox{\definedfont[Serif*dimensions-d sa 2]g}\hss}\stopcontent \startcaption \hbox{3em 3ex 3ex} \stopcaption
    \stopcombination
\stopplacefigure

This feature only makes sense for fonts that need a fixed width, like the
\CJK\ fonts that are used for asian scripts. Normally those fonts already
have fixed dimensions, but this feature can be used to fix problematic
fonts or add some more space. However, for such large fonts this also brings a
larger memory footprint.

A special case is the following:

\startbuffer
\definefontfeature
  [dimensions-e]
  [dimensions=strut]
\stopbuffer

\typebuffer \getbuffer

This will make the height and depth the same as the {\em current} strut height
and depth:

\startbuffer
\ruledhbox{\definedfont[Serif*default,dimensions-e at  8pt]clipped}
\ruledhbox{\definedfont[Serif*default,dimensions-e at 12pt]clipped}
\ruledhbox{\definedfont[Serif*default,dimensions-e at 24pt]clipped}
\stopbuffer

\typebuffer

The dimensions are (in this case) limited:

\startlinecorrection[blank] \dontleavehmode \hpack{\maincolor\inlinebuffer} \stoplinecorrection

Another special case is \type {dimensions=mono} which will make an characters the
fonts em|-|width. This is handy when you define font fallbacks where glyphs come
from a non monospaced font.

\stopsection

\startsection[title=Unicoding]

Nowadays we will mostly use fonts that ship with a \UNICODE\ aware encoding. And
in \CONTEXT, even if we use a \TYPEONE\ font, it gets mapped onto \UNICODE.
However, there are some exceptions, for instance the Zapf Dingbats in \TYPEONE\
format. These have a rather obscure private encoding and the glyph names run from
\type {a1} upto \type {a206} and have no relation to what the glyph represents.

In the case of Dingbats we're somewhat lucky that they ended up in \UNICODE, so
we can relocate the glyphs to match their rightful place. This is done by means
of a goodies file. We already discussed this in \in {section} [goodies] so we
only repeat the usage.

\startbuffer
\definefontfeature
  [dingbats]
  [mode=base,
   goodies=dingbats,
   unicoding=yes]

\definefontsynonym
  [ZapfDingbats]
  [file:uzdr.afm]
  [features=dingbats]
\stopbuffer

\typebuffer \getbuffer

I tend to qualify the Dingbat font in \TEX\ distributions as rather unstable
because of name changes and them either or not being included. Therefore it's best to
use the hard coded name because that triggers the most visible error message when
the font is not found.

A font like this can for instance be used with the glyph placement macros as is
demonstrated below. In the last line we see that a direct \UTF\ input also works
out well.

\starttabulate[|||T|]
\HL
\NC \type{\getglyphdirect     {ZapfDingbats*dingbats}{\number"2701}} \NC \getglyphdirect     {ZapfDingbats*dingbats}{\number"2701} \NC \NC \NR
\NC \type{\getglyphdirect     {ZapfDingbats*dingbats}{\char"2701}}   \NC \getglyphdirect     {ZapfDingbats*dingbats}{\char"2701}   \NC \NC \NR
\NC \type{\getnamedglyphdirect{ZapfDingbats*dingbats}{a1}}           \NC \getnamedglyphdirect{ZapfDingbats*dingbats}{a1}           \NC \NC \NR
\NC \type{\getnamedglyphdirect{ZapfDingbats*dingbats}{a11}}          \NC \getnamedglyphdirect{ZapfDingbats*dingbats}{a11}          \NC \NC \NR
\HL
\NC \type{\getglyphdirect     {ZapfDingbats}{\number"2701}}          \NC \getglyphdirect     {ZapfDingbats}{\number"2701}          \NC unknown \NC \NR
\NC \type{\getglyphdirect     {ZapfDingbats}{\char"2701}}            \NC \getglyphdirect     {ZapfDingbats}{\char"2701}            \NC unknown \NC \NR
\NC \type{\getnamedglyphdirect{ZapfDingbats}{a1}}                    \NC \getnamedglyphdirect{ZapfDingbats}{a1}                    \NC \NC \NR
\NC \type{\getnamedglyphdirect{ZapfDingbats}{a11}}                   \NC \getnamedglyphdirect{ZapfDingbats}{a11}                   \NC \NC \NR
\HL
\NC \type{\definedfont[ZapfDingbats*dingbats]✁}                      \NC \definedfont[ZapfDingbats*dingbats]✁                      \NC \NC \NR
\HL
\stoptabulate

Keep in mind that fonts like Dejavu (that we use here as document font) already
has these characters which is why it shows up in the verbose part of the table.

\stopsection

\startsection[title=Protrusion]

Protrusion is a feature that \LUATEX\ inherits from \PDFTEX. It is sometimes
referred to as hanging punctuation but in our case any character qualifies. Also,
hanging is not frozen but can be tuned in detail. Currently the engine defines
protrusion in terms of the emwidth which is unfortunate and likely to change.
\footnote {In general the low level implementation can be optimized as there are
better mechanisms in \LUATEX.}

It is sometimes believed that protrusion improves for instance narrower columns,
but I'm pretty sure that this is not the case. It is true that it is taken into
account when breaking a paragraph into lines, and that we then have a little bit
more width available, but at the same time it is an extra constraint: if we
protrude we have to do it for each line (and the whole main body of text) so it's
just a different solution space. The main reason for applying this feature is
{\em not} that the lines look better or that we get better looking narrow lines
but that the right and left margins look nicer. Personally I don't like half
protrusion of punctuation and hyphens. Best is to have small values for regular
characters to improve the visual appearance and use full protrusion for hyphens
(and maybe punctuation).

\startsubsubject[title=protrusion classes]

In \CONTEXT\ we've always defined protrusion as a percentage of the width of a
glyph. From \MKII\ we inherit the level of control as well as the ability to
define vectors. The shared properties are collected in so called classes and the
character specific properties in vectors. The following classes are predefined:

\showprotrusionclass

The names are used in the definitions:

\starttyping
\definefontfeature[default][protrusion=quality]
\stoptyping

Currently adding a class only has a \LUA\ interface.

\startbuffer
\startluacode
fonts.protrusions.classes.myown = {
    vector = 'myown',
    factor = 1,
}
\stopluacode
\stopbuffer

\typebuffer \getbuffer

\stopsubsubject

\startsubsubject[title=protrusion vectors]

Vectors are larger but not as large as you might expect. Only a subset of
characters needs to be defined. This is because in practice only latin scripts
are candidates and these scripts have glyphs that look a lot like each other. As
we only operate on the horizontal direction characters like \quote
{aàáâãäå} look the same from the left and right so we only have to define
the protrusion for \quote {a}.

As with classes, you can define your own vectors:

\startbuffer
\startluacode
fonts.protrusions.vectors.myown = table.merged (
    fonts.protrusions.vectors.quality,
    {
        [0x002C] = { 0, 2 }, -- comma
    }
)
\stopluacode
\stopbuffer

\typebuffer \getbuffer

\stopsubsubject

\startsubsubject[title=protrusion vector pure]
    \showprotrusionvector[name=pure]
\stopsubsubject

\startsubsubject[title=protrusion vector punctuation]
    \showprotrusionvector[name=punctuation]
\stopsubsubject

\startsubsubject[title=protrusion vector alpha]
    \showprotrusionvector[name=alpha]
\stopsubsubject

\startsubsubject[title=protrusion vector quality]
    \showprotrusionvector[name=quality]
\stopsubsubject

\startsubsubject[title=examples of protrusion]

Next we show the quality protrusion. For this we use \type {tufte.tex} as
this one for sure will result in punctuation and other candidates for
protrusion.

\startbuffer[define]
\definefontfeature
  [whatever]
  [default]
  [protrusion=quality]

\definefont[MyTestA][Serif*default  at 10pt]
\definefont[MyTestB][Serif*whatever at 10pt]
\stopbuffer

\startbuffer[example]
\startoverlay
    {\ruledvbox \bgroup
        \hsize\textwidth
        \MyTestA
        \setupalign[normal]
        \input{tufte}
     \egroup}
    {\ruledvbox \bgroup
        \hsize\textwidth
        \MyTestB
        \setupalign[hanging,normal]
        \maincolor
        \input{tufte}
     \egroup}
\stopoverlay
\stopbuffer

\typebuffer[define]
\getbuffer [define]

We use the following example. The results are shown in \in {figure}
[protrusion:quality]. The colored text is the protruding one.

\typebuffer[example]

\startplacefigure[reference=protrusion:quality,title=The difference between no protrusion and quality protrusion.]
    \getbuffer [example]
\stopplacefigure

The previously defined own class and vector is somewhat more extreme:

\startbuffer[define]
\definefontfeature
  [whatever]
  [default]
  [protrusion=myown]

\definefont[MyTestA][Serif*default  at 10pt]
\definefont[MyTestB][Serif*whatever at 10pt]
\stopbuffer

\typebuffer[define]
\getbuffer [define]

In \in {figure} [protrusion:myown] we see that the somewhat extreem definition of
the comma also pulls the preceding character into the margin.

\startplacefigure[reference=protrusion:myown,title=The influence of extreme protrusion on preceding characters.]
    \getbuffer [example]
\stopplacefigure

\stopsubsubject

\stopsection

\startsection[title=Expansion]

Expansion is also an inheritance of \PDFTEX. \footnote {As with protrusion the
implementation in the engine is somewhat suboptimal and inefficient and will be
upgraded to a more \LUATEX-ish way.} This mechanism selectively expands
characters, normally upto 5\%. One reason for applying it is that we have less
visually incompatible spacing, especially when we have underfull or cramped
lines. For each (broken) line the badness is reconsidered with either shrink or
stretch applied to all characters in that line. So, in the worst case a shrunken
line is followed by a stretched one and that can be visible when the scaling
factors are chosen wrong.

As with protrusion, the solution space is larger but so are the constraints. But
contrary to protrusion here the look and feel of the whole line can be made
better but at the cost of much more runtime and larger (\PDF) files.

\startsubsubject[title=protrusion classes]

The amount of expansion depends in the shape of the character. Vertical strokes
are more sensitive for expansion then horizontal ones. So an \quote {o} can
get a different scaling than an \quote {m}. As with protrusion we have collected
the properties in classes:

\showexpansionclass

The smaller the step, the more instances of a font we get, the better it
looks, and the larger the files become. it's best not to use too many stretch
and shrink steps. A stretch of 2 and shrink of 2 and step of .25 results in
upto 8~instances plus the regular sized one.

\stopsubsubject

\startsubsubject[title=expansion vectors]

We only have one vector: \type {quality}:

\showexpansionvector[name=quality]

\stopsubsubject

\startsubsubject[title=an example of expansion]

We use \type {zapf.tex} as example text, if only because Hermann Zapf introduced
this optimization. Keep in mind that you can combine expansion and protrusion.

\startbuffer[define]
\definefontfeature
  [whatever]
  [default]
  [expansion=quality]

\definefont[MyTestA][Serif*default  at 10pt]
\definefont[MyTestB][Serif*whatever at 10pt]
\stopbuffer

\startbuffer[example]
\startoverlay
    {\ruledvbox \bgroup
        \hsize\textwidth
        \MyTestA
        \setupalign[normal]
        \input{tufte}
     \egroup}
    {\ruledvbox \bgroup
        \hsize\textwidth
        \MyTestB
        \setupalign[hz,normal]
        \maincolor
        \input{tufte}
     \egroup}
\stopoverlay
\stopbuffer

\typebuffer[define]
\getbuffer [define]

We use the following example. The results are shown in \in {figure}
[expansion:quality]. The colored text is the protruding one.

\typebuffer[example]

\startplacefigure[reference=expansion:quality,title=The difference between no expansion and quality expansion.]
    \getbuffer [example]
\stopplacefigure

You can see what happens in \in {figure} [expansion:visualized].

\startbuffer[example]
    \setupalign[hz]
    \enabletrackers[*expansion*]
    \definefontfeature[boundingbox][boundingbox={frame,empty}]
    \definedfont[Serif*default,quality,boundingbox @ 12.1pt]
    \samplefile{sapolsky}\par
    \disabletrackers[*expansion*]
\stopbuffer

\typebuffer[example]

\startplacefigure[reference=expansion:visualized,title=The injected expansion kerns.]
    \getbuffer [example]
\stopplacefigure

\stopsubsubject

\startsubsubject[title=Expansion and kerning]

When we expand glyphs we also need to look at the font kerns between them. In the
original implementation taken from \PDFTEX\ expansion was implemented using pseudo
fonts (with expanded glyph widths) and expansion of inter|-|character kerns was
based on font information. In \LUATEX\ we have expansion factors in glyph nodes
instead which is more efficient and gives a cleaner separation between front- and
backend as the backend has no need to consult the font.

For the font kerns we set the kern compensation directly and for that we use the
average expansion factors of the neighbouring fonts so technically we support
kerns between different fonts). This also has the advantage that kerns injected
in node mode are treated well, given that they are tagged as font kern.

So what is the effect (and need) of scaling font kerns? Let's look at an example.
Kerns can be positive but also negative:

\startlinecorrection
\startcombination
    {\vbox {
        \forgetall
        \hpack to 3cm{\hss\ruledhbox{\maincolor V\kern-1ptA}\hss}
        \hpack to 3cm{\hss\ruledhbox{\maincolor V\kern 0ptA}\hss}
    }} {negative}
    {\vbox {
        \forgetall
        \hpack to 3cm{\hss\ruledhbox{\maincolor I\kern.25ptI}\hss}
        \hpack to 3cm{\hss\ruledhbox{\maincolor I\kern  0ptI}\hss}
    }} {positive}
\stopcombination
\stoplinecorrection

If we use a rediculous amount of stretch we get the following. In the top line we
scale the kern, in the bottom line we don't.

\startlinecorrection
\startcombination
    {\vbox {
        \definedfont[file:texgyrepagella-regular.otf at 12pt]%
        \forgetall
        \hpack to 3cm{\maincolor \hss\strut \scale[xscale=5000]{V}\kern-5pt\scale[xscale=5000]{A}\hss}
        \hpack to 3cm{\maincolor \hss\strut \scale[xscale=5000]{V}\kern-1pt\scale[xscale=5000]{A}\hss}
    }} {negative}
    {\vbox {
        \definedfont[file:texgyrepagella-regular.otf at 12pt]%
        \forgetall
        \hpack to 3cm{\maincolor \hss\strut \scale[xscale=5000]{I}\kern1.25pt\scale[xscale=5000]{I}\hss}
        \hpack to 3cm{\maincolor \hss\strut \scale[xscale=5000]{I}\kern0.25pt\scale[xscale=5000]{I}\hss}
    }} {positive}
\stopcombination
\stoplinecorrection

The reason that we mention this is that when we apply \OPENTYPE\ features,
positioning not necessarily result in font kerns. For instance ligatures can be
the result of careful applied kerns and in some scripts kerns are used to connect
glyphs. This means that we best cannot expand kerns by default. How bad is
that? By looking at the examples above one would say \quotation {real bad}.

But say that we have about 1pt of font kerns, then a 5\% expansion (which is
already a lot) amounts to 0.05pt so to \blackrule [width=1pt, height=max,
depth=max] we add \blackrule [width=.05pt, height=max, depth=max] which is so
little that it probably goes unnoticed. Even if we use extreme kerns, as between
VA, in practice the small amount of stretch or shrink added to a font kern goes
unnoticed.

In \in {figure} [hz:natural] we have overlayed the different strategies. The
sample and width is chosen such that we see something. On a display you can
scale up these examples and inspect if there is really something to see,
but on paper zooming in helps, as in \in {figure} [hz:zoomed]. Even then the
effect of expanded kerns is invisible. The used definitions are:

\definecolor[hz:test:tr][r=1,a=1,t=.5]
\definecolor[hz:test:tg][g=1,a=1,t=.5]
\definecolor[hz:test:tb][b=1,a=1,t=.5]

\startbuffer
\setupfontexpansion
    [extremehz]
    [stretch=5,shrink=5,step=.5,vector=default,factor=1]
\setupfontexpansion
    [regularhz]
    [stretch=2,shrink=2,step=.5,vector=default,factor=1]
\setupfontexpansion
    [minimalhz]
    [stretch=2,shrink=2,step=.5,vector=default,factor=.5]

\definefontfeature
    [extremehz] [default]
    [mode=node,expansion=extremehz]
\definefontfeature
    [regularhz] [default]
    [mode=node,expansion=regularhz]
\definefontfeature [minimalhz] [default]
    [mode=node,expansion=minimalhz]

\definefont
    [ExtremeHzFont]
    [file:texgyrepagella-regular.otf*extremehz at 10pt]
\definefont
    [RegularHzFont]
    [file:texgyrepagella-regular.otf*regularhz at 10pt]
\definefont
    [MinimalHzFont]
    [file:texgyrepagella-regular.otf*minimalhz at 10pt]
\stopbuffer

\typebuffer \getbuffer

\edef\HzSampleText{\cldloadfile{ward}}

\def\NoHzSample  {\vbox{\hsize 10cm \color[hz:test:tr]{\setupalign  [nohz]\HzSampleText\par}}}
\def\HzSample    {\vbox{\hsize 10cm \color[hz:test:tg]{\setupalign    [hz]\HzSampleText\par}}}
\def\FullHzSample{\vbox{\hsize 10cm \color[hz:test:tb]{\setupalign[fullhz]\HzSampleText\par}}}

\startplacefigure[reference=hz:natural,title={The two expansion methods compared.}]
    \showfontkerns
    \dontcomplain
    \startcombination[1*3]
        {\ExtremeHzFont\ruledhpack{\startoverlay {\NoHzSample} {\HzSample    } \stopoverlay}} {no hz \& hz}
        {\ExtremeHzFont\ruledhpack{\startoverlay {\NoHzSample} {\FullHzSample} \stopoverlay}} {no hz \& full hz}
        {\ExtremeHzFont\ruledhpack{\startoverlay {\HzSample  } {\FullHzSample} \stopoverlay}} {hz \& full hz}
    \stopcombination
\stopplacefigure

\startplacefigure[reference=hz:zoomed,title={The two expansion methods compared (zoomed in).}]
    \showfontkerns
    \dontcomplain
    \startcombination[3*3]

        {\ExtremeHzFont
         \clip[nx=6,ny=5,x=2,y=2,sx=2]{\startoverlay {\NoHzSample} {\HzSample    } \stopoverlay}} {extreme: no hz \& hz}
        {\ExtremeHzFont
         \clip[nx=6,ny=5,x=2,y=2,sx=2]{\startoverlay {\NoHzSample} {\FullHzSample} \stopoverlay}} {extreme: no hz \& full hz}
        {\ExtremeHzFont
         \clip[nx=6,ny=5,x=2,y=2,sx=2]{\startoverlay {\HzSample  } {\FullHzSample} \stopoverlay}} {extreme: hz \& full hz}

        {\RegularHzFont
         \clip[nx=6,ny=5,x=2,y=2,sx=2]{\startoverlay {\NoHzSample} {\HzSample    } \stopoverlay}} {regular: no hz \& hz}
        {\RegularHzFont
         \clip[nx=6,ny=5,x=2,y=2,sx=2]{\startoverlay {\NoHzSample} {\FullHzSample} \stopoverlay}} {regular: no hz \& full hz}
        {\RegularHzFont
         \clip[nx=6,ny=5,x=2,y=2,sx=2]{\startoverlay {\HzSample  } {\FullHzSample} \stopoverlay}} {regular: hz \& full hz}

        {\MinimalHzFont
         \clip[nx=6,ny=5,x=2,y=2,sx=2]{\startoverlay {\NoHzSample} {\HzSample    } \stopoverlay}} {minimal: no hz \& hz}
        {\MinimalHzFont
         \clip[nx=6,ny=5,x=2,y=2,sx=2]{\startoverlay {\NoHzSample} {\FullHzSample} \stopoverlay}} {minimal: no hz \& full hz}
        {\MinimalHzFont
         \clip[nx=6,ny=5,x=2,y=2,sx=2]{\startoverlay {\HzSample  } {\FullHzSample} \stopoverlay}} {minimal: hz \& full hz}

    \stopcombination
\stopplacefigure

In \CONTEXT\ the \type {hz} alignment option only enables expansion of glyphs,
while \type {fullhz} also applies it to kerns. It will be clear that you can just
stick to using the \type {hz} directive (if you want expansion at all) because
this directive is normally disabled and because most fonts are processed in node
mode.

\stopsubsubject

\stopsection

\startsection[title=Composing]

This feature is seldom needed but can come in handy for old fonts or when
some special language is to be supported. When writing this section I tested
this feature with Dejavu and only two additional characters were added:

\definefontfeature
  [default-plus-compose]
  [compose=yes]

\definefont
  [MyComposedSerif]
  [Serif*default-plus-compose]

% we need to cheat a bit as we don't have the main character in mono

\startlines \MyComposedSerif
\type{fonts > combining > }\hbox to .5em{\hss Ѷ\hss}\type{ (U+00476) = }\hbox to .5em{\hss Ѵ\hss}\type{ (U+00474) + ̏ (U+0030F)}
\type{fonts > combining > }\hbox to .5em{\hss ѷ\hss}\type{ (U+00477) = }\hbox to .5em{\hss ѵ\hss}\type{ (U+00475) + ̏ (U+0030F)}
\stoplines

This trace showed up after giving:

\starttyping
\enabletrackers
  [fonts.composing.define]

\definefontfeature
  [default-plus-compose]
  [compose=yes]

\definefont
  [MyFont]
  [Serif*default-plus-compose]
\stoptyping

Fonts like Latin Modern have lots of glyphs but still lack some. Although the
composer can add some of the missing, some of those new virtual glyphs probably
will never look real good. For instance, putting additional accents on top of
already accented uppercase characters will fail when that character has a rather
tight (or even clipped) boundingbox in order not to spoil the lineheight. You can
get some more insight in the process by turning on tracing:

\starttyping
\enabletrackers[fonts.composing.visualize]
\stoptyping

One reason why composing can be suboptimal is that it uses the boundingbox of the
characters that are combined. If you really depend on a specific font and need
some of the missing characters it makes sense to spend some time on optimizing
the rendering. This can be done via the goodies mechanism. As an example we've
added \type {lm-compose-test.lfg} to the distribution. First we show how it
looks at the \TEX\ end:

\startbuffer
\enabletrackers[fonts.composing.visualize]

\definefontfeature
  [default-plus-compose]
  [compose=yes]

\loadfontgoodies
  [lm-compose-test] % playground

\definefont
  [MyComposedSerif]
  [file:lmroman10regular*default-plus-compose at 48pt]
\stopbuffer

\typebuffer \getbuffer

\blank
\backgroundline
  [halfcolor]
  {\MyComposedSerif B\quad\char"1E02\quad\char"1E04}
\blank

The positions of the dot accents on top and below the capital B is defined
in a goodie file:

\starttyping
return {
  name = "lm-compose-test",
  version = "1.00",
  comment = "Goodies that demonstrate composition.",
  author = "Hans and Mojca",
  copyright = "ConTeXt development team",
  compositions = {
    ["lmroman12-regular"] = compose,
  }
}
\stoptyping

As this is an experimental feature there are several ways to deal with
this. For instance:

\starttyping
local defaultfraction = 10.0

local compose = {
  dy       = defaultfraction,
  [0x1E02] = { -- B dot above
      dy = 150
  },
  [0x1E04] = { -- B dot below
      dy = 150
  },
}
\stoptyping

Here the fraction is relative to the difference between the height of the
accentee and the accent. A better solution is the following:

\starttyping
local compose = {
  [0x1E02] = { -- B dot above
    anchored = "top",
  },
  [0x1E04] = { -- B dot below
    anchored = "bottom",
  },
  [0x0042] = { -- B
    anchors = {
      top = {
        x = 300, y = 700,
      },
      bottom = {
        x = 300, y = -30,
      },
    },
  },
  [0x0307] = {
    anchors = {
      top = {
        x = -250, y =  550,
      },
    },
  },
  [0x0323] = {
    anchors = {
      bottom = {
        x = -250, y =  -80,
      },
    },
  },
}
\stoptyping

This approach is more or less the same as \OPENTYPE\ anchoring. It takes a bit
more effort to define these tables but the result is better.

\stopsection

\startsection[title=Kerning]

Inter|-|character kerning is not supported at the font level and with good
reason. The fact that something is conceptually possible doesn't mean that we
should use or support it. Normally proper kerning (or the lack of it) is part
of a font design and for some scripts different kerning is not even an option.

On the average \TEX\ does a proper job on justification but not all programs
are that capable. As a consequence designers (at least we ran into it) tend to
stick to flush left rendering because they don't trust their system to do a
proper job otherwise. On the other hand they seem to have no problem with
messing up the inter|-|character spacing and even combine that with excessive
inter|-|word spacing {\em if} they want to achieve justification (without
hyphenation). And it can become even worse when extreme glyph expansion (like
hz) is applied.

Anyhow, it will be clear that consider messing with properties like kerning that
are part of the font design is to be done careful.

\definecharacterkerning [extremekerning] [factor=.125]

\start \setcharacterkerning[extremekerning]

For running text additional kerning makes no sense. It not only looks
bad, it also spoils the grayness of a text. When it is applied we need
to deal with special cases. For instance ligatures make no sense so they
should be disabled. Additional kerning should relate to already present
kerning and interword spacing should be adapted accordingly. Embedded
non|-|characters also need to be treated well.

\par \stop

This paragraph was typeset as follows:

\starttyping
\definecharacterkerning [extremekerning] [factor=.125]

\setcharacterkerning[extremekerning] ... text ...
\stoptyping

Where additional kerning can make sense, is in titles. The previous
command can do that job. In addition we have a mechanism that
fills a given space. This mechanism uses the following definition:

\starttyping
\setupcharacterkerning
  [stretched]
  [factor=max,
   width=\availablehsize]
\stoptyping

\startbuffer
\stretched{\bfd to the limit}
\stopbuffer

\typebuffer

\blank \start \color[maincolor]{\getbuffer} \stop \blank

The following does not work:

\startbuffer
\ruledhbox to 5cm{\stretched{\bfd to the limit}}
\stopbuffer

\typebuffer

\blank \start \color[maincolor]{\getbuffer} \stop \blank

But this works ok:

\startbuffer
\setupcharacterkerning
  [stretched]
  [width=]

\stretched{\bfd to the limit}
\stopbuffer

\typebuffer

\blank \start \color[maincolor]{\getbuffer} \stop \blank

You can also say this:

\startbuffer
\stretched[width=]{\bfd to the limit}
\stopbuffer

\typebuffer

\blank \start \color[maincolor]{\getbuffer} \stop \blank

or:

\startbuffer
\ruledhbox{\stretched[width=10cm]{\bfd to the limit}}
\stopbuffer

\typebuffer

\blank \start \color[maincolor]{\getbuffer} \stop \blank

You can get some insight in what kerning does to your font by the following
command:

\startbuffer
\usemodule[typesetting-kerning]

\starttext
  \showcharacterkerningsteps
    [style=Bold,
     sample=how to violate a proper font design,
     text=rubish,
     first=0,
     last=45,
     step=5]
\stoptext
\stopbuffer

\typebuffer

\blank \getbuffer \blank

\stopsection

\startsection[title=Extra font kerns]

Fonts are processed independent of each other. Sometimes that is unfortunate for
kerning, although in practice it won't happen that often. We can enable an
additional kerning mechanism to deal with these cases. The \type
{\setextrafontkerns} command takes one argument between square brackets. The
effect can be seen below:

\startbuffer
    VA {\smallcaps va} V{\smallcaps a}
    VA {\bf VA} V{\bf A} {\bf V}A
    V{\it A}
\stopbuffer

\starttabulate[|Tl|l|p|]
\HL
\BC key \BC result \BC logic \NC \NR
\HL
\NC no kerns \NC \showfontkerns\setextrafontkerns[reset]\subff{f:kern}\inlinebuffer \NC no kerns at all \NC \NR
\NC kerns    \NC \showfontkerns\setextrafontkerns[reset]\inlinebuffer \NC kerns within a font (feature) run \NC \NR
\HL
\NC none     \NC \showfontkerns\setextrafontkerns [none]\inlinebuffer \NC only extra kerns within fonts \NC \NR
\NC min      \NC \showfontkerns\setextrafontkerns  [min]\inlinebuffer \NC minimal kerns within and across fonts \NC \NR
\NC max      \NC \showfontkerns\setextrafontkerns  [max]\inlinebuffer \NC maximum kerns within and across fonts \NC \NR
\NC mixed    \NC \showfontkerns\setextrafontkerns[mixed]\inlinebuffer \NC averaged kerns within and across fonts \NC \NR
\HL
\stoptabulate

The content is defined as:

\typebuffer

This mechanism obeys grouping so you have complete control over where and when
it gets applied. The \type {\showfontkerns} command can be used to trace the
injection of (font) kerns.

\stopsection

\startsection[title=Ligatures]

For some Latin fonts ligature building is quite advanced, take Unifraktur. I have no
problem admitting that I find fraktur hard to read, but this one actually is sort of
an exception. It's also a good candidate for a screen presentation where you mainly
made notes for yourself: no one has to read it, but it looks great, especially if
you consider it to be drawn by a pen.

Anyway, we will use the following code as example (based on some remarks on the
fonts website).

\startbuffer[sample]
sitzen / ſitzen / effe fietsen / ch ck ſt tz ſi fi
\stopbuffer

\typebuffer[sample]

Some ligatures are implemented in the usual way, using the \type {liga} and \type {dlig}
features, others kick in thanks to \type {ccmp}. This fact alone is an illustration that
the low level \OPENTYPE\ ligature feature is not related to ligatures at all but a more
generic mechanism: you can basically combine multiple shapes into one in all features
exposed to the user.

We define a bunch of specific feature sets:

\startbuffer
\definefontfeature
  [unifraktur-a]
  [default]
\definefontfeature
  [unifraktur-b]
  [default]
  [goodies=unifraktur,keepligatures=yes]
\definefontfeature
  [unifraktur-c]
  [default]
  [ccmp=yes]
\definefontfeature
  [unifraktur-d]
  [default]
  [ccmp=yes,goodies=unifraktur,keepligatures=yes]
\definefontfeature
  [unifraktur-e]
  [default]
  [liga=no,rlig=no,clig=no,dlig=no,ccmp=yes,keepligatures=auto]
\stopbuffer

\getbuffer \typebuffer

and also some fonts:

\startbuffer
\definefont[TestA][UnifrakturCook*unifraktur-a sa 0.9]
\definefont[TestB][UnifrakturCook*unifraktur-b sa 0.9]
\definefont[TestC][UnifrakturCook*unifraktur-c sa 0.9]
\definefont[TestD][UnifrakturCook*unifraktur-d sa 0.9]
\definefont[TestE][UnifrakturCook*unifraktur-e sa 0.9]
\stopbuffer

\getbuffer \typebuffer

We show these five alternatives here:

\starttabulate[|T||]
\NC liga                        \NC \TestA\getbuffer[sample] \NC \NR
\NC liga + keepligatures        \NC \TestB\getbuffer[sample] \NC \NR
\NC liga + ccmp                 \NC \TestC\getbuffer[sample] \NC \NR
\NC liga + ccmp + keepligatures \NC \TestD\getbuffer[sample] \NC \NR
\NC ccmp + keepligatures        \NC \TestE\getbuffer[sample] \NC \NR
\stoptabulate

The real fun starts when we want to add extra spacing between characters. Some
ligatures need to get broken and some kept.

\startbuffer
\setupcharacterkerning[kerncharacters][factor=0.5]
\setupcharacterkerning[letterspacing] [factor=0.5]
\stopbuffer

\getbuffer \typebuffer

\enabletrackers[typesetters.kerns.ligatures]

Next we will see how ligatures behave depending on how the mechanisms are set
up. The colors indicate what trickery is used:

\starttabulate[|T||]
\NC \color[darkred]  {red}   \NC kept by dynamic feature \NC \NR
\NC \color[darkgreen]{green} \NC kept by static feature  \NC \NR
\NC \color[darkblue] {blue}  \NC keep by goodie          \NC \NR
\stoptabulate

First we use \type {\kerncharacters}:

\starttabulate[|T||]
\NC liga                        \NC \kerncharacters {\TestA\getbuffer[sample]} \NC \NR
\NC liga + keepligatures        \NC \kerncharacters {\TestB\getbuffer[sample]} \NC \NR
\NC liga + ccmp                 \NC \kerncharacters {\TestC\getbuffer[sample]} \NC \NR
\NC liga + ccmp + keepligatures \NC \kerncharacters {\TestD\getbuffer[sample]} \NC \NR
\NC ccmp + keepligatures        \NC \kerncharacters {\TestE\getbuffer[sample]} \NC \NR
\stoptabulate

In the next example we use \type {\letterspacing}:

\starttabulate[|T||]
\NC liga                        \NC \letterspacing {\TestA\getbuffer[sample]} \NC \NR
\NC liga + keepligatures        \NC \letterspacing {\TestB\getbuffer[sample]} \NC \NR
\NC liga + ccmp                 \NC \letterspacing {\TestC\getbuffer[sample]} \NC \NR
\NC liga + ccmp + keepligatures \NC \letterspacing {\TestD\getbuffer[sample]} \NC \NR
\NC ccmp + keepligatures        \NC \letterspacing {\TestE\getbuffer[sample]} \NC \NR
\stoptabulate

\disabletrackers[typesetters.kerns.ligatures]

The difference is that the letterspacing variant dynamically adds the predefined
featureset \type {letterspacing} which is defined in a similar way as \type
{unifraktur-e}. In the case of this font, this variant is the better one to use.
In fact, this variant probably works okay with most fonts. However, by not hard
coding this behaviour we keep control, as one never knows what the demands are.
When no features are used, information from the (given) goodie file \type
{unifraktur.lfg} is consulted:

\starttyping
letterspacing = {
  -- watch it: zwnj's are used (in the tounicodes too)
  keptligatures = {
    ["c_afii301_k.ccmp"] = true, -- ck
    ["c_afii301_h.ccmp"] = true, -- ch
    ["t_afii301_z.ccmp"] = true, -- tz
    ["uniFB05"]          = true, -- ſt
  },
}
\stoptyping

These kick in when we don't disable ligatures by setting features (case~e).

There are two pseudo features that can help us out when a font doesn't provide
the wanted ligatures but has the right glyphs for building them. The \UNICODE\
database has some information about how characters can be (de)composed and we can
use that information to create virtual glyphs:

\starttyping
\definefontfeature
  [default] [default]
  [char-ligatures=yes,mode=node]
\stoptyping

and:

\starttyping
\definefontfeature
  [default] [default]
  [compat-ligatures=yes,mode=node]
\stoptyping

This feature was added after some discussion on the \CONTEXT\ mailing list about
the following use case.

\startbuffer
\definefontfeature
  [default-l] [default]
  [char-ligatures=yes,
   compat-ligatures=yes,
   mode=node]

\definefont[LigCd][cambria*default]
\definefont[LigPd][texgyrepagellaregular*default]
\definefont[LigCl][cambria*default-l]
\definefont[LigPl][texgyrepagellaregular*default-l]
\stopbuffer

\typebuffer \getbuffer

These definitions result in:

\starttabulate[|l|l|l|l|l|]
\NC                    \NC \type {\LigCd}     \NC \type {\LigPd}     \NC \type {\LigCl}     \NC \type {\LigPl}     \NC \NR
\NC \type{PEL·LÍCULES} \NC \LigCd PEL·LÍCULES \NC \LigPd PEL·LÍCULES \NC \LigCl PEL·LÍCULES \NC \LigPl PEL·LÍCULES \NC \NR
\NC \type{pel·lícules} \NC \LigCd pel·lícules \NC \LigPd pel·lícules \NC \LigCl pel·lícules \NC \LigPl pel·lícules \NC \NR
\NC \type{PEĿLÍCULES}  \NC \LigCd PEĿLÍCULES  \NC \LigPd PEĿLÍCULES  \NC \LigCl PEĿLÍCULES  \NC \LigPl PEĿLÍCULES  \NC \NR
\NC \type{peŀlícules}  \NC \LigCd peŀlícules  \NC \LigPd peŀlícules  \NC \LigCl peŀlícules  \NC \LigPl peŀlícules  \NC \NR
\stoptabulate

Of course one can wonder is this is the right approach and if it's not better to
use a font that provides the needed characters in the first place.

\stopsection

\startsection[title=New features]

\startsubsection[title=Substitution]

It is possible to add new features via \LUA. Here is an example of a single
substitution:

\startbuffer
\startluacode
    fonts.handlers.otf.addfeature {
        name = "stest",
        type = "substitution",
        data = {
            a = "X",
            b = "P",
        }
    }
\stopluacode
\stopbuffer

\typebuffer \getbuffer

We show an overview at the end of this section, but here is a simple example
already. You need to define the feature before defining a font because otherwise
the font will not know about it.

\startbuffer
\definefontfeature[stest][stest=yes]
\definedfont[file:dejavu-serifbold.ttf*default]
abracadabra: \addff{stest}abracadabra
\stopbuffer

\typebuffer \start \blank \maincolor \getbuffer \blank \stop

Instead of (more readable) glyph names you can also give \UNICODE\ numbers:

\starttyping
\startluacode
    fonts.handlers.otf.addfeature {
        name = "stest",
        type = "substitution",
        data = {
            [0x61] = 0x58
            [0x62] = 0x50
        }
    }
\stopluacode
\stoptyping

The definition is quite simple: we just map glyph names (or unicodes) onto
other ones. An alternate is also possible:

\startbuffer
\startluacode
    fonts.handlers.otf.addfeature {
        name = "atest",
        type = "alternate",
        data = {
            a = { "X", "Y" },
            b = { "P", "Q" },
        }
    }
\stopluacode
\stopbuffer

\typebuffer \getbuffer

Less useful is a multiple substitution. Normally this one is part of a chain of
replacements.

\startbuffer
\startluacode
    fonts.handlers.otf.addfeature {
        name = "mtest",
        type = "multiple",
        data = {
            a = { "X", "Y" },
            b = { "P", "Q" },
        }
    }
\stopluacode
\stopbuffer

\typebuffer \getbuffer

A ligature (or multiple to one) is also possible but normally only makes sense when
there is indeed a ligature. We use a similar definition for mapping the \TEX\ input
sequence \type {---} onto an \emdash.

\startbuffer
\startluacode
    fonts.handlers.otf.addfeature {
        name = "ltest",
        type = "ligature",
        data = {
            ['1'] = { "a", "b" },
            ['2'] = { "d", "a" },
        }
    }
\stopluacode
\stopbuffer

\typebuffer \getbuffer

\stopsubsection

\startsubsection[title=Positioning]

You can define a kern feature too but when doing so you need to use measures in
font units.

\startbuffer
\startluacode
    fonts.handlers.otf.addfeature {
        name = "ktest",
        type = "kern",
        data = {
            a = { b = -500 },
        }
    }
\stopluacode
\stopbuffer

\typebuffer \getbuffer

Pairwise positioning is more complex and involves two (optional) arrays
that specify \type {{dx dy wd ht}} for each of the two glyphs. In the next
example we only displace the second glyph.

\startbuffer
\startluacode
    fonts.handlers.otf.addfeature {
        name = "ptest",
        type = "pair",
        data = {
            ["a"] = { ["b"] = { false,  { -1000, 1200, 0, 0 } } },
        }
    }
\stopluacode
\stopbuffer

\typebuffer \getbuffer

Of course you need to know a bit about the metrics of the glyphs involved so in
practice this boils down to trial and error.

A single character (glyph) can also be tweaked, although normally this is done
better in a manipulator when loading the font. Anyway:

\startbuffer
\startluacode
    fonts.handlers.otf.addfeature {
        name = "stest",
        type = "single",
        data = {
            a = { -30, 0, -50, 0 },
        }
    }
\stopluacode
\stopbuffer

\typebuffer \getbuffer

This will reduce the left and right edges and make the glyph a pretty tight one. The
values are for Latin Modern.

\stopsubsection

\startsubsection[title=Examples]

We didn't show usage yet. This is because we need to define a feature before we
define a font. New features will be added to a font when it gets defined.

\startbuffer
\definefontfeature[stest][stest=yes]
\definefontfeature[atest][atest=2]
\definefontfeature[mtest][mtest=yes]
\definefontfeature[ltest][ltest=yes]
\definefontfeature[ktest][ktest=yes]
\definefontfeature[ptest][ptest=yes]
\definefontfeature[ctest][ctest=yes]

\definedfont[file:dejavu-serif.ttf*default]

\starttabulate[|l|l|l|]
\NC operation    \NC feature       \NC              abracadabra \NC \NR
\HL
\NC substitution \NC \type {stest} \NC \addff{stest}abracadabra \NC \NR
\NC alternate    \NC \type {atest} \NC \addff{atest}abracadabra \NC \NR
\NC multiple     \NC \type {mtest} \NC \addff{mtest}abracadabra \NC \NR
\NC ligature     \NC \type {ltest} \NC \addff{ltest}abracadabra \NC \NR
\NC kern         \NC \type {ktest} \NC \addff{ktest}abracadabra \NC \NR
\NC pair         \NC \type {ptest} \NC \addff{ptest}abracadabra \NC \NR
\NC chain sub    \NC \type {ctest} \NC \addff{ctest}abracadabra \NC \NR
\stoptabulate
\stopbuffer

\typebuffer \getbuffer

\stopsubsection

\startsubsection[title=Contexts]

A more complex substitution is the following:

\startbuffer
\startluacode
    fonts.handlers.otf.addfeature {
        name    = "ytest",
        type    = "chainsubstitution",
        lookups = {
            {
                type = "substitution",
                data = {
                    ["b"] = "B",
                    ["c"] = "C",
                },
            },
        },
        data = {
            rules = {
                {
                    before  = { { "a" } },
                    current = { { "b", "c" } },
                    lookups = { 1 },
                },
            },
        },
    }
\stopluacode
\stopbuffer

\typebuffer \getbuffer

Here the dataset is a sequence of rules. There can be a \type {before}, \type
{current} and \type {after} match. The replacements are specified with the \type
{lookups} entry and the numbers are indices in the provided \type {lookups}
table.

Here is another example. This one demonstrates that one can check against spaces
(some fonts kerns against them) and against boundaries as well. The later is
something \CONTEXT\ specific. First we define a feature that create ligatures but
only when we touch a space:

\startbuffer
\startluacode
    fonts.handlers.otf.addfeature {
        name    = "test-a",
        type    = "chainsubstitution",
        lookups = {
            {
                type = "ligature",
                data = {
                    ['1'] = { "a", "b" },
                    ['2'] = { "c", "d" },
                },
            },
        },
        data = {
            rules = {
                {
                    before  = { { " " } },
                    current = { { "a" }, { "b" } },
                    lookups = { 1 },
                },
                {
                    current = { { "c" }, { "d" } },
                    after   = { { " " } },
                    lookups = { 1 },
                },
            },
        },
    }
\stopluacode
\stopbuffer

\typebuffer \getbuffer

The next example also checks against whatever boundary we have.

\startbuffer
\startluacode
    fonts.handlers.otf.addfeature {
        name    = "test-b",
        type    = "chainsubstitution",
        lookups = {
            {
                type = "ligature",
                data = {
                    ['1'] = { "a", "b" },
                    ['2'] = { "c", "d" },
                },
            },
        },
        data = {
            rules = {
                {
                    before  = { { " ", 0xFFFC } },
                    current = { { "a" }, { "b" } },
                    lookups = { 1 },
                },
                {
                    current = { { "c" }, { "d" } },
                    after   = { { 0xFFFC, " " } },
                    lookups = { 1 },
                },
            },
        },
    }
\stopluacode
\stopbuffer

\typebuffer \getbuffer

We can actually simplify this one to:

\startbuffer
\startluacode
    fonts.handlers.otf.addfeature {
        name    = "test-c",
        type    = "chainsubstitution",
        lookups = {
            {
                type = "ligature",
                data = {
                    ['1'] = { "a", "b" },
                    ['2'] = { "c", "d" },
                },
            },
        },
        data = {
            rules = {
                {
                    before  = { { 0xFFFC } },
                    current = { { "a" }, { "b" } },
                    lookups = { 1 },
                },
                {
                    current = { { "c" }, { "d" } },
                    after   = { { 0xFFFC } },
                    lookups = { 1 },
                },
            },
        },
    }
\stopluacode
\stopbuffer

\typebuffer \getbuffer

As a bonus we show how to do more complex things:

\startbuffer
\startluacode
    fonts.handlers.otf.addfeature {
        name    = "test-d",
        type    = "chainsubstitution",
        lookups = {
            {
                type = "substitution",
                data = {
                    ["a"] = "A",
                    ["b"] = "B",
                    ["c"] = "C",
                    ["d"] = "D",
                },
            },
            {
                type = "ligature",
                data = {
                    ['1'] = { "a", "b" },
                    ['2'] = { "c", "d" },
                },
            },
        },
        data = {
            rules = {
                {
                    before  = { { 0xFFFC } },
                    current = { { "a" }, { "b" } },
                    lookups = { 2 },
                },
                {
                    current = { { "c" }, { "d" } },
                    after   = { { 0xFFFC } },
                    lookups = { 2 },
                },
                {
                    current = { { "a" } },
                    after   = { { "b" } },
                    lookups = { 1 },
                },
                {
                    current = { { "c" } },
                    after   = { { "d" } },
                    lookups = { 1 },
                },
            },
        },
    }
\stopluacode
\stopbuffer

\typebuffer \getbuffer

\definefontfeature[test-a][test-a=yes]
\definefontfeature[test-b][test-b=yes]
\definefontfeature[test-c][test-c=yes]
\definefontfeature[test-d][test-d=yes]

\startbuffer
abababcdcd abababcdcd abababcdcd
\stopbuffer

With the test text:

\typebuffer

These four result in:

\blank \start

    \definedfont[file:dejavu-serif.ttf*default]

    \start \addff{test-a} \getbuffer \stop\par
    \start \addff{test-b} \getbuffer \stop\par
    \start \addff{test-c} \getbuffer \stop\par
    \start \addff{test-d} \getbuffer \stop\par

\stop \blank

\stopsubsection

\startsubsection[title={Language dependencies}]

When \OPENTYPE\ was not around we only had to deal with ligatures, smallcaps and
oldstyle and of course kerns. Their number was so small that the term \quote
{features} was not even used. In practice one just loaded a font that had
oldstyle or smallcaps or none of that and was done. There were different fonts and
sold separately.

In \OPENTYPE\ we have more variation and although these fonts can be much more
advanced the lack of standardization (for instance what gets initialized, or what
shapes are in the default slots) can lead to messy setups. Some fonts bind
features to scripts, some don't, which means that:

\starttyping
\definefontfeature[smallcaps][smcp=yes,script=dflt]
\definefontfeature[smallcaps][smcp=yes,script=latn]
\definefontfeature[smallcaps][smcp=yes,script=cyrl]
\stoptyping

are in fact different and you don't know in advance if you need to specify \type
{dflt} or \type {latn}. In practice for a feature like smallcaps there is no
difference between languages, but for ligatures there can be.

When we extend an existing feature we can think of:

\starttyping
\definefontfeature[smallcaps][default][smcp=yes,script=auto]
\definefontfeature[smallcaps][default][smcp=yes,script=*]
\stoptyping

but that can have side effects too (for instance disabling language specific
features). The easiest way to explore this language dependency is to make
a feature of our own.

\startbuffer
\startluacode
fonts.handlers.otf.addfeature {
    name     = "simplify",
    type     = "multiple",
    prepend  = true,
    features = {
        ["*"] = {
            ["deu"] = true
        }
    },
    data     = {
        [utf.byte("ä")] = { "a", "e" },
        [utf.byte("Ä")] = { "A", "E" },
        [utf.byte("ü")] = { "u", "e" },
        [utf.byte("Ü")] = { "U", "E" },
        [utf.byte("ö")] = { "o", "e" },
        [utf.byte("Ö")] = { "O", "E" },
        [utf.byte("ß")] = { "s", "z" },
        [utf.byte("ẞ")] = { "S", "Z" },
    },
}
\stopluacode
\stopbuffer

\typebuffer \getbuffer

Here we implement a language specific feature that we use at the \TEX\ end:

\startbuffer
\definefontfeature
  [simplify-de]
  [simplify=yes,
   language=deu]
\stopbuffer

\typebuffer \getbuffer

that we can use as:

\startbuffer
\definedfont[Serif*default,simplify-de]%
äüöß
{\de äüöß}
{\nl äüöß}
\stopbuffer

\typebuffer

and get: \start \maincolor \inlinebuffer \stop, but as you see, both German and
Dutch get the same treatment, which might not be what you want, because in Dutch
the diearesis has a different meaning.

\startbuffer
\definedfont[Serif*default]%
                       äüöß
{\de\addff{simplify-de}äüöß}
{\nl                   äüöß}
\stopbuffer

\typebuffer

The above is restricts the usage so now we get: \start \maincolor \inlinebuffer
\stop, which is more language bound. You don't need much imagination for
extending this:

\startbuffer
\definefontfeature
  [simplify]
  [simplify=yes,
   language=deu]
\stopbuffer

\typebuffer \getbuffer

\startbuffer
\definedfont[Serif*default]%
                    äüöß
{\de\addff{simplify}äüöß}
{\nl\addff{simplify}äüöß}
\stopbuffer

So what do we expect with the next?

\typebuffer

We get: \start \maincolor \inlinebuffer \stop, and we see that the language
setting is not taken into account! This is because the font already has been set
up with a script and language combination. The solution is to temporary set the
font related language explicitly:

\definefontfeature
  [simplify]
  [simplify=yes]

\startbuffer
\definedfont[Serif*default]%
                                  äüöß
{\de\addfflanguage\addff{simplify}äüöß}
{\nl\addfflanguage\addff{simplify}äüöß}
\stopbuffer

\typebuffer

So we can automatically switch to language specific features if we want to:
\start \maincolor \inlinebuffer \stop.

Let's now move to another level of complexity: support for more than one language
as in fact this example was made for Dutch in the first place, but the German
outcome is a bit more visible.

\startbuffer
\startluacode
fonts.handlers.otf.addfeature {
    name     = "simplify",
    type     = "multiple",
    prepend  = true,
 -- prepend  = "smcp",
    dataset  =
    {
        {
            features = {
                ["*"] = {
                    ["nld"] = true
                }
            },
            data     = {
             -- [utf.byte("ä")] = { "a" },
             -- [utf.byte("Ä")] = { "A" },
             -- [utf.byte("ü")] = { "u" },
             -- [utf.byte("Ü")] = { "U" },
             -- [utf.byte("ö")] = { "o" },
             -- [utf.byte("Ö")] = { "O" },
                [utf.byte("ij")] = { "i", "j" },
                [utf.byte("IJ")] = { "I", "J" },
                [utf.byte("æ")] = { "a", "e" },
                [utf.byte("Æ")] = { "A", "E" },
            },
        },
        {
         -- type     = "multiple", -- local values possible
            features = {
                ["*"] = {
                    ["deu"] = true
                }
            },
            data     = {
                [utf.byte("ä")] = { "a", "e" },
                [utf.byte("Ä")] = { "A", "E" },
                [utf.byte("ü")] = { "u", "e" },
                [utf.byte("Ü")] = { "U", "E" },
                [utf.byte("ö")] = { "o", "e" },
                [utf.byte("Ö")] = { "O", "E" },
                [utf.byte("ß")] = { "s", "z" },
                [utf.byte("ẞ")] = { "S", "Z" },
            },
        }
    }
}
\stopluacode
\stopbuffer

\typebuffer \getbuffer

For this we use the following example:

\startbuffer
\definedfont[Serif*default,simplify]%
                   äüöß ijæ
{\de\addfflanguage äüöß ijæ}
{\nl\addfflanguage äüöß ijæ}
\stopbuffer

\typebuffer

Because the Dutch is hard to check we use an \type {æ} replacement too and
commented the similarities with German: \start \maincolor \inlinebuffer \stop.
But still we're not done, say that we want smallcaps too:

\startbuffer
\definefontfeature[alwayssmcp][smcp=always]%
\definedfont[Serif*default,simplify,alwayssmcp]%
                   äüöß ijæ
{\de\addfflanguage äüöß ijæ}
{\nl\addfflanguage äüöß ijæ}
\stopbuffer

\typebuffer

This comes out as: \start \maincolor \inlinebuffer \stop.

The reason for specifying \type{smcp} as \type {always} is that otherwise we
get language specific smallcaps while often they are not bound to a language
but to the defaults. The good news is that we can do this automatically:

\startbuffer
\setupfonts[language=auto]%
\definefontfeature[alwayssmcp][smcp=always]%
\definedfont[Serif*default,simplify,alwayssmcp]%
     äüöß ijæ
{\de äüöß ijæ}
{\nl äüöß ijæ}
\stopbuffer

\typebuffer

But be aware that this applies to all situations. Here we get: \start \maincolor
\inlinebuffer \stop.

\stopsubsection

\startsubsection[title=Syntax summary]

In the examples we have seen several ways to define features. One of the
differences is that you either set a \type {data} field directly, or that you
specify a dataset. The fields in a dataset entry overload the ones given at the
top level or when not set the top level value will be taken. There is a bit
of (downward compatibility) tolerance built in, but best not depend on that.

\starttyping
fonts.handlers.otf.addfeature {
    name     = "demo",
    features = {
        [<script>] = {
            [<language>] = true
        }
    },
    prepend  = true | featurename | position,
    dataset  = {
        {
            type = "substitution",
            data = {
                [<char|code>] = <char|code>,
            }
        },
        {
            type = "alternate",
            data = {
                [<char|code>] = { <char|code>, <char|code>, ... },
            }
        },
        {
            type = "multiple",
            data = {
                [<char|code>] = { <char|code>, <char|code>, ... },
            }
        },
        {
            type = "ligature",
            data = {
                [<char|code>] = { <char|code>, <char|code>, ... },
            }
        },
        {
            type = "kern",
            data = {
                [<char|code>] = { [<char|code>] = <value> },
            }
        },
        {
            type = "pair",
            data = {
                [<char|code>] = {
                    [<char|code>] = {
                        false | { <value>, <value>, <value>, <value> },
                        false | { <value>, <value>, <value>, <value> }
                    }
                }
            }
        },
        {
            type    = "chainsubstitution",
            lookups = {
                {
                    type = <typename>,
                    data = <mapping>,
                },
            },
            data = {
                rules = {
                    {
                        before  = { { [<char|code>], ... } },
                        current = { { [<char|code>], ... } },
                        after   = { { [<char|code>], ... } },
                        lookups = { <index>, ... },
                    },
                },
            },
        },
    },
}
\stoptyping

\stopsubsection

\startsubsection[title=Extra characters]

\startbuffer[hyphenchars]
\startluacode

    local privateslots = fonts.constructors.privateslots

    local function addspecialhyphen(tfmdata)

        local exheight = tfmdata.parameters.xheight
        local emwidth  = tfmdata.parameters.quad
        local width    = emwidth  /  4
        local height   = exheight / 10
        local depth    = exheight /  2
        local offset   = emwidth  /  6

        tfmdata.characters[privateslots.righthyphenchar] = {
            -- no dimensions
            commands = {

                { "right", offset },

                { "push" },
                { "right", -width },
                { "down", depth },
                { "rule", height, width },
                { "pop" },

                { "right", -width/5 },
                { "down", depth + height },
                { "rule", 3*height, width/5 },

            }
        }

        tfmdata.characters[privateslots.lefthyphenchar] = {
            -- no dimensions
            commands = {

                { "right", -offset },

                { "push" },
                { "down", depth + height },
                { "rule", 3*height, width/5 },
                { "pop" },

                { "down", depth },
                { "rule", height, width },

            }
        }

    end

    fonts.constructors.features.otf.register {
        name        = "specialhyphen",
        description = "special hyphen",
        manipulators = {
            base = addspecialhyphen,
            node = addspecialhyphen,
        }
    }

\stopluacode
\stopbuffer

You can add virtual characters to fonts. Here we give an example that is derived
from an example posted on the mailing list. By default, when we hyphenated a word,
we get this:

\definefont[DemoFont] [Serif*default]

\blank \start \DemoFont \maincolor \hsize 1mm averylongword \par \stop \blank

The default character that is appended at the end and beginning of a line
can be specified as follows:

\startbuffer
\setuplanguage
  [en]
  [righthyphenchar=45,
   lefthyphenchar=45]
\stopbuffer

\typebuffer

So now we get:

\blank \start \getbuffer \DemoFont \maincolor \hsize 1mm averylongword \par \stop \blank

Say that we want a different signal, for instance some rule. Here is how that can
be done:

\typebuffer[hyphenchars]

\getbuffer[hyphenchars]

Watch the way we use private slots. You can best use a unique glyph name as these
numbers are shared between fonts. With:

\startbuffer
\definefontfeature
  [default]
  [default]
  [specialhyphen=yes]
\definefont
  [DemoFont]
  [Serif*default at 24pt]
\setuplanguage
  [en]
  [righthyphenchar=\getprivateglyphslot{righthyphenchar},
   lefthyphenchar=\getprivateglyphslot{lefthyphenchar}]
\stopbuffer

\typebuffer

We get:

\startlinecorrection[blank]
\getbuffer
\framed
  [foregroundstyle=\DemoFont \setupinterlinespace,
   offset=none,
   frame=no,
   width=1mm,
   align={flushleft}]
  {\hsize 1mm \maincolor averylongword\par}
\stoplinecorrection

You need to keep in mind that some of these settings are global but in practice that is
not a real problem. Here is how you reset:

\startbuffer
\definefontfeature
  [default]
  [default]
  [specialhyphen=no]
\setuplanguage
  [en]
  [righthyphenchar=45,
   lefthyphenchar=0]
\stopbuffer

\typebuffer \getbuffer

\stopsubsection

\startsubsection[title=Goodies]

The examples above extend a font in the \TEX\ document (normally a style) but you
can use a goodies file too, for instance \type {cambria.lfg}.

\starttyping
return {
    name = "cambria",
    version = "1.00",
    comment = "Goodies that complement cambria.",
    author = "Hans Hagen",
    copyright = "ConTeXt development team",
    extensions = {
        {
            name = "kern", -- adds to kerns
            type = "pair",
            data = {
                [0x0153] = { -- combining acute
                    [0x0301] = { -- aeligature
                        false,
                        { -500, 0, 0, 0 }
                    }
                },
            }
        }
    }
}
\stoptyping

Here we use the feature name \type {kern} and therefore we don't have to define a
specific (new) feature for it. Such a goodie is then used as follows:

\starttyping
\definefontsynonym
  [Serif]
  [cambria]
  [features=default,
   goodies=cambria]
\stoptyping

You can find such definitions in the \type {type-imp-*.mkiv} files.

\stopsubsection

\stopsection

\startsection[title=Spacing]

% By default the font loader deduces the spacing from the space character or
% other font properties. You can influence this by the \type {space} feature.
%
% \starttyping
% \definefontfeature
%   [korean]
%   [default]
%   [script=hang,
%    language=kor,
%    space=local] % or locl
% \stoptyping
%
% Instead of the usual \type {yes} (which means: use character 32), \type {local}
% or \type {locl} (which means: use a replacement provided by the \type{locl}
% feature), you can also pass a character, so
%
% \starttyping
% \definefontfeature
%   [spacy]
%   [default]
%   [space=A]
% \stoptyping
%
% is valid.

As you probably know, \TEX\ has no space character. When the input is read,
characters tagged as space are intercepted and become glue. Compare this:

\startlinecorrection[blank]
    \startcombination
        {\framed
            [width=3cm,height=15mm,align={middle,lohi},foregroundcolor=maincolor]
            {\dorecurse{5}{test }}}
        {\type{text test...}}
        {\framed
            [width=3cm,height=15mm,align={middle,lohi},foregroundcolor=maincolor]
            {\dorecurse{5}{test\char32\relax}}}
        {\type{text\char32test...}}
    \stopcombination
\stoplinecorrection

Most fonts have a space character and you can actually use it and indeed a space
character will be injected but as it is not glue, the line break algorithm will
not see it as space.

Al the magic done with space characters other than the native space character
(decimal 32) are at some point translated into glue.

\starttabulate[||T|p|]
\NC \bf command \NC \UNICODE \NC width \NC \NR

\NC \type{\nobreakspace}
    \type{\nbsp}                     \NC U+00A0 \NC space           \NC \NR
\NC \type{\ideographicspace}         \NC U+2000 \NC quad/2          \NC \NR
\NC \type{\ideographichalffillspace} \NC U+2001 \NC quad            \NC \NR
\NC \type{\twoperemspace}
    \type{\enspace}                  \NC U+2002 \NC quad/2          \NC \NR
\NC \type{\emspace}
    \type{\quad}                     \NC U+2003 \NC quad            \NC \NR
\NC \type{\threeperemspace}          \NC U+2004 \NC quad/3          \NC \NR
\NC \type{\fourperemspace}           \NC U+2005 \NC quad/4          \NC \NR
\NC \type{\fiveperemspace}           \NC        \NC quad/5          \NC \NR
\NC \type{\sixperemspace}            \NC U+2006 \NC quad/6          \NC \NR
\NC \type{\figurespace}              \NC U+2007 \NC width of zero   \NC \NR
\NC \type{\punctuationspace}         \NC U+2008 \NC width of period \NC \NR
\NC \type{\breakablethinspace}       \NC U+2009 \NC quad/8          \NC \NR
\NC \type{\hairspace}                \NC U+200A \NC quad/8          \NC \NR
\NC \type{\zerowidthspace}           \NC U+200B \NC 0               \NC \NR
\NC \type{\zerowidthnonjoiner}
    \type{\zwnj}                     \NC U+200C \NC 0               \NC \NR
\NC \type{\zerowidthjoiner}
    \type{\zwj}                      \NC U+200D \NC 0               \NC \NR
\NC \type{\narrownobreakspace}       \NC U+202F \NC quad/8          \NC \NR
\NC \type{\zerowidthnobreakspace}    \NC U+FEFF \NC                 \NC \NR
\NC \type{\optionalspace}            \NC        \NC space when not followed by punctuation \NC \NR
\stoptabulate

% "205F  % space/8 (math)

The last one is not un \UNICODE\ and the fifths of an emspace is not in \UNICODE\
either. This emspace (or quad in \TEX\ speak) is a font property. The width of
the space used by \CONTEXT\ is dreived form this value. In case of a monospace
fonts, the following logic is applied:

\startitemize
    \startitem
        When there is a space character, the width of that character is used.
    \stopitem
    \startitem
        Otherwise, when there is an emdash present, the width if that character
        is used.
    \stopitem
    \startitem
        Otherwise, when there is an \type {charwidth} property available (the
        average width), that valua is used.
    \stopitem
\stopitemize

When a proportional font is used, we do as follows:

\startitemize
    \startitem
        When there is a space character, the width of that character is used.
    \stopitem
    \startitem
        Otherwise, when there is an emdash present, the width of that character
        divided by two is used.
    \stopitem
    \startitem
        Otherwise, when there is an \type {charwidth} property available (the
        average width), that value is used.
    \stopitem
\stopitemize

In both cases, when no value is set we use the units of the font (often 1000 or
2048). In \TEX\ a space glue also has stretch and shrink. Here we follow the
traditional \TEX\ logic:

\startitemize
    \startitem
        The stretch is set to half the width of a space but to zero with a mono
        spaced font.
    \stopitem
    \startitem
        The shrink is set to one third of the width of a space but to zero with a
        mono spaced font.
    \stopitem
\stopitemize

The xheight is set to the values specified by the font and when this is unset the
height of the character \type {x} will be used but when this character is not in
the font, we use two fifths of the font's units (normally the same as the
emwidth). The italic angle is also taken from the font (and is of course zero for
a not italic font). Most fonts have these properties set so we seldom have to
fall back to a guess.

\stopsection

\startsection[title=Ligatures]

Not all fonts provide ligature control (normally related to languages), so here is a
trick.

\starttyping
\blockligatures[fi,ff]
\blockligatures[fl]

\definefontfeature
  [default]
  [default]
  [blockligatures=yes]

\setupbodyfont[pagella]

...
\stoptyping

This way it works globally. Of course you can also bind it to a font instance:

\startbuffer
\blockligatures[fi,fl]

\definefontfeature
  [default:blockligs]
  [default]
  [blockligatures=yes]

\definefont[DemoBlockY][Serif*default:blockligs at 20pt]
\definefont[DemoBlockN][Serif*default           at 20pt]

Here we have no ligatures: {\DemoBlockY fi ff fl}, while here we get
them: {\DemoBlockN fi ff fl}. Of course it also depends on the font.
\stopbuffer

\typebuffer \start \showfontkerns \getbuffer \par \stop

There is one limitation: you need to specify the blocked ligatures before a font
gets defined and because we share resources it even has to happen before the
first font gets loaded. So, the \type {\blockligatures} commands go before
setting up the body font. This is no real problem because it's a hack anyway.

The next example combines several tricks:

\startbuffer[definitions]
\startluacode
    fonts.handlers.otf.addfeature {
        name = "kernligatures",
        type = "kern",
        data = {
            f = { i = 50, l = 50 },
        }
    }
\stopluacode

\blockligatures[u:fl:a]

\definefontfeature[default:b][default][blockligatures=yes]
\definefontfeature[default:k][default][blockligatures=yes,kernligatures=yes]

\showfontkerns
\stopbuffer

\startbuffer[demo]
{\definedfont[Brill*default   @ 11pt]auflage}\par
{\definedfont[Brill*default:b @ 11pt]auflage}\par
{\definedfont[Brill*default:k @ 11pt]auflage}\par
\stopbuffer

\typebuffer[definitions,demo] \getbuffer[definitions]

\startlinecorrection
    \externalfigure[demo.buffer][width=4cm]
\stoplinecorrection

Processing fonts is complicated by the fact that a text can be hyphenated. This
complicates for instance ligature building which can cross the pre, post and|/|or
replace bounds. The current implementation does a decent job although there will
always be border cases. And, figuring out what goes wrong is a pain. There are
several ways to trace what happens and here's one. As mentioned, blocking only
works when we haven't not yet defined a font instance, so we use a funny size
here.

\startbuffer
\blockligatures[u:fl:a]

\definefontfeature
  [blockligatures]
  [default]
  [blockligatures=yes]

\startotfcompositionlist{texgyrepagella-regular*blockligatures @ 14.5pt}{l2r}
    \HL
    \showotfcompositionsample{auflage}
    \showotfcompositionsample{a\discretionary{-}{}{}uflage}
    \showotfcompositionsample{au\discretionary{-}{}{}flage}
    \showotfcompositionsample{auf\discretionary{-}{}{}lage}
    \showotfcompositionsample{aufl\discretionary{-}{}{}age}
    \showotfcompositionsample{aufla\discretionary{-}{}{}ge}
    \showotfcompositionsample{auflag\discretionary{-}{}{}e}
    \HL
    \showotfcompositionsample{auflegt}
    \showotfcompositionsample{a\discretionary{-}{}{}uflegt}
    \showotfcompositionsample{au\discretionary{-}{}{}flegt}
    \showotfcompositionsample{auf\discretionary{-}{}{}legt}
    \showotfcompositionsample{aufl\discretionary{-}{}{}egt}
    \showotfcompositionsample{aufle\discretionary{-}{}{}gt}
    \showotfcompositionsample{aufleg\discretionary{-}{}{}t}
    \HL
\stopotfcompositionlist
\stopbuffer

\typebuffer \getbuffer

Here is another example. This one demonstrates that ligatures can force
collapsing of discretionaries.

\startbuffer
\startotfcompositionlist{Serif*default @ 11pt}{l2r}
    \HL
    \showotfcompositionsample{effe}
    \showotfcompositionsample{efficient}
    \HL
\stopotfcompositionlist
\stopbuffer

\typebuffer \getbuffer

\stopsection

\startsection[title=Collections]

    {\em Todo.}

\stopsection

\stopchapter