font-fea.mkvi /size: 15 Kb    last modification: 2020-07-01 14:35
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\unexpanded\def\definefontfeature
123  {\dotripleargument\font_basics_define_font_feature}
124
125\def\font_basics_define_font_feature[#featureset][#parent][#settings]%
126  {\clf_definefontfeature{#featureset}{#parent}{#settings}}
127
128\unexpanded\def\adaptfontfeature
129  {\dodoubleargument\font_basics_adapt_font_feature}
130
131\def\font_basics_adapt_font_feature[#pattern][#settings]%
132  {\clf_adaptfontfeature{#pattern}{#settings}}
133
134\unexpanded\def\fontfeatureslist
135  {\dodoubleargument\font_basics_features_list}
136
137\def\font_basics_features_list[#name][#separator]% todo: arg voor type
138  {\clf_featurelist{#name}{\detokenize{#separator}}}
139
140\ifcase\contextlmtxmode
141    \attribute\zerocount\zerocount
142    \def\font_dynamic_value{\attribute\zerocount}
143\else
144    \attribute\zerocount\attributeunsetvalue
145    \glyphdatafield\zerocount
146    \let\font_dynamic_value\glyphdatafield
147\fi
148
149% beware: these are global features on top of existing font features
150
151\let\currentfeature      \s!current
152\let\m_font_feature_list \s!current
153\let\m_font_feature_asked\empty
154
155\newconstant\c_font_feature_state
156
157% hashing at this end is slower
158
159\unexpanded\def\addfeature        {\doifelsenextoptionalcs\font_feature_add_yes      \font_feature_add_nop      }
160\unexpanded\def\subtractfeature   {\doifelsenextoptionalcs\font_feature_subtract_yes \font_feature_subtract_nop }
161\unexpanded\def\replacefeature    {\doifelsenextoptionalcs\font_feature_replace_yes  \font_feature_replace_nop  }
162\unexpanded\def\resetandaddfeature{\doifelsenextoptionalcs\font_feature_reset_add_yes\font_feature_reset_add_nop}
163\unexpanded\def\feature           {\doifelsenextoptionalcs\font_feature_yes          \font_feature_nop          }
164
165\unexpanded\def\font_feature_add_yes      [#feature]{\edef\m_font_feature_asked{#feature}\font_feature_add}
166\unexpanded\def\font_feature_add_nop        #feature{\edef\m_font_feature_asked{#feature}\font_feature_add}
167
168\unexpanded\def\font_feature_subtract_yes [#feature]{\edef\m_font_feature_asked{#feature}\font_feature_subtract}
169\unexpanded\def\font_feature_subtract_nop   #feature{\edef\m_font_feature_asked{#feature}\font_feature_subtract}
170
171\unexpanded\def\font_feature_replace_yes  [#feature]{\edef\m_font_feature_asked{#feature}\font_feature_replace}
172\unexpanded\def\font_feature_replace_nop    #feature{\edef\m_font_feature_asked{#feature}\font_feature_replace}
173
174\unexpanded\def\font_feature_reset_add_yes[#feature]{\edef\m_font_feature_asked{#feature}\font_feature_reset_add}
175\unexpanded\def\font_feature_reset_add_nop  #feature{\edef\m_font_feature_asked{#feature}\font_feature_reset_add}
176
177\let\doaddfeature        \font_feature_add_nop       % low level faster ones
178\let\dosubtractfeature   \font_feature_subtract_nop
179\let\doreplacefeature    \font_feature_replace_nop
180\let\doresetandaddfeature\font_feature_reset_add_nop
181
182\unexpanded\def\font_feature_add
183  {\ifnum\c_font_feature_state=\plusone
184     \ifx\m_font_feature_asked\currentfeature\else
185       \font_feature_add_indeed
186     \fi
187   \else
188     \font_feature_add_indeed
189   \fi}
190
191\unexpanded\def\font_feature_add_indeed
192  {\clf_addfeature{\m_font_feature_list}{\m_font_feature_asked}%
193   \edef\m_font_feature_list{\m_font_feature_list+\m_font_feature_asked}% also + at the lua end
194   \c_font_feature_state\plusone
195   \let\currentfeature\m_font_feature_asked}
196
197\unexpanded\def\font_feature_subtract
198  {\ifnum\c_font_feature_state=\minusone
199     \ifx\m_font_feature_asked\currentfeature\else
200       \font_feature_subtract_indeed
201     \fi
202   \else
203     \font_feature_subtract_indeed
204   \fi}
205
206\unexpanded\def\font_feature_subtract_indeed
207  {\clf_subtractfeature{\m_font_feature_list}{\m_font_feature_asked}%
208   \edef\m_font_feature_list{\m_font_feature_list-\m_font_feature_asked}% also - at the lua end
209   \c_font_feature_state\minusone
210   \let\currentfeature\m_font_feature_asked}
211
212\unexpanded\def\font_feature_replace
213  {\ifnum\c_font_feature_state=\zerocount
214     \ifx\m_font_feature_asked\currentfeature\else
215       \font_feature_replace_indeed
216     \fi
217   \else
218     \font_feature_replace_indeed
219   \fi}
220
221\unexpanded\def\font_feature_replace_indeed
222  {\clf_replacefeature{\m_font_feature_list}{\m_font_feature_asked}%
223   \edef\m_font_feature_list{\m_font_feature_list=\m_font_feature_asked}% also = at the lua end
224   \c_font_feature_state\zerocount
225   \let\currentfeature\m_font_feature_asked}
226
227\unexpanded\def\resetfeature
228  {\ifx\currentfeature\s!current \else
229     \font_feature_reset_indeed
230   \fi}
231
232\unexpanded\def\font_feature_reset_indeed
233  {\let\m_font_feature_asked\empty
234   \let\currentfeature      \s!current
235   \let\m_font_feature_list \s!current
236   \clf_resetfeature}
237
238\unexpanded\def\revivefeature
239  {\ifx\currentfeature\s!current \else
240     \font_feature_revive_indeed
241   \fi}
242
243\unexpanded\def\font_feature_revive_indeed
244  {\clf_revivefeature{\m_font_feature_list}}
245
246\unexpanded\def\font_feature_reset_add
247  {\ifnum\c_font_feature_state=\plusone
248     \ifx\m_font_feature_asked\currentfeature\else
249       \font_feature_reset_add_indeed
250     \fi
251   \else
252     \font_feature_reset_add_indeed
253   \fi}
254
255\unexpanded\def\font_feature_reset_add_indeed
256  {\clf_addfeature{\s!current}{\m_font_feature_asked}%
257   \edef\m_font_feature_list{\s!current+\m_font_feature_asked}% also + at the lua end
258   \c_font_feature_state\plusone
259   \let\currentfeature\m_font_feature_asked}
260
261\installcorenamespace{featureyes}
262\installcorenamespace{featurenop}
263
264%\unexpanded\def\font_feature_yes[#method]{\csname\??featureyes\ifcsname\??featureyes#method\endcsname#method\else\s!unknown\fi\endcsname}
265%\unexpanded\def\font_feature_nop  #method{\csname\??featurenop\ifcsname\??featurenop#method\endcsname#method\else\s!unknown\fi\endcsname}
266
267\unexpanded\def\font_feature_yes[#method]{\begincsname\??featureyes#method\endcsname}
268\unexpanded\def\font_feature_nop  #method{\begincsname\??featurenop#method\endcsname}
269
270\letvalue{\??featureyes +}\addfeature
271\letvalue{\??featurenop +}\addfeature
272\letvalue{\??featureyes -}\subtractfeature
273\letvalue{\??featurenop -}\subtractfeature
274\letvalue{\??featureyes =}\replacefeature
275\letvalue{\??featurenop =}\replacefeature
276\letvalue{\??featureyes !}\resetandaddfeature
277\letvalue{\??featurenop !}\resetandaddfeature
278\letvalue{\??featureyes >}\revivefeature
279\letvalue{\??featurenop >}\revivefeature
280\letvalue{\??featureyes <}\resetfeature
281\letvalue{\??featurenop <}\resetfeature
282
283\letvalue{\??featureyes\v!more   }\addfeature      % add set to previous set and combine with font set
284\letvalue{\??featurenop\v!more   }\addfeature
285\letvalue{\??featureyes\v!less   }\subtractfeature % subtract set from previous set and combine with font set
286\letvalue{\??featurenop\v!less   }\subtractfeature
287\letvalue{\??featureyes\v!new    }\replacefeature  % replace font set
288\letvalue{\??featurenop\v!new    }\replacefeature
289\letvalue{\??featureyes\v!reset  }\resetfeature    % forget sets and revert to font set
290\letvalue{\??featurenop\v!reset  }\resetfeature
291\letvalue{\??featureyes\v!default}\revivefeature   % make sure the current set is used on top of the font set
292\letvalue{\??featurenop\v!default}\revivefeature
293\letvalue{\??featureyes\v!old    }\revivefeature
294\letvalue{\??featurenop\v!old    }\revivefeature
295\letvalue{\??featureyes\v!local  }\resetandaddfeature
296\letvalue{\??featurenop\v!local  }\resetandaddfeature
297\letvalue{\??featureyes\s!unknown}\empty
298\letvalue{\??featurenop\s!unknown}\empty
299
300% experimental bonus:
301
302% \unexpanded\def\addfflanguage
303%   {\ifnum\c_font_feature_state=\plusone
304%      \ifx\currentlanguage\currentfeature\else
305%        \font_feature_add_language_indeed
306%      \fi
307%    \else
308%      \font_feature_add_language_indeed
309%    \fi}
310%
311% \unexpanded\def\font_feature_add_language_indeed
312%   {\clf_addfeature{\m_font_feature_list}{\currentlanguage}%
313%    \edef\m_font_feature_list{\m_font_feature_list+\currentlanguage}% also + at the lua end
314%    \c_font_feature_state\plusone
315%    \let\currentfeature\currentlanguage}
316%
317% some 3% slower:
318
319% \unexpanded\def\addfflanguage
320%   {\let\m_font_feature_asked\currentlanguage
321%    \font_feature_add}
322
323\let\m_font_feature_language\currentlanguage
324
325\unexpanded\def\addfflanguage
326  {\ifx\currentlanguage\m_font_feature_language\else
327     \let\m_font_feature_language\currentlanguage
328     \let\m_font_feature_asked   \currentlanguage
329     \font_feature_add
330   \fi}
331
332% just for old times sake:
333
334\unexpanded\def\featureattribute#feature%
335  {\clf_featureattribute{#feature}}
336
337\unexpanded\def\setfontfeature#feature%
338  {\edef\currentfeature{#feature}%
339   \let\m_font_feature_list\currentfeature
340   \clf_setfontfeature{\currentfeature}}
341
342\let\resetfontfeature\resetfeature
343
344%  these are obsolete (don't use them any longer)
345
346\let\addfontfeaturetoset        \font_feature_add_nop
347\let\subtractfontfeaturefromset \font_feature_subtract_nop
348\let\addfontfeaturetofont       \font_feature_add_nop
349\let\subtractfontfeaturefromfont\font_feature_subtract_nop
350
351\let\setff\setfontfeature
352\let\addfs\addfontfeaturetoset
353\let\subfs\subtractfontfeaturefromset
354\let\addff\addfontfeaturetofont
355\let\subff\subtractfontfeaturefromfont
356
357%D \macros
358%D   {os}
359%D
360%D In good old \TEX, the old style numerals were often taken
361%D from the math fonts. No longer.
362
363\definefontfeature
364  [just-os]
365  [mode=node,onum=yes]
366
367%unexpanded\def\sc{\setfontfeature{smallcaps}}
368\unexpanded\def\os{\setfontfeature{just-os}}
369
370% \doifelsecurrentfonthasfeature{smcp}{YES}{NO}
371% \doifelsecurrentfonthasfeature{crap}{YES}{NO}
372% \doifelsecurrentfonthasfeature{kern}{YES}{NO}
373
374\def\doifelsecurrentfonthasfeature#feature% expandable
375  {\clf_doifelsecurrentfonthasfeature{#feature}}
376
377\let\doifcurrentfonthasfeatureelse\doifelsecurrentfonthasfeature
378
379\def\doifelsefontfeature#feature% expandable
380  {\clf_doifelsefontfeature{#feature}}
381
382\let\doiffontfeatureelse\doifelsefontfeature
383
384\def\doifunknownfontfeature#feature% expandable
385  {\clf_doifunknownfontfeature{#feature}}
386
387% new:
388
389\clf_registerlanguagefeatures
390
391% also new
392
393\unexpanded\def\useaddfontfeatureparameter#namespace% faster local variant
394  {\edef\m_font_feature_asked{#namespace\c!features}%
395   \ifx\m_font_feature_asked\empty\else
396     \font_feature_add
397   \fi}
398
399% let's put this here:
400
401\unexpanded\def\slashedzero
402  {\dontleavehmode
403   \begingroup
404  %\addff{zero}
405   \font_feature_add_nop{zero}%
406   0%
407   \endgroup}
408
409% not nice but maybe handy
410
411% \starttyping
412% \blockligatures[fi,ff] \blockligatures[fl]
413%
414% \definefontfeature[default:b][default][blockligatures=yes]
415%
416% \setupbodyfont[pagella] \showfontkerns
417%
418% \definedfont[Serif*default:b]
419%
420% \startTEXpage[offset=1em]
421%     fi ff fl
422% \stopTEXpage
423% \stoptyping
424
425\unexpanded\def\blockligatures[#1]{\clf_blockligatures{#1}}
426
427\protect \endinput
428