summaryrefslogtreecommitdiff
path: root/tex/context/base/mkiv/font-ini.mkvi
diff options
context:
space:
mode:
Diffstat (limited to 'tex/context/base/mkiv/font-ini.mkvi')
-rw-r--r--tex/context/base/mkiv/font-ini.mkvi2582
1 files changed, 2582 insertions, 0 deletions
diff --git a/tex/context/base/mkiv/font-ini.mkvi b/tex/context/base/mkiv/font-ini.mkvi
new file mode 100644
index 000000000..ee146c1a5
--- /dev/null
+++ b/tex/context/base/mkiv/font-ini.mkvi
@@ -0,0 +1,2582 @@
+%D \module
+%D [ file=font-ini,
+%D version=1998.09.11, % (second)
+%D version=2001.02.20, % (third)
+%D title=\CONTEXT\ Font Macros,
+%D subtitle=Initialization,
+%D author=Hans Hagen,
+%D date=\currentdate,
+%D copyright={PRAGMA ADE \& \CONTEXT\ Development Team}]
+%C
+%C This module is part of the \CONTEXT\ macro||package and is
+%C therefore copyrighted by \PRAGMA. See mreadme.pdf for
+%C details.
+
+% todo: < 3 pt => 3pt
+% todo: check where more class usage
+% todo: split font-nam (style/alternative/size)
+% todo: split font-dim (scales etc)
+% todo: reconsider defaultfontclass
+%
+
+%D Watch out: as we define inside macros in sometimes special ways,
+%D an occasional \type {\normaldef} is used in order to please the
+%D \MKVI\ parser.
+
+%D Beware, we use a special set of parameters here:
+%D
+%D \starttabulate[|l|l|]
+%D \NC system variable (fixed) \NC \type {\s!text} \NC \NR
+%D \NC system variable (fixed) \NC \type {\s!script} \NC \NR
+%D \NC system variable (fixed) \NC \type {\s!scriptscript} \NC \NR
+%D \NC system variable (fixed) \NC \type {\s!x} \NC \NR
+%D \NC system variable (fixed) \NC \type {\s!xx} \NC \NR
+%D \NC variable (value) \NC \type {\v!big} \NC \NR
+%D \NC variable (value) \NC \type {\v!small} \NC \NR
+%D \NC constant (regular key) \NC \type {\c!interlinespace} \NC \NR
+%D \NC constant (regular key) \NC \type {\c!em} \NC \NR
+%D \stoptabulate
+%D
+%D The math related ones are similar to the ones used in \TEX\ itself,
+%D the size related ones show up as keywords in the user interface
+%D when switching sizes, and the two constants are used in key|/|value
+%D situations.
+
+%D We should consider design sizes ... maybe kick 'm out which removes
+%D the size code and simplifies things considerably. After all, there
+%D will be no latin modern math in sizes.
+
+\writestatus{loading}{ConTeXt Font Macros / Initialization}
+
+%D Documentation is somewhat messy as it contains bits and pieces of
+%D previous versions.
+
+\unprotect
+
+%D There are several ways to specify a font. Three of them are
+%D pure \TeX\ ones, the fourth one is new:
+%D
+%D \starttyping
+%D \font\name=cmr12
+%D \font\name=cmr12 at 10pt
+%D \font\name=cmr12 scaled 2
+%D \font\name=cmr12 sa 1.440
+%D \stoptyping
+%D
+%D The non||\TEX\ alternative \type{sa} stands for {\em scaled
+%D at}. This means as much as: scale the bodyfontsize with this
+%D factor. The scaled option is not that useful as one needs to
+%D know the design size.
+%D
+%D Because \type {sa} (scaled at) and \type {mo} (mapped on)
+%D are not low level \TEX\ supported alternatives, we have to
+%D test for it ourselves. In doing so, we need an auxiliary
+%D \DIMENSION. We cannot use \type{\scratchdimen} because font
+%D loading can happen at any moment due to postponed loading.
+%D We could instead have used dirty grouping tricks, but this
+%D one works too.
+
+% \enableexperiments[fonts.autorscale]
+%
+% \starttypescript[mscore]
+% \definetypeface [mscore] [rm] [serif] [mscoretimes] [default]
+% \definetypeface [mscore] [ss] [sans] [mscorearial] [default] [rscale=auto] % 0.860]
+% \definetypeface [mscore] [tt] [mono] [mscorecourier] [default] [rscale=auto] % 1.065]
+% \definetypeface [mscore] [mm] [math] [times] [default] [rscale=auto] % 1.020]
+% \stoptypescript
+%
+% \starttext
+% \setupbodyfont[mscore,12pt]
+% \startTEXpage
+% test \ss test \tt test
+% \stopTEXpage
+% \stoptext
+
+% \definetypeface[one][rm][serif][computer-roman][default]
+% \definetypeface[two][rm][serif][computer-roman][default][rscale=.9]
+%
+% {\one \bf test \two test}
+% {\one \bf test \pushcurrentfont \two \popcurrentfont test}
+
+%D \macros
+%D {rm,ss,tt,hw,cg}
+%D
+%D Fonts are defined in separate files. When we define a font,
+%D we distinguish between several styles. In most cases we will
+%D use:
+%D
+%D \startlinecorrection
+%D \starttable[|l||]
+%D \HL
+%D \NC roman regular serif \NC \type{\rm} \NC\FR
+%D \NC sansserif sans support \NC \type{\ss} \NC\MR
+%D \NC type teletype mono \NC \type{\tt} \NC\LR
+%D \HL
+%D \stoptable
+%D \stoplinecorrection
+%D
+%D The number of styles is not limited to these three. When
+%D using Lucida Bright we can for instance also define:
+%D
+%D \startlinecorrection
+%D \starttable[|l||]
+%D \HL
+%D \NC handwritten \NC \type{\hw} \NC\FR
+%D \NC calligraphic \NC \type{\cg} \NC\LR
+%D \HL
+%D \stoptable
+%D \stoplinecorrection
+%D
+%D Within such a font set (\type{cmr}) and style (\type{\rm})
+%D we can define a number of text font alternatives:
+%D
+%D \startlinecorrection
+%D \starttable[|l||]
+%D \HL
+%D \NC typeface \NC \type{\tf} \NC\FR
+%D \NC boldface \NC \type{\bf} \NC\MR
+%D \NC slanted \NC \type{\sl} \NC\MR
+%D \NC italic \NC \type{\it} \NC\MR
+%D \NC boldslanted \NC \type{\bs} \NC\MR
+%D \NC bolditalic \NC \type{\bi} \NC\MR
+%D \NC smallcaps \NC \type{\sc} \NC\LR
+%D \HL
+%D \stoptable
+%D \stoplinecorrection
+%D
+%D Internally fonts are stored as combination of size, style
+%D and alternative, e.g. \type{12pt}+\type{\ss}+\type{\bf}.
+%D Users are not confronted with sizes, but use the style or
+%D style+alternative to activate them.
+%D
+%D During the definition of a bodyfont one can also declare the
+%D available larger alternatives:
+%D
+%D \starttyping
+%D \tf \tfa \tfb \tfc ...
+%D \bf \bfa \bfb \bfc ...
+%D \sl \sla \slb \slc ...
+%D \stoptyping
+%D
+%D The smaller ones are automatically supplied and derived from
+%D the the bodyfont environment.
+%D
+%D \starttyping
+%D \tfx \tfxx
+%D \bfx \bfxx
+%D \slx \slxx
+%D \stoptyping
+%D
+%D There are only two smaller alternatives per style. The
+%D larger alternatives on the other hand have no limitations.
+%D
+%D These larger alternatives are mostly used in chapter and
+%D section titles or on title pages. When one switches to a
+%D larger alternative, the bold an other ones automatically
+%D adapt themselves:
+%D
+%D \startbuffer
+%D \tfd Hi \bf there\sl, here \tfb I \bf am
+%D \stopbuffer
+%D
+%S \startnarrower
+%D \typebuffer
+%S \stopnarrower
+%D
+%D therefore becomes:
+%D
+%D \startexample
+%D \getbuffer
+%D \stopexample
+%D
+%D Maybe this mechanism isn't always as logic, but as said
+%D before, we tried to make it as intuitive as possible.
+%D
+%D So a specific kind of glyph can be characterized by:
+%D
+%D \startnarrower
+%D family (cmr) + bodyfont (12pt) + style (rm) + alternative (bf) + size (a)
+%D \stopnarrower
+%D
+%D The last component (the size) is optional.
+%D
+%D We introduced \type{\tf} as command to call for the current
+%D normally sized typeface. This commands results in roman,
+%D sans serif, teletype or whatever style is in charge. Such
+%D rather massive switches of style sometimes take more
+%D processing time than comfortable. Of course there is a
+%D workaround for this: we can call fonts directly by means of
+%D commands like:
+%D
+%D \starttyping
+%D \rmtf \sssl \tttf \rmbsa
+%D \stoptyping
+%D
+%D One should realize that this fast calls have limitations,
+%D they lack for instance automatic super- and subscript
+%D support.
+%D
+%D This leaves us two more commands: \type{\tx} and
+%D \type{\txx}. These activate a smaller and even more smaller
+%D font than the current one and adapt themselves to the
+%D current alternative, so when \type{\bf} is active,
+%D \type{\tx} gives a smaller boldface, which in turn can be
+%D called directly by \type{\bfx}.
+%D
+%D These two smaller alternatives are specified by the bodyfont
+%D environment and therefore not necessarily have similar sizes
+%D as \type{\scriptsize} and \type{\scriptscriptsize}. The main
+%D reason for this incompatibility (which can easily be undone)
+%D lays in the fact that we often want a bit bigger characters
+%D than in math mode. In \CONTEXT\ for instance the \type{\tx}
+%D and \type{\txx} commands are used for surrogate
+%D \cap{smallcaps} which support both nesting and alternatives,
+%D like in {\bf\cap{a \cap{small} world}}, which was typeset by
+%D
+%D \starttyping
+%D \bf\cap{a \cap{small} world}
+%D \stoptyping
+%D
+%D And compare $\rm \scriptstyle THIS$ with the slightly larger
+%D \cap{THIS}: \ruledhbox{$\rm \scriptstyle scriptstyle: THIS$}
+%D or \ruledhbox{\cap{x style: THIS}} makes a big difference.
+%D
+%D The \type{x..d} sizes should be used grouped. If you
+%D don't group them, i.e. call them in a row, \CONTEXT\ will
+%D not be able to sort out your intention (\type {x} inside
+%D \type {d} inside \type {x}. etc.). The following table
+%D demonstrates this:
+%D
+%D \def\FontState{\setstrut\ruledhbox{\strut Hello}}
+%D
+%D \starttabulate[|||||]
+%D \HL
+%D \NC \rlap{\quad\bf grouped} \NC \NC \type {\tx} \NC \type {\txx} \NC \NR
+%D \HL
+%D \NC \type{\tfx} \NC \tfx \FontState \NC \tfx \tx \FontState \NC \tfx \txx \FontState \NC \NR
+%D \NC \type{\tfxx} \NC \tfxx \FontState \NC \tfxx\tx \FontState \NC \tfxx\txx \FontState \NC \NR
+%D \NC \type{\tf} \NC \tf \FontState \NC \tf \tx \FontState \NC \tf \txx \FontState \NC \NR
+%D \NC \type{\tfa} \NC \tfa \FontState \NC \tfa \tx \FontState \NC \tfa \txx \FontState \NC \NR
+%D \NC \type{\tfb} \NC \tfb \FontState \NC \tfb \tx \FontState \NC \tfb \txx \FontState \NC \NR
+%D \NC \type{\tfc} \NC \tfc \FontState \NC \tfc \tx \FontState \NC \tfc \txx \FontState \NC \NR
+%D \NC \type{\tfd} \NC \tfd \FontState \NC \tfd \tx \FontState \NC \tfd \txx \FontState \NC \NR
+%D \NC \type{\tfx} \NC \tfx \FontState \NC \tfx \tx \FontState \NC \tfx \txx \FontState \NC \NR
+%D \NC \type{\tfxx} \NC \tfxx \FontState \NC \tfxx\tx \FontState \NC \tfxx\txx \FontState \NC \NR
+%D \HL
+%D \stoptabulate
+%D
+%D \blank
+%D
+%D \starttabulate[|||||]
+%D \HL
+%D \NC \rlap{\quad\bf stacked} \NC \NC \type {\tx} \NC \type {\txx} \NC \NR
+%D \HL
+%D \NC \type{\tfx}
+%D \NC \tfx \FontState
+%D \NC \tfx \tx \FontState
+%D \NC \tfx \txx \FontState
+%D \NC \NR
+%D \NC \type{\tfxx}
+%D \NC \tfx\tfxx \FontState
+%D \NC \tfx\tfxx \tx \FontState
+%D \NC \tfx\tfxx \txx \FontState
+%D \NC \NR
+%D \NC \type{\tf}
+%D \NC \tfx\tfxx\tf \FontState
+%D \NC \tfx\tfxx\tf \tx \FontState
+%D \NC \tfx\tfxx\tf \txx \FontState
+%D \NC \NR
+%D \NC \type{\tfa}
+%D \NC \tfx\tfxx\tf\tfa \FontState
+%D \NC \tfx\tfxx\tf\tfa \tx \FontState
+%D \NC \tfx\tfxx\tf\tfa \txx \FontState
+%D \NC \NR
+%D \NC \type{\tfb}
+%D \NC \tfx\tfxx\tf\tfa\tfb \FontState
+%D \NC \tfx\tfxx\tf\tfa\tfb \tx \FontState
+%D \NC \tfx\tfxx\tf\tfa\tfb \txx \FontState
+%D \NC \NR
+%D \NC \type{\tfc}
+%D \NC \tfx\tfxx\tf\tfa\tfb\tfc \FontState
+%D \NC \tfx\tfxx\tf\tfa\tfb\tfc \tx \FontState
+%D \NC \tfx\tfxx\tf\tfa\tfb\tfc \txx \FontState
+%D \NC \NR
+%D \NC \type{\tfd}
+%D \NC \tfx\tfxx\tf\tfa\tfb\tfd \FontState
+%D \NC \tfx\tfxx\tf\tfa\tfb\tfd \tx \FontState
+%D \NC \tfx\tfxx\tf\tfa\tfb\tfd \txx \FontState
+%D \NC \NR
+%D \NC \type{\tfx}
+%D \NC \tfx\tfxx\tf\tfa\tfb\tfc\tfx \FontState
+%D \NC \tfx\tfxx\tf\tfa\tfb\tfc\tfx \tx \FontState
+%D \NC \tfx\tfxx\tf\tfa\tfb\tfc\tfx \txx \FontState
+%D \NC \NR
+%D \NC \type{\tfxx}
+%D \NC \tfx\tfxx\tf\tfa\tfb\tfc\tfx\tfxx \FontState
+%D \NC \tfx\tfxx\tf\tfa\tfb\tfc\tfx\tfxx \tx \FontState
+%D \NC \tfx\tfxx\tf\tfa\tfb\tfc\tfx\tfxx \txx \FontState
+%D \NC \NR
+%D \HL
+%D \stoptabulate
+
+\fontslantperpoint \nullfont 0\scaledpoint
+\fontinterwordspace \nullfont 256377\scaledpoint
+\fontinterwordstretch\nullfont 128188\scaledpoint
+\fontinterwordshrink \nullfont 85459\scaledpoint
+\fontexheight \nullfont 338952\scaledpoint
+\fontemwidth \nullfont 786432\scaledpoint
+\fontextraspace \nullfont 85459\scaledpoint
+
+%D Tracing
+
+\newtoks\t_font_tracers_definitions
+
+\unexpanded\def\tracefontdefinitions
+ {\the\t_font_tracers_definitions}
+
+%D Some housekeeping macros:
+
+\unexpanded\def\setfontparameters
+ {\setfalse\c_font_synchronize
+ \the\everybodyfont
+ \settrue\c_font_synchronize}
+
+\unexpanded\def\savefont
+ {\edef\savedfont{\the\font}% gives \csname
+ \pushmacro\savedfont}
+
+\unexpanded\def\restorefont
+ {\popmacro\savedfont
+ \savedfont}
+
+\unexpanded\def\pushcurrentfont
+ {\edef\popcurrentfont
+ {\def\noexpand\fontbody {\fontbody}%
+ \def\noexpand\fontstyle {\fontstyle}%
+ \def\noexpand\fontalternative{\fontalternative}%
+ \def\noexpand\fontsize {\fontsize}%
+ \font_helpers_check_big_math_synchronization
+ \font_helpers_synchronize_font}}
+
+%D \macros{definedfont}
+
+\let\thedefinedfont\relax % not to be confused with \everydefinefont
+
+\unexpanded\def\definedfont
+ {\doifelsenextoptionalcs\font_basics_defined_font_yes\font_basics_defined_font_nop}
+
+\def\font_basics_defined_font_yes[#specification]%
+ {\c_font_feature_inheritance_mode\c_font_feature_inheritance_fontonly
+ \font_basics_define_font_without_parameters{thedefinedfont}{#specification}%
+ \thedefinedfont
+ \the\everydefinedfont}
+
+\def\font_basics_defined_font_nop
+ {\c_font_feature_inheritance_mode\c_font_feature_inheritance_fontonly
+ \thedefinedfont
+ \the\everydefinedfont}
+
+%D \macros{startfont}
+
+\unexpanded\def\startfont{\begingroup\definedfont}
+\unexpanded\def\stopfont {\endgroup}
+
+%D \macros
+%D {everybodyfont,everyglobalbodyfont}
+%D
+%D Every change in bodyfont size has conseqences for the baseline
+%D distance and skips between paragraphs. These are initialized
+%D in other modules. Here we only provide the hooks that
+%D garantees their handling.
+%D
+%D At the system level one can initialize thing like:
+%D
+%D \starttyping
+%D \appendtoks \setupspacing \to \everybodyfont
+%D \stoptyping
+
+%D \macros
+%D {globalbodyfontsize,localbodyfontsize,bodyfontsize}
+
+%D Here we have to distinguish between the global (overal) bodyfont
+%D size and the local (sometimes in the textflow) size. We store
+%D these dimensions in two \DIMENSION\ registers. These registers are
+%D not to be misused in calculations.
+
+\ifdefined\globalbodyfontsize\else \newdimen\globalbodyfontsize \fi \globalbodyfontsize=12pt
+\ifdefined\localbodyfontsize \else \newdimen\localbodyfontsize \fi \localbodyfontsize =\globalbodyfontsize
+\ifdefined\bodyfontsize \else \newdimen\bodyfontsize \fi \bodyfontsize =\globalbodyfontsize
+
+%D When we assign for instance 12pt to a \DIMENSION\ register the \type
+%D {\the}'d value comes out as 12.0pt, which is often not the way users
+%D specify the bodyfont size. Therefore we use normalized values. They
+%D are cached to save overhead in \LUA\ calls.
+
+% \setnewconstant\fontdigits\plustwo % from now on always 2
+
+\installcorenamespace{fontnormalizedbody}
+
+% \def\normalizebodyfontsize#macro#body%
+% {\expandafter\let\expandafter#macro\csname\??fontnormalizedbody\number\fontdigits:\number\dimexpr#body\endcsname
+% \ifx#macro\relax
+% \normalizebodyfontsize_indeed#macro{#body}%
+% \fi}
+%
+% \def\normalizebodyfontsize_indeed#macro#body%
+% {\edef#macro{\ctxcommand{nbfs(\number\dimexpr#body,\number\fontdigits)}}%
+% \global\expandafter\let\csname\??fontnormalizedbody\number\fontdigits:\number\dimexpr#body\endcsname#macro}
+%
+% \def\thenormalizedbodyfontsize#body%
+% {\ctxcommand{nbfs(\number\dimexpr#body\relax,\number\fontdigits)}}
+%
+% caching is less relevant now
+
+\def\normalizebodyfontsize#macro#body%
+ {\expandafter\let\expandafter#macro\csname\??fontnormalizedbody\number\dimexpr#body\endcsname
+ \ifx#macro\relax
+ \normalizebodyfontsize_indeed#macro{#body}%
+ \fi}
+
+\def\normalizebodyfontsize_indeed#macro#body%
+ {\edef#macro{\clf_nbfs\dimexpr#body\relax}%
+ \global\expandafter\let\csname\??fontnormalizedbody\number\dimexpr#body\endcsname#macro}
+
+\def\thenormalizedbodyfontsize#body%
+ {\clf_nbfs\dimexpr#body\relax}
+
+\edef\normalizedglobalbodyfontsize{\thenormalizedbodyfontsize\bodyfontsize}
+\edef\normalizedlocalbodyfontsize {\thenormalizedbodyfontsize\bodyfontsize}
+\edef\normalizedbodyfontsize {\thenormalizedbodyfontsize\bodyfontsize}
+
+%D \macros
+%D {mapfontsize}
+%D
+%D For special purposes, like in math, you may want to use
+%D slightly different sizes than the ones given. This happens
+%D for instance with the Math Times fonts. Mapped font sizes
+%D can be specified by using the \type {mo} key instead of
+%D \type {sa} in font definitions.
+%D
+%D \startbuffer
+%D \mapfontsize[10pt][11pt]
+%D \mapfontsize[11pt][12pt]
+%D \mapfontsize[12pt][13pt]
+%D
+%D \definefont[test][Serif]\test TEST \par
+%D \definefont[test][Serif sa 5]\test TEST \par
+%D \definefont[test][Serif mo 5]\test TEST \par
+%D \definefont[test][Serif sa d]\test TEST \par
+%D \definefont[test][Serif at 60pt]\test TEST \par
+%D \definefont[test][Serif scaled 6000]\test TEST \par
+%D \stopbuffer
+%D
+%D \typebuffer
+%D
+%D \startpacked
+%D \getbuffer
+%D \stoppacked
+
+\installcorenamespace{mappedfontsize}
+
+\unexpanded\def\mapfontsize
+ {\dodoubleargument\font_basics_map_fontsize}
+
+\def\font_basics_map_fontsize[#from][#to]%
+ {\setvalue{\??mappedfontsize\the\dimexpr#from\relax}{#to}}
+
+\def\font_basics_set_mapped_fontsize#from%
+ {\ifcsname\??mappedfontsize\the\dimexpr#from\relax\endcsname
+ \lastnamedcs\else#from%
+ \fi}
+
+\installcorenamespace{fontbodyknown}
+\installcorenamespace{fontclassyes} % fontclass
+\installcorenamespace{fontclassnop} % nofontclass
+
+\def\font_helpers_process_relative_size_list#command% could be a toks
+ {#command\v!big
+ #command\v!small}
+
+\let\v_font_size_relative \plusone
+\def\v_font_size_absolute {\fontbody}
+
+\let\v_font_rscale_default\!!plusone
+\let\p_font_rscale \v_font_rscale_default
+
+\def\font_helpers_check_relative_font_id % can be plugged in later
+ {\let\p_font_rscale\minusone
+ \let\p_font_rscale\v_font_rscale_default}
+
+\def\font_helpers_check_relative_font_size#style%
+ {\edef\p_font_rscale
+ {\ifcsname\??fontclass\fontclass#style\s!rscale\endcsname
+ \lastnamedcs
+ \else\ifcsname\??fontclass\defaultfontclass#style\s!rscale\endcsname % brr
+ \lastnamedcs
+ \else
+ \v_font_rscale_default
+ \fi\fi}%
+ % move elsewhere
+ \ifx\p_font_rscale\v!auto
+ \let\p_font_rscale\plusone
+ \font_helpers_check_relative_font_id
+ \else
+ \let\relativefontid\minusone
+ \fi}
+
+\def\font_rscale_xx#style%
+ {\ifcsname\??fontclass\fontclass#style\s!rscale\endcsname
+ \lastnamedcs
+ \else
+ \v_font_rscale_default
+ \fi}
+
+\def\font_rscale_mm
+ {\ifcsname\??fontclass\fontclass\s!mm\s!rscale\endcsname
+ \lastnamedcs
+ \else
+ \v_font_rscale_default
+ \fi}
+
+\def\font_helpers_register_fontbody#body%
+ {\expandafter\let\csname\??fontbodyknown#body\endcsname\empty}
+
+%D \macros
+%D {definefontstyle,definefontsize,definefontalternative}
+%D
+%D When setting of switching the overall style we can use the
+%D short identifier like rm and ss, but when defined we can
+%D also use more verbose names like roman or sansserif. Such
+%D names are defined by:
+%D
+%D \starttyping
+%D \definefontstyle [serif,rm] [rm]
+%D \definefontstyle [sansserif,ss] [ss]
+%D \stoptyping
+
+\installcorenamespace{fontstyle} % full style prefix (roman etc)
+\installcorenamespace{fontshortstyle} % short style prefix (rm etc)
+
+\installcorenamespace{fontstyleknown}
+\installcorenamespace{fontalternativeknown}
+\installcorenamespace{fontsizeknown}
+
+\newtoks\t_font_style_commands
+\newtoks\t_font_size_commands
+\newtoks\t_font_alternative_commands
+
+\setnewmacro\m_font_style_command \gobbleoneargument
+\setnewmacro\m_font_size_command \gobbleoneargument
+\setnewmacro\m_font_alternative_command\gobbleoneargument
+
+\def\font_helpers_process_style_list #command{\def\m_font_style_command {#command}\the\t_font_style_commands}
+\def\font_helpers_process_size_list #command{\def\m_font_size_command {#command}\the\t_font_size_commands}
+\def\font_helpers_process_alternative_list#command{\def\m_font_alternative_command{#command}\the\t_font_alternative_commands}
+
+\def\font_helpers_register_style #style{\expandafter\let\csname\??fontstyleknown #style\endcsname\empty}
+\def\font_helpers_register_size #size{\expandafter\let\csname\??fontsizeknown #size\endcsname\empty}
+\def\font_helpers_register_alternative#alternative{\expandafter\let\csname\??fontalternativeknown#alternative\endcsname\empty}
+
+\unexpanded\def\definefontstyle
+ {\dodoubleargument\font_basics_define_fontstyle}
+
+\def\font_basics_define_fontstyle[#commands][#style]% style: rm ss tt ...
+ {\ifcsname\??fontstyleknown#style\endcsname \else % can be delayed till used (cg, hw)
+ \font_helpers_register_style{#style}%
+ % todo: apptoks
+ \t_font_style_commands\expandafter{\the\t_font_style_commands\m_font_style_command{#style}}%
+ \fi
+ \processcommalist[#commands]{\font_basics_define_fontstyle_indeed{#style}}}
+
+\def\font_basics_define_fontstyle_indeed#style#command%
+ {\setvalue{\??fontshortstyle#command}{#style}%
+ \setvalue{\??fontstyle #command}{\csname#style\endcsname}}
+
+\unexpanded\def\definefontsize[#size]%
+ {\ifcsname\??fontsizeknown#size\endcsname \else
+ \font_helpers_register_size{#size}%
+ \t_font_size_commands\expandafter{\the\t_font_size_commands
+ \m_font_size_command{#size}}%
+ \fi
+ \font_helpers_check_fontname_combinations}
+
+\unexpanded\def\definefontalternative[#alternative]%
+ {\ifcsname\??fontalternativeknown#alternative\endcsname \else
+ \font_helpers_register_alternative{#alternative}%
+ % todo: apptoks
+ \t_font_alternative_commands\expandafter{\the\t_font_alternative_commands
+ \m_font_alternative_command{#alternative}}%
+ \fi
+ \font_helpers_check_fontname_combinations}
+
+\unexpanded\def\font_helpers_check_fontname_combinations % we need to split math and text here ... todo (math only has mr and mb)
+ {\font_helpers_process_style_list\font_helpers_check_fontname_combinations_s}
+
+\def\font_helpers_check_fontname_combinations_s#style%
+ {\font_helpers_process_alternative_list{\font_helpers_check_fontname_combinations_indeed_s_a{#style}}}
+
+\def\font_helpers_check_fontname_combinations_indeed_s_a#style#alternative%
+ {\font_helpers_process_size_list{\font_basics_check_fontname_combination{#style}{#alternative}}}
+
+\definefontstyle [\s!mm] [\s!mm]
+\definefontstyle [\s!rm] [\s!rm]
+\definefontstyle [\s!ss] [\s!ss]
+\definefontstyle [\s!tt] [\s!tt]
+
+%D We define all the font switching commands globally. After all they are part
+%D of the formal font interface once defined. The size can be empty (so
+%D checking is needed as \type {\bf} is already defined)
+
+%D The \type {\normal..} variants are available as extras for cases where
+%D the \type {..} is overloaded.
+
+\newmacro\m_font_mm
+
+\def\font_basics_check_fontname_combination#style% alternative size
+ {\edef\m_font_mm{#style}%
+ \ifx\m_font_mm\s!mm % prevents \max and alike (re)defs
+ \expandafter\font_basics_check_math_bodyfont
+ \else
+ \expandafter\font_basics_check_text_bodyfont
+ \fi{#style}} % no \m_font_mm, not expanded later on
+
+% \def\font_basics_check_math_bodyfont#style#alternative#size%
+% {%setugvalue{#alternative}{\font_helpers_set_current_font_alternative{#alternative}}% \mr \mb
+% \setugvalue{#style}{\font_helpers_set_current_font_style{#style}}}% \mm
+
+\def\font_basics_check_math_bodyfont#style#alternative#size%
+ {}
+
+\def\font_basics_check_text_bodyfont#style#alternative#size% size can be empty (checking needed as \bf is already defined)
+ {\setugvalue{#style#size}{\font_helpers_set_current_font_style_size{#style}{#size}}% \rma
+ \setugvalue{#alternative#size}{\font_helpers_set_current_font_alternative_size{#alternative}{#size}}% \sla
+ \setugvalue{#style#alternative#size}{\font_helpers_set_current_font_style_alternative_size{#style}{#alternative}{#size}}% \rmsla
+ \ifcsname\s!normal#style\endcsname % text/math check
+ \expandafter\let\csname#style\expandafter\endcsname\csname\s!normal#style\endcsname
+ \else
+ \setugvalue{#style}{\font_helpers_set_current_font_style{#style}}% \rm
+ \fi
+ \ifcsname\s!normal#alternative\endcsname % text/math check
+ \expandafter\let\csname#alternative\expandafter\endcsname\csname\s!normal#alternative\endcsname
+ \else
+ \setugvalue{#alternative}{\font_helpers_set_current_font_alternative{#alternative}}% \sl
+ \fi
+ \setugvalue{#style\s!x}{\font_helpers_set_current_font_x_style_alternative{#style}}% \rmx
+ \setugvalue{#style\s!xx}{\font_helpers_set_current_font_xx_style_alternative{#style}}% \rmxx
+ \setugvalue{#alternative\s!x}{\font_helpers_set_current_font_x_alternative{#alternative}}% \slx
+ \setugvalue{#alternative\s!xx}{\font_helpers_set_current_font_xx_alternative{#alternative}}% \slxx
+ \setugvalue{#style#alternative}{\font_helpers_set_current_font_style_alternative{#style}{#alternative}}}% \rmsl
+
+%D Scaling macros:
+%D
+%D This system is somewhat complicated by two (possible conflicting)
+%D demands:
+%D
+%D \startitemize
+%D \item We support wildcards like \type {sa *} which will adapt
+%D to the current size. This is also the default specification.
+%D \item We support named scales like \type {sa d}; beware: \type
+%D {x} and \type {xx} are valid scales but they are not alway
+%D the same as the ones used in for instance \type {\bfx} because
+%D there the sized come from the bodyfont environment. In the
+%D future there maybe a switch that also honors the environment
+%D in named scales.
+%D \stopitemize
+%D
+%D Keep in mind that the smaller sizes are just for text super and
+%D subscripts while larger sizes can be used in titles where for
+%D instance math follows the size.
+
+% b:x{\definedfont[SerifBold sa b]x}{\bfb x $x^x$}\par
+% 1:x{\definedfont[SerifBold sa 1]x}{\bf x $x^x$}\par
+% x:x{\definedfont[SerifBold sa x]x}{\bfx x $x^x$}\par
+% xx:x{\definedfont[SerifBold sa xx]x}{\bfxx x $x^x$}\par
+%
+% *:x{\definedfont[Serif sa *]x}\par
+% 1:x{\definedfont[Serif sa 1]x}\par
+% 2:x{\definedfont[Serif sa 2]x}\par
+% 3:x{\definedfont[Serif sa 3]x}\par
+% 4:x{\definedfont[Serif sa 4]x}\par
+% 5:x{\definedfont[Serif sa 5]x}\par
+
+\def\safontscale{\number\dimexpr\v_font_size_absolute\relax}
+\def\mofontscale{\number\dimexpr\font_basics_set_mapped_fontsize\v_font_size_absolute\relax}
+
+\let\somefontname\s!unknown
+\let\somefontspec\s!unknown
+\let\somefontsize\zerocount
+
+\newcount\scaledfontmode % also used at the lua end
+\newcount\scaledfontsize % also used at the lua end
+\newcount\lastfontid % also used at the lua end / tex end
+\newtoks \everydefinefont
+
+\let\relativefontid\minusone % todo, not yet used
+
+\let\c_font_feature_inheritance_fontnone \zerocount % none
+\let\c_font_feature_inheritance_fontonly \plusone % fontonly
+\let\c_font_feature_inheritance_classonly \plustwo % classonly
+\let\c_font_feature_inheritance_fontfirst \plusthree % fontfirst
+\let\c_font_feature_inheritance_classfirst\plusfour % classfirst
+
+\let\c_font_feature_inheritance_default \c_font_feature_inheritance_fontfirst
+
+\setnewconstant\c_font_feature_inheritance_mode \c_font_feature_inheritance_default
+
+\newdimen \d_font_scaled_text_face
+\newdimen \d_font_scaled_font_size
+\newconditional\c_font_body_scale
+\newfraction \f_font_body_scale
+
+\unexpanded\def\font_helpers_low_level_define#specification#csname%
+ {% we can now set more at the lua end
+ \global\let\somefontname\defaultfontfile
+ \let\somefontsize\empty
+ \clf_definefont_one{\detokenize\expandafter{\normalexpanded{#specification}}}% the escapestring catches at \somedimen
+ % sets \scaledfontmode and \somefontname and \somefontsize
+ \ifcase\fontface\relax
+ % \let\v_font_size_absolute\textface % fontbody
+ \or
+ \let\v_font_size_absolute\textface
+ \or
+ \let\v_font_size_absolute\scriptface
+ \or
+ \let\v_font_size_absolute\scriptscriptface
+ \or
+ \let\v_font_size_absolute\xtextface
+ \or
+ \let\v_font_size_absolute\xxtextface
+ \fi
+ %
+ \ifcase\scaledfontmode\relax
+ % none, avoid the designsize if possible
+ \d_font_scaled_font_size-\plusthousand\scaledpoint
+ \or
+ % at
+ \d_font_scaled_font_size\somefontsize
+ \or
+ % sa
+ \d_font_scaled_font_size\v_font_size_absolute\relax
+ \d_font_scaled_font_size\currentfontbodysize\d_font_scaled_font_size % uses \somefontsize set by lua
+ \or
+ % mo
+ \d_font_scaled_font_size\font_basics_set_mapped_fontsize\v_font_size_absolute
+ \d_font_scaled_font_size\currentfontbodysize\d_font_scaled_font_size
+ \or
+ % scaled, don't use this one as it's unpredictable
+ \d_font_scaled_font_size-\somefontsize\scaledpoint
+ \else % ht cp
+ % experiment, yet undocumented
+ \d_font_scaled_font_size\somefontsize
+ \fi
+ \relax
+ \d_font_scaled_font_size\v_font_size_relative\d_font_scaled_font_size
+ \ifconditional\c_font_auto_size
+ \font_helpers_check_body_scale\fontsize
+ \ifconditional\c_font_body_scale
+ \d_font_scaled_font_size\f_font_body_scale\d_font_scaled_font_size
+ \d_font_scaled_text_face\f_font_body_scale\dimexpr\textface\relax
+ \else
+ \d_font_scaled_font_size\f_font_body_scale
+ \d_font_scaled_text_face\textface
+ \fi
+ \else
+ \d_font_scaled_text_face\textface
+ \fi
+ \edef\somefontspec{at \number\d_font_scaled_font_size sp}%
+ \edef\somefontfile{\truefontname\somefontname}%
+ \ifx\somefontfile\s!unknown
+ \edef\somefontfile{\defaultfontfile}%
+ \fi
+ \font_helpers_update_font_parameters
+ \font_helpers_update_font_class_parameters
+ % \writestatus{fonts}{low level define: #csname/\somefontfile/\number\d_font_scaled_font_size/\fontface/\number\d_font_scaled_text_face}%
+ \clf_definefont_two
+ \ifx\fontclass\empty\s!false\else\s!true\fi
+ {#csname}%
+ {\somefontfile}%
+ \d_font_scaled_font_size
+ \c_font_feature_inheritance_mode
+ {\m_font_class_features}%
+ {\m_font_features}%
+ {\m_font_class_fallbacks}%
+ {\m_font_fallbacks}%
+ \fontface
+ \d_font_scaled_text_face
+ \relativefontid
+ {\m_font_class_goodies}%
+ {\m_font_goodies}%
+ {\m_font_class_designsize}%
+ {\m_font_designsize}%
+ \scaledfontmode
+ \relax
+ \ifcase\scaledfontsize
+ %\scaledfontsize\plusone
+ \let\somefontspec\empty
+ \let\lastrawfontcall\relax
+ \expandafter\let\csname#csname\endcsname\relax
+ \else
+ \edef\somefontspec{at \number\scaledfontsize sp}% we need the resolved designsize (for fallbacks)
+ \expandafter\let\expandafter\lastrawfontcall\csname#csname\endcsname
+ \the\everydefinefont
+ \fi
+ \c_font_feature_inheritance_mode\c_font_feature_inheritance_default}
+
+% \def\font_helpers_check_body_scale#fontsize% gets character (x xx a etc)
+% {\ifcsname\??fontenvironments\fontclass\fontbody #fontsize\endcsname \setfalse\c_font_body_scale \expandafter\let\expandafter\f_font_body_scale
+% \csname\??fontenvironments\fontclass\fontbody #fontsize\endcsname \else
+% \ifcsname\??fontenvironments\fontclass\s!default#fontsize\endcsname \settrue \c_font_body_scale \expandafter\let\expandafter\f_font_body_scale
+% \csname\??fontenvironments\fontclass\s!default#fontsize\endcsname \else
+% \ifcsname\??fontenvironments \fontbody #fontsize\endcsname \setfalse\c_font_body_scale \expandafter\let\expandafter\f_font_body_scale
+% \csname\??fontenvironments \fontbody #fontsize\endcsname \else
+% \ifcsname\??fontenvironments \s!default#fontsize\endcsname \settrue \c_font_body_scale \expandafter\let\expandafter\f_font_body_scale
+% \csname\??fontenvironments \s!default#fontsize\endcsname \else
+% \ifcsname\??fontenvironments\fontclass\s!default\s!text \endcsname \settrue \c_font_body_scale \expandafter\let\expandafter\f_font_body_scale
+% \csname\??fontenvironments\fontclass\s!default\s!text \endcsname \else
+% \ifcsname\??fontenvironments \s!default\s!text \endcsname \settrue \c_font_body_scale \expandafter\let\expandafter\f_font_body_scale
+% \csname\??fontenvironments \s!default\s!text \endcsname
+% \else
+% \settrue \c_font_body_scale
+% \let\f_font_body_scale\plusone
+% \fi\fi\fi\fi\fi\fi}
+
+\def\font_helpers_check_body_scale#fontsize% gets character (x xx a etc)
+ {\ifcsname\??fontenvironments\fontclass\fontbody#fontsize\endcsname
+ \expandafter\let\expandafter\f_font_body_scale\lastnamedcs
+ \setfalse\c_font_body_scale % !
+ \else\ifcsname\??fontenvironments\fontclass\s!default#fontsize\endcsname
+ \expandafter\let\expandafter\f_font_body_scale\lastnamedcs
+ \settrue\c_font_body_scale
+ \else\ifcsname\??fontenvironments\fontbody#fontsize\endcsname
+ \expandafter\let\expandafter\f_font_body_scale\lastnamedcs
+ \setfalse\c_font_body_scale % !
+ \else\ifcsname\??fontenvironments\s!default#fontsize\endcsname
+ \expandafter\let\expandafter\f_font_body_scale\lastnamedcs
+ \settrue\c_font_body_scale
+ \else\ifcsname\??fontenvironments\fontclass\s!default\s!text\endcsname
+ \expandafter\let\expandafter\f_font_body_scale\lastnamedcs
+ \settrue\c_font_body_scale
+ \else\ifcsname\??fontenvironments\s!default\s!text\endcsname
+ \expandafter\let\expandafter\f_font_body_scale\lastnamedcs
+ \settrue\c_font_body_scale
+ \else
+ \let\f_font_body_scale\plusone
+ \settrue\c_font_body_scale
+ \fi\fi\fi\fi\fi\fi}
+
+%D The following macros are used at the \LUA\ end. Watch the \type {\normal}
+%D hackery: this makes the mkvi parser happy.
+
+% \normaldef\fntsetdefname {\global\let\somefontname\defaultfontfile} % do before calling
+% \normaldef\fntsetnopsize {\let\somefontsize\empty} % do before calling
+% \normaldef\fntsetsomename{\normalgdef\somefontname} % takes argument
+% \normaldef\fntsetsomesize{\normaldef\somefontsize} % takes argument
+
+\newif\ifskipfontcharacteristics \skipfontcharacteristicstrue
+
+%D When fontclasses are used, we define the font global, since namespaces are
+%D used. Otherwise we parse the specs each time.
+
+\let\fontfile\s!unknown
+
+%D \macros
+%D {everyfont,everyfontswitch}
+
+\ifdefined\everyfont \else \newtoks\everyfont \fi
+\ifdefined\everyfontswitch \else \newtoks\everyfontswitch \fi
+
+\def\setfontcharacteristics{\the\everyfont}
+
+%D \macros
+%D {definefont}
+%D
+%D We also accept \type{sa a}||\type{sa d} as specification.
+%D
+%D Before we implement the main definition macro, we first show
+%D one for local use:
+%D
+%D \starttyping
+%D \definefont[Some][LucidaBright at 100pt] \Some some
+%D \definefont[More][LucidaBright scaled 3000] \More more
+%D \definefont[Nice][LucidaBright mo 2] \Nice nice
+%D \definefont[Text][LucidaBright sa 5.4] \Text last
+%D \stoptyping
+%D
+%D The implementation looks as follows:
+
+\unexpanded\def\definefont % [name][spec][1.6 | line=10pt | setup_id]
+ {\dotripleempty\font_basics_define_font}
+
+\def\font_basics_define_font
+ {\ifthirdargument
+ \expandafter\font_basics_define_font_a
+ \else
+ \expandafter\font_basics_define_font_b
+ \fi}
+
+\def\font_basics_define_font_a[#name][#specification][#settings]% [name][spec][1.6 | line=10pt | setup_id]
+ {\doifelsesetups{#settings}%
+ {\setuvalue{#name}{\font_basics_define_font_with_setups {#name}{#specification}{#settings}}}
+ {\setuvalue{#name}{\font_basics_define_font_with_parameters{#name}{#specification}{#settings}}}}
+
+\def\font_basics_define_font_b[#name][#specification][#dummy]%
+ {\setuvalue{#name}{\font_basics_define_font_without_parameters{#name}{#specification}}}
+
+\def\font_basics_define_font_with_parameters#name#specification#settings%
+ {\font_basics_define_font_without_parameters{#name}{#specification}%
+ \setuplocalinterlinespace[#settings]%
+ \setupspacing\relax} % is this really needed ?
+
+\def\font_basics_define_font_with_setups#name#specification#settings%
+ {\font_basics_define_font_without_parameters{#name}{#specification}%
+ \setups[#settings]}
+
+%D Beware, in the frozen variants no settings are supported yet, but that might happen
+%D some day.
+
+\unexpanded\def\definefrozenfont
+ {\dotripleempty\font_basics_define_frozen_font}
+
+% \def\font_basics_define_frozen_font[#name][#specification][#settings]%
+% {\begingroup
+% \font_basics_define_font[#name][#specification][#settings]%
+% \csname#name\endcsname
+% \expandafter\expandafter\expandafter\endgroup\expandafter\let\csname#name\endcsname\lastrawfontcall}
+
+\def\font_basics_define_frozen_font[#name][#specification][#settings]%
+ {\begingroup
+ \font_basics_define_font[#name][#specification][#settings]%
+ \csname#name\endcsname
+ \global\let\lastglobalrawfontcall\lastrawfontcall
+ \endgroup
+ \expandafter\let\csname#name\endcsname\lastglobalrawfontcall}
+
+%D The instance namespace protection makes the switch local so that we can redefine a
+%D logical name and/or change the size in between.
+
+% todo: now mathsize twice in name (so it can go here)
+% todo: check when mathsize is needed
+
+\ifdefined\??fontinstanceready \else \installcorenamespace{fontinstanceready} \fi
+\ifdefined\??fontinstancebasic \else \installcorenamespace{fontinstancebasic} \fi
+\ifdefined\??fontinstanceclass \else \installcorenamespace{fontinstanceclass} \fi
+
+\newconditional\c_font_auto_size \settrue\c_font_auto_size
+
+\let\lastfontidentifier\empty
+
+\def\v_font_identifier_basic{\??fontinstancebasic \lastfontidentifier-\fontsize-\fontface}
+\def\v_font_identifier_class{\??fontinstanceclass\fontclass-\lastfontidentifier-\fontsize-\fontface}
+
+\let\v_font_identifier_basic_saved\v_font_identifier_basic
+\let\v_font_identifier_class_saved\v_font_identifier_class
+
+% \def\v_font_identifier_class{\??fontinstanceclass\fontclass-\lastfontidentifier-\fontstyle-\fontsize} % no \fontface
+
+\def\font_basics_define_font_without_parameters#identifier#2%
+ {\c_font_feature_inheritance_mode\c_font_feature_inheritance_fontonly
+ \edef\lastfontidentifier{#identifier}%
+ \let\v_font_size_relative\v_font_rscale_default
+ \let\v_font_size_absolute\fontbody
+ \font_helpers_low_level_define{#2}\v_font_identifier_basic
+ \csname\v_font_identifier_basic\endcsname
+ \setfalse\c_font_auto_size
+ \setfontcharacteristics
+ \the\everyfontswitch
+ \let\v_font_identifier_basic\v_font_identifier_basic_saved}
+
+\unexpanded\def\font_helpers_trigger#identifier% make a traced variant
+ {\edef\lastfontidentifier{#identifier}%
+ \ifcsname\v_font_identifier_class\endcsname
+ % \writestatus{fonts}{trigger: reusing \v_font_identifier_class}%
+ \expandafter\font_helpers_trigger_reuse
+ \else
+ % \writestatus{fonts}{trigger: defining \v_font_identifier_class}%
+ \expandafter\font_helpers_trigger_define
+ \fi}
+
+\def\font_helpers_trigger_define#relative#absolute#specification%
+ {\def\v_font_size_relative{#relative}%
+ \def\v_font_size_absolute{#absolute}%
+ \font_helpers_low_level_define{#specification}\v_font_identifier_class
+ \csname\v_font_identifier_class\endcsname
+ \setfalse\c_font_auto_size
+ \ifskipfontcharacteristics \else
+ \setfontcharacteristics
+ \the\everyfontswitch
+ \fi
+ \let\v_font_identifier_class\v_font_identifier_class_saved}
+
+\def\font_helpers_trigger_reuse#relative#absolute#specification%
+ {\csname\v_font_identifier_class\endcsname
+ \setfalse\c_font_auto_size
+ \ifskipfontcharacteristics \else
+ \setfontcharacteristics
+ \the\everyfontswitch
+ \fi
+ \let\v_font_identifier_class\v_font_identifier_class_saved}
+
+%D \macros
+%D {currentfontbodyscale}
+%D
+%D Sometimes we need to have access to the font scale
+%D including the \type{a}||\type{d} sizes. The next macro
+%D returns the current scaling factor. Take a look at
+%D \type {cont-log.tex} for an example of its use.
+
+\installcorenamespace{fontenvironments}
+
+% \def\currentfontbodysize
+% {\ifcsname\??fontenvironments\s!default\somefontsize\endcsname
+% \csname\??fontenvironments\s!default\somefontsize\endcsname
+% \else
+% \somefontsize
+% \fi}
+%
+% \def\currentfontbodyscale
+% {\csname\??fontenvironments\s!default
+% \ifcsname\??fontenvironments\s!default\fontsize\endcsname \fontsize \else
+% \ifcsname\??fontenvironments\s!default\s!text \endcsname \s!text \fi\fi
+% \endcsname}
+
+% \def\currentfontbodysize % gets number (the normal sa 1 etc)
+% {\ifcsname\??fontenvironments\fontclass\s!default\somefontsize\endcsname
+% \csname\??fontenvironments\fontclass\s!default\somefontsize\endcsname
+% \else\ifcsname\??fontenvironments\s!default\somefontsize\endcsname
+% \csname\??fontenvironments\s!default\somefontsize\endcsname
+% \else
+% \somefontsize
+% \fi\fi}
+
+\def\currentfontbodysize % gets number (the normal sa 1 etc)
+ {\ifcsname\??fontenvironments\fontclass\s!default\somefontsize\endcsname
+ \lastnamedcs
+ \else\ifcsname\??fontenvironments\s!default\somefontsize\endcsname
+ \lastnamedcs
+ \else
+ \somefontsize
+ \fi\fi}
+
+\def\currentfontbodyscale % gets character (x xx a etc)
+ {\csname\??fontenvironments
+ \ifcsname\??fontenvironments\fontclass\s!default\fontsize\endcsname\fontclass\s!default\fontsize\else
+ \ifcsname\??fontenvironments \s!default\fontsize\endcsname \s!default\fontsize\else
+ \ifcsname\??fontenvironments\fontclass\s!default\s!text \endcsname\fontclass\s!default\s!text \else
+ \ifcsname\??fontenvironments \s!default\s!text \endcsname \s!default\s!text \else
+ \s!default \fi\fi\fi\fi
+ \endcsname}
+
+\def\font_currentfontbodyscale % gets character (x xx a etc)
+ {\ifcsname\??fontenvironments\fontclass\s!default\fontsize\endcsname\lastnamedcs\else
+ \ifcsname\??fontenvironments \s!default\fontsize\endcsname\lastnamedcs\else
+ \ifcsname\??fontenvironments\fontclass\s!default\s!text \endcsname\lastnamedcs\else
+ \ifcsname\??fontenvironments \s!default\s!text \endcsname\lastnamedcs\else
+ \csname\??fontenvironments \s!default \endcsname \fi\fi\fi\fi}
+
+\def\currentfontscale % used in default definition
+ {\csname\??fontenvironments
+ \ifcsname\??fontenvironments\fontclass\s!default\xfontsize\endcsname\fontclass\s!default\fontsize\else
+ \ifcsname\??fontenvironments \s!default\xfontsize\endcsname \s!default\fontsize\else
+ \ifcsname\??fontenvironments\fontclass\s!default\s!text \endcsname\fontclass\s!default\s!text \else
+ \ifcsname\??fontenvironments \s!default\s!text \endcsname \s!default\s!text \else
+ \s!default \fi\fi\fi\fi
+ \endcsname}
+
+\def\font_currentfontscale % used in default definition
+ {\ifcsname\??fontenvironments\fontclass\s!default\xfontsize\endcsname\lastnamedcs\else
+ \ifcsname\??fontenvironments \s!default\xfontsize\endcsname\lastnamedcs\else
+ \ifcsname\??fontenvironments\fontclass\s!default\s!text \endcsname\lastnamedcs\else
+ \ifcsname\??fontenvironments \s!default\s!text \endcsname\lastnamedcs\else
+ \csname\??fontenvironments \s!default \endcsname \fi\fi\fi\fi}
+
+\setvalue{\??fontenvironments\s!default}{1}
+
+%D In the following macros we use \type{\currentxfontsize} to
+%D hold the current x||size of the font. This enables us to
+%D support for instance \type{\sl} inside a \type{\tx} switch.
+
+\newconstant\currentxfontsize
+
+\def\xfontsize{\ifcase\currentxfontsize\fontsize\or\s!x\else\s!xx\fi}
+
+%D Now we enter the area of font switching. The switching
+%D mechanism has to take care of several situations, like:
+%D
+%D \startitemize[packed]
+%D \item changing the overal document fonts (including margins,
+%D headers and footers)
+%D \item changing local fonts (only the running text)
+%D \item smaller and even more smaller alternatives (super-
+%D and subscripts)
+%D \stopitemize
+%D
+%D \TEX\ offers a powerfull family mechanism for super- and
+%D subscripts in math mode. In text mode however, we don't use
+%D families for the smaller alternatives, and therefore have
+%D to take care of it otherwise.
+
+%D \macros
+%D {definebodyfontenvironment,setupbodyfontenvironment}
+%D
+%D The relationship between the several sizes of a font, is
+%D defined by:
+%D
+%D \showsetup{definebodyfontenvironment}
+%D
+%D Later on we will see how these parameters are used, so for
+%D the moment we stick with an example:
+%D
+%D \starttyping
+%D \definebodyfontenvironment
+%D [12pt]
+%D [ text=12pt,
+%D script=9pt,
+%D scriptscript=7pt,
+%D x=10pt,
+%D xx=8pt,
+%D big=12pt,
+%D small=10pt]
+%D \stoptyping
+%D
+%D The first argument specifies the bodyfont size to which the
+%D settings apply. All second parameters are specified in
+%D dimensions and tell us more about related sizes.
+%D
+%D Afterwards, one can change values with
+%D
+%D \showsetup{setupbodyfontenvironment}
+%D
+%D When instead of a size the keyword \type{unknown} is
+%D passed, fractions (relations) are used instead of fixed
+%D sizes.
+
+%D {\bf Remark:} We need to cover the following cases, otherwise users can
+%D get confused:
+%D
+%D \starttyping
+%D \setupbodyfont[23pt]
+%D
+%D \definebodyfontenvironment[23pt]
+%D \setupbodyfont[23pt]
+%D
+%D \definebodyfontenvironment[23pt]
+%D \definebodyfont[23pt][rm,ss,tt][default]
+%D \setupbodyfont[23pt]
+%D \stoptyping
+%D
+%D Beware: while some font defs can be global, the bodyfont
+%D environment checks local. This means that multiple local
+%D checks resulting in definitions are not that efficient.
+%D So, apart from an occasional switch, one should define an
+%D environment at the outer level.
+
+% \definebodyfontenvironment[33pt]
+% \definebodyfontenvironment[dejavu][default][1=.5]
+% \definebodyfontenvironment[dejavu][default][x=1.2]
+% \definebodyfontenvironment[dejavu][default][a=5]
+% \definebodyfontenvironment[dejavu][33pt][x=100pt]
+
+% the lookup order is:
+%
+% [class] [dimension] [parameters]
+% [class] [default] [parameters] % factors
+% [dimension] [parameters]
+% [default] [parameters] % factors
+%
+% with defaults providing factors
+
+% todo: class:size
+% todo: make assignments global
+
+\letvalue\??fontenvironments\empty % so we default to empty
+
+\def\bodyfontvariable#parameter%
+ {\csname\??fontenvironments
+ \ifcsname\??fontenvironments\fontclass\normalizedbodyfontsize#parameter\endcsname\fontclass\normalizedbodyfontsize#parameter\else
+ \ifcsname\??fontenvironments\fontclass #parameter\endcsname\fontclass #parameter\else
+ \ifcsname\??fontenvironments \normalizedbodyfontsize#parameter\endcsname \normalizedbodyfontsize#parameter\else
+ \ifcsname\??fontenvironments\s!default #parameter\endcsname\s!default #parameter\fi\fi\fi\fi
+ \endcsname}
+
+\def\font_bodyfontvariable#parameter%
+ {\ifcsname\??fontenvironments\fontclass\normalizedbodyfontsize#parameter\endcsname\lastnamedcs\else
+ \ifcsname\??fontenvironments\fontclass #parameter\endcsname\lastnamedcs\else
+ \ifcsname\??fontenvironments \normalizedbodyfontsize#parameter\endcsname\lastnamedcs\else
+ \ifcsname\??fontenvironments\s!default #parameter\endcsname\lastnamedcs\fi\fi\fi\fi}
+
+\def\bodyfontsizevariable#size#parameter%
+ {\csname\??fontenvironments
+ \ifcsname\??fontenvironments\fontclass#size#parameter\endcsname\fontclass#size#parameter\else
+ \ifcsname\??fontenvironments\fontclass #parameter\endcsname\fontclass #parameter\else
+ \ifcsname\??fontenvironments #size#parameter\endcsname #size#parameter\else
+ \ifcsname\??fontenvironments\s!default #parameter\endcsname\s!default #parameter\fi\fi\fi\fi
+ \endcsname}
+
+\def\font_bodyfontsizevariable#size#parameter%
+ {\ifcsname\??fontenvironments\fontclass#size#parameter\endcsname\lastnamedcs\else
+ \ifcsname\??fontenvironments\fontclass #parameter\endcsname\lastnamedcs\else
+ \ifcsname\??fontenvironments #size#parameter\endcsname\lastnamedcs\else
+ \ifcsname\??fontenvironments\s!default #parameter\endcsname\lastnamedcs\fi\fi\fi\fi}
+
+\def\bodyfontinterlinespace{\bodyfontvariable\c!interlinespace} % used elsewhere
+
+% \def\bodyfontdimension#class#size#parameter#body%
+% {\the\dimexpr
+% \ifcsname\??fontenvironments #class#size#parameter\endcsname
+% \csname\??fontenvironments #class#size#parameter\endcsname \else
+% \ifcsname\??fontenvironments#class\s!default#parameter\endcsname
+% \csname\??fontenvironments#class\s!default#parameter\endcsname\dimexpr#body\relax\else % factor
+% \ifcsname\??fontenvironments #size#parameter\endcsname
+% \csname\??fontenvironments #size#parameter\endcsname \else
+% \csname\??fontenvironments \s!default#parameter\endcsname\dimexpr#body\relax\fi\fi\fi % factor
+% \relax}
+
+\def\bodyfontdimension#class#size#parameter#body%
+ {\the\dimexpr
+ \ifcsname\??fontenvironments #class#size#parameter\endcsname \lastnamedcs \else
+ \ifcsname\??fontenvironments#class\s!default#parameter\endcsname \lastnamedcs\dimexpr#body\relax\else % factor
+ \ifcsname\??fontenvironments #size#parameter\endcsname \lastnamedcs \else
+ \lastnamedcs\dimexpr#body\relax\fi\fi\fi % factor
+ \relax}
+
+\unexpanded\def\definebodyfontenvironment
+ {\dotripleempty\font_basics_define_body_font_environment}
+
+\let\setupbodyfontenvironment\definebodyfontenvironment
+
+\installcorenamespace{fontenvironmentknown}
+
+\def\font_helpers_register_environment#class#body%
+ {\expandafter\let\csname\??fontenvironmentknown#class#body\endcsname\empty}
+
+\newmacro\m_font_body
+\newmacro\m_font_body_normalized
+
+\def\font_basics_define_body_font_environment
+ {\ifthirdargument
+ \singleexpandafter\font_basics_define_body_font_environment_class
+ \else\ifsecondargument
+ \doubleexpandafter\font_basics_define_body_font_environment_empty
+ \else
+ \doubleexpandafter\font_basics_define_body_font_environment_unset
+ \fi\fi}
+
+%D First we handle the class specific case. Beware: you can change values before
+%D a bodyfont is loaded but changing them afterwards can be sort of tricky as
+%D values are not consulted afterwards.
+
+\def\processbodyfontenvironmentlist#1% no \unexpanded as then we cannot use it in alignments
+ {\clf_processbodyfontsizes{\strippedcsname#1}}
+
+\def\bodyfontenvironmentlist
+ {\clf_getbodyfontsizes}
+
+\def\font_basics_define_body_font_environment_class[#class][#body][#settings]%
+ {\edef\m_font_body{#body}%
+ \ifx\m_font_body\s!default
+ % these are the last resort within a class
+ \getrawparameters[\??fontenvironments#class\s!default][#settings]%
+ \else
+ \normalizebodyfontsize\m_font_body_normalized\m_font_body
+ \font_basics_define_body_font_environment_size[#class][\m_font_body_normalized][#settings]%
+ \clf_registerbodyfontsize{\m_font_body_normalized}%
+ \fi}
+
+%D The empty case uses the same code but needs to ignore the current class
+%D settings (just to be sure, as it's not really needed).
+
+\def\font_basics_define_body_font_environment_empty[#body][#settings][#dummy]%
+ {\pushmacro\fontclass
+ \let\fontclass\empty
+ \font_basics_define_body_font_environment_class[][#body][#settings]%
+ \popmacro\fontclass}
+
+\def\font_basics_define_body_font_environment_unset[#body][#dummya][#dummyb]%
+ {\pushmacro\fontclass
+ \let\fontclass\empty
+ \font_basics_define_body_font_environment_class[][#body][]%
+ \popmacro\fontclass}
+
+%D We don't check too soon as we can refer to later definitions.
+
+\newconditional\c_font_defining_environment_state % controls messages
+
+\def\font_basics_define_body_font_environment_size[#class][#normalizedbody][#settings]% normalized body
+ {\getrawparameters[\??fontenvironments#class#normalizedbody][#settings]%
+ \ifcsname\??fontenvironmentknown#class#normalizedbody\endcsname
+ % environment and size already defined
+ \else\ifproductionrun
+ \pushmacro\fontclass
+ \edef\fontclass{#class}%
+ \font_helpers_register_environment{#class}{#normalizedbody}%
+ \settrue\c_font_defining_environment_state
+ \font_helpers_define_unknown_font{#normalizedbody}% current class
+ \setfalse\c_font_defining_environment_state
+ \popmacro\fontclass
+ \fi\fi
+ \font_helpers_register_fontbody{#normalizedbody}}
+
+%D Checking
+
+\def\font_helpers_check_bodyfont_environment#normalizedbody#body%
+ {\ifcsname\??fontenvironmentknown\fontclass#normalizedbody\endcsname
+ % already defined
+ \else
+ \font_helpers_check_bodyfont_environment_indeed{#normalizedbody}{#body}%
+ \fi}
+
+\def\font_helpers_check_bodyfont_environment_indeed#normalizedbody#body%
+ {\font_helpers_register_environment\fontclass{#normalizedbody}%
+ \ifcsname\??fontbodyknown#normalizedbody\endcsname
+ \else
+ \font_helpers_define_unknown_font{#normalizedbody}%
+ \fi}
+
+%D We default all parameters to the main bodyfont size, so the next
+%D setup is valid too:
+%D
+%D \starttyping
+%D \definebodyfontenvironment[24pt]
+%D \stoptyping
+%D
+%D All parameters can be redefined when needed, so one doesnot have to
+%D stick to the default ones.
+
+%D \macros
+%D {definebodyfont}
+%D
+%D The next step in defining a bodyfont involves the actual font
+%D files, which can be recognized by their extension
+%D \type{tfm}. Installing those file is often beyond the
+%D scope of the user and up to the system administrator.
+%D
+%D \showsetup{definebodyfont}
+%D
+%D This commands takes three arguments: a (series of) bodyfont
+%D size(s), the style group to which the definitions belong,
+%D and an alternative, as specified by the \TEX\ (math) families,
+%D extended with~a, b~\unknown.
+%D
+%D We show two examples, that show all the alternative
+%D scaling options. The \type{\tfa} alternatives can be
+%D extended with \type{\bfa}, \type{\slb}, etc. or even
+%D \type{e} and higher alternatives. The magic scaled
+%D values are derived from plain \TEX's \type {\magstep}:
+%D
+%D \starttyping
+%D \definebodyfont [12pt] [rm]
+%D [tf=cmr12,
+%D bf=cmbx12,
+%D it=cmti12,
+%D sl=cmsl12,
+%D bi=cmbxti10 at 12pt,
+%D bs=cmbxsl10 at 12pt,
+%D tfa=cmr12 scaled 1.200,
+%D tfb=cmr12 scaled 1.440,
+%D tfc=cmr12 scaled 1.728,
+%D tfd=cmr12 scaled 2.074,
+%D sc=cmcsc10 at 12pt]
+%D
+%D \definebodyfont [12pt,11pt,10pt,9pt,8pt] [rm]
+%D [tf=lbr sa 1,
+%D bf=lbd sa 1,
+%D it=lbi sa 1,
+%D sl=lbsl sa 1,
+%D bi=lbdi sa 1,
+%D bs=lbdi sa 1,
+%D tfa=lbr sa 1.200,
+%D tfb=lbr sa 1.440,
+%D tfc=lbr sa 1.728,
+%D tfd=lbr sa 2.074,
+%D sc=lbr sa 0.833]
+%D \stoptyping
+%D
+%D The second example shows that we can define more sizes at
+%D once. The main difference between these examples is that the
+%D Computer Modern Roman come in many design sizes. This means
+%D that there we cannot define them in bulk using \type{sa}.
+%D Instead of \type{rm} (roman) one can define \type{ss} (sans
+%D serif), \type{tt} (teletype), \type{hw} (hand written),
+%D \type{cg} (calygraphic) and whatever styles.
+%D
+%D The first argument may be a comma separated list. This,
+%D combined with specifications using \type{sa} can save a lot
+%D of typing. Although all arguments should be specified, we
+%D treat the second argument as optional.
+%D
+%D Defining a bodyfont involves two actions: defining the
+%D specific style related alternatives, like \type{\rma},
+%D \type{\bfa} and \type{\rmsla}, and storing the definitions
+%D of their bodyfont size related fonts. The first step is
+%D bodyfont independant but executed every time. This permits
+%D user definitions like \type{\tfw} or \type{\bfq} for real
+%D large alternatives.
+
+%D If we move design size info to the lfg file (after all only lm
+%D has design sizes) we can get rid of much code .. 2012 or so.
+
+\installcorenamespace{fontdefinitions}
+
+% [class] [name] [rm,ss] [settings]
+% [class] [10pt,11pt] [rm,ss] [settings]
+% [class] [10pt,11pt] [rm,ss] [name]
+
+% [class] [name] [settings] == [name] [rm] [settings]
+% [class] [10pt,11pt] [settings] == [name] [rm] [settings]
+% [class] [10pt,11pt] [name] == [10pt,11pt] [rm] [name]
+
+\unexpanded\def\definebodyfont
+ {\doquadrupleempty\font_basics_define_body_font}
+
+\def\font_basics_define_body_font[#1][#2][#3][#4]%
+ {\iffourthargument
+ \processcommacommand[#1]{\font_basics_define_body_font_class_given[#2][#3][#4]}%
+ \else
+ \font_basics_define_body_font_class_known[#1][#2][#3]%
+ \fi}
+
+\def\font_basics_define_body_font_class_given[#1][#2][#3]#4%
+ {\pushmacro\fontclass
+ \doifelse{#4}\s!default
+ {\let\fontclass\empty}
+ {\def\fontclass{#4}}%
+ \definebodyfont[#1][#2][#3]%
+ \popmacro\fontclass}
+
+\def\font_basics_define_body_font_class_known
+ {\ifthirdargument
+ \singleexpandafter\font_basics_define_body_font_a
+ \else\ifsecondargument
+ \doubleexpandafter\font_basics_define_body_font_b
+ \else
+ \doubleexpandafter\font_basics_define_body_font_c
+ \fi\fi}
+
+\unexpanded\def\font_basics_define_body_font_b[#whatever][#specification][#dummy]% body|identifier defs|identifier
+ {\font_basics_define_body_font_a[#whatever][\s!rm][#specification]}
+
+\unexpanded\def\font_basics_define_body_font_c[#whatever][#dummya][#dummyb]% body|identifier
+ {\font_basics_define_body_font_a[bwhatever][\s!rm][]}
+
+\unexpanded\def\font_basics_define_body_font_a[#whatever]%
+ {\doifelsenumber{#whatever}%
+ \font_basics_define_body_font_body
+ \font_basics_define_body_font_name
+ [#whatever]}
+
+\unexpanded\def\font_basics_define_body_font_body[#body][#style][#specification]%
+ {\doifelseassignment{#specification}
+ \font_basics_define_body_font_body_assignment
+ \font_basics_define_body_font_body_identifier
+ [#body][#style][#specification]}%
+
+\unexpanded\def\font_basics_define_body_font_name[#name][#style][#specification]%
+ {\doifelseassignment{#specification}
+ \font_basics_define_body_font_name_assignment
+ \font_basics_define_body_font_name_identifier
+ [#name][#style][#specification]}%
+
+\unexpanded\def\font_basics_define_body_font_body_assignment[#bodylist][#stylelist][#assignments]%
+ {\processcommalist[#bodylist]{\font_basics_define_body_font_body_assignment_a{#stylelist}{#assignments}}}
+
+\unexpanded\def\font_basics_define_body_font_body_assignment_a#stylelist#assignments#body%
+ {\normalizebodyfontsize\m_font_asked_body{#body}%
+ % normally we define quite a lot in advance, i.e global defs
+ \font_helpers_check_bodyfont_environment\m_font_asked_body\m_font_asked_body % !!
+ \processcommalist[#stylelist]{\font_basics_define_body_font_body_assignment_b{#assignments}}}
+
+\unexpanded\def\font_basics_define_body_font_body_assignment_b#assignments#style%
+ {\edef\m_font_asked_style{#style}%
+ \processcommalist[#assignments]\font_basics_define_body_font_defs}
+
+\unexpanded\def\font_basics_define_body_font_defs
+ {\ifx\fontclass\empty
+ \expandafter\font_basics_define_body_font_defs_nop
+ \else
+ \expandafter\font_basics_define_body_font_defs_yes
+ \fi}
+
+\unexpanded\def\font_basics_define_body_font_defs_yes_normal#assignment%
+ {\ifx\m_font_asked_style\s!mm
+ \expandafter\font_basics_define_body_font_yes_mm
+ \else
+ \expandafter\font_basics_define_body_font_yes_xx
+ \fi[#assignment]}
+
+\unexpanded\def\font_basics_define_body_font_defs_nop_normal#assignment%
+ {\ifx\m_font_asked_style\s!mm
+ \expandafter\font_basics_define_body_font_nop_mm
+ \else
+ \expandafter\font_basics_define_body_font_nop_xx
+ \fi[#assignment]}
+
+\unexpanded\def\font_basics_define_body_font_defs_yes_traced#assignment%
+ {\writestatus\m!fonts{[\fontclass] [\m_font_asked_body] [\m_font_asked_style] [#assignment]}%
+ \ifx\m_font_asked_style\s!mm
+ \expandafter\font_basics_define_body_font_yes_mm
+ \else
+ \expandafter\font_basics_define_body_font_yes_xx
+ \fi[#assignment]}
+
+\unexpanded\def\font_basics_define_body_font_defs_nop_traced#assignment%
+ {\writestatus\m!fonts{[\fontclass] [\m_font_asked_body] [\m_font_asked_style] [#assignment]}%
+ \ifx\m_font_asked_style\s!mm
+ \expandafter\font_basics_define_body_font_nop_mm
+ \else
+ \expandafter\font_basics_define_body_font_nop_xx
+ \fi[#assignment]}
+
+\let\font_basics_define_body_font_defs_yes\font_basics_define_body_font_defs_yes_normal
+\let\font_basics_define_body_font_defs_nop\font_basics_define_body_font_defs_nop_normal
+
+\appendtoks
+ \let\font_basics_define_body_font_defs_yes\font_basics_define_body_font_defs_yes_traced
+ \let\font_basics_define_body_font_defs_nop\font_basics_define_body_font_defs_nop_traced
+\to \t_font_tracers_definitions
+
+% We split into two characters (first part of spec) and the rest: the first two are the style and
+% the rest is a size, although in practice one will seldom define the size directly. We might even
+% drop that as it gives faster code.
+
+\unexpanded\def\font_basics_define_body_font_nop_xx[#one#two#rest=#value]% local
+ {\ifcsname\m_font_asked_style#one#two#rest\endcsname\else\font_basics_check_fontname_combination\m_font_asked_style{#one#two}{#rest}\fi
+ \expandafter\let\csname\??fontinstanceclass\m_font_asked_body-\m_font_asked_style-#one#two-#rest-0\endcsname\undefined
+ \unexpanded\expandafter\normaledef\csname\??fontinstanceready\m_font_asked_body-\m_font_asked_style-#one#two-#rest-0\endcsname
+ {\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}}}%
+ \expandafter\let\csname\??fontinstanceclass\m_font_asked_body-\m_font_asked_style-#one#two-#rest-4\endcsname\undefined
+ \unexpanded\expandafter\normaledef\csname\??fontinstanceready\m_font_asked_body-\m_font_asked_style-#one#two-#rest-4\endcsname
+ {\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}}}%
+ \expandafter\let\csname\??fontinstanceclass\m_font_asked_body-\m_font_asked_style-#one#two-#rest-5\endcsname\undefined
+ \unexpanded\expandafter\normaledef\csname\??fontinstanceready\m_font_asked_body-\m_font_asked_style-#one#two-#rest-5\endcsname
+ {\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}}}%
+ }
+
+\unexpanded\def\font_basics_define_body_font_yes_xx[#one#two#rest=#value]% global
+ {\ifcsname\m_font_asked_style#one#two#rest\endcsname\else\font_basics_check_fontname_combination\m_font_asked_style{#one#two}{#rest}\fi
+ \global\expandafter\let\csname\??fontinstanceclass\fontclass-\m_font_asked_body-\m_font_asked_style-#one#two-#rest-1\endcsname\undefined
+ \unexpanded\expandafter\normalxdef\csname\??fontinstanceready\fontclass-\m_font_asked_body-\m_font_asked_style-#one#two-#rest-0\endcsname
+ {\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}}}%
+ \global\expandafter\let\csname\??fontinstanceclass\fontclass-\m_font_asked_body-\m_font_asked_style-#one#two-#rest-2\endcsname\undefined
+ \unexpanded\expandafter\normalxdef\csname\??fontinstanceready\fontclass-\m_font_asked_body-\m_font_asked_style-#one#two-#rest-4\endcsname
+ {\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}}}%
+ \global\expandafter\let\csname\??fontinstanceclass\fontclass-\m_font_asked_body-\m_font_asked_style-#one#two-#rest-3\endcsname\undefined
+ \unexpanded\expandafter\normalxdef\csname\??fontinstanceready\fontclass-\m_font_asked_body-\m_font_asked_style-#one#two-#rest-5\endcsname
+ {\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}}}%
+ }
+
+% \writestatus{fonts}{define \m_asked_style\space yes: {\expandafter\meaning\csname\fontclass\m_font_asked_body\m_font_asked_style#one#two#rest\endcsname}
+
+%D Here the rest concerns rl or lr so in this case it is not a size specifier but
+%D a directional one.
+
+\unexpanded\def\font_basics_define_body_font_nop_mm[#one#two#rest=#value]% local
+ {%\ifcsname\s!mm\endcsname\else\font_basics_check_fontname_combination\s!mm{#one#two}{#rest}\fi
+ \expandafter\let\csname\??fontinstanceclass\m_font_asked_body-\s!mm-#one#two#rest-1\endcsname\undefined
+ % \expandafter\let\csname\??fontinstanceclass\m_font_asked_body-\s!mm-#one#two#rest-2\endcsname\undefined
+ % \expandafter\let\csname\??fontinstanceclass\m_font_asked_body-\s!mm-#one#two#rest-3\endcsname\undefined
+ \unexpanded\expandafter\normaledef\csname\??fontinstanceready\m_font_asked_body-\s!mm-#one#two#rest\endcsname
+ {\font_helpers_trigger{\m_font_asked_body-\s!mm-#one#two#rest}{\noexpand\font_rscale_mm}{\m_font_asked_body}{\normalunexpanded{#value}}}%
+ }
+
+% \writestatus{fonts}{define \m_asked_style\space nop: \expandafter\meaning\csname\m_font_asked_body\m_font_asked_style#one#two#rest\endcsname}%
+
+\unexpanded\def\font_basics_define_body_font_yes_mm[#one#two#rest=#value]% global
+ {%\ifcsname\s!mm\endcsname\else\font_basics_check_fontname_combination\s!mm{#one#two}{#rest}\fi
+ \global\expandafter\let\csname\??fontinstanceclass\fontclass-\m_font_asked_body-\s!mm-#one#two#rest-1\endcsname\undefined
+ % \global\expandafter\let\csname\??fontinstanceclass\fontclass-\m_font_asked_body-\s!mm-#one#two#rest-2\endcsname\undefined
+ % \global\expandafter\let\csname\??fontinstanceclass\fontclass-\m_font_asked_body-\s!mm-#one#two#rest-3\endcsname\undefined
+ \unexpanded\expandafter\normalxdef\csname\??fontinstanceready\fontclass-\m_font_asked_body-\s!mm-#one#two#rest\endcsname
+ {\font_helpers_trigger{\m_font_asked_body-\s!mm-#one#two#rest}{\number\p_font_rscale}{\m_font_asked_body}{\normalunexpanded{#value}}}%
+ }
+
+% \writestatus{fonts}{define \m_asked_style\space yes: \expandafter\meaning\csname\fontclass\m_font_asked_body\m_font_asked_style#one#two#rest\endcsname}%
+
+\unexpanded\def\font_basics_define_body_font_body_identifier[#bodylist][#stylelist][#name]%
+ {\processcommalist[#bodylist]{\font_basics_define_body_font_body_identifier_a{#stylelist}{#name}}}
+
+\unexpanded\def\font_basics_define_body_font_body_identifier_a#stylelist#name#body%
+ {\normalizebodyfontsize\m_font_asked_body{#body}%
+ \font_helpers_check_bodyfont_environment\m_font_asked_body\m_font_asked_body % !!
+ \processcommalist[#stylelist]{\font_basics_define_body_font_body_identifier_b{#name}}}
+
+\unexpanded\def\font_basics_define_body_font_body_identifier_b#name#style%
+ {\edef\m_font_asked_style{#style}%
+ %\writestatus\m!fonts{[\fontclass] [\m_font_asked_body] [\m_font_asked_style] => [#name]}%
+ \csname\??fontdefinitions#name:\m_font_asked_style\endcsname} % no checking
+
+\unexpanded\def\font_basics_define_body_font_name_assignment[#name][#stylelist][#assignments]%
+ {\processcommalist[#stylelist]{\font_basics_define_body_font_name_assignment_a{#name}{#assignments}}}
+
+\unexpanded\def\font_basics_define_body_font_name_assignment_a#name#assignments#style%
+ {%\writestatus\m!fonts{[#name:#style] => [#assignments]}%
+ \setevalue{\??fontdefinitions#name:#style}{\font_basics_define_body_font_default{#assignments}}}
+
+\unexpanded\def\font_basics_define_body_font_name_identifier[#name][#stylelist][#identifier]%
+ {\processcommalist[#stylelist]{\font_basics_define_body_font_name_identifier_a{#name}{#identifier}}}
+
+\unexpanded\def\font_basics_define_body_font_name_identifier_a#name#identifier#style%
+ {%\writestatus\m!fonts{[#name:#style] => [##identifier:#style]}%
+ \ifcsname\??fontdefinitions#name:#style\endcsname
+ \expandafter\let\csname\??fontdefinitions#name:#style\expandafter\endcsname\csname\??fontdefinitions#identifier:#style\endcsname
+ \else
+ \expandafter\def\csname\??fontdefinitions#name:#style\endcsname{\csname\??fontdefinitions#identifier:#style\endcsname}%
+ \fi}
+
+%D The unknown:
+
+\newconditional\c_font_defining_unknown
+\newconditional\c_font_defining_state
+
+\unexpanded\def\font_helpers_define_unknown_font#body% one level only
+ {\font_helpers_register_fontbody{#body}% prevents loop, can go
+ \setfalse\c_font_defining_state
+ \font_helpers_process_relative_size_list{\font_helpers_define_unknown_check_sizes{#body}}%
+ \ifconditional\c_font_defining_state
+ \setfalse\c_font_defining_state
+ \font_helpers_process_style_list{\font_helpers_define_unknown_check_definitions{#body}}%
+ \ifconditional\c_font_defining_state
+ \ifconditional\c_font_defining_environment_state\else
+ \showmessage\m!fonts{14}{#body}% main
+ \fi
+ \setfalse\c_font_defining_state
+ \font_helpers_register_fontbody{#body}%
+ % needed ?
+ \ifconditional\c_font_defining_unknown
+ \else
+ \settrue\c_font_defining_unknown
+ \font_helpers_process_relative_size_list{\font_helpers_define_unknown_check_relatives{#body}}%
+ \setfalse\c_font_defining_unknown
+ \fi
+ \fi
+ \fi}
+
+\def\font_helpers_define_unknown_check_sizes#body#relativesize%
+ {\ifcsname\??fontenvironments\s!default#relativesize\endcsname % fontclass ?
+ % how \lastnamedcs here
+ \expandafter\normalizebodyfontsize\csname\??fontenvironments#body#relativesize\endcsname{\csname\??fontenvironments\s!default#relativesize\endcsname\dimexpr#body\relax}%
+ \settrue\c_font_defining_state
+ \fi}
+
+\def\font_helpers_define_unknown_check_definitions#body#style%
+ {\ifcsname\??fontdefinitions\s!default:#style\endcsname
+ \edef\m_font_asked_body{#body}%
+ \edef\m_font_asked_style{#style}%
+ \lastnamedcs
+ \settrue\c_font_defining_state
+ \fi}
+
+\def\font_helpers_define_unknown_check_relatives#body#relativesize%
+ {\ifcsname\??fontbodyknown\csname\??fontenvironments#body#relativesize\endcsname\endcsname \else
+ % how \lastnamedcs here
+ \expandafter\font_helpers_define_unknown_font\csname\??fontenvironments#body#relativesize\endcsname
+ \settrue\c_font_defining_state
+ \fi}
+
+\unexpanded\def\font_basics_define_body_font_default#assignments%
+ {\font_helpers_check_relative_font_size\m_font_asked_style % still needed here?
+ \ifcsname\m_font_asked_style\endcsname\else
+ \normalexpanded{\definefontstyle[\m_font_asked_style][\m_font_asked_style]}%
+ \fi
+ \processcommalist[#assignments]\font_basics_define_body_font_defs
+ \let\p_font_rscale\v_font_rscale_default}
+
+%D These macros show that quite some definitions take place. Fonts are not loaded
+%D yet! This means that at format generation time, no font files are present.
+
+\unexpanded\def\font_basics_switch_points#body%
+ {\ifcsname\??fontbodyknown#body\endcsname \else
+ % we need to check the relative sizes for this body
+ \font_helpers_define_unknown_font{#body}%
+ \fi%
+ \ifcsname\??fontbodyknown#body\endcsname % always true now
+ \font_basics_complete_switch{#body}%
+ \localbodyfontsize#body\relax
+ \normalizebodyfontsize\normalizedbodyfontsize\localbodyfontsize
+ \font_helpers_check_bodyfont_environment\normalizedbodyfontsize\normalizedbodyfontsize % !!
+ \else
+ \showmessage\m!fonts4{#body}%
+ \fi}
+
+\unexpanded\def\font_basics_switch_style#style%
+ {\ifcsname\??fontstyle#style\endcsname
+ \lastnamedcs
+ \edef\fontstyle{#style}%
+ \ifmmode\mr\fi % in order to be compatible with \rm in math mode
+ % \the\everybodyfont % cleaner, in setting size as well as style
+ \else
+ \showmessage\m!fonts5{#style}%
+ \fi}
+
+%D Here comes the main font switching macros. These macros
+%D handle changes in size as well as returning to the global
+%D bodyfont size.
+
+\ifdefined\font_preloads_at_definition \else \let\font_preloads_at_definition\relax \fi
+
+\def\font_helpers_set_font#method#specification%
+ {\edef\m_font_specification{#specification}%
+ \ifx\m_font_specification\empty \else
+ \ifx\m_font_specification\v!global % we can have all kind of presets
+ \restoreglobalbodyfont
+ \else
+ \processcommacommand[\m_font_specification]{\font_helpers_set_font_check_size}%
+ \processcommacommand[\m_font_specification]{\font_helpers_set_font_set_font{#method}}%
+ \ifproductionrun
+ \font_preloads_at_definition
+ \font_basics_switch_points\normalizedbodyfontsize
+ \font_basics_switch_style\fontstyle
+ \ifx\defaultfontclass\empty
+ \let\defaultfontclass\fontclass
+ \fi
+ \fi
+ \fi
+ \currentxfontsize\zerocount
+ \fi}
+
+\def\font_helpers_set_font_check_size#option%
+ {\doifelsenumber{#option}{\font_helpers_check_bodyfont_environment{#option}{#option}}\donothing}
+
+\def\font_helpers_set_font_set_font#method#option% method=1: set, method=2: switch
+ {\doifsomething{#option}{\font_helpers_set_font_set_font_option{#method}{#option}}}
+
+\def\font_helpers_set_font_set_font_option#method#option%
+ {\doifelsenumber{#option}%
+ \font_helpers_set_font_set_font_option_body
+ \font_helpers_set_font_set_font_option_keyword
+ {#method}{#option}{#option}}
+
+\newmacro\m_font_keyword
+
+\unexpanded\def\font_helpers_set_font_set_font_option_keyword#method#keyword#message%
+ {\edef\m_font_keyword{#keyword}%
+ \ifcsname\??fontenvironments\normalizedbodyfontsize\m_font_keyword\endcsname
+ \edef\m_font_step{\font_bodyfontvariable\m_font_keyword}%
+ \normalexpanded{\font_helpers_set_font_set_font_option_body{#method}{\m_font_step}{#message}}%
+ \else\ifx\m_font_keyword\v!reset
+ \let\fontstyle\empty % new 31/7/2006
+ \let\fontsize \empty
+ \else\ifcsname\??fontstyle\m_font_keyword\endcsname
+ \let\fontstyle\m_font_keyword
+ \else
+ \setcurrentfontclass\m_font_keyword
+ \ifcase#method\relax
+ \let\globalfontclass\globalfontclass % -)
+ \else
+ \let\globalfontclass\fontclass
+ \fi
+ \font_helpers_set_fontstyle_of_fontclass
+ \fi\fi\fi}
+
+\def\font_helpers_set_fontstyle_of_fontclass % will be overloaded later
+ {\let\fontstyle\s!rm}
+
+\unexpanded\def\font_helpers_set_font_set_font_option_body#method#body#message%
+ {\normalizebodyfontsize\normalizedsetfont{#body}% redundant for some calls
+ \ifcsname\??fontbodyknown\normalizedsetfont\endcsname \else
+ \font_helpers_define_unknown_font\normalizedsetfont
+ \fi
+ \ifcsname\??fontbodyknown\normalizedsetfont\endcsname
+ \localbodyfontsize\normalizedsetfont
+ \let\normalizedbodyfontsize\normalizedsetfont
+ \else
+ \showmessage\m!fonts4{#message}%
+ %\font_helpers_set_font_set_font_option_body_fallbacks{#method}{#body}%
+ \fi}
+
+% we need to check the fontclass
+
+\def\registerfontclass#class%
+ {\letgvalue{\??fontclassyes#class}\v!yes} % global ?
+
+\def\setcurrentfontclass#class%
+ {\ifcsname\??fontclassyes#class\endcsname
+ \edef\fontclass{#class}%
+ \else\ifcsname\??fontclassnop#class\endcsname
+ % already tried
+ \else % too messy: \ifcase\currentgrouplevel % (unpredictable)
+ \trycurrentfontclass{#class}%
+ \fi\fi} % \fi}
+
+\ifdefined\trycurrentfontclass \else
+
+ \unexpanded\def\trycurrentfontclass#typeface%
+ {\letvalueempty{\??fontclassnop#typeface}}
+
+\fi
+
+\let\defaultfontstyle \s!rm
+\let\defaultfontalternative\s!tf
+\let\defaultfontsize \empty
+\let\defaultfontface \!!zerocount
+
+%D So far for synchronisation. (We can inline the following macros.)
+
+\unexpanded\def\setcurrentfont#body#style#alternative#size% not used
+ {\edef\fontbody {#body}%
+ \edef\fontstyle {#style}%
+ \edef\fontalternative{#alternative}%
+ \edef\fontsize {#size}%
+ \font_helpers_check_big_math_synchronization
+ \font_helpers_synchronize_font}
+
+\unexpanded\def\setcurrentfontbody#body% % not used
+ {\edef\fontbody{#body}%
+ \font_helpers_synchronize_font}
+
+% For Taco: optional fall backs:
+
+\ifdefined\font_typescripts_inherit_check \else
+ \let\font_typescripts_inherit_check\gobbleoneargument % implemented in type-ini
+\fi
+
+\unexpanded\def\font_helpers_set_current_font_style#style%
+ {\edef\fontstyle{#style}%
+ \font_typescripts_inherit_check\fontstyle
+ \ifmmode\mr\fi % otherwise \rm not downward compatible ... not adapted yet
+ \font_helpers_synchronize_font}
+
+\unexpanded\def\font_helpers_set_current_xsize_alternative#xsize#alternative%
+ {\edef\fontface{#xsize}%
+ \edef\fontalternative{#alternative}%
+ \font_helpers_synchronize_font}
+
+\unexpanded\def\font_helpers_set_current_font_alternative#alternative%
+ {\edef\fontalternative{#alternative}%
+ \font_helpers_synchronize_font}
+
+\unexpanded\def\font_helpers_set_current_font_size#size%
+ {\edef\fontsize{#size}%
+ \font_helpers_check_big_math_synchronization % double? better in everymath?
+ \font_helpers_synchronize_font}
+
+\unexpanded\def\font_helpers_set_current_font_style_alternative#style#alternative% \rmsl
+ {\edef\fontstyle {#style}%
+ \edef\fontalternative{#alternative}%
+ \font_helpers_synchronize_font}
+
+\unexpanded\def\font_helpers_set_current_font_style_size#style#size% \rma
+ {\edef\fontstyle{#style}%
+ \edef\fontsize {#size}%
+ \font_helpers_check_big_math_synchronization % double? better in everymath?
+ \font_helpers_synchronize_font}
+
+\unexpanded\def\font_helpers_set_current_font_alternative_size#alternative#size% \sla
+ {\edef\fontalternative{#alternative}%
+ \edef\fontsize {#size}%
+ \font_helpers_check_big_math_synchronization % double? better in everymath?
+ \font_helpers_synchronize_font}
+
+\unexpanded\def\font_helpers_set_current_font_style_alternative_size#style#alternative#size% \rmsla
+ {\edef\fontstyle {#style}%
+ \edef\fontalternative{#alternative}%
+ \edef\fontsize {#size}%
+ \font_helpers_check_big_math_synchronization % double? better in everymath?
+ \font_helpers_synchronize_font}
+
+\unexpanded\def\font_helpers_synchronize_font % we can have dups i.e. no need to let fontstrategy
+ {\ifx\fontclass\empty
+ \applyfontstrategies
+ \else
+ \applyfontclassstrategies
+ \fi
+ \setfalse\c_font_auto_size
+ \ifskipfontcharacteristics
+ \setfontcharacteristics
+ \the\everyfontswitch
+ \fi}
+
+%D This is the resolver for special cases (sizes) and in practice it is not called that often
+%D so further optimization makes no sense.
+
+\def\font_helpers_check_strategy_class_a % --- --- --- --- % pt tt bf a
+ {\ifcsname\??fontinstanceready\fontclass-\fontbody-\fontstyle-\fontalternative-\fontsize-\fontface\endcsname
+ \setfalse\c_font_auto_size
+ \lastnamedcs
+ \else
+ \expandafter\font_helpers_check_strategy_class_b
+ \fi}
+
+\def\font_helpers_check_strategy_class_b % --- --- --- def % pt tt bf
+ {\ifcsname\??fontinstanceready\fontclass-\fontbody-\fontstyle-\fontalternative-\defaultfontsize-\fontface\endcsname
+ \settrue\c_font_auto_size
+ \lastnamedcs
+ \else
+ \expandafter\font_helpers_check_strategy_class_c
+ \fi}
+
+\def\font_helpers_check_strategy_class_c % --- --- def --- % pt tt tf a
+ {\ifcsname\??fontinstanceready\fontclass-\fontbody-\fontstyle-\defaultfontalternative-\fontsize-\fontface\endcsname
+ \settrue\c_font_auto_size
+ \lastnamedcs
+ \else
+ \expandafter\font_helpers_check_strategy_class_d
+ \fi}
+
+\def\font_helpers_check_strategy_class_d % --- --- def def % pt tt tf
+ {\ifcsname\??fontinstanceready\fontclass-\fontbody-\fontstyle-\defaultfontalternative-\defaultfontsize-\fontface\endcsname
+ \settrue\c_font_auto_size
+ \lastnamedcs
+ \else
+ \expandafter\font_helpers_check_strategy_class_e
+ \fi}
+
+\def\font_helpers_check_strategy_class_e % --- def def def % pt rm tf
+ {\ifcsname\??fontinstanceready\fontclass-\fontbody-\defaultfontstyle-\defaultfontalternative-\defaultfontsize-\fontface\endcsname
+ \setfalse\c_font_auto_size
+ \lastnamedcs
+ \else
+ \expandafter\font_helpers_check_strategy_class_f
+ \fi}
+
+\def\font_helpers_check_strategy_class_f % def def def def % rm tf
+ {\ifcsname\??fontinstanceready\fontclass-\defaultfontbody-\defaultfontstyle-\defaultfontalternative-\defaultfontsize-\fontface\endcsname
+ \settrue\c_font_auto_size
+ \lastnamedcs
+ \else
+ \expandafter\font_helpers_check_strategy_a
+ \fi}
+
+% no class
+
+\def\font_helpers_check_strategy_a % --- --- --- --- % pt tt bf a
+ {\ifcsname\??fontinstanceready\fontbody-\fontstyle-\fontalternative-\fontsize-\fontface\endcsname
+ \setfalse\c_font_auto_size
+ \lastnamedcs
+ \else
+ \expandafter\font_helpers_check_strategy_b
+ \fi}
+
+\def\font_helpers_check_strategy_b % --- --- --- --- % pt tt bf a
+ {\ifcsname\??fontinstanceready\fontbody-\fontstyle-\fontalternative-\defaultfontsize-\fontface\endcsname
+ \settrue\c_font_auto_size
+ \lastnamedcs
+ \else
+ \expandafter\font_helpers_check_strategy_c
+ \fi}
+
+\def\font_helpers_check_strategy_c % --- --- --- --- % pt tt bf a
+ {\ifcsname\??fontinstanceready\fontbody-\fontstyle-\defaultfontalternative-\fontsize-\fontface\endcsname
+ \settrue\c_font_auto_size
+ \lastnamedcs
+ \else
+ \expandafter\font_helpers_check_strategy_d
+ \fi}
+
+\def\font_helpers_check_strategy_d % --- --- --- --- % pt tt bf a
+ {\ifcsname\??fontinstanceready\fontbody-\fontstyle-\defaultfontalternative-\defaultfontsize-\fontface\endcsname
+ \settrue\c_font_auto_size
+ \lastnamedcs
+ \else
+ \expandafter\font_helpers_check_strategy_e
+ \fi}
+
+\def\font_helpers_check_strategy_e % --- --- --- --- % pt tt bf a
+ {\ifcsname\??fontinstanceready\fontbody-\defaultfontstyle-\defaultfontalternative-\defaultfontsize-\fontface\endcsname
+ \setfalse\c_font_auto_size
+ \lastnamedcs
+ \else
+ \expandafter\font_helpers_check_strategy_f
+ \fi}
+
+\def\font_helpers_check_strategy_f % --- --- --- --- % pt tt bf a
+ {\ifcsname\??fontinstanceready\defaultfontbody-\defaultfontstyle-\defaultfontalternative-\defaultfontsize-\fontface\endcsname
+ \settrue\c_font_auto_size
+ \lastnamedcs
+ \fi}
+
+\let\applyfontstrategies \font_helpers_check_strategy_a
+\let\applyfontclassstrategies\font_helpers_check_strategy_class_a
+
+%D Let's synchronize:
+
+\newconditional\c_font_synchronize \settrue\c_font_synchronize
+
+\prependtoks
+ \ifconditional\c_font_synchronize
+ \font_helpers_synchronize_math
+ \font_helpers_synchronize_font % problem: syncs last font
+ \fi
+\to \everybodyfont
+
+%D Setting the normal sizes as well as the x and xx smaller
+%D sizes is accomplished by the next set of macros. When in
+%D math mode, the commands \type{\tx} and \type{\txx} are
+%D just a switch to the script and double script styles, but
+%D in text mode the values defined by the bodyfontenvironment are
+%D used. Here we also set \type{\currentxfontsize}.
+
+\def\font_helpers_set_current_font_xxx_alternative#alternative#xsize#scriptstyle%
+ {\ifmmode
+ #scriptstyle%
+ \else
+ \font_helpers_set_current_xsize_alternative{#xsize}{#alternative}%
+ \fi}
+
+\def\font_helpers_set_current_font_x_alternative#alternative%
+ {\font_helpers_set_current_font_xxx_alternative{#alternative}{4}\scriptstyle
+ \currentxfontsize\plusone
+ \let\tx\txx}
+
+\def\font_helpers_set_current_font_xx_alternative#alternative%
+ {\font_helpers_set_current_font_xxx_alternative{#alternative}{5}\scriptscriptstyle
+ \currentxfontsize\plustwo
+ \let\tx\empty
+ \let\txx\empty}
+
+\def\font_helpers_reset_x_fontsize
+ {\ifcase\currentxfontsize\else
+ \currentxfontsize\zerocount
+ \let\tx\normaltx
+ \let\txx\normaltxx
+ \fi}
+
+\def\font_helpers_check_nested_x_fontsize % option
+% {\ifcase\currentxfontsize\else\ifx\fontsize\empty\else
+% \currentxfontsize\zerocount
+% \let\fontsize\empty
+% \let\tx\normaltx
+% \let\txx\normaltxx
+% \fi\fi}
+ {}
+
+\def\font_helpers_set_current_font_x_alternative#alternative%
+ {\font_helpers_check_nested_x_fontsize
+ \font_helpers_set_current_font_xxx_alternative{#alternative}{4}\scriptstyle
+ \currentxfontsize\plusone
+ \let\tx\txx}
+
+\def\font_helpers_set_current_font_xx_alternative#alternative%
+ {\font_helpers_check_nested_x_fontsize
+ \font_helpers_set_current_font_xxx_alternative{#alternative}{5}\scriptscriptstyle
+ \currentxfontsize\plustwo
+ \let\tx\empty
+ \let\txx\empty}
+
+% This alterative is not really needed, but for old time's sake
+% we keep it there. We can speed it up when needed.
+
+\def\font_helpers_set_current_font_x_style_alternative #alternative{\csname#alternative\endcsname\tx}
+\def\font_helpers_set_current_font_xx_style_alternative#alternative{\csname#alternative\endcsname\txx}
+
+%D These macros also show us that when we call for \type{\tx},
+%D this macro is redefined to be \type{\txx}. Therefore calls
+%D like:
+%D
+%D \startbuffer
+%D {small \tx is \tx beautiful}
+%D {small \tx is \txx beautiful}
+%D {small \txx is \tx beautiful}
+%D {small \txx is \txx beautiful}
+%D \stopbuffer
+%D
+%D \typebuffer
+%D
+%D result in:
+%D
+%D \startlines
+%D \getbuffer
+%D \stoplines
+%D
+%D Setting the main size involves the style list and therefore
+%D takes a bit more time. Keep in mind that the fontsize is
+%D represented by a character or empty.
+
+% \unexpanded\def\tx {\font_helpers_set_current_font_x_alternative \fontalternative}
+% \unexpanded\def\txx{\font_helpers_set_current_font_xx_alternative\fontalternative}
+
+\unexpanded\def\tx
+ {\ifmmode
+ \scriptstyle
+ \else
+ \let\fontface\!!plusfour
+ \let\fontalternative\fontalternative
+ \font_helpers_synchronize_font
+ \fi
+ \currentxfontsize\plusone
+ \let\tx\txx}
+
+\unexpanded\def\txx
+ {\ifmmode
+ \scriptscriptstyle
+ \else
+ \let\fontface\!!plusfive
+ \let\fontalternative\fontalternative
+ \font_helpers_synchronize_font
+ \fi
+ \currentxfontsize\plustwo}
+
+\let\normaltx \tx
+\let\normaltxx\txx
+
+%D When asking for a complete font switch, for instance from 10
+%D to 12~points, the next macro does the job. First we
+%D normalize the size, next we define the current range of
+%D text, script and scriptscript sizes, then we set the text
+%D fonts and the math families and finally we activate the
+%D default typeface and also set the font specific parameters
+%D assigned to \type{\everybodyfont}
+
+\def\textface {\currentbodyfontdimension\s!text }
+\def\scriptface {\currentbodyfontdimension\s!script }
+\def\scriptscriptface{\currentbodyfontdimension\s!scriptscript}
+\def\xtextface {\currentbodyfontdimension\s!x }
+\def\xxtextface {\currentbodyfontdimension\s!xx }
+
+% \unexpanded\def\font_basics_complete_switch#size%
+% {\bodyfontsize#size\relax
+% \normalizebodyfontsize\normalizedbodyfontsize\bodyfontsize
+% \edef\textface {\currentbodyfontdimension\s!text }%
+% \edef\scriptface {\currentbodyfontdimension\s!script }%
+% \edef\scriptscriptface{\currentbodyfontdimension\s!scriptscript}}%
+
+\installcorenamespace{fontbodyfaces}
+
+\unexpanded\def\font_basics_complete_switch#size%
+ {\bodyfontsize#size\relax
+ \normalizebodyfontsize\normalizedbodyfontsize\bodyfontsize
+ \expandafter\let\expandafter\font_basics_set_faces\csname\??fontbodyfaces\fontbody\endcsname
+ \ifx\font_basics_set_faces\relax
+ \font_basics_set_faces_preset
+ \fi
+ \font_basics_set_faces}
+
+\def\font_basics_set_faces_preset
+ {\edef\font_basics_set_faces{% 0.2 sec on 10K \tfa
+ \noexpand\edef\noexpand\textface {\currentbodyfontdimension\s!text }%
+ \noexpand\edef\noexpand\scriptface {\currentbodyfontdimension\s!script }%
+ \noexpand\edef\noexpand\scriptscriptface{\currentbodyfontdimension\s!scriptscript}%
+ \noexpand\edef\noexpand\xtextface {\currentbodyfontdimension\s!x }%
+ \noexpand\edef\noexpand\xxtextface {\currentbodyfontdimension\s!xx }%
+ }%
+ \global\expandafter\let\csname\??fontbodyfaces\fontbody\endcsname\font_basics_set_faces}
+
+% \def\currentbodyfontdimension#parameter%
+% {\the\dimexpr
+% \ifcsname\??fontenvironments\fontclass\normalizedbodyfontsize#parameter\endcsname
+% \csname\??fontenvironments\fontclass\normalizedbodyfontsize#parameter\endcsname \else
+% \ifcsname\??fontenvironments\fontclass\s!default #parameter\endcsname
+% \csname\??fontenvironments\fontclass\s!default #parameter\endcsname
+% \dimexpr\normalizedbodyfontsize\relax \else % factor
+% \ifcsname\??fontenvironments \normalizedbodyfontsize#parameter\endcsname
+% \csname\??fontenvironments \normalizedbodyfontsize#parameter\endcsname \else
+% \csname\??fontenvironments \s!default #parameter\endcsname
+% \dimexpr\normalizedbodyfontsize\relax \fi\fi\fi % factor
+% \relax}
+
+\def\currentbodyfontdimension#parameter% there can be factors here
+ {\the\dimexpr
+ \ifcsname\??fontenvironments\fontclass\normalizedbodyfontsize#parameter\endcsname
+ \lastnamedcs
+ \else\ifcsname\??fontenvironments\fontclass\s!default#parameter\endcsname
+ \lastnamedcs
+ \dimexpr\normalizedbodyfontsize\relax
+ \else\ifcsname\??fontenvironments\normalizedbodyfontsize#parameter\endcsname
+ \lastnamedcs
+ \else
+ \csname\??fontenvironments\s!default#parameter\endcsname
+ \dimexpr\normalizedbodyfontsize\relax
+ \fi\fi\fi
+ \relax}
+
+%D \macros
+%D {setupbodyfont,switchtobodyfont}
+%D
+%D The next two macros are user ones. With \type{\setupbodyfont}
+%D one can set the document bodyfont size, font family, style
+%D and/or options defined in files, for example:
+%D
+%D \starttyping
+%D \setupbodyfont[modern,12pt,roman]
+%D \stoptyping
+%D
+%D This command affects the document as a whole: text, headers
+%D and footers. The second macro however affects only the text:
+%D
+%D \starttyping
+%D \switchtobodyfont[10pt]
+%D \stoptyping
+%D
+%D So we've got:
+%D
+%D \showsetup{setupbodyfont}
+%D \showsetup{switchtobodyfont}
+%D
+%D Both macros look alike. The second one also has to take
+%D all kind of keywords into account.
+
+\ifx\saveinterlinespace \undefined \let\saveinterlinespace \relax \fi
+\ifx\restoreinterlinespace\undefined \let\restoreinterlinespace\relax \fi
+
+% \newtoks \everysetupbodyfont
+% \newtoks \everyswitchtobodyfont
+
+\unexpanded\def\setupbodyfont
+ {\doifelsenextoptionalcs\font_basics_setupbodyfont_yes\font_basics_setupbodyfont_nop}
+
+\def\font_basics_setupbodyfont_nop
+ {\restoreglobalbodyfont
+ \saveinterlinespace}
+
+\def\font_basics_setupbodyfont_yes[#specification]%
+ {\doifsomething{#specification}
+ {\font_helpers_set_font\plusone{#specification}%
+ \globalbodyfontsize\localbodyfontsize
+ \normalizebodyfontsize\normalizedglobalbodyfontsize\globalbodyfontsize
+ \let\globalfontstyle\fontstyle
+ \ifproductionrun
+ \the\everybodyfont
+ \the\everyglobalbodyfont
+ \saveinterlinespace
+ \fi
+ \the\everysetupbodyfont}}
+
+\unexpanded\def\font_basics_switchtobodyfont#specification%
+ {\edef\m_font_step{\font_bodyfontvariable{#specification}}%
+ \ifx\m_font_step\empty
+ \font_helpers_set_font\zerocount{#specification}%
+ \else
+ \font_helpers_switch_bodyfont_step % so we have a fast [small] switch
+ \fi
+ \the\everybodyfont
+ \the\everyswitchtobodyfont}
+
+\unexpanded\def\switchtobodyfont[#specification]% could become an ifx
+ {\doifsomething{#specification}{\font_basics_switchtobodyfont{#specification}}}
+
+
+\unexpanded\def\usebodyfontparameter#1%
+ {\edef\m_font_bodyfont_asked{#1\c!bodyfont}%
+ \ifx\m_font_bodyfont_asked\empty\else
+ \font_basics_switchtobodyfont\m_font_bodyfont_asked
+ \fi}
+
+\def\font_helpers_switch_bodyfont_step
+ {\font_basics_switch_points\m_font_step
+ \font_basics_switch_style \fontstyle}
+
+%D The following alternative is meant for math||to||text
+%D switching and will be optimized.
+
+\unexpanded\def\fastswitchtobodyfont#name%
+ {\ifcsname\??fontenvironments\normalizedbodyfontsize#name\endcsname
+ %\edef\futurebodyfontsize{\csname\??fontenvironments\normalizedbodyfontsize#name\endcsname}%
+ \edef\futurebodyfontsize{\lastnamedcs}%
+ \ifcsname\??fontbodyknown\futurebodyfontsize\endcsname
+ \font_basics_complete_switch\futurebodyfontsize
+ \localbodyfontsize\futurebodyfontsize\relax
+ \fi
+ \fi
+ \csname\??fontstyle\fontstyle\endcsname
+ \the\everybodyfont}
+
+%D \starttyping
+%D $\cases{& \ccaron}$ $x=\hbox{\ccaron $x=\hbox{\ccaron}$}$
+%D \stoptyping
+
+%D \macros
+%D {usebodyfont}
+%D
+%D This looks nicer then a switch in the preamble
+%D
+%D \starttyping
+%D \usebodyfont[pagella,10pt]
+%D \usebodyfont[termes,10pt]
+%D \usebodyfont[dejavu,10pt]
+%D
+%D \setupbodyfont[dejavu]
+%D
+%D \starttext
+%D test
+%D \stoptext
+%D \stoptyping
+
+% \unexpanded\def\usebodyfont[#1]%
+% {\pushmacro\fontclass
+% \switchtobodyfont[#1]%
+% \popmacro\fontclass
+% \ifx\fontclass\empty\else\setupbodyfont\relax\fi}
+
+\unexpanded\def\usebodyfont[#1]%
+ {\pushmacro\fontclass
+ \font_helpers_set_font\zerocount{#1}%
+ \popmacro\fontclass
+ \ifx\fontclass\empty \else
+ \font_basics_setupbodyfont_nop
+ \fi}
+
+%D Handy for manuals:
+
+
+%D The \type {\tochar} commmand takes a specification:
+%D
+%D \starttabulate[|l|l|l|]
+%D \NC e \NC entity \NC e:eacute \NC \NR
+%D \NC x \NC hexadecimal unicode \NC x:013D \NC \NR
+%D \NC d \NC decimal unicode \NC d:123 \NC \NR
+%D \NC s \NC hexadecimal index (slot) \NC s:210D \NC \NR
+%D \NC i \NC decimal index \NC i:456 \NC \NR
+%D \NC n \NC name \NC n:eight \NC \NR
+%D \NC c \NC name \NC c:x \NC \NR
+%D \stoptabulate
+%D
+%D This is an expandable command!
+
+\unexpanded\def\fontchar #character{\clf_fontchar{#character}}
+\unexpanded\def\fontcharbyindex #index{\clf_fontcharbyindex#index\relax}
+ \def\tochar #specifications{\clf_tochar{#specifications}} % expanded (also used in edef)
+
+%D The next auxilliary macro is an alternative to \type {\fontname}.
+
+\def\purefontname#font{\clf_purefontname{\fontname#font}}
+
+%D \macros
+%D {switchstyleonly}
+%D
+%D For switching a style but keeping the alternative, there
+%D is:
+%D
+%D \starttyping
+%D {\bf text \switchstyleonly\ss text}
+%D {\bf text \switchstyleonly[ss]text}
+%D {\sl text \switchstyleonly[sansserif]text}
+%D \stoptyping
+
+\unexpanded\def\switchstyleonly
+ {\doifelsenextoptionalcs\font_basics_switch_style_only_opt\font_basics_switch_style_only_arg}
+
+\def\font_basics_switch_style_only_arg#name% stupid version
+ {\font_helpers_set_current_font_style{\csname\??fontshortstyle\checkedstrippedcsname#name\endcsname}%
+ \the\everybodyfont} % needed ?
+
+\def\font_basics_switch_style_only_opt[#name]% todo : check
+ {\font_helpers_set_current_font_style{\csname\??fontshortstyle#name\endcsname}%
+ \the\everybodyfont} % needed ?
+
+%D \macros
+%D {definebodyfontswitch}
+%D
+%D \PLAIN\ \TEX\ defines some macro's like \type{\tenpoint}
+%D to switch to a specific bodyfontsize. Just for the sake of
+%D compatibility we can define them like:
+%D
+%D \starttyping
+%D \definebodyfontswitch [twelvepoint] [12pt]
+%D \stoptyping
+%D
+%D We don't support language specific synonyms here.
+
+\unexpanded\def\definebodyfontswitch
+ {\dodoubleargument\font_basics_define_bodyfont_switch}
+
+\def\font_basics_define_bodyfont_switch[#command][#specification]% no longer a commalist (not useful)
+ {\setvalue{#command}{\switchtobodyfont[#specification]}}%
+
+%D \macros
+%D {setsmallbodyfont,setmainbodyfont,setbigbodyfont}
+%D
+%D When we're typesetting at for instance 10pt, we can call for
+%D the \type{small} as well as the \type{big} alternative,
+%D related to this main size, using \type{\switchtobodyfont[small]}.
+%D The three alternatives can be activated by the next three
+%D system calls and are defined by the bodyfontenvironment.
+
+\newmacro\m_font_step
+
+\def\font_helpers_set_bodyfont_step#step%
+ {\edef\m_font_step{\font_bodyfontvariable{#step}}% not always \cs
+ \font_basics_switch_points\m_font_step
+ \font_basics_switch_style \fontstyle}
+
+\unexpanded\def\setsmallbodyfont{\font_helpers_set_bodyfont_step\v!small\the\everybodyfont}
+\unexpanded\def\setbigbodyfont {\font_helpers_set_bodyfont_step\v!big \the\everybodyfont}
+
+\unexpanded\def\setmainbodyfont
+ {\font_basics_switch_points\normalizedbodyfontsize
+ \font_basics_switch_style\fontstyle
+ \the\everybodyfont
+ \the\everyglobalbodyfont
+ \saveinterlinespace}
+
+%D \macros
+%D {restoreglobalbodyfont}
+%D
+%D Users can set whatever font available while typesetting text.
+%D Pagenumbers, footers, headers etc. however must be typeset
+%D in the main bodyfont and style of the document. Returning to
+%D the global state can be done with the next macro:
+%D
+%D This macro has to be called when entering the pagebody
+%D handling routine as well as the footnote insert routine.
+%D Users can access this feature |<|for instance when one wants
+%D to typeset tables and alike in the main bodyfont and style
+%D while the running text is temporary set to a smaller one|>|
+%D by saying \type{\switchtobodyfont[global]}.
+
+\let\globalfontstyle\s!rm
+
+\unexpanded\def\fullrestoreglobalbodyfont
+ {\let\fontsize\defaultfontsize
+ \let\fontbody\defaultfontbody
+ \let\fontface\defaultfontface
+ \currentxfontsize\zerocount
+ \let\fontclass\globalfontclass
+ \font_basics_switch_points\normalizedglobalbodyfontsize
+ \font_basics_switch_style\globalfontstyle
+ \redoconvertfont % just in case a pagebreak occurs
+ \tf
+ \the\everybodyfont
+ \the\everyglobalbodyfont
+ \saveinterlinespace}
+
+\unexpanded\def\partialrestoreglobalbodyfont
+ {\let\fontsize\defaultfontsize
+ \let\fontbody\defaultfontbody
+ \let\fontface\defaultfontface
+ \currentxfontsize\zerocount
+ \redoconvertfont
+ \tf
+ \the\everybodyfont % indeed needed
+ \the\everyglobalbodyfont % indeed needed
+ \saveinterlinespace}
+
+\unexpanded\def\restoreglobalbodyfont % ook style etc
+ {\ifx\fontclass\globalfontclass
+ \ifx\fontstyle\globalfontstyle
+ \ifx\normalizedbodyfontsize\normalizedglobalbodyfontsize
+ \partialrestoreglobalbodyfont
+ \else
+ \fullrestoreglobalbodyfont
+ \fi
+ \else
+ \fullrestoreglobalbodyfont
+ \fi
+ \else
+ \fullrestoreglobalbodyfont
+ \fi}
+
+% in case of troubles: \let\restorebodyfont\fullrestoreglobalbodyfont
+
+%D Here are some fast variants that can be used in cases where no font
+%D system is needed and where fonts are frozen:
+%D
+%D \starttyping
+%D \definefont [TestA][Serif at 10pt]
+%D \predefinefont[TestB][Serif at 20pt]
+%D
+%D \testfeatureonce{1000}{{\TestA}} % .312
+%D \testfeatureonce{1000}{{\TestB}} % < .016
+%D \testfeatureonce{1000}{{\definedfont[Serif at 30pt]}} % .312
+%D \testfeatureonce{1000}{{\predefinedfont[Serif at 40pt]}} % < .016
+%D \stoptyping
+
+\installcorenamespace{predefinedfont}
+
+\unexpanded\def\predefinefont[#1]#2[#3]% global !
+ {\setugvalue{#1}{\font_basics_predefine{#1}{#3}}}
+
+\unexpanded\def\predefinedfont[#1]% global !
+ {\ifcsname\??predefinedfont#1\endcsname
+ \lastnamedcs
+ \else
+ \font_basics_predefined{#1}%
+ \fi}
+
+\unexpanded\def\font_basics_predefine#1#2%
+ {\font_basics_defined_font_yes[#2]%
+ \global\expandafter\let\csname#1\expandafter\endcsname\csname\v_font_identifier_basic\endcsname}
+
+\unexpanded\def\font_basics_predefined#1%
+ {\font_basics_predefine{\??predefinedfont#1}{#1}}
+
+%D Handy helper:
+
+\unexpanded\def\savedefinedfont[#1]%
+ {\bgroup
+ \definedfont[#1]%
+ \xdef\saveddefinedfontid {\number\fontid\font}%
+ \xdef\saveddefinedfontname{\fontname\font}%
+ \egroup}
+
+\def\saveddefinedfontid {\number\fontid\font}
+\def\saveddefinedfontname{\fontname\font}
+
+% yes or no:
+
+% \let\font_basics_check_text_bodyfont_slow\font_basics_check_text_bodyfont
+%
+% \unexpanded\def\font_basics_check_text_bodyfont
+% {\ifproductionrun
+% % not per se \s!..'s
+% \glet\font_basics_check_text_bodyfont \font_basics_check_text_bodyfont_slow
+% \glet\font_basics_check_text_bodyfont_fast\relax
+% \expandafter\font_basics_check_text_bodyfont
+% \else
+% \expandafter\font_basics_check_text_bodyfont_fast
+% \fi}
+%
+% \def\font_basics_check_text_bodyfont_fast#style#alternative#size% size can be empty (checking needed as \bf is already defined)
+% {\setugvalue{#style#size}% \rma
+% {\let\fontstyle#style%
+% \let\fontsize #size%
+% \font_helpers_check_big_math_synchronization % double? better in everymath?
+% \font_helpers_synchronize_font}%
+% \setugvalue{#alternative#size}% \sla
+% {\let\fontalternative#alternative%
+% \let\fontsize #size%
+% \font_helpers_check_big_math_synchronization % double? better in everymath?
+% \font_helpers_synchronize_font}%
+% \setugvalue{#style#alternative#size}% \rmsla
+% {\let\fontstyle #style%
+% \let\fontalternative#alternative%
+% \let\fontsize #size%
+% \font_helpers_check_big_math_synchronization % double? better in everymath?
+% \font_helpers_synchronize_font}%
+% \ifcsname\s!normal#style\endcsname % text/math check
+% \expandafter\let\csname#style\expandafter\endcsname\csname\s!normal#style\endcsname
+% \else
+% \setugvalue{#style}% \rm
+% {\let\fontstyle#style%
+% \font_typescripts_inherit_check\fontstyle
+% \ifmmode\mr\fi % otherwise \rm not downward compatible ... not adapted yet
+% \font_helpers_synchronize_font}%
+% \fi
+% \ifcsname\s!normal#alternative\endcsname % text/math check
+% \expandafter\let\csname#alternative\expandafter\endcsname\csname\s!normal#alternative\endcsname
+% \else
+% \setugvalue{#alternative}% \sl
+% {\let\fontalternative#alternative%
+% \font_helpers_synchronize_font}%
+% \fi
+% \setugvalue{#style\s!x}% \rmx
+% {\csname#style\endcsname\tx}%
+% \setugvalue{#style\s!xx}% \rmxx
+% {\csname#style\endcsname\txx}%
+% \setugvalue{#alternative\s!x}% \slx
+% {\font_helpers_check_nested_x_fontsize
+% \ifmmode
+% \scriptstyle
+% \else
+% \let\fontface\!!plusfour
+% \let\fontalternative#alternative%
+% \font_helpers_synchronize_font
+% \fi
+% \currentxfontsize\plusone
+% \let\tx\txx}%
+% \setugvalue{#alternative\s!xx}% \slxx
+% {\font_helpers_check_nested_x_fontsize
+% \ifmmode
+% \scriptscriptstyle
+% \else
+% \let\fontface\!!plusfive
+% \let\fontalternative#alternative%
+% \font_helpers_synchronize_font
+% \fi
+% \currentxfontsize\plustwo
+% \let\tx\empty
+% \let\txx\empty}%
+% \setugvalue{#style#alternative}% \rmsl
+% {\let\fontstyle #style%
+% \let\fontalternative#alternative%
+% \font_helpers_synchronize_font}}
+
+\protect \endinput