font-ini.mklx /size: 122 Kb    last modification: 2025-02-21 11:03
1%D \module
2%D   [       file=font-ini,
3%D        version=1998.09.11, % (second)
4%D        version=2001.02.20, % (third)
5%D          title=\CONTEXT\ Font Macros,
6%D       subtitle=Initialization,
7%D         author=Hans Hagen,
8%D           date=\currentdate,
9%D      copyright={PRAGMA ADE \& \CONTEXT\ Development Team}]
10%C
11%C This module is part of the \CONTEXT\ macro||package and is
12%C therefore copyrighted by \PRAGMA. See mreadme.pdf for
13%C details.
14
15% maybe:
16
17% \glyphweight
18% \glyphslant
19%
20% in backend get from lua: (when 'true' passed)
21%
22% width   -> width   + 2 * weight
23% height  -> height  + weight
24% depth   -> depth   + weight
25% xoffset -> xoffset - weight
26% yoffset -> yoffset - weight
27% weight  -> weight
28
29% todo: frozen tolerant iftok etc
30
31% todo: < 3 pt => 3pt
32% todo: check where more class usage
33% todo: split font-nam (style/alternative/size)
34% todo: split font-dim (scales etc)
35% todo: reconsider defaultfontclass
36
37%D Beware, we use a special set of parameters here:
38%D
39%D \starttabulate[|l|l|]
40%D \NC system variable (fixed) \NC \type {\s!text}           \NC \NR
41%D \NC system variable (fixed) \NC \type {\s!script}         \NC \NR
42%D \NC system variable (fixed) \NC \type {\s!scriptscript}   \NC \NR
43%D \NC system variable (fixed) \NC \type {\s!x}              \NC \NR
44%D \NC system variable (fixed) \NC \type {\s!xx}             \NC \NR
45%D \NC variable (value)        \NC \type {\v!big}            \NC \NR
46%D \NC variable (value)        \NC \type {\v!small}          \NC \NR
47%D \NC constant (regular key)  \NC \type {\c!interlinespace} \NC \NR
48%D \NC constant (regular key)  \NC \type {\c!em}             \NC \NR
49%D \stoptabulate
50%D
51%D The math related ones are similar to the ones used in \TEX\ itself,
52%D the size related ones show up as keywords in the user interface
53%D when switching sizes, and the two constants are used in key|/|value
54%D situations.
55
56%D We should consider design sizes ... maybe kick 'm out which removes
57%D the size code and simplifies things considerably. After all, there
58%D will be no latin modern math in sizes.
59
60\writestatus{loading}{ConTeXt Font Macros / Initialization}
61
62%D Documentation is somewhat messy as it contains bits and pieces of
63%D previous versions.
64
65\unprotect
66
67%D There are several ways to specify a font. Three of them are pure \TEX\ ones, the
68%D fourth one is new:
69%D
70%D \starttyping
71%D \font\name=cmr12
72%D \font\name=cmr12 at 10pt
73%D \font\name=cmr12 scaled 2
74%D \font\name=cmr12 sa 1.440
75%D \stoptyping
76%D
77%D The non||\TEX\ alternative \type{sa} stands for {\em scaled at}. This means as
78%D much as: scale the bodyfontsize with this factor. The scaled option is not that
79%D useful as one needs to know the design size.
80%D
81%D Because \type {sa} (scaled at) and \type {mo} (mapped on) are not low level \TEX\
82%D supported alternatives, we have to test for it ourselves. In doing so, we need an
83%D auxiliary \DIMENSION. We cannot use \type{\scratchdimen} because font loading can
84%D happen at any moment due to postponed loading. We could instead have used dirty
85%D grouping tricks, but this one works too.
86
87% \enableexperiments[fonts.autorscale]
88%
89% \starttypescript[mscore]
90%     \definetypeface [mscore] [rm] [serif] [mscoretimes]   [default]
91%     \definetypeface [mscore] [ss] [sans]  [mscorearial]   [default] [rscale=auto] % 0.860]
92%     \definetypeface [mscore] [tt] [mono]  [mscorecourier] [default] [rscale=auto] % 1.065]
93%     \definetypeface [mscore] [mm] [math]  [times]         [default] [rscale=auto] % 1.020]
94% \stoptypescript
95%
96% \starttext
97%    \setupbodyfont[mscore,12pt]
98%    \startTEXpage
99%        test \ss test \tt test
100%    \stopTEXpage
101% \stoptext
102
103% \definetypeface[one][rm][serif][computer-roman][default]
104% \definetypeface[two][rm][serif][computer-roman][default][rscale=.9]
105%
106% {\one \bf test \two test}
107% {\one \bf test \pushcurrentfont \two \popcurrentfont test}
108
109%D \macros
110%D   {rm,ss,tt,hw,cg}
111%D
112%D Fonts are defined in separate files. When we define a font, we distinguish
113%D between several styles. In most cases we will use:
114%D
115%D \startlinecorrection
116%D \starttable[|l||]
117%D \HL
118%D \NC roman regular serif    \NC \type{\rm} \NC\FR
119%D \NC sansserif sans support \NC \type{\ss} \NC\MR
120%D \NC type teletype mono     \NC \type{\tt} \NC\LR
121%D \HL
122%D \stoptable
123%D \stoplinecorrection
124%D
125%D The number of styles is not limited to these three. When using Lucida Bright we
126%D can for instance also define:
127%D
128%D \startlinecorrection
129%D \starttable[|l||]
130%D \HL
131%D \NC handwritten  \NC \type{\hw} \NC\FR
132%D \NC calligraphic \NC \type{\cg} \NC\LR
133%D \HL
134%D \stoptable
135%D \stoplinecorrection
136%D
137%D Within such a font set (\type{cmr}) and style (\type{\rm}) we can define a number
138%D of text font alternatives:
139%D
140%D \startlinecorrection
141%D \starttable[|l||]
142%D \HL
143%D \NC typeface    \NC \type{\tf} \NC\FR
144%D \NC boldface    \NC \type{\bf} \NC\MR
145%D \NC slanted     \NC \type{\sl} \NC\MR
146%D \NC italic      \NC \type{\it} \NC\MR
147%D \NC boldslanted \NC \type{\bs} \NC\MR
148%D \NC bolditalic  \NC \type{\bi} \NC\MR
149%D \NC smallcaps   \NC \type{\sc} \NC\LR
150%D \HL
151%D \stoptable
152%D \stoplinecorrection
153%D
154%D Internally fonts are stored as combination of size, style
155%D and alternative, e.g. \type{12pt}+\type{\ss}+\type{\bf}. Users are not confronted
156%D with sizes, but use the style or style+alternative to activate them.
157%D
158%D During the definition of a bodyfont one can also declare the available larger
159%D alternatives:
160%D
161%D \starttyping
162%D \tf \tfa \tfb \tfc ...
163%D \bf \bfa \bfb \bfc ...
164%D \sl \sla \slb \slc ...
165%D \stoptyping
166%D
167%D The smaller ones are automatically supplied and derived from
168%D the the bodyfont environment.
169%D
170%D \starttyping
171%D \tfx \tfxx
172%D \bfx \bfxx
173%D \slx \slxx
174%D \stoptyping
175%D
176%D There are only two smaller alternatives per style. The larger alternatives on the
177%D other hand have no limitations.
178%D
179%D These larger alternatives are mostly used in chapter and section titles or on
180%D title pages. When one switches to a larger alternative, the bold an other ones
181%D automatically adapt themselves:
182%D
183%D \startbuffer
184%D \tfd Hi \bf there\sl, here \tfb I \bf am
185%D \stopbuffer
186%D
187%S \startnarrower
188%D \typebuffer
189%S \stopnarrower
190%D
191%D therefore becomes:
192%D
193%D \startexample
194%D \getbuffer
195%D \stopexample
196%D
197%D Maybe this mechanism isn't always as logic, but as said before, we tried to make
198%D it as intuitive as possible.
199%D
200%D So a specific kind of glyph can be characterized by:
201%D
202%D \startnarrower
203%D family (cmr) + bodyfont (12pt) + style (rm) + alternative (bf) + size (a)
204%D \stopnarrower
205%D
206%D The last component (the size) is optional.
207%D
208%D We introduced \type {\tf} as command to call for the current normally sized
209%D typeface. This commands results in roman, sans serif, teletype or whatever style
210%D is in charge. Such rather massive switches of style sometimes take more
211%D processing time than comfortable. Of course there is a workaround for this: we
212%D can call fonts directly by means of commands like:
213%D
214%D \starttyping
215%D \rmtf \sssl \tttf \rmbsa
216%D \stoptyping
217%D
218%D One should realize that this fast calls have limitations, they lack for instance
219%D automatic super- and subscript support.
220%D
221%D This leaves us two more commands: \type {\tx} and \type {\txx}. These activate a
222%D smaller and even more smaller font than the current one and adapt themselves to
223%D the current alternative, so when \type {\bf} is active, \type {\tx} gives a
224%D smaller boldface, which in turn can be called directly by \type {\bfx}.
225%D
226%D These two smaller alternatives are specified by the bodyfont environment and
227%D therefore not necessarily have similar sizes as \type {\scriptsize} and \type
228%D {\scriptscriptsize}. The main reason for this incompatibility (which can easily
229%D be undone) lays in the fact that we often want a bit bigger characters than in
230%D math mode. In \CONTEXT\ for instance the \type {\tx} and \type {\txx} commands
231%D are used for surrogate \cap {smallcaps} which support both nesting and
232%D alternatives, like in {\bf \cap {a \cap {small} world}}, which was typeset by
233%D
234%D \starttyping
235%D \bf\cap{a \cap{small} world}
236%D \stoptyping
237%D
238%D And compare $\rm \scriptstyle THIS$ with the slightly larger \cap {THIS}:
239%D \ruledhbox {$\rm \scriptstyle scriptstyle: THIS$} or \ruledhbox {\cap {x style:
240%D THIS}} makes a big difference.
241%D
242%D The \type {x..d} sizes should be used grouped. If you don't group them, i.e. call
243%D them in a row, \CONTEXT\ will not be able to sort out your intention (\type {x}
244%D inside \type {d} inside \type {x}. etc.). The following table demonstrates this:
245%D
246%D \def\FontState{\setstrut\ruledhbox{\strut Hello}}
247%D
248%D \starttabulate[|||||]
249%D \HL
250%D \NC \rlap{\quad\bf grouped} \NC \NC \type {\tx} \NC \type {\txx} \NC \NR
251%D \HL
252%D \NC \type{\tfx}  \NC \tfx  \FontState \NC \tfx \tx \FontState \NC \tfx \txx \FontState  \NC \NR
253%D \NC \type{\tfxx} \NC \tfxx \FontState \NC \tfxx\tx \FontState \NC \tfxx\txx \FontState  \NC \NR
254%D \NC \type{\tf}   \NC \tf   \FontState \NC \tf  \tx \FontState \NC \tf  \txx \FontState  \NC \NR
255%D \NC \type{\tfa}  \NC \tfa  \FontState \NC \tfa \tx \FontState \NC \tfa \txx \FontState  \NC \NR
256%D \NC \type{\tfb}  \NC \tfb  \FontState \NC \tfb \tx \FontState \NC \tfb \txx \FontState  \NC \NR
257%D \NC \type{\tfc}  \NC \tfc  \FontState \NC \tfc \tx \FontState \NC \tfc \txx \FontState  \NC \NR
258%D \NC \type{\tfd}  \NC \tfd  \FontState \NC \tfd \tx \FontState \NC \tfd \txx \FontState  \NC \NR
259%D \NC \type{\tfx}  \NC \tfx  \FontState \NC \tfx \tx \FontState \NC \tfx \txx \FontState  \NC \NR
260%D \NC \type{\tfxx} \NC \tfxx \FontState \NC \tfxx\tx \FontState \NC \tfxx\txx \FontState  \NC \NR
261%D \HL
262%D \stoptabulate
263%D
264%D \blank
265%D
266%D \starttabulate[|||||]
267%D \HL
268%D \NC \rlap{\quad\bf stacked} \NC \NC \type {\tx} \NC \type {\txx} \NC \NR
269%D \HL
270%D \NC \type{\tfx}
271%D \NC \tfx                                   \FontState
272%D \NC \tfx                              \tx  \FontState
273%D \NC \tfx                              \txx \FontState
274%D \NC \NR
275%D \NC \type{\tfxx}
276%D \NC \tfx\tfxx                              \FontState
277%D \NC \tfx\tfxx                         \tx  \FontState
278%D \NC \tfx\tfxx                         \txx \FontState
279%D \NC \NR
280%D \NC \type{\tf}
281%D \NC \tfx\tfxx\tf                           \FontState
282%D \NC \tfx\tfxx\tf                      \tx  \FontState
283%D \NC \tfx\tfxx\tf                      \txx \FontState
284%D \NC \NR
285%D \NC \type{\tfa}
286%D \NC \tfx\tfxx\tf\tfa                       \FontState
287%D \NC \tfx\tfxx\tf\tfa                  \tx  \FontState
288%D \NC \tfx\tfxx\tf\tfa                  \txx \FontState
289%D \NC \NR
290%D \NC \type{\tfb}
291%D \NC \tfx\tfxx\tf\tfa\tfb                   \FontState
292%D \NC \tfx\tfxx\tf\tfa\tfb              \tx  \FontState
293%D \NC \tfx\tfxx\tf\tfa\tfb              \txx \FontState
294%D \NC \NR
295%D \NC \type{\tfc}
296%D \NC \tfx\tfxx\tf\tfa\tfb\tfc               \FontState
297%D \NC \tfx\tfxx\tf\tfa\tfb\tfc          \tx  \FontState
298%D \NC \tfx\tfxx\tf\tfa\tfb\tfc          \txx \FontState
299%D \NC \NR
300%D \NC \type{\tfd}
301%D \NC \tfx\tfxx\tf\tfa\tfb\tfd               \FontState
302%D \NC \tfx\tfxx\tf\tfa\tfb\tfd          \tx  \FontState
303%D \NC \tfx\tfxx\tf\tfa\tfb\tfd          \txx \FontState
304%D \NC \NR
305%D \NC \type{\tfx}
306%D \NC \tfx\tfxx\tf\tfa\tfb\tfc\tfx           \FontState
307%D \NC \tfx\tfxx\tf\tfa\tfb\tfc\tfx      \tx  \FontState
308%D \NC \tfx\tfxx\tf\tfa\tfb\tfc\tfx      \txx \FontState
309%D \NC \NR
310%D \NC \type{\tfxx}
311%D \NC \tfx\tfxx\tf\tfa\tfb\tfc\tfx\tfxx      \FontState
312%D \NC \tfx\tfxx\tf\tfa\tfb\tfc\tfx\tfxx \tx  \FontState
313%D \NC \tfx\tfxx\tf\tfa\tfb\tfc\tfx\tfxx \txx \FontState
314%D \NC \NR
315%D \HL
316%D \stoptabulate
317
318\fontslantperpoint   \nullfont      0\scaledpoint
319\fontinterwordspace  \nullfont 256377\scaledpoint
320\fontinterwordstretch\nullfont 128188\scaledpoint
321\fontinterwordshrink \nullfont  85459\scaledpoint
322\fontexheight        \nullfont 338952\scaledpoint
323\fontemwidth         \nullfont 786432\scaledpoint
324\fontextraspace      \nullfont  85459\scaledpoint
325
326\appendtoks
327    \fontslantperpoint   \nullfont      0\scaledpoint
328    \fontinterwordspace  \nullfont 256377\scaledpoint
329    \fontinterwordstretch\nullfont 128188\scaledpoint
330    \fontinterwordshrink \nullfont  85459\scaledpoint
331    \fontexheight        \nullfont 338952\scaledpoint
332    \fontemwidth         \nullfont 786432\scaledpoint
333    \fontextraspace      \nullfont  85459\scaledpoint
334\to \everyjob
335
336%D Tracing
337
338\newtoks\t_font_tracers_definitions
339
340\permanent\protected\def\tracefontdefinitions
341  {\expand\t_font_tracers_definitions}
342
343%D Some housekeeping macros:
344
345\permanent\protected\def\setfontparameters
346  {\c_font_synchronize\conditionalfalse
347   \expand\everybodyfont
348   \c_font_synchronize\conditionaltrue}
349
350\mutable\lettonothing\savedfont
351
352\installmacrostack\savedfont
353
354% \fontname\font               : string
355% \fontid  \font               : integer
356% \the     \font               : token (reference to font)
357%          \fontspecifiedname  : string
358% \the     \fontspecifiedsize  : dimension
359
360\permanent\protected\def\savefont
361  {\edef\savedfont{\the\font}%
362   \push_macro_savedfont}
363
364\permanent\protected\def\restorefont
365  {\pop_macro_savedfont
366   \savedfont}
367
368\aliased\let\popcurrentfont\relax
369
370\permanent\protected\def\pushcurrentfont
371  {\enforced\permanent\protected\edef\popcurrentfont
372     {\def\noexpand\fontbody       {\fontbody}%
373      \def\noexpand\fontstyle      {\fontstyle}%
374      \def\noexpand\fontalternative{\fontalternative}%
375      \def\noexpand\fontsize       {\fontsize}%
376      \font_helpers_check_big_math_synchronization
377      \font_helpers_synchronize_font}}
378
379%D \macros{definedfont}
380
381\mutable\let\thedefinedfont\relax % not to be confused with \everydefinefont
382
383\permanent\tolerant\protected\def\definedfont[#specification]%
384  {\ifarguments
385      \c_font_feature_inheritance_mode\c_font_feature_inheritance_fontonly
386   \or
387      \c_font_feature_inheritance_mode\c_font_feature_inheritance_fontonly
388      \font_basics_define_font_without_parameters{thedefinedfont}{#specification}%
389   \fi
390   \thedefinedfont
391   \expand\everydefinedfont}
392
393%D \macros{startfont}
394
395\permanent\protected\def\startfont{\begingroup\definedfont}
396\permanent\protected\def\stopfont {\endgroup}
397
398%D \macros
399%D   {everybodyfont,everyglobalbodyfont}
400%D
401%D Every change in bodyfont size has conseqences for the baseline distance and skips
402%D between paragraphs. These are initialized in other modules. Here we only provide
403%D the hooks that garantees their handling.
404%D
405%D At the system level one can initialize thing like:
406%D
407%D \starttyping
408%D \appendtoks \setupspacing \to \everybodyfont
409%D \stoptyping
410
411%D \macros
412%D   {globalbodyfontsize,localbodyfontsize,bodyfontsize}
413%D
414%D Here we have to distinguish between the global (overal) bodyfont size and the
415%D local (sometimes in the textflow) size. We store these dimensions in two
416%D \DIMENSION\ registers. These registers are not to be misused in calculations.
417
418%D Ascender, descender and capheight are unreliable and often wrong. One can use
419%D alternatives in the OS/2 table but these then can be too large. We therefore
420%D just use ( and X as template characters to derive these properties.
421
422% \protected\def\ShowScenders
423%   {\dontleavehmode
424%    \hpack\bgroup
425%      \setbox\scratchbox\hpack{(\showstruts\strut X\textbar g)}%
426%      {\lightgray \srule height 1fa depth 1fd width \wd\scratchbox\relax}%
427%      \kern-\wd\scratchbox
428%      \box\scratchbox
429%    \egroup}
430%
431% {\switchtobodyfont[modern,10pt]  \ShowScenders}\blank
432% {\switchtobodyfont[pagella,10pt] \ShowScenders}\blank
433% {\switchtobodyfont[cambria,10pt] \ShowScenders}\blank
434
435\ifdefined\globalbodyfontsize \else \newdimension\globalbodyfontsize \fi \globalbodyfontsize=12pt
436\ifdefined\localbodyfontsize  \else \newdimension\localbodyfontsize  \fi \localbodyfontsize =\globalbodyfontsize
437\ifdefined\bodyfontsize       \else \newdimension\bodyfontsize       \fi \bodyfontsize      =\globalbodyfontsize
438
439\permanent\protected\def\widthofzero{\scaledfontcharwd\font\zeroasciicode}
440
441% \definedatluaend\ascender
442% \definedatluaend\descender
443% \definedatluaend\capheight
444
445\pushoverloadmode
446    \newuserunit\globalbodyfontsize fs % normally local is the same as em
447    \newuserunit\widthofzero        ch % from css
448    \newuserunit\ascender           fa
449    \newuserunit\descender          fd
450    \newuserunit\capheight          fc
451\popoverloadmode
452
453% this would also work
454%
455% \permanent\protected\untraced\def\ascender {\dimexpr1fa\relax}
456% \permanent\protected\untraced\def\descender{\dimexpr1fd\relax}
457% \permanent\protected\untraced\def\capheight{\dimexpr1fc\relax}
458%
459% \pushoverloadmode
460%     \newuserunit\fontproperty       fa % more a proof of concept
461%     \newuserunit\fontproperty       fd
462%     \newuserunit\fontproperty       fc
463% \popoverloadmode
464
465%D When we assign for instance 12pt to a \DIMENSION\ register the \type {\the}'d
466%D value comes out as 12.0pt, which is often not the way users specify the bodyfont
467%D size. Therefore we use normalized values. They are cached to save overhead in
468%D \LUA\ calls.
469
470\installcorenamespace{fontnormalizedbody}
471
472\permanent\protected\def\normalizebodyfontsize#macro#body%
473  {\scratchdimen\ifchkdimension#body\or\lastchkdimension\else#body\dimexpr\fontbody\relax\fi
474   \expandafter\let\expandafter#macro\csname\??fontnormalizedbody\number\scratchdimen\endcsname
475   \ifrelax#macro%
476      \normalizebodyfontsize_indeed#macro%
477   \fi}
478
479\def\normalizebodyfontsize_indeed#macro%
480  {\edef#macro{\clf_normalizedbodyfontsize\scratchdimen}%
481   \gletcsname\??fontnormalizedbody\number\scratchdimen\endcsname#macro}
482
483\permanent\def\thenormalizedbodyfontsize#body%
484  {\clf_normalizedbodyfontsize{#body}}
485
486\mutable\edef\normalizedglobalbodyfontsize{\thenormalizedbodyfontsize\bodyfontsize}
487\mutable\edef\normalizedlocalbodyfontsize {\thenormalizedbodyfontsize\bodyfontsize}
488\mutable\edef\normalizedbodyfontsize      {\thenormalizedbodyfontsize\bodyfontsize}
489
490%D \macros
491%D   {mapfontsize}
492%D
493%D For special purposes, like in math, you may want to use slightly different sizes
494%D than the ones given. This happens for instance with the Math Times fonts. Mapped
495%D font sizes can be specified by using the \type {mo} key instead of \type {sa} in
496%D font definitions.
497%D
498%D \startbuffer
499%D \mapfontsize[10pt][11pt]
500%D \mapfontsize[11pt][12pt]
501%D \mapfontsize[12pt][13pt]
502%D
503%D \definefont[test][Serif]\test TEST \par
504%D \definefont[test][Serif sa 5]\test TEST \par
505%D \definefont[test][Serif mo 5]\test TEST \par
506%D \definefont[test][Serif sa d]\test TEST \par
507%D \definefont[test][Serif at 60pt]\test TEST \par
508%D \stopbuffer
509%D
510%D \typebuffer
511%D
512%D \startpacked
513%D \getbuffer
514%D \stoppacked
515
516%D Size mapping only applies to math fonts.
517
518\installcorenamespace{mappedfontsize}
519
520%letcsname\??mappedfontsize\s!text        \endcsname\!!plusone
521\letcsname\??mappedfontsize\s!script      \endcsname\!!plustwo
522\letcsname\??mappedfontsize\s!scriptscript\endcsname\!!plusthree
523
524\permanent\tolerant\protected\def\mapfontsize[#class]#spacer[#from]#spacer[#to]%
525  {\ifarguments
526     % ignore
527   \or
528     % reset
529     \letcsname\??mappedfontsize#class:1\endcsname\undefined
530     \letcsname\??mappedfontsize#class:2\endcsname\undefined
531     \letcsname\??mappedfontsize#class:3\endcsname\undefined
532   \or
533     % unsupported
534   \or
535     % set
536     \defcsname
537       \??mappedfontsize
538       #class:%
539       \begincsname\??mappedfontsize#from\endcsname
540     \endcsname{#to}%
541   \fi}
542
543\permanent\tolerant\protected\def\checkedmapfontsize[#class]#spacer[#from]#spacer[#to]% used in typescripts
544  {\ifcsname\??mappedfontsize#class:\begincsname\??mappedfontsize#from\endcsname\endcsname
545     % keep (user) value
546   \else
547     \mapfontsize[#class][#from][#to]%
548   \fi}
549
550\permanent\tolerant\def\mappedfontsize#class#from%
551  {\begincsname
552     \??mappedfontsize
553     #class:%
554     \begincsname\??mappedfontsize#from\endcsname
555   \endcsname}
556
557\def\font_basics_set_mapped_fontsize#from%
558  {\ifcsname\??mappedfontsize\fontclass:\fontface\endcsname
559    %\the\dimexpr\lastnamedcs\dimexpr#from\relax\relax
560    %\the\dimexpr\lastnamedcs\dimexpr\bodyfontsize\relax\relax
561     \the\dimexpr\lastnamedcs\dimexpr\normalizedbodyfontsize\relax\relax
562   \else % we could use default
563     #from%
564   \fi}
565
566\appendtoks
567    \def\font_basics_set_mapped_fontsize#from%
568      {\ifcsname\??mappedfontsize\fontclass:\fontface\endcsname % really ?
569         \the\dimexpr\lastnamedcs\dimexpr\normalizedbodyfontsize\relax\relax
570       \else % we could use default
571         #from%
572       \fi}%
573\to \everycompactfontmode
574
575% \defcsname font_basics_mapped_fontsize_1\endcsname{\begincsname\??mappedfontsize\fontclass:1\endcsname}
576% \defcsname font_basics_mapped_fontsize_2\endcsname{\begincsname\??mappedfontsize\fontclass:2\endcsname}
577% \defcsname font_basics_mapped_fontsize_3\endcsname{\begincsname\??mappedfontsize\fontclass:3\endcsname}
578
579% Somehow moving rscale into here doesn't work out ok, so for now we don't do that
580%
581% \the\floatexpr\v_font_size_relative*\plusthousand\relax
582
583\defcsname font_basics_mapped_fontsize_1\endcsname
584  {\the\plusthousand}
585
586\defcsname font_basics_mapped_fontsize_2\endcsname
587  {\tointeger{%
588     \plusthousand
589    *\dimexpr
590       \ifcsname\??mappedfontsize\fontclass:2\endcsname
591         \lastnamedcs\dimexpr\textface\relax
592       \else
593         \scriptface
594       \fi
595     \relax
596    /\dimexpr\textface\relax}}
597
598\defcsname font_basics_mapped_fontsize_3\endcsname
599  {\tointeger{%
600     \plusthousand
601    *\dimexpr
602       \ifcsname\??mappedfontsize\fontclass:3\endcsname
603         \lastnamedcs\dimexpr\textface\relax
604       \else
605         \scriptscriptface
606       \fi
607     \relax
608    /\dimexpr\textface\relax}}
609
610\installcorenamespace{fontbodyknown}
611\installcorenamespace{fontclassyes}   % fontclass
612\installcorenamespace{fontclassnop}   % nofontclass
613
614\def\font_helpers_process_relative_size_list#command% could be a toks
615  {#command\v!big
616   #command\v!small}
617
618\let\v_font_size_relative  \plusone
619\def\v_font_size_absolute {\fontbody}
620
621\let\v_font_rscale_default\!!plusone
622\let\p_font_rscale        \v_font_rscale_default
623
624\def\font_helpers_check_relative_font_id % can be plugged in later
625  {\let\p_font_rscale\minusone
626   \let\p_font_rscale\v_font_rscale_default}
627
628\def\font_helpers_check_relative_font_size#style%
629  {\edef\p_font_rscale
630     {\ifcsname\??fontclass\fontclass#style\s!rscale\endcsname
631        \lastnamedcs
632      \orelse\ifcsname\??fontclass\defaultfontclass#style\s!rscale\endcsname % brr
633        \lastnamedcs
634      \else
635        \v_font_rscale_default
636      \fi}%
637   % move elsewhere
638   \ifx\p_font_rscale\v!auto
639     \let\p_font_rscale\plusone
640     \font_helpers_check_relative_font_id
641   \fi}
642
643\def\font_rscale_xx#style%
644  {\ifcsname\??fontclass\fontclass#style\s!rscale\endcsname
645     \lastnamedcs
646   \else
647     \v_font_rscale_default
648   \fi}
649
650\def\font_rscale_mm
651  {\ifcsname\??fontclass\fontclass\s!mm\s!rscale\endcsname
652     \lastnamedcs
653   \else
654     \v_font_rscale_default
655   \fi}
656
657\protected\def\font_helpers_register_fontbody#body%
658  {\letcsname\??fontbodyknown#body\endcsname\empty}
659
660%D \macros
661%D   {definefontstyle,definefontsize,definefontalternative}
662%D
663%D When setting of switching the overall style we can use the short identifier like
664%D rm and ss, but when defined we can also use more verbose names like roman or
665%D sansserif. Such names are defined by:
666%D
667%D \starttyping
668%D \definefontstyle [serif,rm] [rm]
669%D \definefontstyle [sansserif,ss] [ss]
670%D \stoptyping
671
672\installcorenamespace{fontstyle}      % full style prefix (roman etc)
673\installcorenamespace{fontshortstyle} % short style prefix (rm etc)
674
675\installcorenamespace{fontstyleknown}
676\installcorenamespace{fontalternativeknown}
677\installcorenamespace{fontsizeknown}
678
679\newtoks\t_font_style_commands
680\newtoks\t_font_size_commands
681\newtoks\t_font_alternative_commands
682
683\setnewmacro\m_font_style_command      \gobbleoneargument
684\setnewmacro\m_font_size_command       \gobbleoneargument
685\setnewmacro\m_font_alternative_command\gobbleoneargument
686
687\def\font_helpers_process_style_list      #command{\def\m_font_style_command      {#command}\expand\t_font_style_commands}
688\def\font_helpers_process_size_list       #command{\def\m_font_size_command       {#command}\expand\t_font_size_commands}
689\def\font_helpers_process_alternative_list#command{\def\m_font_alternative_command{#command}\expand\t_font_alternative_commands}
690
691\def\font_helpers_register_style            #style{\letcsname\??fontstyleknown            #style\endcsname\empty}
692\def\font_helpers_register_size              #size{\letcsname\??fontsizeknown              #size\endcsname\empty}
693\def\font_helpers_register_alternative#alternative{\letcsname\??fontalternativeknown#alternative\endcsname\empty}
694
695\permanent\protected\def\definefontstyle[#commands]#spacer[#style]% style: rm ss tt ...
696  {\ifcsname\??fontstyleknown#style\endcsname \else % can be delayed till used (cg, hw)
697     \font_helpers_register_style{#style}%
698     \toksapp\t_font_style_commands{\m_font_style_command{#style}}%
699   \fi
700   \processcommalist[#commands]{\font_basics_define_fontstyle_indeed{#style}}}
701
702\def\font_basics_define_fontstyle_indeed#style#command%
703  {\defcsname\??fontshortstyle#command\endcsname{#style}%
704   \defcsname\??fontstyle     #command\endcsname{\csname#style\endcsname}} % we could pre-expand
705
706\permanent\protected\def\definefontsize[#size]%
707  {\ifcsname\??fontsizeknown#size\endcsname \else
708     \font_helpers_register_size{#size}%
709     \toksapp\t_font_size_commands{\m_font_size_command{#size}}%
710   \fi
711   \font_helpers_check_fontname_combinations}
712
713\permanent\protected\def\definefontalternative[#alternative]%
714  {\ifcsname\??fontalternativeknown#alternative\endcsname \else
715     \font_helpers_register_alternative{#alternative}%
716     \toksapp\t_font_alternative_commands{\m_font_alternative_command{#alternative}}%
717   \fi
718   \font_helpers_check_fontname_combinations}
719
720\protected\def\font_helpers_check_fontname_combinations % we need to split math and text here ... todo (math only has mr and mb)
721  {\font_helpers_process_style_list\font_helpers_check_fontname_combinations_s}
722
723\def\font_helpers_check_fontname_combinations_s#style%
724  {\font_helpers_process_alternative_list{\font_helpers_check_fontname_combinations_indeed_s_a{#style}}}
725
726\def\font_helpers_check_fontname_combinations_indeed_s_a#style#alternative%
727  {\font_helpers_process_size_list{\font_basics_check_fontname_combination{#style}{#alternative}}}
728
729\definefontstyle [\s!mm] [\s!mm]
730\definefontstyle [\s!rm] [\s!rm]
731\definefontstyle [\s!ss] [\s!ss]
732\definefontstyle [\s!tt] [\s!tt]
733
734%D We define all the font switching commands globally. After all they are part of
735%D the formal font interface once defined. The size can be empty (so checking is
736%D needed as \type {\bf} is already defined).
737%D
738%D The \type {\normal..} variants are available as extras for cases where the \type
739%D {..} is overloaded.
740
741\newmacro\m_font_mm
742
743\def\font_basics_check_fontname_combination#style% alternative size
744  {\edef\m_font_mm{#style}%
745   \ifx\m_font_mm\s!mm % prevents \max and alike (re)defs
746     \expandafter\font_basics_check_math_bodyfont
747   \else
748     \expandafter\font_basics_check_text_bodyfont
749   \fi{#style}} % no \m_font_mm, not expanded later on
750
751\def\font_basics_check_math_bodyfont#style#alternative#size%
752  {}
753
754\def\font_basics_check_text_bodyfont_step#whatever#body% size can be empty (checking needed as \bf is already defined)
755  {\ifcsname#whatever\endcsname\else
756    %\permanent\setugvalue{#whatever}{#body}%
757     \permanent\protected\gdefcsname#whatever\endcsname{#body}%
758   \fi}
759
760\def\font_basics_check_text_bodyfont#style#alternative#size% size can be empty (checking needed as \bf is already defined)
761  {\font_basics_check_text_bodyfont_step{#style#size}{\font_helpers_set_current_font_style_size{#style}{#size}}% \rma
762   \font_basics_check_text_bodyfont_step{#alternative#size}{\font_helpers_set_current_font_alternative_size{#alternative}{#size}}% \sla
763   \font_basics_check_text_bodyfont_step{#style#alternative#size}{\font_helpers_set_current_font_style_alternative_size{#style}{#alternative}{#size}}% \rmsla
764   \font_basics_check_text_bodyfont_step{#style}{\font_helpers_set_current_font_style{#style}}% \rm
765   \font_basics_check_text_bodyfont_step{#alternative}{\font_helpers_set_current_font_alternative{#alternative}}% \sl
766   \font_basics_check_text_bodyfont_step{#style\s!x }{\font_helpers_set_current_font_x_style_alternative{#style}}% \rmx
767   \font_basics_check_text_bodyfont_step{#style\s!xx}{\font_helpers_set_current_font_xx_style_alternative{#style}}% \rmxx
768   \font_basics_check_text_bodyfont_step{#alternative\s!x }{\font_helpers_set_current_font_x_alternative{#alternative}}% \slx
769   \font_basics_check_text_bodyfont_step{#alternative\s!xx}{\font_helpers_set_current_font_xx_alternative{#alternative}}% \slxx
770   \font_basics_check_text_bodyfont_step{#style#alternative}{\font_helpers_set_current_font_style_alternative{#style}{#alternative}}}% \rmsl
771
772%D Scaling macros:
773%D
774%D This system is somewhat complicated by two (possible conflicting) demands:
775%D
776%D \startitemize
777%D \item We support wildcards like \type {sa *} which will adapt to the current
778%D       size. This is also the default specification.
779%D \item We support named scales like \type {sa d}; beware: \type {x} and \type {xx}
780%D       are valid scales but they are not alway the same as the ones used in for
781%D       instance \type {\bfx} because there the sized come from the bodyfont
782%D       environment. In the future there maybe a switch that also honors the
783%D       environment in named scales.
784%D \stopitemize
785%D
786%D Keep in mind that the smaller sizes are just for text super and subscripts while
787%D larger sizes can be used in titles where for instance math follows the size.
788
789% b:x{\definedfont[SerifBold sa  b]x}{\bfb  x $x^x$}\par
790% 1:x{\definedfont[SerifBold sa  1]x}{\bf   x $x^x$}\par
791% x:x{\definedfont[SerifBold sa  x]x}{\bfx  x $x^x$}\par
792% xx:x{\definedfont[SerifBold sa xx]x}{\bfxx x $x^x$}\par
793%
794% *:x{\definedfont[Serif sa *]x}\par
795% 1:x{\definedfont[Serif sa 1]x}\par
796% 2:x{\definedfont[Serif sa 2]x}\par
797% 3:x{\definedfont[Serif sa 3]x}\par
798% 4:x{\definedfont[Serif sa 4]x}\par
799% 5:x{\definedfont[Serif sa 5]x}\par
800
801% \permanent\def\safontscale{\number\dimexpr\v_font_size_absolute\relax}
802% \permanent\def\mofontscale{\number\dimexpr\font_basics_set_mapped_fontsize\v_font_size_absolute\relax}
803
804\mutable\let\somefontname \s!unknown
805\mutable\let\somefontspec \s!unknown
806\mutable\let\somefontfile \s!unknown
807\mutable\let\somefontsize \zerocount
808
809\mutable\lettonothing\somefontsizex
810\mutable\lettonothing\somefontsizey
811
812% \newinteger\scaledfontmode % font-lib.mklx
813% \newinteger\scaledfontsize % font-lib.mklx
814% \newinteger\lastfontid     % font-lib.mklx
815
816\newtoks \everydefinefont
817
818\aliased\let\c_font_feature_inheritance_fontnone  \zerocount  % none
819\aliased\let\c_font_feature_inheritance_fontonly  \plusone    % fontonly
820\aliased\let\c_font_feature_inheritance_classonly \plustwo    % classonly
821\aliased\let\c_font_feature_inheritance_fontfirst \plusthree  % fontfirst
822\aliased\let\c_font_feature_inheritance_classfirst\plusfour   % classfirst
823
824\aliased\let\c_font_feature_inheritance_default\c_font_feature_inheritance_fontfirst
825
826\setnewconstant\c_font_feature_inheritance_mode\c_font_feature_inheritance_default
827
828\newdimension  \d_font_scaled_text_face
829\newdimension  \d_font_scaled_font_size
830\newconditional\c_font_body_scale
831\newfraction   \f_font_body_scale
832
833\newinteger    \c_font_scaled_glyph_scale
834
835\immutable\dimensiondef\d_font_scaled_default 10pt
836
837% todo: move all to lua: use localcall for resolving filename
838
839% \newcountinteger\c_font_future_glyph_scale     % font-lib.mklx
840% \newcountinteger\c_font_scaled_font_mode_saved % font-lib.mklx
841% \newcountinteger\c_font_scaled_points          % font-lib.mklx
842
843\mutable\lettonothing\somefontspec
844
845\mutable\let\lastrawfontcall      \relax
846\mutable\let\lastglobalrawfontcall\relax
847
848\immutable\dimensiondef\d_font_default_size 10pt
849
850%lettonothing\m_font_class_direction   % no longer used
851\lettonothing\m_font_class_features
852\lettonothing\m_font_class_fallbacks
853\lettonothing\m_font_class_goodies
854
855\lettonothing\m_font_direction
856\lettonothing\m_font_features
857\lettonothing\m_font_fallbacks
858\lettonothing\m_font_goodies
859
860\protected\def\font_helpers_low_level_define#specification#csname% normal mode
861  {\font_ignore_compact_font_mode
862   % we can now set more at the lua end
863   \glet\somefontname\defaultfontfile
864   \lettonothing\somefontsize
865   \lettonothing\somefontsizex
866   \lettonothing\somefontsizey
867   \clf_definefont_one{\detokenize\expandafter{\normalexpanded{#specification}}}% the escapestring catches at \somedimen
868   % sets \scaledfontmode and \somefontname and \somefontsize
869   \ifcase\fontface\relax
870     % this was commented but we need it in order to be compatible to compact mode
871     \let\v_font_size_absolute\textface
872   \or
873     \let\v_font_size_absolute\textface
874   \or
875     \let\v_font_size_absolute\scriptface
876   \or
877     \let\v_font_size_absolute\scriptscriptface
878   \or
879     \let\v_font_size_absolute\xtextface
880   \or
881     \let\v_font_size_absolute\xxtextface
882   \fi
883   %
884   \ifcase\scaledfontmode\relax
885     \d_font_scaled_font_size\d_font_default_size
886   \or
887     % at
888     \d_font_scaled_font_size\somefontsize
889   \or
890     % sa
891     \d_font_scaled_font_size\v_font_size_absolute\relax
892     \d_font_scaled_font_size\currentfontbodysize\d_font_scaled_font_size % uses \somefontsize set by lua
893   \or
894     % mo % mapped font size will go away
895     \d_font_scaled_font_size\font_basics_set_mapped_fontsize\v_font_size_absolute
896     \d_font_scaled_font_size\currentfontbodysize\d_font_scaled_font_size
897   \or
898     % scaled, don't use this one as it's unpredictable (we fallback on scaled 1200 -> sa 1.2)
899     \d_font_scaled_font_size-\somefontsize\scaledpoint
900   \else % ht cp
901     % experiment, yet undocumented
902     \d_font_scaled_font_size\somefontsize
903   \fi
904   \relax
905   \d_font_scaled_font_size\v_font_size_relative\d_font_scaled_font_size
906   \relax
907   %
908   \ifconditional\c_font_auto_size
909     \font_helpers_check_body_scale\fontsize
910     \ifconditional\c_font_body_scale
911       \d_font_scaled_font_size\f_font_body_scale\d_font_scaled_font_size
912       \d_font_scaled_text_face\f_font_body_scale\dimexpr\textface\relax
913     \else
914       \d_font_scaled_font_size\f_font_body_scale
915       \d_font_scaled_text_face\textface
916     \fi
917   \else
918     \d_font_scaled_text_face\textface
919   \fi
920   %
921   \edef\somefontspec{at \number\d_font_scaled_font_size sp}%
922   \edef\somefontfile{\truefontname\somefontname}%
923   \ifx\somefontfile\s!unknown
924     \edef\somefontfile{\defaultfontfile}%
925   \fi
926   \font_helpers_update_font_parameters
927   \font_helpers_update_font_class_parameters
928   \clf_definefont_two
929      \ifempty\fontclass\s!false\else\s!true\fi
930      {#csname}%
931      \somefontfile
932      \d_font_scaled_font_size
933      \c_font_feature_inheritance_mode
934      \m_font_class_features
935      \m_font_features
936      \m_font_class_fallbacks
937      \m_font_fallbacks
938      \fontface
939      \d_font_scaled_text_face
940      \m_font_class_goodies
941      \m_font_goodies
942      \m_font_class_designsize
943      \m_font_designsize
944      \scaledfontmode
945   \relax
946   \ifcase\scaledfontsize
947    %\scaledfontsize\plusone
948     \lettonothing\somefontspec
949     \let\lastrawfontcall\relax
950     \mutable\letcsname#csname\endcsname\relax
951   \else
952     \edef\somefontspec{at \number\scaledfontsize sp}% we need the resolved designsize (for fallbacks) % \the\scaledfontsize
953     \expandafter\let\expandafter\lastrawfontcall\csname#csname\endcsname
954     \expand\everydefinefont
955   \fi
956   \c_font_feature_inheritance_mode\c_font_feature_inheritance_default}
957
958\mutable\lettonothing\somefontslant
959\mutable\lettonothing\somefontweight
960\mutable\lettonothing\somefontextend
961\mutable\lettonothing\somefontsqueeze
962
963\protected\def\font_helpers_low_level_define_compact#specification#csname%
964  {% we can now set more at the lua end
965   \glet\somefontname\defaultfontfile
966   \lettonothing\somefontsize
967   \lettonothing\somefontsizex
968   \lettonothing\somefontsizey
969   \clf_definefont_one{\detokenize\expandafter{\normalexpanded{#specification}}}% the escapestring catches at \somedimen
970   %
971   \ifcase\scaledfontmode\relax
972     \d_font_scaled_font_size\d_font_default_size
973   \or
974     % at
975     \d_font_scaled_font_size\somefontsize
976   \or
977     % sa
978     \d_font_scaled_font_size\textface
979     \d_font_scaled_font_size\currentfontbodysize\d_font_scaled_font_size % uses \somefontsize set by lua
980   \or
981     % mo
982     \d_font_scaled_font_size\font_basics_set_mapped_fontsize\textface
983     \d_font_scaled_font_size\currentfontbodysize\d_font_scaled_font_size
984   \or
985     % scaled, don't use this one as it's unpredictable (we fallback on scaled 1200 -> sa 1.2)
986     \d_font_scaled_font_size-\somefontsize\scaledpoint
987   \else % ht cp
988     \d_font_scaled_font_size\somefontsize
989   \fi
990   \relax
991   \d_font_scaled_font_size\v_font_size_relative\d_font_scaled_font_size
992   \relax
993   %
994   \ifconditional\c_font_auto_size
995     \font_helpers_check_body_scale\fontsize
996     \ifconditional\c_font_body_scale
997       \d_font_scaled_font_size\f_font_body_scale\d_font_scaled_font_size
998       \d_font_scaled_text_face\f_font_body_scale\dimexpr\textface\relax
999     \else
1000       \d_font_scaled_font_size\f_font_body_scale
1001       \d_font_scaled_text_face\textface
1002     \fi
1003   \else
1004     \d_font_scaled_text_face\textface
1005   \fi
1006   %
1007   \ifnum\c_font_scaled_font_mode_saved>\plusfour
1008     \c_font_scaled_font_mode_saved\scaledfontmode
1009     \scaledfontmode\zerocount
1010   \fi
1011   \c_font_future_glyph_scale\numexpr\plushundred*\d_font_scaled_font_size/\maxcard\relax
1012   %
1013   \edef\somefontspec{at \number\d_font_scaled_font_size sp}%
1014   % this has to happen at the tex end ...
1015   \edef\somefontfile{\truefontname\somefontname}%
1016   \ifx\somefontfile\s!unknown
1017     \edef\somefontfile{\defaultfontfile}%
1018   \fi
1019   \font_helpers_update_font_parameters
1020   \font_helpers_update_font_class_parameters
1021   % ... till here
1022  %\writestatus{fonts}{low level define: #csname/\somefontfile/\number\d_font_scaled_font_size/\fontface/\number\d_font_scaled_text_face}%
1023   \clf_definefont_two
1024      \ifempty\fontclass\s!false\else\s!true\fi
1025      {#csname}%
1026      \somefontfile
1027      \d_font_scaled_font_size
1028      \c_font_feature_inheritance_mode
1029      \m_font_class_features
1030      \m_font_features
1031      \m_font_class_fallbacks
1032      \m_font_fallbacks
1033      \zerocount
1034      \d_font_scaled_default
1035      \m_font_class_goodies
1036      \m_font_goodies
1037      \m_font_class_designsize
1038      \m_font_designsize
1039      \scaledfontmode
1040   \relax
1041   \ifcase\scaledfontsize
1042    %\scaledfontsize\plusone
1043     \lettonothing\somefontspec
1044     \let\lastrawfontcall\relax
1045     \mutable\letcsname#csname\endcsname\relax
1046   \else
1047     \edef\somefontspec{at \number\scaledfontsize sp}% we need the resolved designsize (for fallbacks) % \the\scaledfontsize
1048     %
1049     \glyphscale\c_font_future_glyph_scale
1050     \glyphxscale\ifempty\somefontsizex\plusthousand\else\somefontsizex\fi\relax
1051     \glyphyscale\ifempty\somefontsizey\plusthousand\else\somefontsizey\fi\relax
1052     %
1053     \expandafter\let\expandafter\lastrawfontcall\csname#csname\endcsname
1054     \ifrelax\lastrawfontcall
1055       \lettonothing\somefontspec
1056     \else
1057       \ifempty\somefontextend \else\glyphxscale\somefontextend \relax\fi
1058       \ifempty\somefontsqueeze\else\glyphyscale\somefontsqueeze\relax\fi
1059       \glyphslant \ifempty\somefontslant \zerocount\else\somefontslant \fi\relax
1060       \glyphweight\ifempty\somefontweight\zerocount\else\somefontweight\fi\relax
1061       \mutable\fontspecdef\lastrawfontcall
1062            \lastnamedcs
1063            all \glyphscale \glyphxscale \glyphyscale \glyphslant \glyphweight
1064       \relax
1065       \mutable\ifempty\fontclass\letcsname\else\gletcsname\fi#csname\endcsname\lastrawfontcall
1066       \expand\everydefinefont
1067     \fi
1068   \fi
1069   \c_font_feature_inheritance_mode\c_font_feature_inheritance_default}
1070
1071\appendtoks
1072    \enforced\let\font_helpers_low_level_define\font_helpers_low_level_define_compact
1073\to \everycompactfontmode
1074
1075\def\font_helpers_check_body_scale#fontsize%  gets character (x xx a etc)
1076  {\ifcsname\??fontenvironments\fontclass:\fontstyle\fontbody#fontsize\endcsname
1077     \lettolastnamedcs\f_font_body_scale
1078     \c_font_body_scale\conditionalfalse % !
1079   \orelse\ifcsname\??fontenvironments\fontclass:\fontstyle\s!default#fontsize\endcsname
1080     \lettolastnamedcs\f_font_body_scale
1081     \c_font_body_scale\conditionaltrue
1082   \orelse\ifcsname\??fontenvironments\fontclass\fontbody#fontsize\endcsname
1083     \lettolastnamedcs\f_font_body_scale
1084     \c_font_body_scale\conditionalfalse % !
1085   \orelse\ifcsname\??fontenvironments\fontclass\s!default#fontsize\endcsname
1086     \lettolastnamedcs\f_font_body_scale
1087     \c_font_body_scale\conditionaltrue
1088   % bonus:
1089   \orelse\ifcsname\??fontenvironments\fontclass\s!default\s!parent\endcsname
1090      \ifcsname\??fontenvironments\lastnamedcs#fontsize\endcsname
1091        \lettolastnamedcs\f_font_body_scale
1092      \else
1093        \let\f_font_body_scale\plusone
1094      \fi
1095      \c_font_body_scale\conditionaltrue
1096   %
1097   \orelse\ifcsname\??fontenvironments\fontbody:\fontstyle#fontsize\endcsname
1098     \lettolastnamedcs\f_font_body_scale
1099     \c_font_body_scale\conditionalfalse % !
1100   \orelse\ifcsname\??fontenvironments\fontbody#fontsize\endcsname
1101     \lettolastnamedcs\f_font_body_scale
1102     \c_font_body_scale\conditionalfalse % !
1103   \orelse\ifcsname\??fontenvironments\s!default#fontsize\endcsname
1104     \lettolastnamedcs\f_font_body_scale
1105     \c_font_body_scale\conditionaltrue
1106   \orelse\ifcsname\??fontenvironments\fontclass\s!default\s!text\endcsname
1107     \lettolastnamedcs\f_font_body_scale
1108     \c_font_body_scale\conditionaltrue
1109   \orelse\ifcsname\??fontenvironments\s!default\s!text\endcsname
1110     \lettolastnamedcs\f_font_body_scale
1111     \c_font_body_scale\conditionaltrue
1112   \else
1113     \let\f_font_body_scale\plusone
1114     \c_font_body_scale\conditionaltrue
1115   \fi}
1116
1117\newif\ifskipfontcharacteristics \skipfontcharacteristicstrue
1118
1119% \tracingfonts\plussix % <id: name @ size>
1120
1121%D When fontclasses are used, we define the font global, since namespaces are used.
1122%D Otherwise we parse the specs each time.
1123
1124\mutable\let\fontfile\s!unknown
1125
1126%D Relatively new:
1127
1128\installcorenamespace{fonts}
1129\installcorenamespace{fontslanguage}
1130
1131\installsetuponlycommandhandler \??fonts {fonts}
1132
1133\newconstant\c_fonts_auto_language
1134
1135\letcsname\??fontslanguage\v!auto\endcsname\plusone % experimental
1136%letcsname\??fontslanguage\v!yes \endcsname\plustwo % less efficient, for experiments
1137
1138\appendtoks
1139    \c_fonts_auto_language
1140      \ifcsname\??fontslanguage\fontsparameter\c!language\endcsname
1141        \lastnamedcs
1142      \else
1143        \zerocount
1144      \fi
1145\to \everysetupfonts
1146
1147\appendtoks
1148    \ifcase\c_fonts_auto_language
1149        % nothing
1150    \or
1151        \addfflanguage
1152  % \or
1153        % font
1154    \fi
1155\to \everylanguage
1156
1157% \setupfonts
1158%   [\c!language=\v!auto]
1159
1160%D \macros
1161%D  {everyfont,everyfontswitch}
1162
1163\ifdefined\everyfont       \else \newtoks\everyfont       \fi
1164\ifdefined\everyfontswitch \else \newtoks\everyfontswitch \fi
1165
1166\permanent\def\setfontcharacteristics{\expand\everyfont}
1167
1168% \appendtoks
1169%     \ifcase\c_fonts_auto_language
1170%         % nothing
1171%     \or
1172%         % auto
1173%     \or
1174%         \addfflanguage
1175%     \fi
1176% \to \everyfont
1177
1178%D \macros
1179%D   {definefont}
1180%D
1181%D We also accept \type{sa a}||\type{sa d} as specification.
1182%D
1183%D Before we implement the main definition macro, we first show one for local use:
1184%D
1185%D \starttyping
1186%D \definefont[Some][LucidaBright at 100pt]    \Some some
1187%D \definefont[Nice][LucidaBright mo 2]        \Nice nice
1188%D \definefont[Text][LucidaBright sa 5.4]      \Text last
1189%D \stoptyping
1190%D
1191%D The implementation looks as follows:
1192
1193\permanent\tolerant\protected\def\definefont[#1]#*[#2]#*[#3]%  [name][spec][1.6 | line=10pt | setup_id]
1194  {\ifparameter#3\or
1195     \expandafter\font_basics_define_font_a
1196   \else
1197     \expandafter\font_basics_define_font_b
1198   \fi[#1][#2][#3]}
1199
1200\def\font_basics_define_font_a[#name][#specification][#settings]% [name][spec][1.6 | line=10pt | setup_id]
1201  {\ifsetups{#settings}%
1202     \mutable\protected\defcsname#name\endcsname{\font_basics_define_font_with_setups    {#name}{#specification}{#settings}}%
1203   \else
1204     \mutable\protected\defcsname#name\endcsname{\font_basics_define_font_with_parameters{#name}{#specification}{#settings}}%
1205   \fi}
1206
1207\def\font_basics_define_font_b[#name][#specification][#dummy]%
1208  {\mutable\protected\defcsname#name\endcsname{\font_basics_define_font_without_parameters{#name}{#specification}}}
1209
1210\def\font_basics_define_font_with_parameters#name#specification#settings%
1211  {\font_basics_define_font_without_parameters{#name}{#specification}%
1212   \setuplocalinterlinespace[#settings]%
1213   \setupspacing\relax} % is this really needed ?
1214
1215\def\font_basics_define_font_with_setups#name#specification#settings%
1216  {\font_basics_define_font_without_parameters{#name}{#specification}%
1217   \directsetup{#settings}}
1218
1219%D Beware, in the frozen variants no settings are supported yet, but that might happen
1220%D some day.
1221
1222\permanent\tolerant\protected\def\definefrozenfont[#name]#spacer[#specification]#spacer[#settings]%
1223  {\ifparameter#name\or
1224     \begingroup
1225       \definefont[#name][#specification][#settings]%
1226       \csname#name\endcsname
1227       \glet\lastglobalrawfontcall\lastrawfontcall
1228     \endgroup
1229     \aliased\letcsname#name\endcsname\lastglobalrawfontcall
1230   \fi}
1231
1232%D The instance namespace protection makes the switch local so that we can redefine a
1233%D logical name and/or change the size in between.
1234
1235% todo: now mathsize twice in name (so it can go here)
1236% todo: check when mathsize is needed
1237
1238\ifdefined\??fontinstanceready \else \installcorenamespace{fontinstanceready} \fi
1239\ifdefined\??fontinstancebasic \else \installcorenamespace{fontinstancebasic} \fi
1240\ifdefined\??fontinstanceclass \else \installcorenamespace{fontinstanceclass} \fi
1241
1242\newconditional\c_font_auto_size \c_font_auto_size\conditionaltrue
1243
1244\mutable\lettonothing\lastfontidentifier
1245
1246\def\v_font_identifier_basic{\??fontinstancebasic           \lastfontidentifier-\fontsize-\fontface}
1247\def\v_font_identifier_class{\??fontinstanceclass\fontclass-\lastfontidentifier-\fontsize-\fontface}
1248
1249\let\v_font_identifier_basic_saved\v_font_identifier_basic
1250\let\v_font_identifier_class_saved\v_font_identifier_class
1251
1252\appendtoks
1253    \def\v_font_identifier_basic{\??fontinstancebasic           \lastfontidentifier-\fontsize}%
1254    \def\v_font_identifier_class{\??fontinstanceclass\fontclass-\lastfontidentifier-\fontsize}%
1255    %
1256    \let\v_font_identifier_basic_saved\v_font_identifier_basic
1257    \let\v_font_identifier_class_saved\v_font_identifier_class
1258\to \everycompactfontmode
1259
1260\def\font_basics_define_font_without_parameters#identifier#2%
1261  {\relax % intercept lookahead, in case we scan for a number
1262   \c_font_feature_inheritance_mode\c_font_feature_inheritance_fontonly
1263   \cdef\lastfontidentifier{#identifier}%
1264   \let\v_font_size_relative\v_font_rscale_default
1265   \let\v_font_size_absolute\fontbody
1266   \font_helpers_low_level_define{#2}\v_font_identifier_basic
1267   \csname\v_font_identifier_basic\endcsname
1268   \c_font_auto_size\conditionalfalse
1269   \expand\everyfont % \setfontcharacteristics
1270   \expand\everyfontswitch
1271   \let\v_font_identifier_basic\v_font_identifier_basic_saved}
1272
1273\protected\def\font_helpers_trigger#identifier% make a traced variant
1274  {\cdef\lastfontidentifier{#identifier}%
1275   \ifcsname\v_font_identifier_class\endcsname
1276     % \writestatus{fonts}{trigger: reusing \v_font_identifier_class}%
1277     \expandafter\font_helpers_trigger_reuse
1278   \else
1279     % \writestatus{fonts}{trigger: defining \v_font_identifier_class}%
1280     \expandafter\font_helpers_trigger_define
1281   \fi}
1282
1283\def\font_helpers_trigger_define#relative#absolute#specification%
1284  {\def\v_font_size_relative{#relative}%
1285   \def\v_font_size_absolute{#absolute}%
1286   \font_helpers_low_level_define{#specification}\v_font_identifier_class
1287   \csname\v_font_identifier_class\endcsname
1288   \c_font_auto_size\conditionalfalse
1289   \ifskipfontcharacteristics \else
1290     \expand\everyfont % \setfontcharacteristics
1291     \expand\everyfontswitch
1292   \fi
1293   \let\v_font_identifier_class\v_font_identifier_class_saved}
1294
1295\def\font_helpers_trigger_reuse#relative#absolute#specification%
1296  {\csname\v_font_identifier_class\endcsname
1297   \c_font_auto_size\conditionalfalse
1298   \ifskipfontcharacteristics \else
1299     \expand\everyfont % \setfontcharacteristics
1300     \expand\everyfontswitch
1301   \fi
1302   \let\v_font_identifier_class\v_font_identifier_class_saved}
1303
1304%D \macros
1305%D   {currentfontbodyscale}
1306%D
1307%D Sometimes we need to have access to the font scale including the \type {a}||\type
1308%D {d} sizes. The next macro returns the current scaling factor. Take a look at
1309%D \type {cont-log.tex} for an example of its use.
1310
1311\installcorenamespace{fontenvironments}
1312
1313\permanent\def\currentfontbodysize % gets number (the normal sa 1 etc)
1314  {\ifcsname\??fontenvironments\fontclass:\fontstyle\s!default\somefontsize\endcsname
1315     \lastnamedcs
1316   \orelse\ifcsname\??fontenvironments\fontclass\s!default\somefontsize\endcsname
1317     \lastnamedcs
1318   \orelse\ifcsname\??fontenvironments\fontclass\s!default\s!parent\endcsname
1319     \ifcsname\??fontenvironments\lastnamedcs\somefontsize\endcsname
1320       \lastnamedcs
1321     \else
1322       \somefontsize
1323     \fi
1324   \orelse\ifcsname\??fontenvironments\s!default\somefontsize\endcsname
1325     \lastnamedcs
1326   \else
1327     \somefontsize
1328   \fi}
1329
1330\permanent\def\currentfontbodyscale % gets character (x xx a etc)
1331  {\csname
1332     \ifcsname\??fontenvironments\fontclass:\fontstyle\s!default\fontsize\endcsname\csnamestring\orelse
1333     \ifcsname\??fontenvironments\fontclass           \s!default\fontsize\endcsname\csnamestring\orelse
1334     \ifcsname\??fontenvironments                     \s!default\fontsize\endcsname\csnamestring\orelse
1335     \ifcsname\??fontenvironments\fontclass:\fontstyle\s!default\s!text  \endcsname\csnamestring\orelse
1336     \ifcsname\??fontenvironments\fontclass           \s!default\s!text  \endcsname\csnamestring\orelse
1337     \ifcsname\??fontenvironments                     \s!default\s!text  \endcsname\csnamestring\else
1338              \??fontenvironments                     \s!default                                \fi
1339   \endcsname}
1340
1341\permanent\def\currentfontscale % used in default definition
1342  {\csname
1343     \ifcsname\??fontenvironments\fontclass:\fontstyle\s!default\wildcardfontsize\endcsname\csnamestring\orelse
1344     \ifcsname\??fontenvironments\fontclass           \s!default\wildcardfontsize\endcsname\csnamestring\orelse
1345     \ifcsname\??fontenvironments                     \s!default\wildcardfontsize\endcsname\csnamestring\orelse
1346     \ifcsname\??fontenvironments\fontclass:\fontstyle\s!default\s!text          \endcsname\csnamestring\orelse
1347     \ifcsname\??fontenvironments\fontclass           \s!default\s!text          \endcsname\csnamestring\orelse
1348     \ifcsname\??fontenvironments                     \s!default\s!text          \endcsname\csnamestring\else
1349              \??fontenvironments                     \s!default                                        \fi
1350   \endcsname}
1351
1352\def\font_currentfontscale % used in default definition
1353  {\ifcsname\??fontenvironments\fontclass:\fontstyle\s!default\wildcardfontsize\endcsname\lastnamedcs\orelse
1354   \ifcsname\??fontenvironments\fontclass           \s!default\wildcardfontsize\endcsname\lastnamedcs\orelse
1355   \ifcsname\??fontenvironments                     \s!default\wildcardfontsize\endcsname\lastnamedcs\orelse
1356   \ifcsname\??fontenvironments\fontclass:\fontstyle\s!default\s!text          \endcsname\lastnamedcs\orelse
1357   \ifcsname\??fontenvironments\fontclass           \s!default\s!text          \endcsname\lastnamedcs\orelse
1358   \ifcsname\??fontenvironments                     \s!default\s!text          \endcsname\lastnamedcs\else
1359     \csname\??fontenvironments                     \s!default                 \endcsname            \fi}
1360
1361\defcsname\??fontenvironments\s!default\endcsname{1}
1362
1363%D Now we enter the area of font switching. The switching mechanism has to take care
1364%D of several situations, like:
1365%D
1366%D \startitemize[packed]
1367%D \item changing the overal document fonts (including margins, headers and footers)
1368%D \item changing local fonts (only the running text)
1369%D \item smaller and even more smaller alternatives (super- and subscripts)
1370%D \stopitemize
1371%D
1372%D \TEX\ offers a powerful family mechanism for super- and subscripts in math mode.
1373%D In text mode however, we don't use families for the smaller alternatives, and
1374%D therefore have to take care of it otherwise.
1375%D
1376%D \macros
1377%D   {definebodyfontenvironment,setupbodyfontenvironment}
1378%D
1379%D The relationship between the several sizes of a font, is
1380%D defined by:
1381%D
1382%D \showsetup{definebodyfontenvironment}
1383%D
1384%D Later on we will see how these parameters are used, so for the moment we stick
1385%D with an example:
1386%D
1387%D \starttyping
1388%D \definebodyfontenvironment
1389%D   [12pt]
1390%D   [        text=12pt,
1391%D          script=9pt,
1392%D    scriptscript=7pt,
1393%D               x=10pt,
1394%D              xx=8pt,
1395%D             big=12pt,
1396%D           small=10pt]
1397%D \stoptyping
1398%D
1399%D The first argument specifies the bodyfont size to which the settings apply. All
1400%D second parameters are specified in dimensions and tell us more about related
1401%D sizes.
1402%D
1403%D Afterwards, one can change values with
1404%D
1405%D \showsetup{setupbodyfontenvironment}
1406%D
1407%D When instead of a size the keyword \type{unknown} is
1408%D passed, fractions (relations) are used instead of fixed
1409%D sizes.
1410
1411%D {\bf Remark:} We need to cover the following cases, otherwise users can get
1412%D confused:
1413%D
1414%D \starttyping
1415%D \setupbodyfont[23pt]
1416%D
1417%D \definebodyfontenvironment[23pt]
1418%D \setupbodyfont[23pt]
1419%D
1420%D \definebodyfontenvironment[23pt]
1421%D \definebodyfont[23pt][rm,ss,tt][default]
1422%D \setupbodyfont[23pt]
1423%D \stoptyping
1424%D
1425%D Beware: while some font defs can be global, the bodyfont environment checks
1426%D local. This means that multiple local checks resulting in definitions are not
1427%D that efficient. So, apart from an occasional switch, one should define an
1428%D environment at the outer level.
1429
1430% \definebodyfontenvironment[33pt]
1431% \definebodyfontenvironment[dejavu][default][1=.5]
1432% \definebodyfontenvironment[dejavu][default][x=1.2]
1433% \definebodyfontenvironment[dejavu][default][a=5]
1434% \definebodyfontenvironment[dejavu][33pt][x=100pt]
1435
1436% the lookup order is:
1437%
1438% [class] [dimension] [parameters]
1439% [class] [default]   [parameters] % factors
1440%         [dimension] [parameters]
1441%         [default]   [parameters] % factors
1442%
1443% with defaults providing factors
1444
1445% todo: class:size
1446% todo: make assignments global
1447
1448% \setupbodyfontenvironment [all]     [12pt] [x=4pt,small=4pt]
1449% \setupbodyfontenvironment [pagella] [12pt] [x=4pt,small=4pt]
1450%
1451% \setupbodyfont[pagella,12pt]
1452%
1453% \starttext normal {\tx tx} {\small small} \stoptext
1454
1455\letcsname\??fontenvironments\endcsname\empty % so we default to empty
1456
1457\permanent\def\bodyfontvariable#parameter%
1458  {\begincsname
1459     \ifcsname\??fontenvironments\fontclass:\fontstyle\normalizedbodyfontsize#parameter\endcsname\csnamestring\orelse
1460     \ifcsname\??fontenvironments\fontclass           \normalizedbodyfontsize#parameter\endcsname\csnamestring\orelse
1461     \ifcsname\??fontenvironments\fontclass:\fontstyle                       #parameter\endcsname\csnamestring\orelse
1462     \ifcsname\??fontenvironments\fontclass                                  #parameter\endcsname\csnamestring\orelse
1463     \ifcsname\??fontenvironments\fontclass \s!default                        \s!parent\endcsname\csnamestring\orelse
1464     \ifcsname\??fontenvironments                     \normalizedbodyfontsize#parameter\endcsname\csnamestring\orelse
1465     \ifcsname\??fontenvironments           \s!default                       #parameter\endcsname\csnamestring\else
1466              \??fontenvironments                                                                             \fi
1467   \endcsname}
1468
1469\permanent\def\bodyfontsizevariable#size#parameter% used in s-fonts-show
1470  {\begincsname
1471     \ifcsname\??fontenvironments\fontclass:\fontstyle#size#parameter\endcsname\csnamestring\orelse
1472     \ifcsname\??fontenvironments\fontclass           #size#parameter\endcsname\csnamestring\orelse
1473     \ifcsname\??fontenvironments\fontclass:\fontstyle     #parameter\endcsname\csnamestring\orelse
1474     \ifcsname\??fontenvironments\fontclass                #parameter\endcsname\csnamestring\orelse
1475     \ifcsname\??fontenvironments\fontclass \s!default      \s!parent\endcsname\csnamestring\orelse
1476     \ifcsname\??fontenvironments                     #size#parameter\endcsname\csnamestring\orelse
1477     \ifcsname\??fontenvironments           \s!default     #parameter\endcsname\csnamestring\else
1478              \??fontenvironments                                                           \fi
1479   \endcsname}
1480
1481%
1482
1483\def\font_bodyfontvariable#parameter%
1484         {\ifcsname\??fontenvironments\fontclass:\fontstyle\normalizedbodyfontsize#parameter\endcsname\lastnamedcs
1485   \orelse\ifcsname\??fontenvironments\fontclass           \normalizedbodyfontsize#parameter\endcsname\lastnamedcs
1486   \orelse\ifcsname\??fontenvironments\fontclass:\fontstyle                       #parameter\endcsname\lastnamedcs
1487   \orelse\ifcsname\??fontenvironments\fontclass                                  #parameter\endcsname\lastnamedcs
1488   \orelse\ifcsname\??fontenvironments\fontclass\s!default                         \s!parent\endcsname\begincsname\??fontenvironments\lastnamedcs#parameter\endcsname
1489   \orelse\ifcsname\??fontenvironments                     \normalizedbodyfontsize#parameter\endcsname\lastnamedcs
1490   \orelse\ifcsname\??fontenvironments          \s!default                        #parameter\endcsname\lastnamedcs\fi}
1491
1492\def\font_bodyfontsizevariable#size#parameter%
1493         {\ifcsname\??fontenvironments\fontclass:\fontstyle    #size#parameter\endcsname\lastnamedcs
1494   \orelse\ifcsname\??fontenvironments\fontclass               #size#parameter\endcsname\lastnamedcs
1495   \orelse\ifcsname\??fontenvironments\fontclass:\fontstyle         #parameter\endcsname\lastnamedcs
1496   \orelse\ifcsname\??fontenvironments\fontclass                    #parameter\endcsname\lastnamedcs
1497   \orelse\ifcsname\??fontenvironments\fontclass\s!default           \s!parent\endcsname\begincsname\??fontenvironments\lastnamedcs#parameter\endcsname
1498   \orelse\ifcsname\??fontenvironments                         #size#parameter\endcsname\lastnamedcs
1499   \orelse\ifcsname\??fontenvironments\s!default                    #parameter\endcsname\lastnamedcs\fi}
1500
1501\permanent\def\currentbodyfontdimension#parameter% there can be factors here
1502  {\todimension{%
1503            \ifcsname\??fontenvironments\fontclass:\fontstyle\normalizedbodyfontsize#parameter\endcsname
1504     \orelse\ifcsname\??fontenvironments\fontclass:\fontstyle\s!default #parameter\endcsname
1505     \orelse\ifcsname\??fontenvironments\fontclass\normalizedbodyfontsize#parameter\endcsname
1506     \orelse\ifcsname\??fontenvironments\fontclass\s!default#parameter\endcsname
1507     % bonus:
1508     \orelse\ifcsname\??fontenvironments\fontclass\s!default\s!parent\endcsname
1509            \ifcsname\??fontenvironments\lastnamedcs#parameter\endcsname\fi
1510     %
1511     \orelse\ifcsname\??fontenvironments\normalizedbodyfontsize#parameter\endcsname
1512     \orelse\ifcsname\??fontenvironments\s!default#parameter\endcsname
1513     \fi
1514     \lastnamedcs
1515     \ifchkdim\lastnamedcs\or\else
1516       \dimexpr\normalizedbodyfontsize\relax % we need a cheaper one
1517     \fi}}
1518
1519\permanent\def\bodyfontdimension#class#size#parameter#body%
1520  {\todimension{%
1521            \ifcsname\??fontenvironments#class:\fontstyle#size#parameter\endcsname
1522     \orelse\ifcsname\??fontenvironments#class:\fontstyle\s!default#parameter\endcsname
1523     \orelse\ifcsname\??fontenvironments#class#size#parameter\endcsname
1524     \orelse\ifcsname\??fontenvironments#class\s!default#parameter\endcsname
1525     % bonus:
1526     \orelse\ifcsname\??fontenvironments#class\s!default\s!parent\endcsname
1527            \ifcsname\??fontenvironments\lastnamedcs#parameter\endcsname\fi
1528     %
1529     \orelse\ifcsname\??fontenvironments#size#parameter\endcsname
1530     \orelse\ifcsname\??fontenvironments\s!default#parameter\endcsname
1531     \fi
1532     \lastnamedcs
1533     \ifchkdim\lastnamedcs\or\else
1534       \dimexpr#body\relax % we need a cheaper one
1535     \fi}}
1536
1537%D In the following macros we use \type {\currentxfontsize} to hold the current
1538%D x||size of the font. This enables us to support for instance \type {\sl} inside a
1539%D \type {\tx} switch.
1540
1541\newconstant\currentxfontsize
1542
1543\permanent\def\wildcardfontsize {\ifcase\currentxfontsize\fontsize\or\s!x\else\s!xx\fi}
1544\permanent\def\wildcardfontscale{\normalexpanded{\noexpand\bodyfontvariable{\ifcase\currentxfontsize\fontsize\or\s!x\else\s!xx\fi}}}
1545
1546\permanent\def\bodyfontinterlinespace{\bodyfontvariable     \c!interlinespace} % used elsewhere
1547%permanent\def\bodyfontinterlinespace{\font_bodyfontvariable\c!interlinespace} % used elsewhere
1548
1549\installcorenamespace{fontenvironmentknown}
1550
1551\def\font_helpers_register_environment#class#body%
1552  {\letcsname\??fontenvironmentknown#class#body\endcsname\empty}
1553
1554\newmacro\m_font_body
1555\newmacro\m_font_body_normalized
1556
1557\permanent\tolerant\protected\def\definebodyfontenvironment[#1]#*[#2]#*[#3]#*[#4]%
1558  {\ifarguments
1559     \expandafter\font_basics_define_body_font_environment_unset
1560   \or
1561     \expandafter\font_basics_define_body_font_environment_unset
1562   \or
1563     \expandafter\font_basics_define_body_font_environment_empty
1564   \or
1565     \expandafter\font_basics_define_body_font_environment_class
1566   \or
1567     \expandafter\font_basics_define_body_font_environment_detail
1568   \fi[#1][#2][#3][#4]}
1569
1570\aliased\let\setupbodyfontenvironment\definebodyfontenvironment
1571
1572%D First we handle the class specific case. Beware: you can change values before
1573%D a bodyfont is loaded but changing them afterwards can be sort of tricky as
1574%D values are not consulted afterwards.
1575
1576\permanent\def\processbodyfontenvironmentlist#1% no \protected as then we cannot use it in alignments (still?)
1577  {\clf_processbodyfontsizes{\strippedcsname#1}}
1578
1579\permanent\def\bodyfontenvironmentlist
1580  {\clf_getbodyfontsizes}
1581
1582\def\font_basics_define_body_font_environment_detail[#class][#style][#body][#settings]%
1583  {\font_basics_define_body_font_environment_class[#class:#style][#body][#settings][]}
1584
1585\def\font_basics_define_body_font_environment_class[#class][#body][#settings][#dummy]%
1586  {\edef\m_font_body{#body}%
1587   \ifchkdim\m_font_body\or
1588     \normalizebodyfontsize\m_font_body_normalized\m_font_body
1589     \font_basics_define_body_font_environment_size[#class][\m_font_body_normalized][#settings]%
1590     \clf_registerbodyfontsize{\m_font_body_normalized}%
1591   \orelse\ifhastok={#settings}%
1592     \getparameters[\??fontenvironments#class#body][#settings]% old fashioned setter
1593   \else
1594     \setvalue{\??fontenvironments#class#body\s!parent}{#settings}% old fashioned setter
1595    %\getparameters[\??fontenvironments#class#body][\s!parent=#settings]% old fashioned setter
1596   \fi}
1597
1598%D The empty case uses the same code but needs to ignore the current class settings
1599%D (just to be sure, as it's not really needed).
1600
1601\def\font_basics_define_body_font_environment_empty[#body][#settings][#dummya][#dummyb]%
1602  {\push_macro_fontclass
1603   \lettonothing\fontclass
1604   \font_basics_define_body_font_environment_class[][#body][#settings][#dummya]%
1605   \pop_macro_fontclass}
1606
1607\def\font_basics_define_body_font_environment_unset[#body][#dummya][#dummyb][#dummyc]%
1608  {\push_macro_fontclass
1609   \lettonothing\fontclass
1610   \font_basics_define_body_font_environment_class[][#body][][]%
1611   \pop_macro_fontclass}
1612
1613%D We don't check too soon as we can refer to later definitions.
1614
1615\newconditional\c_font_defining_environment_state % controls messages
1616
1617\def\font_basics_define_body_font_environment_size[#class][#normalizedbody][#settings]% normalized body
1618  {\getparameters[\??fontenvironments#class#normalizedbody][#settings]%
1619   \ifcsname\??fontenvironmentknown#class#normalizedbody\endcsname
1620     % environment and size already defined
1621   \orelse\ifproductionrun
1622     \push_macro_fontclass
1623     \cdef\fontclass{#class}%
1624     \font_helpers_register_environment{#class}{#normalizedbody}%
1625     \c_font_defining_environment_state\conditionaltrue
1626     \font_helpers_define_unknown_font{#normalizedbody}% current class
1627     \c_font_defining_environment_state\conditionalfalse
1628     \pop_macro_fontclass
1629   \fi
1630   \font_helpers_register_fontbody{#normalizedbody}}
1631
1632%D Checking
1633
1634\def\font_helpers_check_bodyfont_environment#normalizedbody#body%
1635  {\ifcsname\??fontenvironmentknown\fontclass#normalizedbody\endcsname
1636     % already defined
1637   \else
1638     \font_helpers_check_bodyfont_environment_indeed{#normalizedbody}{#body}%
1639   \fi}
1640
1641\def\font_helpers_check_bodyfont_environment_indeed#normalizedbody#body%
1642  {\font_helpers_register_environment\fontclass{#normalizedbody}%
1643   \ifcsname\??fontbodyknown#normalizedbody\endcsname
1644   \else
1645     \font_helpers_define_unknown_font{#normalizedbody}%
1646   \fi}
1647
1648%D We default all parameters to the main bodyfont size, so the next setup is valid
1649%D too:
1650%D
1651%D \starttyping
1652%D \definebodyfontenvironment[24pt]
1653%D \stoptyping
1654%D
1655%D All parameters can be redefined when needed, so one doesnot have to stick to the
1656%D default ones.
1657
1658%D \macros
1659%D   {definebodyfont}
1660%D
1661%D The next step in defining a bodyfont involves the actual font files, which can be
1662%D recognized by their extension \type {tfm}. Installing those file is often beyond
1663%D the scope of the user and up to the system administrator.
1664%D
1665%D \showsetup{definebodyfont}
1666%D
1667%D This commands takes three arguments: a (series of) bodyfont size(s), the style
1668%D group to which the definitions belong, and an alternative, as specified by the
1669%D \TEX\ (math) families, extended with~a, b~\unknown.
1670%D
1671%D We show two examples, that show all the alternative scaling options. The \type
1672%D {\tfa} alternatives can be extended with \type {\bfa}, \type {\slb}, etc. or even
1673%D \type {e} and higher alternatives. The magic scaled values are derived from plain
1674%D \TEX's \type {\magstep}:
1675%D
1676%D \starttyping
1677%D \definebodyfont [12pt] [rm]
1678%D   [tf=cmr12,
1679%D    bf=cmbx12,
1680%D    it=cmti12,
1681%D    sl=cmsl12,
1682%D    bi=cmbxti10 at 12pt,
1683%D    bs=cmbxsl10 at 12pt,
1684%D   tfa=cmr12    sa a, % scaled 1.200 dropped from lmtx
1685%D   tfb=cmr12    sa b, % scaled 1.440 dropped from lmtx
1686%D   tfc=cmr12    sa c, % scaled 1.728 dropped from lmtx
1687%D   tfd=cmr12    sa d, % scaled 2.074 dropped from lmtx
1688%D    sc=cmcsc10  at 12pt]
1689%D
1690%D \definebodyfont [12pt,11pt,10pt,9pt,8pt] [rm]
1691%D   [tf=lbr  sa 1,
1692%D    bf=lbd  sa 1,
1693%D    it=lbi  sa 1,
1694%D    sl=lbsl sa 1,
1695%D    bi=lbdi sa 1,
1696%D    bs=lbdi sa 1,
1697%D   tfa=lbr  sa a, % scaled 1.200 dropped from lmtx
1698%D   tfb=lbr  sa b, % scaled 1.440 dropped from lmtx
1699%D   tfc=lbr  sa c, % scaled 1.728 dropped from lmtx
1700%D   tfd=lbr  sa d, % scaled 2.074 dropped from lmtx
1701%D    sc=lbr  sa x] % scaled 0.833 dropped from lmtx
1702%D \stoptyping
1703%D
1704%D The second example shows that we can define more sizes at once. The main
1705%D difference between these examples is that the Computer Modern Roman come in many
1706%D design sizes. This means that there we cannot define them in bulk using \type
1707%D {sa}. Instead of \type {rm} (roman) one can define \type {ss} (sans serif), \type
1708%D {tt} (teletype), \type {hw} (hand written), \type {cg} (calygraphic) and whatever
1709%D styles.
1710%D
1711%D The first argument may be a comma separated list. This, combined with
1712%D specifications using \type{sa} can save a lot of typing. Although all arguments
1713%D should be specified, we treat the second argument as optional.
1714%D
1715%D Defining a bodyfont involves two actions: defining the specific style related
1716%D alternatives, like \type {\rma}, \type {\bfa} and \type {\rmsla}, and storing the
1717%D definitions of their bodyfont size related fonts. The first step is bodyfont
1718%D independant but executed every time. This permits user definitions like \type
1719%D {\tfw} or \type {\bfq} for real large alternatives.
1720%D
1721%D If we move design size info to the lfg file (after all only lm has design sizes)
1722%D we can get rid of much code .. 2012 or so.
1723
1724\installcorenamespace{fontdefinitions}
1725
1726% [class] [name]      [rm,ss] [settings]
1727% [class] [10pt,11pt] [rm,ss] [settings]
1728% [class] [10pt,11pt] [rm,ss] [name]
1729
1730% [class] [name]              [settings]   == [name]      [rm] [settings]
1731% [class] [10pt,11pt]         [settings]   == [name]      [rm] [settings]
1732% [class] [10pt,11pt]         [name]       == [10pt,11pt] [rm] [name]
1733
1734\permanent\tolerant\protected\def\definebodyfont[#1]#*[#2]#*[#3]#*[#4]%
1735  {\ifarguments
1736   \or
1737     \font_basics_define_body_font[#1][\s!rm][]%
1738   \or
1739     \font_basics_define_body_font[#1][\s!rm][#2]%
1740   \or
1741     \font_basics_define_body_font[#1][#2][#3]%
1742   \or
1743     \processcommacommand[#1]{\font_basics_define_body_font_class_given[#2][#3][#4]}%
1744   \fi}
1745
1746\protected\def\font_basics_define_body_font[#whatever]%
1747  {\doifelsenumber{#whatever}\font_basics_define_body_font_body\font_basics_define_body_font_name[#whatever]}
1748
1749% \protected\def\font_basics_define_body_font[#whatever]%
1750%   {\ifchknum#whatever\or
1751%      \expandafter\font_basics_define_body_font_body
1752%    \else
1753%      \expandafter\font_basics_define_body_font_name
1754%    \fi[#whatever]}
1755
1756\protected\def\font_basics_define_body_font_class_given[#1][#2][#3]#4%
1757  {\push_macro_fontclass
1758   \ifcstok{#4}\s!default
1759     \lettonothing\fontclass
1760   \else
1761     \cdef\fontclass{#4}%
1762   \fi
1763   \definebodyfont[#1][#2][#3]%
1764   \pop_macro_fontclass}
1765
1766\protected\def\font_basics_define_body_font_body[#body][#style][#specification]%
1767  {\ifhastok={#specification}%
1768     \expandafter\font_basics_define_body_font_body_assignment
1769   \else
1770     \expandafter\font_basics_define_body_font_body_identifier
1771   \fi
1772   [#body][#style][#specification]}%
1773
1774\protected\def\font_basics_define_body_font_name[#name][#style][#specification]%
1775  {\ifhastok={#specification}%
1776     \expandafter\font_basics_define_body_font_name_assignment
1777   \else
1778     \expandafter\font_basics_define_body_font_name_identifier
1779   \fi
1780   [#name][#style][#specification]}%
1781
1782\protected\def\font_basics_define_body_font_body_assignment[#bodylist][#stylelist][#assignments]%
1783  {\processcommalist[#bodylist]{\font_basics_define_body_font_body_assignment_a{#stylelist}{#assignments}}}
1784
1785\protected\def\font_basics_define_body_font_body_assignment_a#stylelist#assignments#body%
1786  {\normalizebodyfontsize\m_font_asked_body{#body}%
1787   % normally we define quite a lot in advance, i.e global defs
1788   \font_helpers_check_bodyfont_environment\m_font_asked_body\m_font_asked_body % !!
1789   \processcommalist[#stylelist]{\font_basics_define_body_font_body_assignment_b{#assignments}}}
1790
1791\protected\def\font_basics_define_body_font_body_assignment_b#assignments#style%
1792  {\edef\m_font_asked_style{#style}%
1793   \processcommalist[#assignments]\font_basics_define_body_font_defs}
1794
1795\protected\def\font_basics_define_body_font_defs
1796  {\ifempty\fontclass
1797     \expandafter\font_basics_define_body_font_defs_nop
1798   \else
1799     \expandafter\font_basics_define_body_font_defs_yes
1800   \fi}
1801
1802\protected\def\font_basics_define_body_font_defs_yes_normal#assignment%
1803  {\ifx\m_font_asked_style\s!mm
1804     \expandafter\font_basics_define_body_font_yes_mm
1805   \else
1806     \expandafter\font_basics_define_body_font_yes_xx
1807   \fi[#assignment]}
1808
1809\protected\def\font_basics_define_body_font_defs_nop_normal#assignment%
1810  {\ifx\m_font_asked_style\s!mm
1811     \expandafter\font_basics_define_body_font_nop_mm
1812   \else
1813     \expandafter\font_basics_define_body_font_nop_xx
1814   \fi[#assignment]}
1815
1816\protected\def\font_basics_define_body_font_defs_yes_traced#assignment%
1817  {\writestatus\m!fonts{[\fontclass] [\m_font_asked_body] [\m_font_asked_style] [#assignment]}%
1818   \ifx\m_font_asked_style\s!mm
1819     \expandafter\font_basics_define_body_font_yes_mm
1820   \else
1821     \expandafter\font_basics_define_body_font_yes_xx
1822   \fi[#assignment]}
1823
1824\protected\def\font_basics_define_body_font_defs_nop_traced#assignment%
1825  {\writestatus\m!fonts{[\fontclass] [\m_font_asked_body] [\m_font_asked_style] [#assignment]}%
1826   \ifx\m_font_asked_style\s!mm
1827     \expandafter\font_basics_define_body_font_nop_mm
1828   \else
1829     \expandafter\font_basics_define_body_font_nop_xx
1830   \fi[#assignment]}
1831
1832\let\font_basics_define_body_font_defs_yes\font_basics_define_body_font_defs_yes_normal
1833\let\font_basics_define_body_font_defs_nop\font_basics_define_body_font_defs_nop_normal
1834
1835\appendtoks
1836    \let\font_basics_define_body_font_defs_yes\font_basics_define_body_font_defs_yes_traced
1837    \let\font_basics_define_body_font_defs_nop\font_basics_define_body_font_defs_nop_traced
1838\to \t_font_tracers_definitions
1839
1840%D We split into two characters (first part of spec) and the rest: the first two are
1841%D the style and the rest is a size, although in practice one will seldom define the
1842%D size directly. We might even drop that as it gives faster code.
1843
1844\protected\def\font_basics_define_body_font_nop_xx[#one#two#rest=#value]% local
1845  {\ifcsname\m_font_asked_style#one#two#rest\endcsname\else\font_basics_check_fontname_combination\m_font_asked_style{#one#two}{#rest}\fi
1846   \letcsname\??fontinstanceclass\m_font_asked_body-\m_font_asked_style-#one#two-#rest-0\endcsname\undefined
1847   \protected\edefcsname\??fontinstanceready\m_font_asked_body-\m_font_asked_style-#one#two-#rest-0\endcsname
1848     {\font_helpers_trigger{\m_font_asked_body-\m_font_asked_style-#one#two#rest}{\noexpand\font_rscale_xx{\m_font_asked_style}}{\m_font_asked_body}{\normalunexpanded{#value}}}%
1849   \letcsname\??fontinstanceclass\m_font_asked_body-\m_font_asked_style-#one#two-#rest-4\endcsname\undefined
1850   \protected\edefcsname\??fontinstanceready\m_font_asked_body-\m_font_asked_style-#one#two-#rest-4\endcsname
1851     {\font_helpers_trigger{\m_font_asked_body-\m_font_asked_style-#one#two#rest}{\noexpand\font_rscale_xx{\m_font_asked_style}}{\m_font_asked_body}{\normalunexpanded{#value}}}%
1852   \letcsname\??fontinstanceclass\m_font_asked_body-\m_font_asked_style-#one#two-#rest-5\endcsname\undefined
1853   \protected\edefcsname\??fontinstanceready\m_font_asked_body-\m_font_asked_style-#one#two-#rest-5\endcsname
1854     {\font_helpers_trigger{\m_font_asked_body-\m_font_asked_style-#one#two#rest}{\noexpand\font_rscale_xx{\m_font_asked_style}}{\m_font_asked_body}{\normalunexpanded{#value}}}%
1855  }
1856
1857\protected\def\font_basics_define_body_font_yes_xx[#one#two#rest=#value]% global
1858  {\ifcsname\m_font_asked_style#one#two#rest\endcsname\else\font_basics_check_fontname_combination\m_font_asked_style{#one#two}{#rest}\fi
1859   \gletcsname\??fontinstanceclass\fontclass-\m_font_asked_body-\m_font_asked_style-#one#two-#rest-1\endcsname\undefined
1860   \protected\xdefcsname\??fontinstanceready\fontclass-\m_font_asked_body-\m_font_asked_style-#one#two-#rest-0\endcsname
1861     {\font_helpers_trigger{\m_font_asked_body-\m_font_asked_style-#one#two#rest-0}{\number\p_font_rscale}{\m_font_asked_body}{\normalunexpanded{#value}}}%
1862   \gletcsname\??fontinstanceclass\fontclass-\m_font_asked_body-\m_font_asked_style-#one#two-#rest-2\endcsname\undefined
1863   \protected\xdefcsname\??fontinstanceready\fontclass-\m_font_asked_body-\m_font_asked_style-#one#two-#rest-4\endcsname
1864     {\font_helpers_trigger{\m_font_asked_body-\m_font_asked_style-#one#two#rest-4}{\number\p_font_rscale}{\m_font_asked_body}{\normalunexpanded{#value}}}%
1865   \gletcsname\??fontinstanceclass\fontclass-\m_font_asked_body-\m_font_asked_style-#one#two-#rest-3\endcsname\undefined
1866   \protected\xdefcsname\??fontinstanceready\fontclass-\m_font_asked_body-\m_font_asked_style-#one#two-#rest-5\endcsname
1867     {\font_helpers_trigger{\m_font_asked_body-\m_font_asked_style-#one#two#rest-5}{\number\p_font_rscale}{\m_font_asked_body}{\normalunexpanded{#value}}}%
1868  }
1869
1870\appendtoks
1871    % the undefined need checking here
1872    \protected\def\font_basics_define_body_font_nop_xx[#one#two#rest=#value]% local
1873      {\ifcsname\m_font_asked_style#one#two#rest\endcsname\else\font_basics_check_fontname_combination\m_font_asked_style{#one#two}{#rest}\fi
1874       \letcsname\??fontinstanceclass\m_font_asked_body-\m_font_asked_style-#one#two-#rest\endcsname\undefined
1875       \protected\edefcsname\??fontinstanceready\m_font_asked_body-\m_font_asked_style-#one#two-#rest\endcsname
1876         {\font_helpers_trigger{\m_font_asked_body-\m_font_asked_style-#one#two#rest}{\noexpand\font_rscale_xx{\m_font_asked_style}}{\m_font_asked_body}{\normalunexpanded{#value}}}%
1877    }%
1878    \protected\def\font_basics_define_body_font_yes_xx[#one#two#rest=#value]% global
1879      {\ifcsname\m_font_asked_style#one#two#rest\endcsname\else\font_basics_check_fontname_combination\m_font_asked_style{#one#two}{#rest}\fi
1880       \gletcsname\??fontinstanceready\fontclass-\m_font_asked_body-\m_font_asked_style-#one#two-#rest\endcsname\undefined
1881       \protected\xdefcsname\??fontinstanceready\fontclass-\m_font_asked_body-\m_font_asked_style-#one#two-#rest\endcsname
1882         {\font_helpers_trigger{\m_font_asked_body-\m_font_asked_style-#one#two#rest}{\number\p_font_rscale}{\m_font_asked_body}{\normalunexpanded{#value}}}%
1883    }%
1884\to \everycompactfontmode
1885
1886% \writestatus{fonts}{define \m_asked_style\space yes: {\expandafter\meaning\csname\fontclass\m_font_asked_body\m_font_asked_style#one#two#rest\endcsname}
1887
1888%D Here the rest concerns rl or lr so in this case it is not a size specifier but
1889%D a directional one.
1890
1891%D no need for the: one two rest
1892
1893\protected\def\font_basics_define_body_font_nop_mm[#one#two#rest=#value]% local
1894  {%\ifcsname\s!mm\endcsname\else\font_basics_check_fontname_combination\s!mm{#one#two}{#rest}\fi
1895   \letcsname\??fontinstanceclass\m_font_asked_body-\s!mm-#one#two#rest-1\endcsname\undefined
1896 % \letcsname\??fontinstanceclass\m_font_asked_body-\s!mm-#one#two#rest-2\endcsname\undefined
1897 % \letcsname\??fontinstanceclass\m_font_asked_body-\s!mm-#one#two#rest-3\endcsname\undefined
1898   \protected\xdefcsname\??fontinstanceready\m_font_asked_body-\s!mm-#one#two#rest\endcsname
1899     {\font_helpers_trigger{\m_font_asked_body-\s!mm-#one#two#rest}{\noexpand\font_rscale_mm}{\m_font_asked_body}{\normalunexpanded{#value}}}%
1900  }
1901
1902% \writestatus{fonts}{define \m_asked_style\space nop: \expandafter\meaning\csname\m_font_asked_body\m_font_asked_style#one#two#rest\endcsname}%
1903
1904\protected\def\font_basics_define_body_font_yes_mm[#one#two#rest=#value]% global
1905  {%\ifcsname\s!mm\endcsname\else\font_basics_check_fontname_combination\s!mm{#one#two}{#rest}\fi
1906   \gletcsname\??fontinstanceclass\fontclass-\m_font_asked_body-\s!mm-#one#two#rest-1\endcsname\undefined
1907 % \gletcsname\??fontinstanceclass\fontclass-\m_font_asked_body-\s!mm-#one#two#rest-2\endcsname\undefined
1908 % \gletcsname\??fontinstanceclass\fontclass-\m_font_asked_body-\s!mm-#one#two#rest-3\endcsname\undefined
1909   \protected\xdefcsname\??fontinstanceready\fontclass-\m_font_asked_body-\s!mm-#one#two#rest\endcsname
1910     {\font_helpers_trigger{\m_font_asked_body-\s!mm-#one#two#rest}{\number\p_font_rscale}{\m_font_asked_body}{\normalunexpanded{#value}}}%
1911  }
1912
1913\appendtoks
1914    \protected\def\font_basics_define_body_font_nop_mm[#one#two#rest=#value]% local
1915      {\letcsname\??fontinstanceclass\m_font_asked_body-\s!mm-#one#two#rest\endcsname\undefined
1916       \protected\xdefcsname\??fontinstanceready\m_font_asked_body-\s!mm-#one#two#rest\endcsname
1917         {\font_helpers_trigger{\m_font_asked_body-\s!mm-#one#two#rest}{\noexpand\font_rscale_mm}{\m_font_asked_body}{\normalunexpanded{#value}}}%
1918    }%
1919    \protected\def\font_basics_define_body_font_yes_mm[#one#two#rest=#value]% global
1920      {\gletcsname\??fontinstanceclass\fontclass-\m_font_asked_body-\s!mm-#one#two#rest\endcsname\undefined
1921       \protected\xdefcsname\??fontinstanceready\fontclass-\m_font_asked_body-\s!mm-#one#two#rest\endcsname
1922         {\font_helpers_trigger{\m_font_asked_body-\s!mm-#one#two#rest}{\number\p_font_rscale}{\m_font_asked_body}{\normalunexpanded{#value}}}%
1923    }%
1924\to \everycompactfontmode
1925
1926% \writestatus{fonts}{define \m_asked_style\space yes: \expandafter\meaning\csname\fontclass\m_font_asked_body\m_font_asked_style#one#two#rest\endcsname}%
1927
1928\protected\def\font_basics_define_body_font_body_identifier[#bodylist][#stylelist][#name]%
1929  {\processcommalist[#bodylist]{\font_basics_define_body_font_body_identifier_a{#stylelist}{#name}}}
1930
1931\protected\def\font_basics_define_body_font_body_identifier_a#stylelist#name#body%
1932  {\normalizebodyfontsize\m_font_asked_body{#body}%
1933   \font_helpers_check_bodyfont_environment\m_font_asked_body\m_font_asked_body % !!
1934   \processcommalist[#stylelist]{\font_basics_define_body_font_body_identifier_b{#name}}}
1935
1936\protected\def\font_basics_define_body_font_body_identifier_b#name#style%
1937  {\edef\m_font_asked_style{#style}%
1938  %\writestatus\m!fonts{[\fontclass] [\m_font_asked_body] [\m_font_asked_style] => [#name]}%
1939   \csname\??fontdefinitions#name:\m_font_asked_style\endcsname} % no checking
1940
1941\protected\def\font_basics_define_body_font_name_assignment[#name][#stylelist][#assignments]%
1942  {\processcommalist[#stylelist]{\font_basics_define_body_font_name_assignment_a{#name}{#assignments}}}
1943
1944\protected\def\font_basics_define_body_font_name_assignment_a#name#assignments#style%
1945  {%\writestatus\m!fonts{[#name:#style] => [#assignments]}%
1946   \edefcsname\??fontdefinitions#name:#style\endcsname{\font_basics_define_body_font_default{#assignments}}}
1947
1948\protected\def\font_basics_define_body_font_name_identifier[#name][#stylelist][#identifier]%
1949  {\processcommalist[#stylelist]{\font_basics_define_body_font_name_identifier_a{#name}{#identifier}}}
1950
1951\protected\def\font_basics_define_body_font_name_identifier_a#name#identifier#style%
1952  {%\writestatus\m!fonts{[#name:#style] => [##identifier:#style]}%
1953   \ifcsname\??fontdefinitions#name:#style\endcsname
1954     \letcsname\??fontdefinitions#name:#style\expandafter\endcsname\csname\??fontdefinitions#identifier:#style\endcsname
1955   \else
1956     \defcsname\??fontdefinitions#name:#style\endcsname{\csname\??fontdefinitions#identifier:#style\endcsname}%
1957   \fi}
1958
1959%D The unknown:
1960
1961\newconditional\c_font_defining_unknown
1962\newconditional\c_font_defining_state
1963
1964\protected\def\font_helpers_define_unknown_font#body% one level only
1965  {\font_helpers_register_fontbody{#body}% prevents loop, can go
1966   \c_font_defining_state\conditionalfalse
1967   \font_helpers_process_relative_size_list{\font_helpers_define_unknown_check_sizes{#body}}%
1968   \ifconditional\c_font_defining_state
1969     \c_font_defining_state\conditionalfalse
1970     \font_helpers_process_style_list{\font_helpers_define_unknown_check_definitions{#body}}%
1971     \ifconditional\c_font_defining_state
1972       \ifconditional\c_font_defining_environment_state\else
1973        %\showmessage\m!fonts{14}{#body}% main
1974         \clf_registerunknownbodysize{#body}%
1975       \fi
1976       \c_font_defining_state\conditionalfalse
1977       \font_helpers_register_fontbody{#body}%
1978       % needed ?
1979%
1980% Otherwise no math when we define [class][style][size]
1981%
1982%        \ifconditional\c_font_defining_unknown
1983%        \else
1984%          \c_font_defining_unknown\conditionaltrue
1985%          \font_helpers_process_relative_size_list{\font_helpers_define_unknown_check_relatives{#body}}%
1986%          \c_font_defining_unknown\conditionalfalse
1987%        \fi
1988     \fi
1989   \fi}
1990
1991\def\font_helpers_define_unknown_check_sizes#body#relativesize%
1992  {\ifcsname\??fontenvironments\s!default#relativesize\endcsname % fontclass ?
1993     \expandafter\normalizebodyfontsize\csname\??fontenvironments#body#relativesize\endcsname{\csname\??fontenvironments\s!default#relativesize\endcsname\dimexpr#body\relax}%
1994     \c_font_defining_state\conditionaltrue
1995   \fi}
1996
1997\def\font_helpers_define_unknown_check_definitions#body#style%
1998  {\ifcsname\??fontdefinitions\s!default:#style\endcsname
1999     \edef\m_font_asked_body{#body}%
2000     \edef\m_font_asked_style{#style}%
2001     \lastnamedcs
2002     \c_font_defining_state\conditionaltrue
2003   \fi}
2004
2005\def\font_helpers_define_unknown_check_relatives#body#relativesize%
2006  {\ifcsname\??fontbodyknown\csname\??fontenvironments#body#relativesize\endcsname\endcsname \else
2007     \expandafter\font_helpers_define_unknown_font\csname\??fontenvironments#body#relativesize\endcsname
2008     \c_font_defining_state\conditionaltrue
2009   \fi}
2010
2011\protected\def\font_basics_define_body_font_default#assignments%
2012  {\font_helpers_check_relative_font_size\m_font_asked_style % still needed here?
2013   \ifcsname\m_font_asked_style\endcsname\else
2014     \normalexpanded{\definefontstyle[\m_font_asked_style][\m_font_asked_style]}%
2015   \fi
2016   \processcommalist[#assignments]\font_basics_define_body_font_defs
2017   \let\p_font_rscale\v_font_rscale_default}
2018
2019%D These macros show that quite some definitions take place. Fonts are not loaded
2020%D yet! This means that at format generation time, no font files are present.
2021
2022\protected\def\font_basics_switch_points#body%
2023  {\ifcsname\??fontbodyknown#body\endcsname \else
2024     % we need to check the relative sizes for this body
2025     \font_helpers_define_unknown_font{#body}%
2026   \fi%
2027   \ifcsname\??fontbodyknown#body\endcsname % always true now
2028     \font_basics_complete_switch{#body}%
2029     \localbodyfontsize#body\relax
2030     \normalizebodyfontsize\normalizedbodyfontsize\localbodyfontsize
2031     \font_helpers_check_bodyfont_environment\normalizedbodyfontsize\normalizedbodyfontsize % !!
2032   \else
2033     \showmessage\m!fonts4{#body}%
2034   \fi}
2035
2036\appendtoks
2037    \protected\def\font_basics_switch_points#body%
2038      {\ifcsname\??fontbodyknown#body\endcsname \else
2039         % we need to check the relative sizes for this body
2040         \font_helpers_define_unknown_font{#body}%
2041       \fi%
2042       \ifcsname\??fontbodyknown#body\endcsname % always true now
2043         \font_basics_complete_switch{#body}%
2044         \localbodyfontsize#body\relax
2045         \normalizebodyfontsize\normalizedbodyfontsize\localbodyfontsize
2046         \font_helpers_check_bodyfont_environment\normalizedbodyfontsize\normalizedbodyfontsize % !!
2047       \else
2048         \showmessage\m!fonts4{#body}%
2049       \fi
2050       \glyphscale\numexpr\plushundred*\dimexpr\normalizedbodyfontsize\relax/\maxcard\relax}
2051\to \everycompactfontmode
2052
2053\protected\def\font_basics_switch_style#style%
2054  {\ifcsname\??fontstyle#style\endcsname
2055     \lastnamedcs
2056     \cdef\fontstyle{#style}%
2057     \ifmmode\mr\fi % in order to be compatible with \rm in math mode
2058     % \expand\everybodyfont % cleaner, in setting size as well as style
2059   \else
2060     \showmessage\m!fonts5{#style}%
2061   \fi}
2062
2063%D Here comes the main font switching macros. These macros handle changes in size as
2064%D well as returning to the global bodyfont size.
2065
2066\ifdefined\font_preloads_at_definition \else \let\font_preloads_at_definition\relax \fi
2067
2068\def\font_helpers_set_font#method#specification%
2069  {\edef\m_font_specification{#specification}%
2070   \ifempty\m_font_specification \else
2071     \ifx\m_font_specification\v!global % we can have all kind of presets
2072       \restoreglobalbodyfont
2073     \else % order swapped per nov 2023
2074       \processcommacommand[\m_font_specification]{\font_helpers_set_font_set_font{#method}}%
2075       \processcommacommand[\m_font_specification]{\font_helpers_set_font_check_size}%
2076       \ifproductionrun
2077         \font_preloads_at_definition
2078         \font_basics_switch_points\normalizedbodyfontsize
2079         \font_basics_switch_style\fontstyle
2080         \ifempty\defaultfontclass
2081           \let\defaultfontclass\fontclass
2082         \fi
2083       \fi
2084     \fi
2085     \currentxfontsize\zerocount
2086   \fi}
2087
2088\def\font_helpers_set_font_check_size#option%
2089  {\ifchkdimension#option\or
2090     \font_helpers_check_bodyfont_environment{#option}{#option}%
2091   \fi}
2092
2093\def\font_helpers_set_font_set_font#method#option% method=1: set, method=2: switch
2094  {\ifempty{#option}\else
2095     \font_helpers_set_font_set_font_option{#method}{#option}%
2096   \fi}
2097
2098\def\font_helpers_set_font_set_font_option#method#option%
2099  {\ifchkdimension#option\or
2100     \expandafter\font_helpers_set_font_set_font_option_body
2101   \else
2102     \expandafter\font_helpers_set_font_set_font_option_keyword
2103   \fi{#method}{#option}{#option}}
2104
2105\newmacro\m_font_keyword
2106
2107\protected\def\font_helpers_set_font_set_font_option_keyword#method#keyword#message%
2108  {\edef\m_font_keyword{#keyword}%
2109   \ifcsname\??fontenvironments\normalizedbodyfontsize\m_font_keyword\endcsname
2110     \edef\m_font_step{\font_bodyfontvariable\m_font_keyword}%
2111     \normalexpanded{\font_helpers_set_font_set_font_option_body{#method}{\m_font_step}{#message}}%
2112   \orelse\ifx\m_font_keyword\v!reset
2113     \lettonothing\fontstyle % new 31/7/2006
2114     \lettonothing\fontsize
2115   \orelse\ifcsname\??fontstyle\m_font_keyword\endcsname
2116     \let\fontstyle\m_font_keyword
2117   \else
2118     \setcurrentfontclass\m_font_keyword
2119     \ifcase#method\relax
2120       \let\globalfontclass\globalfontclass % -)
2121     \else
2122       \let\globalfontclass\fontclass
2123     \fi
2124     \font_helpers_set_fontstyle_of_fontclass
2125   \fi}
2126
2127\def\font_helpers_set_fontstyle_of_fontclass % will be overloaded later
2128  {\let\fontstyle\s!rm}
2129
2130\protected\def\font_helpers_set_font_set_font_option_body#method#body#message%
2131  {\normalizebodyfontsize\normalizedsetfont{#body}% redundant for some calls
2132   \ifcsname\??fontbodyknown\normalizedsetfont\endcsname \else
2133     \font_helpers_define_unknown_font\normalizedsetfont
2134   \fi
2135   \ifcsname\??fontbodyknown\normalizedsetfont\endcsname
2136     \localbodyfontsize\normalizedsetfont
2137     \let\normalizedbodyfontsize\normalizedsetfont
2138   \else
2139     \showmessage\m!fonts4{#message}%
2140    %\font_helpers_set_font_set_font_option_body_fallbacks{#method}{#body}%
2141   \fi}
2142
2143% we need to check the fontclass
2144
2145\permanent\protected\def\registerfontclass#class%
2146  {\gletcsname\??fontclassyes#class\endcsname\v!yes} % global ?
2147
2148\permanent\protected\def\setcurrentfontclass#class%
2149  {\ifcsname\??bodyfontalias#class\endcsname
2150     \constant\lettolastnamedcs\fontclass
2151   \orelse\ifcsname\??fontclassyes#class\endcsname
2152     \cdef\fontclass{#class}%
2153   \orelse\ifcsname\??fontclassnop#class\endcsname
2154     % already tried
2155   \else   % too messy: \ifcase\currentgrouplevel % (unpredictable)
2156     \fonts_helpers_try_currentfontclass{#class}%
2157   \fi}
2158
2159\ifdefined\fonts_helpers_try_currentfontclass \else
2160
2161    \protected\def\fonts_helpers_try_currentfontclass#typeface%
2162      {\letcsname\??fontclassnop#typeface\endcsname\empty}
2163
2164\fi
2165
2166%D So far for synchronisation. (We can inline the following macros.)
2167
2168\permanent\protected\def\setcurrentfont#body#style#alternative#size% not used
2169  {\cdef\fontbody       {#body}%
2170   \cdef\fontstyle      {#style}%
2171   \cdef\fontalternative{#alternative}%
2172   \cdef\fontsize       {#size}%
2173   \font_helpers_check_big_math_synchronization
2174   \font_helpers_synchronize_font}
2175
2176\permanent\protected\def\setcurrentfontbody#body% % not used
2177  {\cdef\fontbody{#body}%
2178   \font_helpers_synchronize_font}
2179
2180% For Taco: optional fall backs:
2181
2182\ifdefined\font_typescripts_inherit_check \else
2183    \let\font_typescripts_inherit_check\gobbleoneargument % implemented in type-ini
2184\fi
2185
2186\protected\def\font_helpers_set_current_font_style#style%
2187  {\cdef\fontstyle{#style}%
2188   \font_typescripts_inherit_check\fontstyle
2189   \ifmmode\mr\fi % otherwise \rm not downward compatible ... not adapted yet
2190   \font_helpers_synchronize_font}
2191
2192\mutable\let\f_font_rscale_used\plusone
2193
2194\appendtoks
2195   %\aliased\let\f_font_rscale_used\v_font_rscale_default
2196    \mutable\let\f_font_rscale_used\plusone
2197    \protected\def\font_helpers_set_current_font_style#style%
2198      {\cdef\fontstyle{#style}%
2199       \font_typescripts_inherit_check\fontstyle
2200       \ifmmode\mr\fi % otherwise \rm not downward compatible ... not adapted yet
2201       \font_helpers_synchronize_font
2202       \edef\f_font_rscale_used{\font_rscale_xx{#style}}}%
2203\to \everycompactfontmode
2204
2205\protected\def\font_helpers_set_current_xsize_alternative#xsize#alternative%
2206  {\cdef\fontface{#xsize}%
2207   \cdef\fontalternative{#alternative}%
2208   \font_helpers_synchronize_font}
2209
2210\appendtoks
2211    \protected\def\font_helpers_set_current_xsize_alternative#xsize#alternative%
2212      {\cdef\fontface{0}% % not used in compact mode
2213       \cdef\fontalternative{#alternative}%
2214       \currentxfontsize#xsize\relax
2215       \font_helpers_synchronize_font}%
2216\to \everycompactfontmode
2217
2218\protected\def\font_helpers_set_current_font_alternative#alternative%
2219  {\cdef\fontalternative{#alternative}%
2220   \font_helpers_synchronize_font}
2221
2222\protected\def\font_helpers_set_current_font_size#size%
2223  {\cdef\fontsize{#size}%
2224   \font_helpers_check_big_math_synchronization % double? better in everymath?
2225   \font_helpers_synchronize_font}
2226
2227\protected\def\font_helpers_set_current_font_style_alternative#style#alternative% \rmsl
2228  {\cdef\fontstyle      {#style}%
2229   \cdef\fontalternative{#alternative}%
2230   \font_helpers_synchronize_font}
2231
2232\protected\def\font_helpers_set_current_font_style_size#style#size% \rma
2233  {\cdef\fontstyle{#style}%
2234   \cdef\fontsize {#size}%
2235   \font_helpers_check_big_math_synchronization % double? better in everymath?
2236   \font_helpers_synchronize_font}
2237
2238\protected\def\font_helpers_set_current_font_alternative_size#alternative#size% \sla
2239  {\cdef\fontalternative{#alternative}%
2240   \cdef\fontsize       {#size}%
2241   \font_helpers_check_big_math_synchronization % double? better in everymath?
2242   \font_helpers_synchronize_font}
2243
2244\protected\def\font_helpers_set_current_font_style_alternative_size#style#alternative#size% \rmsla
2245  {\cdef\fontstyle      {#style}%
2246   \cdef\fontalternative{#alternative}%
2247   \cdef\fontsize       {#size}%
2248   \font_helpers_check_big_math_synchronization % double? better in everymath?
2249   \font_helpers_synchronize_font}
2250
2251\protected\def\font_helpers_synchronize_font
2252  {\ifempty\fontclass
2253     \applyfontstrategies
2254   \else
2255     \applyfontclassstrategies
2256   \fi
2257   \c_font_auto_size\conditionalfalse
2258   \ifskipfontcharacteristics \else
2259     \expand\everyfont % \setfontcharacteristics
2260     \expand\everyfontswitch
2261   \fi}
2262
2263\appendtoks
2264    \protected\def\font_helpers_synchronize_font
2265      {\ifempty\fontclass
2266         \applyfontstrategies
2267       \else
2268         \applyfontclassstrategies
2269       \fi
2270       \c_font_auto_size\conditionalfalse
2271       \ifcase\currentxfontsize
2272         % nothing
2273       \or
2274         \normaltx
2275       \else
2276         \normaltxx
2277       \fi
2278       \ifskipfontcharacteristics \else
2279         \expand\everyfont % \setfontcharacteristics
2280         \expand\everyfontswitch
2281       \fi}%
2282\to \everycompactfontmode
2283
2284%D This is the resolver for special cases (sizes) and in practice it is not called
2285%D that often so further optimization makes no sense.
2286
2287\def\font_helpers_check_strategy_class_a % --- --- --- --- % pt tt bf a
2288  {\ifcsname\??fontinstanceready\fontclass-\fontbody-\fontstyle-\fontalternative-\fontsize-\fontface\endcsname
2289     \c_font_auto_size\conditionalfalse
2290     \lastnamedcs
2291   \else
2292     \expandafter\font_helpers_check_strategy_class_b
2293   \fi}
2294
2295\def\font_helpers_check_strategy_class_b % --- --- --- def % pt tt bf
2296  {\ifcsname\??fontinstanceready\fontclass-\fontbody-\fontstyle-\fontalternative-\defaultfontsize-\fontface\endcsname
2297     \c_font_auto_size\conditionaltrue
2298     \lastnamedcs
2299   \else
2300     \expandafter\font_helpers_check_strategy_class_c
2301   \fi}
2302
2303\def\font_helpers_check_strategy_class_c % --- --- def --- % pt tt tf a
2304  {\ifcsname\??fontinstanceready\fontclass-\fontbody-\fontstyle-\defaultfontalternative-\fontsize-\fontface\endcsname
2305     \c_font_auto_size\conditionaltrue
2306     \lastnamedcs
2307   \else
2308     \expandafter\font_helpers_check_strategy_class_d
2309   \fi}
2310
2311\def\font_helpers_check_strategy_class_d % --- --- def def % pt tt tf
2312  {\ifcsname\??fontinstanceready\fontclass-\fontbody-\fontstyle-\defaultfontalternative-\defaultfontsize-\fontface\endcsname
2313     \c_font_auto_size\conditionaltrue
2314     \lastnamedcs
2315   \else
2316     \expandafter\font_helpers_check_strategy_class_e
2317   \fi}
2318
2319\def\font_helpers_check_strategy_class_e % --- def def def % pt rm tf
2320  {\ifcsname\??fontinstanceready\fontclass-\fontbody-\defaultfontstyle-\defaultfontalternative-\defaultfontsize-\fontface\endcsname
2321     \c_font_auto_size\conditionalfalse
2322     \lastnamedcs
2323   \else
2324     \expandafter\font_helpers_check_strategy_class_f
2325   \fi}
2326
2327\def\font_helpers_check_strategy_class_f % def def def def % rm tf
2328  {\ifcsname\??fontinstanceready\fontclass-\defaultfontbody-\defaultfontstyle-\defaultfontalternative-\defaultfontsize-\fontface\endcsname
2329     \c_font_auto_size\conditionaltrue
2330     \lastnamedcs
2331   \else
2332     \expandafter\font_helpers_check_strategy_a
2333   \fi}
2334
2335\appendtoks
2336    \def\font_helpers_check_strategy_class_a % --- --- --- --- % pt tt bf a
2337      {\ifcsname\??fontinstanceready\fontclass-\fontbody-\fontstyle-\fontalternative-\fontsize\endcsname
2338         \c_font_auto_size\conditionalfalse
2339         \lastnamedcs
2340       \else
2341         \expandafter\font_helpers_check_strategy_class_b
2342       \fi}%
2343    %
2344    \def\font_helpers_check_strategy_class_b % --- --- --- def % pt tt bf
2345      {\ifcsname\??fontinstanceready\fontclass-\fontbody-\fontstyle-\fontalternative-\defaultfontsize\endcsname
2346         \c_font_auto_size\conditionaltrue
2347         \lastnamedcs
2348       \else
2349         \expandafter\font_helpers_check_strategy_class_c
2350       \fi}%
2351    %
2352    \def\font_helpers_check_strategy_class_c % --- --- def --- % pt tt tf a
2353      {\ifcsname\??fontinstanceready\fontclass-\fontbody-\fontstyle-\defaultfontalternative-\fontsize\endcsname
2354         \c_font_auto_size\conditionaltrue
2355         \lastnamedcs
2356       \else
2357         \expandafter\font_helpers_check_strategy_class_d
2358       \fi}%
2359    %
2360    \def\font_helpers_check_strategy_class_d % --- --- def def % pt tt tf
2361      {\ifcsname\??fontinstanceready\fontclass-\fontbody-\fontstyle-\defaultfontalternative-\defaultfontsize\endcsname
2362         \c_font_auto_size\conditionaltrue
2363         \lastnamedcs
2364       \else
2365         \expandafter\font_helpers_check_strategy_class_e
2366       \fi}%
2367    %
2368    \def\font_helpers_check_strategy_class_e % --- def def def % pt rm tf
2369      {\ifcsname\??fontinstanceready\fontclass-\fontbody-\defaultfontstyle-\defaultfontalternative-\defaultfontsize\endcsname
2370         \c_font_auto_size\conditionalfalse
2371         \lastnamedcs
2372       \else
2373         \expandafter\font_helpers_check_strategy_class_f
2374       \fi}%
2375    %
2376    \def\font_helpers_check_strategy_class_f % def def def def % rm tf
2377      {\ifcsname\??fontinstanceready\fontclass-\defaultfontbody-\defaultfontstyle-\defaultfontalternative-\defaultfontsize\endcsname
2378         \c_font_auto_size\conditionaltrue
2379         \lastnamedcs
2380       \else
2381         \expandafter\font_helpers_check_strategy_a
2382       \fi}%
2383\to \everycompactfontmode
2384
2385% no class
2386
2387\def\font_helpers_check_strategy_a % --- --- --- --- % pt tt bf a
2388  {\ifcsname\??fontinstanceready\fontbody-\fontstyle-\fontalternative-\fontsize-\fontface\endcsname
2389     \c_font_auto_size\conditionalfalse
2390     \lastnamedcs
2391   \else
2392     \expandafter\font_helpers_check_strategy_b
2393   \fi}
2394
2395\def\font_helpers_check_strategy_b % --- --- --- --- % pt tt bf a
2396  {\ifcsname\??fontinstanceready\fontbody-\fontstyle-\fontalternative-\defaultfontsize-\fontface\endcsname
2397     \c_font_auto_size\conditionaltrue
2398     \lastnamedcs
2399   \else
2400     \expandafter\font_helpers_check_strategy_c
2401   \fi}
2402
2403\def\font_helpers_check_strategy_c % --- --- --- --- % pt tt bf a
2404  {\ifcsname\??fontinstanceready\fontbody-\fontstyle-\defaultfontalternative-\fontsize-\fontface\endcsname
2405     \c_font_auto_size\conditionaltrue
2406     \lastnamedcs
2407   \else
2408     \expandafter\font_helpers_check_strategy_d
2409   \fi}
2410
2411\def\font_helpers_check_strategy_d % --- --- --- --- % pt tt bf a
2412  {\ifcsname\??fontinstanceready\fontbody-\fontstyle-\defaultfontalternative-\defaultfontsize-\fontface\endcsname
2413     \c_font_auto_size\conditionaltrue
2414     \lastnamedcs
2415   \else
2416     \expandafter\font_helpers_check_strategy_e
2417   \fi}
2418
2419\def\font_helpers_check_strategy_e % --- --- --- --- % pt tt bf a
2420  {\ifcsname\??fontinstanceready\fontbody-\defaultfontstyle-\defaultfontalternative-\defaultfontsize-\fontface\endcsname
2421     \c_font_auto_size\conditionalfalse
2422     \lastnamedcs
2423   \else
2424     \expandafter\font_helpers_check_strategy_f
2425   \fi}
2426
2427\def\font_helpers_check_strategy_f % --- --- --- --- % pt tt bf a
2428  {\ifcsname\??fontinstanceready\defaultfontbody-\defaultfontstyle-\defaultfontalternative-\defaultfontsize-\fontface\endcsname
2429     \c_font_auto_size\conditionaltrue
2430     \lastnamedcs
2431   \fi}
2432
2433\appendtoks
2434    \def\font_helpers_check_strategy_a % --- --- --- --- % pt tt bf a
2435      {\ifcsname\??fontinstanceready\fontbody-\fontstyle-\fontalternative-\fontsize\endcsname
2436         \c_font_auto_size\conditionalfalse
2437         \lastnamedcs
2438       \else
2439         \expandafter\font_helpers_check_strategy_b
2440       \fi}%
2441    %
2442    \def\font_helpers_check_strategy_b % --- --- --- --- % pt tt bf a
2443      {\ifcsname\??fontinstanceready\fontbody-\fontstyle-\fontalternative-\defaultfontsize\endcsname
2444         \c_font_auto_size\conditionaltrue
2445         \lastnamedcs
2446       \else
2447         \expandafter\font_helpers_check_strategy_c
2448       \fi}%
2449    %
2450    \def\font_helpers_check_strategy_c % --- --- --- --- % pt tt bf a
2451      {\ifcsname\??fontinstanceready\fontbody-\fontstyle-\defaultfontalternative-\fontsize\endcsname
2452         \c_font_auto_size\conditionaltrue
2453         \lastnamedcs
2454       \else
2455         \expandafter\font_helpers_check_strategy_d
2456       \fi}%
2457    %
2458    \def\font_helpers_check_strategy_d % --- --- --- --- % pt tt bf a
2459      {\ifcsname\??fontinstanceready\fontbody-\fontstyle-\defaultfontalternative-\defaultfontsize\endcsname
2460         \c_font_auto_size\conditionaltrue
2461         \lastnamedcs
2462       \else
2463         \expandafter\font_helpers_check_strategy_e
2464       \fi}%
2465    %
2466    \def\font_helpers_check_strategy_e % --- --- --- --- % pt tt bf a
2467      {\ifcsname\??fontinstanceready\fontbody-\defaultfontstyle-\defaultfontalternative-\defaultfontsize\endcsname
2468         \c_font_auto_size\conditionalfalse
2469         \lastnamedcs
2470       \else
2471         \expandafter\font_helpers_check_strategy_f
2472       \fi}%
2473    %
2474    \def\font_helpers_check_strategy_f % --- --- --- --- % pt tt bf a
2475      {\ifcsname\??fontinstanceready\defaultfontbody-\defaultfontstyle-\defaultfontalternative-\defaultfontsize\endcsname
2476         \c_font_auto_size\conditionaltrue
2477         \lastnamedcs
2478       \fi}%
2479\to \everycompactfontmode
2480
2481\permanent\let\applyfontstrategies     \font_helpers_check_strategy_a
2482\permanent\let\applyfontclassstrategies\font_helpers_check_strategy_class_a
2483
2484\appendtoks
2485    \enforced\permanent\let\applyfontstrategies     \font_helpers_check_strategy_a
2486    \enforced\permanent\let\applyfontclassstrategies\font_helpers_check_strategy_class_a
2487\to \everycompactfontmode
2488
2489%D Let's synchronize:
2490
2491\newconditional\c_font_synchronize \c_font_synchronize\conditionaltrue
2492
2493\prependtoks
2494    \ifconditional\c_font_synchronize
2495        \font_helpers_synchronize_math
2496        \font_helpers_synchronize_font % problem: syncs last font
2497    \fi
2498\to \everybodyfont
2499
2500%D Setting the normal sizes as well as the x and xx smaller sizes is accomplished by
2501%D the next set of macros. When in math mode, the commands \type {\tx} and \type
2502%D {\txx} are just a switch to the script and double script styles, but in text mode
2503%D the values defined by the bodyfontenvironment are used. Here we also set \type
2504%D {\currentxfontsize}.
2505
2506\permanent\protected\def\resettx
2507  {\ifzeronum\currentxfontsize\else
2508     \currentxfontsize\zerocount
2509     \enforced\let\tx\normaltx
2510     \enforced\let\txx\normaltxx
2511    %\enforced\let\sx\normalsx
2512    %\enforced\let\sxx\normalsxx
2513     \let\fontsize\empty
2514     \font_scale_defined
2515    %\font_helpers_check_big_math_synchronization
2516    %\font_helpers_synchronize_font
2517   \fi}
2518
2519\prependtoks
2520    \currentxfontsize\zerocount
2521    \enforced\let\tx \normaltx
2522    \enforced\let\txx\normaltxx
2523    \font_scale_defined
2524\to \everysetupbodyfont
2525
2526\prependtoks
2527    \currentxfontsize\zerocount
2528    \enforced\let\tx \normaltx
2529    \enforced\let\txx\normaltxx
2530    \font_scale_defined
2531\to \everyswitchtobodyfont
2532
2533\def\font_helpers_set_current_font_xxx_alternative#alternative#xsize#scriptstyle%
2534  {\ifmmode
2535     #scriptstyle%
2536   \else
2537     \font_helpers_set_current_xsize_alternative{#xsize}{#alternative}%
2538   \fi}
2539
2540\def\font_helpers_set_current_font_x_alternative#alternative%
2541  {%\font_helpers_check_nested_x_fontsize
2542   \font_helpers_set_current_font_xxx_alternative{#alternative}{4}\scriptstyle
2543   \currentxfontsize\plusone
2544   \enforced\let\tx\txx}
2545
2546\def\font_helpers_set_current_font_xx_alternative#alternative%
2547  {%\font_helpers_check_nested_x_fontsize
2548   \font_helpers_set_current_font_xxx_alternative{#alternative}{5}\scriptscriptstyle
2549   \currentxfontsize\plustwo
2550   \enforced\lettonothing\tx
2551   \enforced\lettonothing\txx}
2552
2553\appendtoks
2554    \def\font_helpers_set_current_font_x_alternative#alternative%
2555      {%\font_helpers_check_nested_x_fontsize
2556       \currentxfontsize\plusone
2557       \font_helpers_set_current_font_xxx_alternative{#alternative}\plusone\scriptstyle
2558       \enforced\let\tx\txx}%
2559    \def\font_helpers_set_current_font_xx_alternative#alternative%
2560      {%\font_helpers_check_nested_x_fontsize
2561       \currentxfontsize\plusone
2562       \font_helpers_set_current_font_xxx_alternative{#alternative}\plustwo\scriptscriptstyle
2563       \enforced\lettonothing\tx
2564       \enforced\lettonothing\txx}%
2565\to \everycompactfontmode
2566
2567%D This alternative is not really needed, but for old time's sake we keep it there.
2568%D We can speed it up when needed.
2569
2570\def\font_helpers_set_current_font_x_style_alternative #alternative{\csname#alternative\endcsname\tx}
2571\def\font_helpers_set_current_font_xx_style_alternative#alternative{\csname#alternative\endcsname\txx}
2572
2573%D These macros also show us that when we call for \type {\tx}, this macro is
2574%D redefined to be \type {\txx}. Therefore calls like:
2575%D
2576%D \startbuffer
2577%D {small \tx  is \tx  beautiful}
2578%D {small \tx  is \txx beautiful}
2579%D {small \txx is \tx  beautiful}
2580%D {small \txx is \txx beautiful}
2581%D \stopbuffer
2582%D
2583%D \typebuffer
2584%D
2585%D result in:
2586%D
2587%D \startlines
2588%D \getbuffer
2589%D \stoplines
2590%D
2591%D Setting the main size involves the style list and therefore takes a bit more
2592%D time. Keep in mind that the fontsize is represented by a character or empty.
2593
2594\def\font_scale_defined
2595  {\let\fontface\!!zerocount
2596  %\let\fontalternative\fontalternative
2597   \font_helpers_synchronize_font}
2598
2599\def\font_scale_defined_x
2600  {\let\fontface\!!plusfour
2601  %\let\fontalternative\fontalternative
2602   \font_helpers_synchronize_font}
2603
2604\def\font_scale_defined_xx
2605  {\let\fontface\!!plusfive
2606  %\let\fontalternative\fontalternative
2607   \font_helpers_synchronize_font}
2608
2609\appendtoks
2610    \def\font_scale_defined
2611     %{\glyphscale\dimexpr\textface*\plushundred/\onepoint\relax
2612     %{\glyphscale\dimexpr\font_rscale_xx\fontstyle\dimexpr\textface*\plushundred/\onepoint\relax\relax
2613      {\glyphscale\dimexpr\f_font_rscale_used\dimexpr\textface*\plushundred/\onepoint\relax\relax
2614       \ifskipfontcharacteristics \else
2615         \expand\everyfont % \setfontcharacteristics
2616         \expand\everyfontswitch
2617       \fi}%
2618    \def\font_scale_defined_x
2619     %{\glyphscale\dimexpr\xtextface*\plushundred/\onepoint\relax
2620     %{\glyphscale\dimexpr\font_rscale_xx\fontstyle\dimexpr\xtextface*\plushundred/\onepoint\relax\relax
2621      {\glyphscale\dimexpr\f_font_rscale_used\dimexpr\xtextface*\plushundred/\onepoint\relax\relax
2622       \ifskipfontcharacteristics \else
2623         \expand\everyfont % \setfontcharacteristics
2624         \expand\everyfontswitch
2625       \fi}%
2626    \def\font_scale_defined_xx
2627     %{\glyphscale\dimexpr\xxtextface*\plushundred/\onepoint\relax
2628     %{\glyphscale\dimexpr\font_rscale_xx\fontstyle\dimexpr\xxtextface*\plushundred/\onepoint\relax\relax
2629      {\glyphscale\dimexpr\f_font_rscale_used\dimexpr\xxtextface*\plushundred/\onepoint\relax\relax
2630       \ifskipfontcharacteristics \else
2631         \expand\everyfont % \setfontcharacteristics
2632         \expand\everyfontswitch
2633       \fi}%
2634\to \everycompactfontmode
2635
2636% to freeze or not ...
2637
2638\permanent\protected\def\tx
2639  {\currentxfontsize\plusone
2640   \ifmmode
2641     \scriptstyle
2642   \else
2643     \font_scale_defined_x
2644   \fi
2645   \enforced\let\tx\txx}
2646
2647\permanent\protected\def\txx
2648  {\currentxfontsize\plustwo
2649   \ifmmode
2650     \scriptscriptstyle
2651   \else
2652     \font_scale_defined_xx
2653   \fi
2654   \enforced\lettonothing\tx
2655   \enforced\lettonothing\txx}
2656
2657\permanent\protected\def\sx
2658  {\currentxfontsize\plusone
2659   \ifmmode
2660     \scriptstyle
2661   \else
2662     \font_scale_defined_x
2663   \fi
2664   \enforced\let\tx\txx
2665   \enforced\let\sx\sxx}
2666
2667\permanent\protected\def\sxx
2668  {\currentxfontsize\plustwo
2669   \ifmmode
2670     \scriptscriptstyle
2671   \else
2672     \font_scale_defined_xx
2673   \fi
2674   \enforced\lettonothing\tx
2675   \enforced\lettonothing\txx
2676   \enforced\lettonothing\sx
2677   \enforced\lettonothing\sxx}
2678
2679\aliased\let\normaltx \tx
2680\aliased\let\normaltxx\txx
2681
2682\aliased\let\normalsx \sx
2683\aliased\let\normalsxx\sxx
2684
2685\lettonothing\useinheritxsizes % will go
2686\lettonothing\usedefinedxsizes % will go
2687
2688%D When asking for a complete font switch, for instance from 10 to 12~points, the
2689%D next macro does the job. First we normalize the size, next we define the current
2690%D range of text, script and scriptscript sizes, then we set the text fonts and the
2691%D math families and finally we activate the default typeface and also set the font
2692%D specific parameters assigned to \type {\everybodyfont}.
2693
2694% todo: per class
2695
2696\permanent\protected\def\textface        {\currentbodyfontdimension\s!text        }
2697\permanent\protected\def\scriptface      {\currentbodyfontdimension\s!script      }
2698\permanent\protected\def\scriptscriptface{\currentbodyfontdimension\s!scriptscript}
2699\permanent\protected\def\xtextface       {\currentbodyfontdimension\s!x           }
2700\permanent\protected\def\xxtextface      {\currentbodyfontdimension\s!xx          }
2701
2702\protected\def\font_basics_complete_switch#size%
2703  {\bodyfontsize#size\relax
2704   \normalizebodyfontsize\normalizedbodyfontsize\bodyfontsize}
2705
2706%D \macros
2707%D   {setupbodyfont,switchtobodyfont}
2708%D
2709%D The next two macros are user ones. With \type {\setupbodyfont} one can set the
2710%D document bodyfont size, font family, style and/or options defined in files, for
2711%D example:
2712%D
2713%D \starttyping
2714%D \setupbodyfont[modern,12pt,roman]
2715%D \stoptyping
2716%D
2717%D This command affects the document as a whole: text, headers and footers. The
2718%D second macro however affects only the text:
2719%D
2720%D \starttyping
2721%D \switchtobodyfont[10pt]
2722%D \stoptyping
2723%D
2724%D So we've got:
2725%D
2726%D \showsetup{setupbodyfont}
2727%D \showsetup{switchtobodyfont}
2728%D
2729%D Both macros look alike. The second one also has to take all kind of keywords into
2730%D account.
2731
2732\ifdefined\saveinterlinespace    \else \let\saveinterlinespace   \relax \fi
2733\ifdefined\restoreinterlinespace \else \let\restoreinterlinespace\relax \fi
2734
2735% \newtoks \everysetupbodyfont
2736% \newtoks \everyswitchtobodyfont
2737
2738\permanent\protected\tolerant\def\setupbodyfont[#specification]%
2739  {\ifparameter#specification\or
2740     \font_helpers_set_font\plusone{#specification}%
2741     \globalbodyfontsize\localbodyfontsize
2742     \normalizebodyfontsize\normalizedglobalbodyfontsize\globalbodyfontsize
2743     \let\globalfontstyle\fontstyle
2744     \ifproductionrun
2745       \expand\everybodyfont
2746       \expand\everyglobalbodyfont
2747       \saveinterlinespace
2748     \fi
2749     \expand\everysetupbodyfont
2750   \else
2751     \restoreglobalbodyfont
2752     \saveinterlinespace
2753   \fi}
2754
2755\permanent\protected\def\switchtobodyfont[#specification]% could become an ifx
2756  {\ifparameter#specification\or
2757     \font_basics_switchtobodyfont{#specification}%
2758   \fi}
2759
2760\protected\def\font_basics_switchtobodyfont#specification%
2761  {\edef\m_font_step{\font_bodyfontvariable{#specification}}%
2762   \ifempty\m_font_step
2763     \font_helpers_set_font\zerocount{#specification}%
2764   \else
2765     \font_helpers_switch_bodyfont_step % so we have a fast [small] switch
2766   \fi
2767   \expand\everybodyfont
2768   \expand\everyswitchtobodyfont
2769\expand\everyfont
2770\expand\everyfontswitch
2771   }
2772
2773\permanent\protected\def\usebodyfontparameter#1%
2774  {\edef\m_font_bodyfont_asked{#1\c!bodyfont}%
2775   \ifempty\m_font_bodyfont_asked\else
2776     \font_basics_switchtobodyfont\m_font_bodyfont_asked
2777   \fi}
2778
2779\def\font_helpers_switch_bodyfont_step
2780  {\font_basics_switch_points\m_font_step
2781   \font_basics_switch_style \fontstyle}
2782
2783%D The following alternative is meant for math||to||text switching and will be
2784%D optimized.
2785
2786\permanent\protected\def\fastswitchtobodyfont#name%
2787  {\ifcsname\??fontenvironments\normalizedbodyfontsize#name\endcsname
2788   % \edef\p_bodyfont{\lastnamedcs}%
2789     \lettolastnamedcs\p_bodyfont
2790     \ifcsname\??fontbodyknown\p_bodyfont\endcsname
2791       \font_basics_complete_switch\p_bodyfont
2792       \localbodyfontsize\p_bodyfont\relax
2793     \fi
2794   \fi
2795   \csname\??fontstyle\fontstyle\endcsname
2796   \expand\everybodyfont
2797\expand\everyfontswitch
2798   }
2799
2800%D \starttyping
2801%D $\cases{& \ccaron}$ $x=\hbox{\ccaron $x=\hbox{\ccaron}$}$
2802%D \stoptyping
2803
2804%D \macros
2805%D   {usebodyfont}
2806%D
2807%D This looks nicer then a switch in the preamble
2808%D
2809%D \starttyping
2810%D \usebodyfont[pagella,10pt]
2811%D \usebodyfont[termes,10pt]
2812%D \usebodyfont[dejavu,10pt]
2813%D
2814%D \setupbodyfont[dejavu]
2815%D
2816%D \starttext
2817%D     test
2818%D \stoptext
2819%D \stoptyping
2820%D
2821%D You can define an meaningfull alias but beware, the font will be partially
2822%D preloaded:
2823%D
2824%D \starttyping
2825%D \aliasbodyfont[mainfont][pagella]
2826%D \switchtobodyfont[mainfont]
2827%D \stoptyping
2828
2829\installcorenamespace{bodyfontalias}
2830
2831\permanent\protected\def\usebodyfont[#1]%
2832  {\ifempty\fontclass
2833     \setupbodyfont[#1]%
2834   \else
2835     \switchtobodyfont[#1]%
2836     \fullrestoreglobalbodyfont
2837   \fi}
2838
2839\permanent\protected\def\aliasbodyfont[#1]#*[#2]%
2840  {\ifparameter#2\or
2841     \cdefcsname\??bodyfontalias#1\endcsname{#2}%
2842   \fi}
2843
2844\fetchmodulecommand \showbodyfontstate \f!font_run
2845
2846%D Handy for manuals:
2847
2848%D The \type {\tochar} commmand takes a specification:
2849%D
2850%D \starttabulate[|l|l|l|]
2851%D \NC e \NC entity                   \NC e:eacute \NC \NR
2852%D \NC x \NC hexadecimal unicode      \NC x:013D   \NC \NR
2853%D \NC d \NC decimal unicode          \NC d:123    \NC \NR
2854%D \NC s \NC hexadecimal index (slot) \NC s:210D   \NC \NR
2855%D \NC i \NC decimal index            \NC i:456    \NC \NR
2856%D \NC n \NC name                     \NC n:eight  \NC \NR
2857%D \NC c \NC name                     \NC c:x      \NC \NR
2858%D \NC u \NC unicode descriptions     \NC u:dog    \NC \NR
2859%D \NC a \NC all (also descriptions)  \NC a:rewind \NC \NR
2860%D \stoptabulate
2861%D
2862%D This is an expandable command!
2863
2864\permanent\protected\def\fontchar       #character{\clf_fontchar{#character}}
2865\permanent\protected\def\fontcharbyindex    #index{\clf_fontcharbyindex#index\relax}
2866\permanent          \def\tochar    #specifications{\clf_tochar{#specifications}} % expanded (also used in edef)
2867
2868%D The next auxilliary macro is an alternative to \type {\fontname}.
2869
2870\permanent\def\purefontname#font{\clf_purefontname{\fontname#font}}
2871
2872%D \macros
2873%D   {switchstyleonly}
2874%D
2875%D For switching a style but keeping the alternative, there
2876%D is:
2877%D
2878%D \starttyping
2879%D {\bf text \switchstyleonly\ss text}
2880%D {\bf text \switchstyleonly[ss]text}
2881%D {\sl text \switchstyleonly[sansserif]text}
2882%D \stoptyping
2883
2884\permanent\protected\def\switchstyleonly
2885  {\doifelsenextoptionalcs\font_basics_switch_style_only_opt\font_basics_switch_style_only_arg}
2886
2887\def\font_basics_switch_style_only_arg#name% stupid version
2888  {\font_helpers_set_current_font_style{\csname\??fontshortstyle\checkedstrippedcsname#name\endcsname}%
2889   \expand\everybodyfont} % needed ?
2890
2891\def\font_basics_switch_style_only_opt[#name]% todo : check
2892  {\font_helpers_set_current_font_style{\csname\??fontshortstyle#name\endcsname}%
2893   \expand\everybodyfont} % needed ?
2894
2895%D \macros
2896%D   {definebodyfontswitch}
2897%D
2898%D \PLAIN\ \TEX\ defines some macro's like \type {\tenpoint} to switch to a specific
2899%D bodyfontsize. Just for the sake of compatibility we can define them like:
2900%D
2901%D \starttyping
2902%D \definebodyfontswitch [twelvepoint] [12pt]
2903%D \stoptyping
2904%D
2905%D We don't support language specific synonyms here.
2906
2907\permanent\tolerant\protected\def\definebodyfontswitch[#command]#spacer[#specification]% no longer a commalist (not useful)
2908  {\frozen\protected\defcsname#command\endcsname{\switchtobodyfont[#specification]}}%
2909
2910%D \macros
2911%D   {setsmallbodyfont,setmainbodyfont,setbigbodyfont}
2912%D
2913%D When we're typesetting at for instance 10pt, we can call for the \type {small} as
2914%D well as the \type {big} alternative, related to this main size, using \type
2915%D {\switchtobodyfont[small]}. The three alternatives can be activated by the next
2916%D three system calls and are defined by the bodyfontenvironment.
2917
2918\newmacro\m_font_step
2919
2920\def\font_helpers_set_bodyfont_step#step%
2921  {\edef\m_font_step{\font_bodyfontvariable{#step}}% not always \cs
2922   \font_basics_switch_points\m_font_step
2923   \font_basics_switch_style \fontstyle}
2924
2925\permanent\protected\def\setsmallbodyfont{\font_helpers_set_bodyfont_step\v!small\expand\everybodyfont}
2926\permanent\protected\def\setbigbodyfont  {\font_helpers_set_bodyfont_step\v!big  \expand\everybodyfont}
2927
2928\permanent\protected\def\setmainbodyfont
2929  {\font_basics_switch_points\normalizedbodyfontsize
2930   \font_basics_switch_style\fontstyle
2931   \expand\everybodyfont
2932   \expand\everyglobalbodyfont
2933   \saveinterlinespace}
2934
2935%D \macros
2936%D   {restoreglobalbodyfont}
2937%D
2938%D Users can set whatever font available while typesetting text. Pagenumbers,
2939%D footers, headers etc. however must be typeset in the main bodyfont and style of
2940%D the document. Returning to the global state can be done with the next macro:
2941%D
2942%D This macro has to be called when entering the pagebody handling routine as well
2943%D as the footnote insert routine. Users can access this feature |<|for instance
2944%D when one wants to typeset tables and alike in the main bodyfont and style while
2945%D the running text is temporary set to a smaller one|>| by saying \type
2946%D {\switchtobodyfont [global]}.
2947
2948\mutable\let\globalfontstyle\s!rm
2949
2950\permanent\protected\def\fullrestoreglobalbodyfont
2951  {\let\fontsize\defaultfontsize
2952   \let\fontbody\defaultfontbody
2953   \let\fontface\defaultfontface
2954   \currentxfontsize\zerocount
2955   \let\fontclass\globalfontclass
2956   \font_basics_switch_points\normalizedglobalbodyfontsize
2957   \font_basics_switch_style\globalfontstyle
2958   \redoconvertfont % just in case a pagebreak occurs
2959   \tf
2960   \expand\everybodyfont
2961   \expand\everyglobalbodyfont
2962   \saveinterlinespace}
2963
2964\permanent\protected\def\partialrestoreglobalbodyfont
2965  {\let\fontsize\defaultfontsize
2966   \let\fontbody\defaultfontbody
2967   \let\fontface\defaultfontface
2968   \currentxfontsize\zerocount
2969   \redoconvertfont
2970   \tf
2971   \expand\everybodyfont % indeed needed
2972   \expand\everyglobalbodyfont % indeed needed
2973   \saveinterlinespace}
2974
2975\permanent\protected\def\restoreglobalbodyfont % ook style etc
2976  {\ifx\fontclass\globalfontclass
2977     \ifx\fontstyle\globalfontstyle
2978       \ifx\normalizedbodyfontsize\normalizedglobalbodyfontsize
2979         \partialrestoreglobalbodyfont
2980       \else
2981         \fullrestoreglobalbodyfont
2982       \fi
2983     \else
2984       \fullrestoreglobalbodyfont
2985     \fi
2986   \else
2987     \fullrestoreglobalbodyfont
2988   \fi}
2989
2990% in case of troubles: \let\restorebodyfont\fullrestoreglobalbodyfont
2991
2992%D Here are some fast variants that can be used in cases where no font system is
2993%D needed and where fonts are frozen:
2994%D
2995%D \starttyping
2996%D \definefont   [TestA][Serif at 10pt]
2997%D \predefinefont[TestB][Serif at 20pt]
2998%D
2999%D \testfeatureonce{1000}{{\TestA}}                         %   .312
3000%D \testfeatureonce{1000}{{\TestB}}                         % < .016
3001%D \testfeatureonce{1000}{{\definedfont[Serif at 30pt]}}    %   .312
3002%D \testfeatureonce{1000}{{\predefinedfont[Serif at 40pt]}} % < .016
3003%D \stoptyping
3004
3005\installcorenamespace{predefinedfont}
3006
3007\permanent\protected\def\predefinefont[#1]#*[#2]% global !
3008  {\protected\gdefcsname#1\endcsname{\font_basics_predefine{#1}{#2}}}
3009
3010\permanent\protected\def\predefinedfont[#1]% global !
3011  {\ifcsname\??predefinedfont#1\endcsname
3012     \lastnamedcs
3013   \else
3014     \font_basics_predefined{#1}%
3015   \fi}
3016
3017\protected\def\font_basics_predefine#1#2%
3018  {\definedfont[#2]%
3019   \gletcsname#1\expandafter\endcsname\csname\v_font_identifier_basic\endcsname}
3020
3021\protected\def\font_basics_predefined#1%
3022  {\font_basics_predefine{\??predefinedfont#1}{#1}}
3023
3024% %D Handy helper:
3025%
3026% % not used and also not okay wrt scales
3027%
3028% \permanent\protected\def\savedefinedfont[#1]% hm, how about scales
3029%   {\bgroup
3030%    \definedfont[#1]%
3031%    \xdef\saveddefinedfontid  {\the\fontid\font}%
3032%    \xdef\saveddefinedfontname{\fontname\font}%
3033%    \egroup}
3034%
3035% \mutable\def\saveddefinedfontid  {\the\fontid\font}
3036% \mutable\def\saveddefinedfontname{\fontname\font}
3037
3038%D Ugly helper:
3039
3040% we can use a \fontspecdef as container
3041
3042\permanent\protected\def\saverunningstyleandcolor
3043  {\enforced\permanent\protected\edef\restorerunningstyleandcolor
3044     {\setfontid          \the\fontid\font
3045      \glyphscale         \the\glyphscale
3046      \glyphxscale        \the\glyphxscale
3047      \glyphyscale        \the\glyphyscale
3048      \glyphslant         \the\glyphslant
3049      \glyphweight        \the\glyphweight
3050      \c_attr_colormodel  \the\c_attr_colormodel
3051      \c_attr_color       \the\c_attr_color
3052      \c_attr_transparency\the\c_attr_transparency
3053      \relax}}
3054
3055\aliased\let\restorerunningstyleandcolor\relax
3056
3057%D Handy for defining additional glyphs:
3058
3059% todo: public implementors
3060
3061\aliased\let\getprivateglyphslot\clf_getprivateglyphslot % kind of private macro
3062
3063\aliased\let\getprivatechar     \clf_getprivatechar     % gives back a utf !
3064\aliased\let\getprivatemathchar \clf_getprivatemathchar % gives back a utf !
3065\aliased\let\getprivateslot     \clf_getprivateslot     % companion to fonts.helpers.addprivate
3066
3067% \protected\def\getprivatemathchar#1%
3068%   {\begingroup\the\textfont\zerocount\getprivatechar{#1}\endgroup}
3069
3070\permanent\protected\def\privatechar % the text variant gets expanded to utf
3071  {\ifmmode
3072     \expandafter\getprivatemathchar
3073   \else
3074     \expandafter\getprivatechar
3075   \fi}
3076
3077%D Some fonts can have color specifiers:
3078%D
3079%D \starttyping
3080%D \definefontfeature[seguiemj-cl][default][colr=yes,ccmp=yes,dist=yes]
3081%D \definefontsynonym[emoji][seguiemj*seguiemj-cl]
3082%D
3083%D \definecolor[emoji-red] [r=.4]
3084%D \definecolor[emoji-gray][s=1,t=.5,a=1]
3085%D
3086%D %definefontcolorpalette [emoji-r] [emoji-red,emoji-gray,textcolor] % bad
3087%D \definefontcolorpalette [emoji-r] [emoji-red,emoji-gray]           % okay
3088%D
3089%D \definefontfeature[seguiemj-r][ccmp=yes,dist=yes,colr=emoji-r]
3090%D
3091%D \definefont[MyEmojiR][seguiemj*seguiemj-r @ 100pt]
3092%D
3093%D \startTEXpage[offset=10pt]
3094%D     \MyEmojiR\resolvedemoji{triangular ruler}
3095%D \stopTEXpage
3096%D \stoptyping
3097
3098\permanent\tolerant\protected\def\definefontcolorpalette[#1]#*[#2]%
3099  {\clf_definefontcolorpalette{#1}{#2}}
3100
3101%D \macros
3102%D   {addfontpath}
3103%D
3104%D A way to add a path at runtime (no need to generate database):
3105
3106\permanent\protected\def\usefontpath[#1]%
3107  {\clf_addfontpath{#1}}
3108
3109%D Experiment (one can use a list):
3110%D
3111%D \starttyping
3112%D \setupfonts
3113%D   [serif=dejavuserif*default,
3114%D     sans=dejavusans*default,
3115%D     mono=dejavusansmono*none]
3116%D
3117%D {\rm A \char1234\ B \char1236\ C}
3118%D {\ss A \char1234\ B \char1236\ C}
3119%D {\ss A \char1234\ B \char1236\ C}
3120%D \stoptyping
3121
3122\appendtoks
3123    \edef\m_list{\fontsparameter\s!serif}%
3124    \ifempty\m_list\else
3125        \registerfallbackfont[\s!serif][\m_list]%
3126    \fi
3127    \edef\m_list{\fontsparameter\s!sans}%
3128    \ifempty\m_list\else
3129        \registerfallbackfont[\s!sans][\m_list]%
3130    \fi
3131    \edef\m_list{\fontsparameter\s!mono}%
3132    \ifempty\m_list\else
3133        \registerfallbackfont[\s!mono][\m_list]%
3134    \fi
3135\to \everysetupfonts
3136
3137%D Handy for testing environments. Options determine position and shift: \typ {[-]},
3138%D \typ {[.4]}, \typ {[-.4]}, etc.
3139
3140\definecolor[currentfont] [darkgray]
3141
3142\permanent\tolerant\protected\def\showcurrentfont[#1]%
3143  {\dontleavehmode\bgroup\setbox\scratchbox\hpack\bgroup
3144    \startcolor[currentfont]%
3145    \scratchdimen #1\exheight
3146    \ifdim\scratchdimen<\zeropoint
3147      \scratchheight\strutht
3148      \scratchdepth \strutdp % \dimexpr\strutdp-\scratchdimen\relax
3149    \else
3150      \scratchheight\strutht % \dimexpr\strutht+0\scratchdimen\relax
3151      \scratchdepth \strutdp
3152    \fi
3153    \virtualvrule
3154      \s!height \scratchheight
3155      \s!depth  \scratchdepth
3156      \s!width .5\onepoint
3157    \relax
3158    \ifdim\scratchdimen>\zeropoint
3159      \raise{\strutht+\scratchdimen-1.5\exheight}%
3160    \else
3161      \lower{\strutdp-\scratchdimen-1.5\exheight}%
3162    \fi
3163    \hpack to \zeropoint \bgroup\normalexpanded{%
3164      \tinyinfofont
3165      \hpack to \zeropoint\bgroup
3166        \hss
3167        \iftok{\fontspecifiedname\font}{\fontname\font}\else
3168          (\fontspecifiedname\font)%
3169        \fi
3170        (\fontname\font)%
3171        \kern.5\onepoint
3172      \egroup
3173      \kern\onepoint
3174      (%
3175      \ifempty\fontclass.\else\fontclass\fi,%
3176      \ifempty\fontstyle.\else\fontstyle\fi,%
3177      \fontbody%
3178      )%
3179      (%
3180      \ifnum\glyphscale =\plusthousand .\else\the\glyphscale \fi,%
3181      \ifnum\glyphxscale=\plusthousand .\else\the\glyphxscale\fi,%
3182      \ifnum\glyphyscale=\plusthousand .\else\the\glyphyscale\fi
3183      )%
3184      (%
3185      \ifnum\glyphslant =\zerocount .\else\the\glyphslant \fi,%
3186      \ifnum\glyphweight=\zerocount .\else\the\glyphweight\fi
3187      )%
3188      (\toscaled\xtextface,\toscaled\xxtextface)\hss
3189    }%
3190    \egroup
3191    \stopcolor
3192  \egroup
3193  \smashbox\scratchbox
3194  \box\scratchbox
3195  \egroup}
3196
3197\protect \endinput
3198