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