font-fea.mklx /size: 14 Kb    last modification: 2025-02-21 11:03
1%D \module
2%D   [       file=font-sty,
3%D        version=2011.01.13, % (copied fron font-ini)
4%D          title=\CONTEXT\ Font Macros,
5%D       subtitle=features,
6%D         author=Hans Hagen,
7%D           date=\currentdate,
8%D      copyright={PRAGMA ADE \& \CONTEXT\ Development Team}]
9%C
10%C This module is part of the \CONTEXT\ macro||package and is
11%C therefore copyrighted by \PRAGMA. See mreadme.pdf for
12%C details.
13
14\writestatus{loading}{ConTeXt Font Macros / Features}
15
16\unprotect
17
18%D Feature management.
19%D
20%D \starttyping
21%D \definefontfeature[smallcaps][smcp=yes,script=latn]
22%D \definefontfeature[smallcaps][SmallCapitals=yes,script=latn]
23%D \definefontfeature[smallcaps][Small Capitals=yes,script=latn]
24%D \definefontfeature[smallcaps][small capitals=yes,script=latn]
25%D \definefontfeature[smallcaps][smallcapitals=yes,script=latn]
26%D
27%D \definedfont[cambria*smallcaps] test
28%D
29%D \starttext
30%D \definefontfeature[basekerned][default][mode=base]
31%D \definefontfeature[nodekerned][default][mode=node]
32%D \definefontfeature[nonekerned][default][mode=base,kern=no]
33%D \setupcolors[state=start]
34%D \startoverlay
35%D     {\vbox{\red  \definedfont[Serif*nonekerned at 12pt]\input tufte }}
36%D     {\vbox{\blue \definedfont[Serif*basekerned at 12pt]\input tufte }}
37%D     {\vbox{\green\definedfont[Serif*nodekerned at 12pt]\input tufte }}
38%D \stopoverlay
39%D \stoptext
40%D
41%D \enabletrackers[otf.kerns]
42%D
43%D \definefontfeature[withkern][default][mode=node]
44%D \definefontfeature[nokern]  [default][mode=node,kern=no]
45%D \definefontfeature[single]  [default][mode=node,cpsp=yes]
46%D \definefontfeature[simple]  [default][mode=node,cpsp=yes,kern=no]
47%D
48%D {\definedfont[Serif*default] [FGFGFGFGFGFGFGFGFGFGFGFGFG ABCDEFGHIJKLMNOPQRSTUVWXYZ] \par}
49%D {\definedfont[Serif*nokern]  [FGFGFGFGFGFGFGFGFGFGFGFGFG ABCDEFGHIJKLMNOPQRSTUVWXYZ] \par}
50%D {\definedfont[Serif*single]  [FGFGFGFGFGFGFGFGFGFGFGFGFG ABCDEFGHIJKLMNOPQRSTUVWXYZ] \par}
51%D {\definedfont[Serif*simple]  [FGFGFGFGFGFGFGFGFGFGFGFGFG ABCDEFGHIJKLMNOPQRSTUVWXYZ] \par}
52%D \stoptyping
53
54% \definefontfeature[slanted]  [default][slant=.25]
55% \definefontfeature[stretched][default][stretch=2]
56%
57% \start \definedfont[SerifBold*slanted   at 20pt] \ruledhbox{Test!} \stop
58% \start \definedfont[SerifBold*stretched at 20pt] \ruledhbox{Test!} \stop
59%
60% \definefontfeature[default]     [liga=yes,texligatures=yes,texquotes=yes]
61% \definefontfeature[default-caps][liga=yes,texligatures=yes,texquotes=yes,smcp=yes,script=latn]
62%
63% \starttypescript [serif] [palatino-nova-regular] [name]
64%     \definefontsynonym[Serif]    [palatinonova-regular][features=default]
65%     \definefontsynonym[SerifCaps][palatinonova-regular][features=default-caps] % also sets Serif
66% \stoptypescript
67%
68% \starttypescript [serif] [palatino-nova-regular] [name]
69%     \definefontsynonym[Serif]          [palatinonova-regular*default]
70%     \definefontsynonym[SerifCaps]      [palatinonova-regular*default-caps]
71% \stoptypescript
72%
73% \definetypeface[mainface][rm][serif][palatino-nova-regular][default] \setupbodyfont[mainface]
74%
75% \starttext
76%   ``Test'' -- --- ff fi fl \sc ``Test'' -- --- ff fi fl
77% \stoptext
78%
79% \definefontfeature
80%   [default-base]
81%   [script=latn,language=dflt,liga=yes,kern=yes,tlig=yes,trep=yes]
82% \definefontfeature
83%   [default-node]
84%   [script=latn,language=dflt,liga=yes,kern=yes,tlig=yes,trep=yes,mode=node]
85% \definefontfeature
86%   [default-none]
87%   [script=latn,language=dflt,liga=yes,kern=no, tlig=yes,trep=yes]
88%
89% \startoverlay
90%     {\vtop{\color[red]  {\font\test=name:lmroman12regular*default-node \test \input ward \input zapf \input linden }}}
91%     {\vtop{\color[green]{\font\test=name:lmroman12regular*default-base \test \input ward \input zapf \input linden }}}
92%     {\vtop{\color[blue] {\font\test=name:lmroman12regular*default-none \test \input ward \input zapf \input linden }}}
93% \stopoverlay
94%
95% \blank
96%
97% \startoverlay
98%     {\vtop{\color[red]  {\font\test=name:texgyrepagella*default-node \test \input ward \input zapf \input linden }}}
99%     {\vtop{\color[green]{\font\test=name:texgyrepagella*default-base \test \input ward \input zapf \input linden }}}
100%     {\vtop{\color[blue] {\font\test=name:texgyrepagella*default-none \test \input ward \input zapf \input linden }}}
101% \stopoverlay
102%
103% \blank
104%
105% \startoverlay
106%     {\vtop{\color[red]  {\font\test=name:palatinonovaregular*default-node \test \input ward \input zapf \input linden }}}
107%     {\vtop{\color[green]{\font\test=name:palatinonovaregular*default-base \test \input ward \input zapf \input linden }}}
108%     {\vtop{\color[blue] {\font\test=name:palatinonovaregular*default-none \test \input ward \input zapf \input linden }}}
109% \stopoverlay
110%
111% \startoverlay
112%     {\vtop{\color[red]  {\font\test=name:OfficinaSerifBookITC*default-node \test \input ward \input zapf \input linden }}}
113%     {\vtop{\color[green]{\font\test=name:OfficinaSerifBookITC*default-base \test \input ward \input zapf \input linden }}}
114%     {\vtop{\color[blue] {\font\test=name:OfficinaSerifBookITC*default-none \test \input ward \input zapf \input linden }}}
115% \stopoverlay
116%
117% \definefontfeature[superdefault][default][compose=yes]
118%
119% {\font\oeps=name:lmroman10regular*default      at 30pt \oeps test \char7683}
120% {\font\oeps=name:lmroman10regular*superdefault at 30pt \oeps test \char7683}
121
122\permanent\tolerant\protected\def\definefontfeature[#featureset]#spacer[#parent]#spacer[#settings]%
123  {\clf_definefontfeature{#featureset}{#parent}{#settings}}
124
125\permanent\tolerant\protected\def\adaptfontfeature[#pattern]#spacer[#settings]%
126  {\clf_adaptfontfeature{#pattern}{#settings}}
127
128\permanent\protected\def\fontfeatureslist[#name]#spacer[#separator]% todo: arg voor type
129  {\clf_featurelist{#name}{\detokenize{#separator}}}
130
131\permanent\protected\def\definefontscriptset[#name]#*[#list]%
132  {\clf_definefontscriptset{#name}{#list}}
133
134\attribute\zerocount\attributeunsetvalue
135
136\glyphdatafield\zerocount
137
138\let\font_dynamic_value\glyphdatafield
139
140% beware: these are global features on top of existing font features
141
142\mutable\let \currentfeature      \s!current
143\let         \m_font_feature_list \s!current
144\lettonothing\m_font_feature_asked
145\newconstant \c_font_feature_state
146
147\newevery\everyfontfeatureswitch
148
149% hashing at this end is slower
150
151\permanent\tolerant\protected\def\addfeature        [#1]#;#2{\edef\m_font_feature_asked{#1#2}\font_feature_add}
152\permanent\tolerant\protected\def\subtractfeature   [#1]#;#2{\edef\m_font_feature_asked{#1#2}\font_feature_subtract}
153\permanent\tolerant\protected\def\replacefeature    [#1]#;#2{\edef\m_font_feature_asked{#1#2}\font_feature_replace}
154\permanent\tolerant\protected\def\resetandaddfeature[#1]#;#2{\edef\m_font_feature_asked{#1#2}\font_feature_reset_add}
155\permanent\tolerant\protected\def\feature           [#1]#;#2{\begincsname\??featureshortcut#1#2\endcsname}
156
157% for old times sake
158
159\permanent\protected\def\doaddfeature        #1{\edef\m_font_feature_asked{#1}\font_feature_add}
160\permanent\protected\def\dosubtractfeature   #1{\edef\m_font_feature_asked{#1}\font_feature_subtract}
161\permanent\protected\def\doreplacefeature    #1{\edef\m_font_feature_asked{#1}\font_feature_replace}
162\permanent\protected\def\doresetandaddfeature#1{\edef\m_font_feature_asked{#1}\font_feature_reset_add}
163
164\protected\def\font_feature_add
165  {\ifnum\c_font_feature_state=\plusone
166     \ifx\m_font_feature_asked\currentfeature\else
167       \font_feature_add_indeed
168     \fi
169   \else
170     \font_feature_add_indeed
171   \fi}
172
173\protected\def\font_feature_add_indeed
174  {\clf_addfeature{\m_font_feature_list}{\m_font_feature_asked}%
175   \edef\m_font_feature_list{\m_font_feature_list+\m_font_feature_asked}% also + at the lua end
176   \c_font_feature_state\plusone
177   \let\currentfeature\m_font_feature_asked
178   \expand\everyfontfeatureswitch}
179
180\protected\def\font_feature_subtract
181  {\ifnum\c_font_feature_state=\minusone
182     \ifx\m_font_feature_asked\currentfeature\else
183       \font_feature_subtract_indeed
184     \fi
185   \else
186     \font_feature_subtract_indeed
187   \fi}
188
189\protected\def\font_feature_subtract_indeed
190  {\clf_subtractfeature{\m_font_feature_list}{\m_font_feature_asked}%
191   \edef\m_font_feature_list{\m_font_feature_list-\m_font_feature_asked}% also - at the lua end
192   \c_font_feature_state\minusone
193   \let\currentfeature\m_font_feature_asked
194   \expand\everyfontfeatureswitch}
195
196\protected\def\font_feature_replace
197  {\ifzero\c_font_feature_state
198     \ifx\m_font_feature_asked\currentfeature\else
199       \font_feature_replace_indeed
200     \fi
201   \else
202     \font_feature_replace_indeed
203   \fi}
204
205\protected\def\font_feature_replace_indeed
206  {\clf_replacefeature{\m_font_feature_list}{\m_font_feature_asked}%
207   \edef\m_font_feature_list{\m_font_feature_list=\m_font_feature_asked}% also = at the lua end
208   \c_font_feature_state\zerocount
209   \let\currentfeature\m_font_feature_asked
210   \expand\everyfontfeatureswitch}
211
212\permanent\protected\def\resetfeature
213  {\ifx\currentfeature\s!current \else
214     \font_feature_reset_indeed
215   \fi}
216
217\protected\def\font_feature_reset_indeed
218  {\lettonothing\m_font_feature_asked
219   \let\currentfeature\s!current
220   \let\m_font_feature_list\s!current
221   \clf_resetfeature}
222
223\permanent\protected\def\revivefeature
224  {\ifx\currentfeature\s!current \else
225     \font_feature_revive_indeed
226   \fi}
227
228\protected\def\font_feature_revive_indeed
229  {\clf_revivefeature{\m_font_feature_list}}
230
231\protected\def\font_feature_reset_add
232  {\ifnum\c_font_feature_state=\plusone
233     \ifx\m_font_feature_asked\currentfeature\else
234       \font_feature_reset_add_indeed
235     \fi
236   \else
237     \font_feature_reset_add_indeed
238   \fi}
239
240\protected\def\font_feature_reset_add_indeed
241  {\clf_addfeature{\s!current}{\m_font_feature_asked}%
242   \edef\m_font_feature_list{\s!current+\m_font_feature_asked}% also + at the lua end
243   \c_font_feature_state\plusone
244   \let\currentfeature\m_font_feature_asked
245   \expand\everyfontfeatureswitch}
246
247\installcorenamespace{featureshortcut}
248
249\letcsname\??featureshortcut +\endcsname\addfeature
250\letcsname\??featureshortcut -\endcsname\subtractfeature
251\letcsname\??featureshortcut =\endcsname\replacefeature
252\letcsname\??featureshortcut !\endcsname\resetandaddfeature
253\letcsname\??featureshortcut >\endcsname\revivefeature
254\letcsname\??featureshortcut <\endcsname\resetfeature
255
256\letcsname\??featureshortcut\v!more   \endcsname\addfeature      % add set to previous set and combine with font set
257\letcsname\??featureshortcut\v!less   \endcsname\subtractfeature % subtract set from previous set and combine with font set
258\letcsname\??featureshortcut\v!new    \endcsname\replacefeature  % replace font set
259\letcsname\??featureshortcut\v!reset  \endcsname\resetfeature    % forget sets and revert to font set
260\letcsname\??featureshortcut\v!default\endcsname\revivefeature   % make sure the current set is used on top of the font set
261\letcsname\??featureshortcut\v!old    \endcsname\revivefeature
262\letcsname\??featureshortcut\v!local  \endcsname\resetandaddfeature
263\letcsname\??featureshortcut\s!unknown\endcsname\empty
264
265% experimental bonus:
266
267% \protected\def\addfflanguage
268%   {\ifnum\c_font_feature_state=\plusone
269%      \ifx\currentlanguage\currentfeature\else
270%        \font_feature_add_language_indeed
271%      \fi
272%    \else
273%      \font_feature_add_language_indeed
274%    \fi}
275%
276% \protected\def\font_feature_add_language_indeed
277%   {\clf_addfeature{\m_font_feature_list}{\currentlanguage}%
278%    \edef\m_font_feature_list{\m_font_feature_list+\currentlanguage}% also + at the lua end
279%    \c_font_feature_state\plusone
280%    \let\currentfeature\currentlanguage}
281%
282% some 3% slower:
283
284% \protected\def\addfflanguage
285%   {\let\m_font_feature_asked\currentlanguage
286%    \font_feature_add}
287
288\let\m_font_feature_language\currentlanguage
289
290\permanent\protected\def\addfflanguage
291  {\ifx\currentlanguage\m_font_feature_language\else
292     \let\m_font_feature_language\currentlanguage
293     \let\m_font_feature_asked   \currentlanguage
294     \font_feature_add
295   \fi}
296
297% just for old times sake:
298
299\permanent\protected\def\featureattribute#feature%
300  {\clf_featureattribute{#feature}}
301
302\permanent\protected\def\setfontfeature#feature%
303  {\edef\currentfeature{#feature}%
304   \let\m_font_feature_list\currentfeature
305   \clf_setfontfeature{\currentfeature}}
306
307%  these are obsolete (don't use them any longer)
308
309\aliased\let\resetfontfeature\resetfeature % obsolete
310
311%  these are obsolete (don't use them any longer)
312
313% \let\addfontfeaturetoset        \font_feature_add_nop      % obsolete
314% \let\subtractfontfeaturefromset \font_feature_subtract_nop % obsolete
315% \let\addfontfeaturetofont       \font_feature_add_nop      % obsolete
316% \let\subtractfontfeaturefromfont\font_feature_subtract_nop % obsolete
317
318% these are obsolete (don't use them any longer)
319
320\aliased\let\setff\setfontfeature    % obsolete
321\aliased\let\addfs\doaddfeature      % obsolete
322\aliased\let\subfs\dosubtractfeature % obsolete
323\aliased\let\addff\doaddfeature      % obsolete
324\aliased\let\subff\dosubtractfeature % obsolete
325
326%D \macros
327%D   {os}
328%D
329%D In good old \TEX, the old style numerals were often taken from the math fonts. No
330%D longer.
331
332\definefontfeature
333  [just-os]
334  [mode=node,onum=yes]
335
336%frozen\protected\def\sc{\setfontfeature{smallcaps}}
337\permanent\protected\def\os{\setfontfeature{just-os}}
338
339% \doifelsecurrentfonthasfeature{smcp}{YES}{NO}
340% \doifelsecurrentfonthasfeature{crap}{YES}{NO}
341% \doifelsecurrentfonthasfeature{kern}{YES}{NO}
342
343\permanent\def\doifelsecurrentfonthasfeature#feature{\clf_doifelsecurrentfonthasfeature{#feature}} % expandable
344\permanent\def\doifelsefontfeature          #feature{\clf_doifelsefontfeature          {#feature}} % expandable
345\permanent\def\doifunknownfontfeature       #feature{\clf_doifunknownfontfeature       {#feature}} % expandable
346
347\aliased\let\doifcurrentfonthasfeatureelse\doifelsecurrentfonthasfeature
348\aliased\let\doiffontfeatureelse          \doifelsefontfeature
349
350% new:
351
352\clf_registerlanguagefeatures
353
354% also new
355
356\permanent\protected\def\useaddfontfeatureparameter#namespace% faster local variant
357  {\edef\m_font_feature_asked{#namespace\c!features}%
358   \ifempty\m_font_feature_asked\else
359     \font_feature_add
360   \fi}
361
362% let's put this here:
363
364\permanent\protected\def\slashedzero
365  {\dontleavehmode
366   \begingroup
367  %\addff{zero}
368   \doaddfeature{zero}%
369   0%
370   \endgroup}
371
372% not nice but maybe handy
373
374% \starttyping
375% \blockligatures[fi,ff] \blockligatures[fl]
376%
377% \definefontfeature[default:b][default][blockligatures=yes]
378%
379% \setupbodyfont[pagella] \showfontkerns
380%
381% \definedfont[Serif*default:b]
382%
383% \startTEXpage[offset=1em]
384%     fi ff fl
385% \stopTEXpage
386% \stoptyping
387
388\permanent\protected\def\blockligatures[#1]{\clf_blockligatures{#1}}
389
390\protect \endinput
391