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