%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 / Hans Hagen \& Ton Otten}]
%C
%C This module is part of the \CONTEXT\ macro||package and is
%C therefore copyrighted by \PRAGMA. See mreadme.pdf for
%C details.

% simplification ... we no longer deal with specific mmtfa specifications

%  todo: always fontclass, then less testing

% \definefontfeature[smallcaps][smcp=yes,script=latn]
% \definefontfeature[smallcaps][SmallCapitals=yes,script=latn]
% \definefontfeature[smallcaps][Small Capitals=yes,script=latn]
% \definefontfeature[smallcaps][small capitals=yes,script=latn]
% \definefontfeature[smallcaps][smallcapitals=yes,script=latn]
%
% \definedfont[cambria*smallcaps] test

% \starttext
% \definefontfeature[basekerned][default][mode=base]
% \definefontfeature[nodekerned][default][mode=node]
% \definefontfeature[nonekerned][default][mode=base,kern=no]
% \setupcolors[state=start]
% \startoverlay
%     {\vbox{\red  \definedfont[Serif*nonekerned at 12pt]\input tufte }}
%     {\vbox{\blue \definedfont[Serif*basekerned at 12pt]\input tufte }}
%     {\vbox{\green\definedfont[Serif*nodekerned at 12pt]\input tufte }}
% \stopoverlay
% \stoptext

% \enabletrackers[otf.kerns]
%
% \definefontfeature[withkern][default][mode=node]
% \definefontfeature[nokern]  [default][mode=node,kern=no]
% \definefontfeature[single]  [default][mode=node,cpsp=yes]
% \definefontfeature[simple]  [default][mode=node,cpsp=yes,kern=no]
%
% {\definedfont[Serif*default] [FGFGFGFGFGFGFGFGFGFGFGFGFG ABCDEFGHIJKLMNOPQRSTUVWXYZ] \par}
% {\definedfont[Serif*nokern]  [FGFGFGFGFGFGFGFGFGFGFGFGFG ABCDEFGHIJKLMNOPQRSTUVWXYZ] \par}
% {\definedfont[Serif*single]  [FGFGFGFGFGFGFGFGFGFGFGFGFG ABCDEFGHIJKLMNOPQRSTUVWXYZ] \par}
% {\definedfont[Serif*simple]  [FGFGFGFGFGFGFGFGFGFGFGFGFG ABCDEFGHIJKLMNOPQRSTUVWXYZ] \par}

% figure out why \fontbody is not expanded

\writestatus{loading}{ConTeXt Font Macros / Initialization}

\registerctxluafile{font-ini}{1.001}
\registerctxluafile{node-fnt}{1.001} % here
\registerctxluafile{font-enc}{1.001}
\registerctxluafile{font-map}{1.001}
\registerctxluafile{font-syn}{1.001}
\registerctxluafile{font-log}{1.001}
\registerctxluafile{font-tfm}{1.001}
\registerctxluafile{font-afm}{1.001}
\registerctxluafile{font-cid}{1.001} % cid maps
\registerctxluafile{font-ott}{1.001} % otf tables
\registerctxluafile{font-otf}{1.001} % otf main
\registerctxluafile{font-otd}{1.001} % otf dynamics
\registerctxluafile{font-oti}{1.001} % otf initialization
\registerctxluafile{font-otb}{1.001} % otf main base
\registerctxluafile{font-otn}{1.001} % otf main node
\registerctxluafile{font-ota}{1.001} % otf analyzers
\registerctxluafile{font-otp}{1.001} % otf pack
\registerctxluafile{font-otc}{1.001} % otf context
\registerctxluafile{font-vf} {1.001}
\registerctxluafile{font-def}{1.001}
\registerctxluafile{font-ctx}{1.001}
\registerctxluafile{font-xtx}{1.001}
\registerctxluafile{font-fbk}{1.001}
\registerctxluafile{font-ext}{1.001}
\registerctxluafile{font-pat}{1.001}
\registerctxluafile{font-chk}{1.001}

\unprotect

% \def\fontrange#1%
%   {\dofontrange{#1 =\bodyfontsize}}
%
% \def\dofontrange#1%
%   {\dodofontrange#1 \relax}% \fontstringA
%
% \def\dodofontrange#1 #2 %
%   {\ifdim\bodyfontsize#2%
%      #1\expandafter\gobbleuntilrelax
%    \else
%      \expandafter\dodofontrange
%    \fi}
%
% \definefont
%   [crap]
%   [\fontrange
%      {Regular        <10pt
%       RegularBold    <12pt
%       RegularSlanted <15pt
%       Regular} sa 1]
%
% may be better:
%
% \definefontrange
%   [crap]
%   [Regular        <10pt
%    RegularBold    <12pt
%    RegularSlanted <15pt]
%   [Regular sa 1]
%
%
% \dostepwiserecurse{2}{15}{1}
%   {{\switchtobodyfont[\recurselevel pt]\crap test}\endgraf}

% adapted, else wrong interlinespace

\def\setfontparameters
  {\synchronizefontsfalse
   \the\everybodyfont
   \synchronizefontstrue}

% handy

\newcounter\pushedfont

\def\savefont
  {\edef\savedfont{\the\font}%
   \pushmacro\savedfont}

\def\restorefont
  {\popmacro\savedfont
   \savedfont}

\def\pushcurrentfont
  {\edef\popcurrentfont
     {\noexpand\def\noexpand\fontbody{\fontbody}%
      \noexpand\def\noexpand\fontstyle{\fontstyle}%
      \noexpand\dosetcurrentfontalternative{\fontalternative}%
      \noexpand\dosetcurrentfontsize{\fontsize}%
      \noexpand\synchronizefont}}

% \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   {definedfont,startfont,doiffontcharelse}
%D
%D A couple of relatively new macros:

% \newtoks \everydefinedfont % not ot be confused with \everydefinefont

\def\dodefinedfont[#1]%
  {\iffirstargument\definefont[thedefinedfont][#1]\fi % we can speed this one up
   \csname thedefinedfont\endcsname
   \the\everydefinedfont}

\unexpanded\def\definedfont
  {\dosingleempty\dodefinedfont}

\unexpanded\def\startfont
  {\bgroup\definedfont}

\def\stopfont
  {\egroup}

\def\doiffontcharelse#1#2%
  {\bgroup
   \definedfont[#1]%
   \iffontchar\font#2\relax
     \egroup\expandafter\firstoftwoarguments
   \else
     \egroup\expandafter\secondoftwoarguments
   \fi}

%D For more detailed (and historic information) we refer to the file
%D \type {font-ini.mkii}. Here we have a much simplified lower level
%D implementation due to a different approach to math. Also the chapter
%D on fonts in the reference manual explains a lot.

%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 \startvoorbeeld
%D \getbuffer
%D \stopvoorbeeld
%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
%D
%D Remark: math support has changed a bit.

%D \macros
%D   {uchar}
%D
%D This macro prepares \CONTEXT\ for \UNICODE\ support. By
%D defining it here, we have at least an safeguard for utility
%D file reading.

\ifdefined\uchar\else \unexpanded\def\uchar#1#2{[#1,#2]} \fi

%D We define some (very private) constants to improve speed,
%D memory usage and consistency.

\def\@size@       {@f@si@} % bodyfont size prefix (12pt etc)
\def\@style@      {@f@st@} % full style prefix (roman etc)
\def\@shortstyle@ {@f@sh@} % short style prefix (rm etc)
\def\@letter@     {@f@le@} % first alternative typeface
\def\@noletter@   {@f@no@} % second alternative typeface
\def\@fontclass@  {@f@cl@} % fontclass

%D \macros
%D   {fontclass, defaultfontclass}
%D
%D The fontclass model was introduced a while after we implement
%D the basic font model and at that time we still defaulted to
%D no model at all. Nowadays we default to the \type {modern}
%D fontclass.

\let\fontclass       \empty
\let\defaultfontclass\empty

%D \macros
%D   {textonly}
%D
%D Traditionally math has a big impact on font definitions, mainly
%D because we need to define alphabet variants using families and
%D fonts. This means that one can easily get 10 fonts loaded per
%D math size. In \MKIV\ we use a different approach: one family
%D which has either a virtual font made of traditional fonts, or
%D an \OPENTYPE\ font that has it all.
%D
%D We currently use only one math family but in the future we
%D might consider using a second one for bold math. For the
%D moment we keep the \MKII\ method of using a token register
%D for definitions but we already dropped the text and symbols
%D ones since they now live in the same family.

\newtoks \mathstrategies

\newif\ifsynchronizemathfonts \synchronizemathfontstrue

\def\synchronizemath % math stuff in mmode
  {\ifsynchronizemathfonts\the\mathstrategies\fi}

\def\textonly{\synchronizemathfontsfalse} % document this

%D The main math font definer. We have removed some optimized
%D code simply because we now always have a fontclass. We could
%D check for fontclass being default or empty and save a few
%D tests but it does not help us when no math is defined.

\chardef\mrfam\zerocount % math regular
\chardef\mbfam\plusone   % math bold

\unexpanded\def\mr{\ifmmode\fam\zerocount\else\setcurrentfontalternative\c!mr\fi} % \fam\csname\c!mr fam\endcsname
\unexpanded\def\mb{\ifmmode\fam\plusone  \else\setcurrentfontalternative\c!mb\fi} % \fam\csname\c!mb fam\endcsname

\def\mathtextsuffix        {-text}
\def\mathscriptsuffix      {-script}
\def\mathscriptscriptsuffix{-scriptscript}

% \let\mathsizesuffix\empty

\let\currentmathsize\empty

\def\mathsizesuffix{\ifcase0\currentmathsize\or\mathtextsuffix\or\mathscriptscriptsuffix\or\mathscriptsuffix\fi}

\def\dodosetmathfamily#1#2%
  {\ifcsname\fontclass       \fontbody\c!mm\fontfamily\fontsize\currentmathsize\endcsname \autofontsizefalse
     \csname\fontclass       \fontbody\c!mm\fontfamily\fontsize\currentmathsize\endcsname \else
   \ifcsname\fontclass       \fontbody\c!mm\fontfamily         \currentmathsize\endcsname \autofontsizetrue
     \csname\fontclass       \fontbody\c!mm\fontfamily         \currentmathsize\endcsname \else
     \dodosetmathfamilyx#1#2%
   \fi\fi
   #1#2\font}

\def\dodosetmathfamilyx#1#2%
  {\ifcsname\defaultfontclass\fontbody\c!mm\fontfamily\fontsize\currentmathsize\endcsname \autofontsizefalse
     \csname\defaultfontclass\fontbody\c!mm\fontfamily\fontsize\currentmathsize\endcsname \else
   \ifcsname\defaultfontclass\fontbody\c!mm\fontfamily         \currentmathsize\endcsname \autofontsizetrue
     \csname\defaultfontclass\fontbody\c!mm\fontfamily         \currentmathsize\endcsname \else
     \dodosetmathfamilyxx#1#2%
   \fi\fi}

\def\dodosetmathfamilyxx#1#2%
  {\ifcsname                 \fontbody\c!mm\fontfamily\fontsize\currentmathsize\endcsname \autofontsizefalse
     \csname                 \fontbody\c!mm\fontfamily\fontsize\currentmathsize\endcsname \else
   \ifcsname                 \fontbody\c!mm\fontfamily         \currentmathsize\endcsname \autofontsizetrue
     \csname                 \fontbody\c!mm\fontfamily         \currentmathsize\endcsname \else
                             \nullfont                                    \autofontsizetrue
   \fi\fi}

\def\dosetmathfamily#1#2%
  {\let\savedfontbody\fontbody % op hoger plan
   \let\fontfamily#2%
   \let\currentmathsize\!!plusthree\let\fontbody\scriptscriptface\dodosetmathfamily\scriptscriptfont#1%
   \let\currentmathsize\!!plustwo  \let\fontbody\scriptface      \dodosetmathfamily\scriptfont      #1%
   \let\currentmathsize\!!plusone  \let\fontbody\textface        \dodosetmathfamily\textfont        #1%
   \let\currentmathsize\empty
   \let\fontbody\savedfontbody
   \autofontsizefalse}

\appendtoks
    \dosetmathfamily\mrfam\c!mr
\to \mathstrategies

% not official !

\chardef\boldmathmode\zerocount % might change ... maybe \mathfontsupport 1 (normal) 2 (bold too)

\def\enableboldmath {\chardef\boldmathmode\plusone  } % todo: \setupbodyfont[boldmath,...]
\def\disableboldmath{\chardef\boldmathmode\zerocount}

\appendtoks
    \ifcase\boldmathmode\or\dosetmathfamily\mbfam\c!mb\fi
\to \mathstrategies

%D All used styles, like rm, ss and tt, are saved in a comma
%D separated list. Appart from practical limitations one can
%D define as many styles as needed.

\def\fontrelativesizelist{\s!text,\s!script,\s!scriptscript,\c!x,\c!xx,\c!big,\c!small}

%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.

\let\defaultrelativefontsize \plusone
\let\localrelativefontsize   \plusone
\def\localabsolutefontsize  {\fontbody}

\let\relativefontsize \defaultrelativefontsize

\def\saverelativefontsize#1#2% #1=rm|ss|.. #2=waarde
  {\setxvalue{\fontclass#1\s!rscale}{#2}}

\def\checkrelativefontsize#1%
  {\edef\relativefontsize
     {\ifcsname\fontclass#1\s!rscale\endcsname
        \csname\fontclass#1\s!rscale\endcsname
      \else\ifcsname\defaultfontclass#1\s!rscale\endcsname
        \csname\defaultfontclass#1\s!rscale\endcsname
      \else
        \defaultrelativefontsize
      \fi\fi}}

% \letvalue{\s!default\s!rscale}\defaultrelativefontsize
%
% \def\checkrelativefontsize#1%
%   {\edef\relativefontsize
%      {\csname
%         \ifcsname\fontclass#1\s!rscale\endcsname
%           \fontclass#1%
%         \else\ifcsname\defaultfontclass#1\s!rscale\endcsname
%           \defaultfontclass#1%
%         \else
%           \s!default
%         \fi\fi
%       \s!rscale\endcsname}}

%D We also save:

\def\savemathtextstyle#1% #1=rm|ss|..
  {\doifsomething{#1}{\setxvalue{\fontclass\c!mm\s!text}{#1}}}

\def\currentmathtextstyle % we default to empty !
  {\executeifdefined{\fontclass\c!mm\s!text}\empty}

%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 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
%
% {\definedfont[cmbx10 at 10pt]x\definedfont[cmbx8 at 10pt]x}

\def\safontscale{\number\dimexpr\localabsolutefontsize\relax}
\def\mofontscale{\number\dimexpr\setmappedfontsize\localabsolutefontsize\relax}

\let\somefontname\s!unknown
\let\somefontspec\s!unknown
\let\somefontsize\zerocount

\newcount\scaledfontmode
\newdimen\scaledfontsize
\newtoks\everydefinefont

\def\currentfontbodysize
  {\ifcsname\??ft\s!default\somefontsize\endcsname
     \csname\??ft\s!default\somefontsize\endcsname
   \else
     \somefontsize
   \fi}

\def\lowleveldefinefont#1#2% #2 = cs
  {%
   \ctxlua{fonts.define.command_1("\luaescapestring{#1}")}% the escapestring catches at \somedimen
   % sets \scaledfontmode and \somefontname and \somefontsize
   \ifcase\scaledfontmode\relax
     % none, avoid the designsize if possible
     \scaledfontsize-1000\scaledpoint
   \or
     % at
     \scaledfontsize\somefontsize
   \or
     % sa
     \scaledfontsize\localabsolutefontsize\relax
     \scaledfontsize\currentfontbodysize\scaledfontsize
   \or
     % mo
     \scaledfontsize\setmappedfontsize\localabsolutefontsize
     \scaledfontsize\currentfontbodysize\scaledfontsize
   \or
     % scaled, don't use this one as it's unpredictable
     \scaledfontsize-\somefontsize\scaledpoint
   \fi
   \scaledfontsize\localrelativefontsize\scaledfontsize
   \ifautofontsize
     \scaledfontsize\currentfontbodyscale\scaledfontsize
   \fi
   \edef\somefontspec{at \number\scaledfontsize sp}%
   \edef\somefontfile{\truefontname\somefontname}%
   \ifx\somefontfile\s!unknown
     \edef\somefontfile{\defaultfontfile}%
   \fi
   \updatefontparameters
   \updatefontclassparameters
   \ctxlua{fonts.define.command_2(
      \ifx\fontclass\empty false\else true\fi,
      "#2", % cs, trailing % is gone
      "\somefontfile",
      \number\scaledfontsize,
      "\@@fontclassfeatures",
      "\@@fontfeatures",
      "\@@fontclassfallbacks",
      "\@@fontfallbacks",
      0\currentmathsize,
      \number\dimexpr\textface\relax
   )}%
   \edef\somefontspec{at \somefontsize}% we need the resolved designsize (for fallbacks)
   \expandafter\let\expandafter\lastrawfontcall\csname#2\endcsname
   \the\everydefinefont}

\def\updatefontclassparameters
  {\edef\@@fontclassfeatures {\ifcsname\fontclass\s!features \endcsname\csname\fontclass\s!features \endcsname\fi}%
   \edef\@@fontclassfallbacks{\ifcsname\fontclass\s!fallbacks\endcsname\csname\fontclass\s!fallbacks\endcsname\fi}}

% resolve

\def\@@thefeaturesyes#1%
  {\ifcsname\??ff\fontclass#1\s!features \endcsname\@EA\let\@EA\@@fontfeatures   \csname\??ff\fontclass#1\s!features \endcsname\else
   \ifcsname\??ff          #1\s!features \endcsname\@EA\let\@EA\@@fontfeatures   \csname\??ff          #1\s!features \endcsname\else
   \ifcsname\??ff\fontclass            #1\endcsname\@EA        \@@thefeaturesyes \csname\??ff\fontclass            #1\endcsname\else
   \ifcsname\??ff                      #1\endcsname\@EA        \@@thefeaturesyes \csname\??ff                      #1\endcsname\else
                                                       \let    \@@fontfeatures   \empty                                        \fi\fi\fi\fi}

\def\@@thefallbacksyes#1%
  {\ifcsname\??ff\fontclass#1\s!fallbacks\endcsname\@EA\let\@EA\@@fontfallbacks  \csname\??ff\fontclass#1\s!fallbacks\endcsname\else
   \ifcsname\??ff          #1\s!fallbacks\endcsname\@EA\let\@EA\@@fontfallbacks  \csname\??ff          #1\s!fallbacks\endcsname\else
   \ifcsname\??ff\fontclass            #1\endcsname\@EA        \@@thefallbacksyes\csname\??ff\fontclass            #1\endcsname\else
   \ifcsname\??ff                      #1\endcsname\@EA        \@@thefallbacksyes\csname\??ff                      #1\endcsname\else
                                                       \let    \@@fontfallbacks  \empty                                        \fi\fi\fi\fi}

\def\@@thefeaturesnop#1%
  {\ifcsname\??ff#1\s!features \endcsname\@EA\let\@EA\@@fontfeatures   \csname\??ff#1\s!features \endcsname\else
   \ifcsname\??ff            #1\endcsname\@EA        \@@thefeaturesnop \csname\??ff            #1\endcsname\else
                                             \let    \@@fontfeatures   \empty                              \fi\fi}

\def\@@thefallbacksnop#1%
  {\ifcsname\??ff#1\s!fallbacks\endcsname\@EA\let\@EA\@@fontfallbacks  \csname\??ff#1\s!fallbacks\endcsname\else
   \ifcsname\??ff            #1\endcsname\@EA        \@@thefallbacksnop\csname\??ff            #1\endcsname\else
                                             \let    \@@fontfallbacks  \empty                              \fi\fi}

\def\updatefontparametersyes
 {\@@thefeaturesyes \somefontname
  \@@thefallbacksyes\somefontname}

\def\updatefontparametersnop
 {\@@thefeaturesnop \somefontname
  \@@thefallbacksnop\somefontname}

\def\updatefontparameters
 {\ifx\fontclass\empty\updatefontparametersnop\else\updatefontparametersyes\fi}

\let\@@fontclassfeatures \empty
\let\@@fontclassfallbacks\empty

\let\@@fontfallbacks\empty
\let\@@fontfeatures \empty
\let\@@hyphenchar   \empty % todo, will go to encoding

%D This brings down maps processing from 466 to 309 seconds
%D ($-33$\%) and mfonts from 42 to 34 seconds ($-15$\%).

\newif\ifskipfontcharacteristics \skipfontcharacteristicstrue

%D When fontclasses are used, we define the font global,
%D since namespaces are used. Otherwise we parse the specs
%D each time.

\let\fontfile\s!unknown

% \definefontfeature[default]     [liga=yes,texligatures=yes,texquotes=yes]
% \definefontfeature[default-caps][liga=yes,texligatures=yes,texquotes=yes,smcp=yes,script=latn]
%
% \starttypescript [serif] [palatino-nova-regular] [name]
%     \definefontsynonym[Serif]    [palatinonova-regular][features=default]
%     \definefontsynonym[SerifCaps][palatinonova-regular][features=default-caps] % also sets Serif
% \stoptypescript
%
% \starttypescript [serif] [palatino-nova-regular] [name]
%     \definefontsynonym[Serif]          [palatinonova-regular*default]
%     \definefontsynonym[SerifCaps]      [palatinonova-regular*default-caps]
% \stoptypescript

% \definetypeface[mainface][rm][serif][palatino-nova-regular][default] \setupbodyfont[mainface]
%
% \starttext
%   ``Test'' -- --- ff fi fl \sc ``Test'' -- --- ff fi fl
% \stoptext

% \starttext
%     \definefont
%         [blabla]
%         [name:Latin Modern Something]
%     \definefont
%         [blabla]
%         [file:texnansi-lmr10]
%     \blabla test
%     \definefont
%         [blabla]
%         [texnansi-lmtt10]
%     \blabla test
% \stoptext

% \starttext
%
% \setupcolors[state=start]
%
% \definefontfeature
%   [default-base]
%   [script=latn,language=dflt,liga=yes,kern=yes,tlig=yes,trep=yes]
% \definefontfeature
%   [default-node]
%   [script=latn,language=dflt,liga=yes,kern=yes,tlig=yes,trep=yes,mode=node]
% \definefontfeature
%   [default-none]
%   [script=latn,language=dflt,liga=yes,kern=no, tlig=yes,trep=yes]
%
% \startoverlay
%     {\vtop{\color[red]  {\font\test=name:lmroman12regular*default-node \test \input ward \input zapf \input linden }}}
%     {\vtop{\color[green]{\font\test=name:lmroman12regular*default-base \test \input ward \input zapf \input linden }}}
%     {\vtop{\color[blue] {\font\test=name:lmroman12regular*default-none \test \input ward \input zapf \input linden }}}
% \stopoverlay
%
% \blank
%
% \startoverlay
%     {\vtop{\color[red]  {\font\test=name:texgyrepagella*default-node \test \input ward \input zapf \input linden }}}
%     {\vtop{\color[green]{\font\test=name:texgyrepagella*default-base \test \input ward \input zapf \input linden }}}
%     {\vtop{\color[blue] {\font\test=name:texgyrepagella*default-none \test \input ward \input zapf \input linden }}}
% \stopoverlay
%
% \blank
%
% \startoverlay
%     {\vtop{\color[red]  {\font\test=name:palatinonovaregular*default-node \test \input ward \input zapf \input linden }}}
%     {\vtop{\color[green]{\font\test=name:palatinonovaregular*default-base \test \input ward \input zapf \input linden }}}
%     {\vtop{\color[blue] {\font\test=name:palatinonovaregular*default-none \test \input ward \input zapf \input linden }}}
% \stopoverlay
%
% \startoverlay
%     {\vtop{\color[red]  {\font\test=name:OfficinaSerifBookITC*default-node \test \input ward \input zapf \input linden }}}
%     {\vtop{\color[green]{\font\test=name:OfficinaSerifBookITC*default-base \test \input ward \input zapf \input linden }}}
%     {\vtop{\color[blue] {\font\test=name:OfficinaSerifBookITC*default-none \test \input ward \input zapf \input linden }}}
% \stopoverlay
%
% \definefontfeature[superdefault][default][compose=yes]
%
% {\font\oeps=name:lmroman10regular*default      at 30pt \oeps test \char7683}
% {\font\oeps=name:lmroman10regular*superdefault at 30pt \oeps test \char7683}
%
% \stoptext

\def \defaultfontfile{\truefontname{Normal}} % was cmtt10, but that one is gone
\edef\nullfontname   {\fontname\nullfont}

%D \macros
%D  {everyfont,everyfontswitch}
%D
%D For special purposes, we provide a hook.

% \newevery \everyfont       \relax
% \newevery \everyfontswitch \relax

%D We also accept \type{sa a}||\type{sa d} as specification.

%D \macros
%D   {definefontsynonym, doifelsefontsynonym,
%D    expandfontsynonym, truefontname, truefontdata}
%D
%D While looking for fonts, fontsynonyms are used for accessing
%D the files!
%D
%D \starttyping
%D \definefontsynonym[Serif][Lucida-Bright]
%D \definefontsynonym[Lucida-Bright][lbr][encoding=texnansi]
%D \stoptyping

\def\classfont#1#2{#1#2} % \definefont[whatever][\classfont{xx}{yy} at 10pt]

% We need to move the feature into the filename else it may be
% overloaded by another reference. For instance the definition of
% a regular and caps variant can use the same font.

% We could use an indirect method ... store in 'array' and refer to
% slot.

\def\definefontsynonym[#1]#2[#3]%
  {\edef\@@fontname{#1}%
   \edef\@@fontfile{#3}%
   \ifx\fontclass\empty
      \expandafter\dodefinefontsynonymnop
   \else
      \expandafter\dodefinefontsynonymyes
   \fi}

\def\dodefinefontsynonymnop
  {\@EA\let\csname\??ff\@@fontname\endcsname\@@fontfile % maybe just #1 #3, saves expansion
   \doifnextoptionalelse\dododefinefontsynonymnop\nonodefinefontsynonymnop}

\def\dodefinefontsynonymyes
  {\@EA\let\csname\??ff\fontclass\@@fontname\endcsname\@@fontfile % maybe just #1 #3, saves expansion
   \doifnextoptionalelse\dododefinefontsynonymyes\nonodefinefontsynonymyes}

\def\dododefinefontsynonymnop[#1]%
  {\let\@@ff@@features \undefined
   \let\@@ff@@fallbacks\undefined
   \expandafter\dogetfontparameternop#1,]=,}

\def\dododefinefontsynonymyes[#1]%
  {\let\@@ff@@features \undefined
   \let\@@ff@@fallbacks\undefined
   \expandafter\dogetfontparameteryes#1,]=,}

\def\dogetfontparameternop#1=#2,%
  {\if]#1%
     \dodododefinefontsynonymnop
   \else
     \expandafter\def\csname @@ff@@#1\endcsname{#2}%
     \expandafter\dogetfontparameternop
   \fi}

\def\dogetfontparameteryes#1=#2,%
  {\if]#1%
     \dodododefinefontsynonymyes
   \else
     \expandafter\def\csname @@ff@@#1\endcsname{#2}%
     \expandafter\dogetfontparameteryes
   \fi}

% hm, was wrong, class/global reversed

\let\fcglobal\global
\let\fcxdef  \xdef
\let\fcglet  \glet

\def\nonodefinefontsynonymnop
  {\@EA\let\csname\??ff\@@fontname\s!features \endcsname\undefined
   \@EA\let\csname\??ff\@@fontname\s!fallbacks\endcsname\undefined}

\def\nonodefinefontsynonymyes
  {\fcglobal\@EA\let\csname\??ff\fontclass\@@fontname\s!features \endcsname\undefined
   \fcglobal\@EA\let\csname\??ff\fontclass\@@fontname\s!fallbacks\endcsname\undefined}

\def\dodododefinefontsynonymnop
  {\@EA\let\csname\??ff\@@fontname\s!features \endcsname\@@ff@@features
   \@EA\let\csname\??ff\@@fontname\s!fallbacks\endcsname\@@ff@@fallbacks}

\def\dodododefinefontsynonymyes
  {\fcglobal\@EA\let\csname\??ff\fontclass\@@fontname\s!features \endcsname\@@ff@@features
   \fcglobal\@EA\let\csname\??ff\fontclass\@@fontname\s!fallbacks\endcsname\@@ff@@fallbacks}

\let\definefontfile\definefontsynonym % dedicated to Taco Hoekwater

\def\setupfontsynonym
  {\dodoubleempty\dosetupfontsynonym}

\def\dosetupfontsynonym[#1][#2]%
  {\edef\@@fontdata{#2}%
   \ifx\@@fontdata\empty \else
     \edef\@@fontfile{#1}%
     \ifx\fontclass\empty
       \getfontparameters
     \else
       \getglobalfontparameters
     \fi
   \fi}

\def\truefontname#1%
  {\@EA\dotruefontname#1*\empty*\relax}

\def\dotruefontname#1*#2#3*#4\relax
  {\ifcsname\??ff\fontclass#1\endcsname
     \ifx#2\empty
       \@EA\truefontname\csname\??ff\fontclass#1\endcsname
     \else
       \@EA\redotruefontname\csname\??ff\fontclass#1\endcsname*#2#3%
     \fi
   \else\ifcsname\??ff\defaultfontclass#1\endcsname
     \ifx#2\empty
       \@EA\truefontname\csname\??ff\defaultfontclass#1\endcsname
     \else
       \@EA\redotruefontname\csname\??ff\defaultfontclass#1\endcsname*#2#3%
     \fi
   \else\ifcsname\??ff#1\endcsname
     \ifx#2\empty
       \@EA\truefontname\csname\??ff#1\endcsname
     \else
       \@EA\redotruefontname\csname\??ff#1\endcsname*#2#3%
     \fi
   \else
     #1\ifx#2\empty\else*#2#3\fi
   \fi\fi\fi}

\def\redotruefontname#1%
  {\@EA\dodotruefontname#1*\relax}

\def\dodotruefontname#1*#2\relax
  {\ifcsname\??ff\fontclass#1\endcsname
     \@EA\redotruefontname\csname\??ff\fontclass#1\endcsname
   \else\ifcsname\??ff\defaultfontclass#1\endcsname
     \@EA\redotruefontname\csname\??ff\defaultfontclass#1\endcsname
   \else\ifcsname\??ff#1\endcsname
     \@EA\redotruefontname\csname\??ff#1\endcsname
   \else
     #1%
   \fi\fi\fi}

\def\expandfontsynonym#1#2% #2 := onelevelexpansion(#1)
  {\ifcsname\??ff\fontclass#2\endcsname
     \expandafter\def\expandafter#1\expandafter{\csname\??ff\fontclass#2\endcsname}%
   \else\ifcsname\??ff\defaultfontclass#2\endcsname
     \expandafter\def\expandafter#1\expandafter{\csname\??ff\defaultfontclass#2\endcsname}%
   \fi\fi}

\def\doifelsefontsynonym#1%
  {\ifcsname\??ff\fontclass#1\endcsname
     \@EA\firstoftwoarguments
   \else\ifcsname\??ff\defaultfontclass#1\endcsname
     \@EAEAEA\firstoftwoarguments
   \else
     \@EAEAEA\secondoftwoarguments
   \fi\fi}

% \definetypeface[palatino][rm][serif][palatino,allbold][default]
%
% \startfontclass[palatino]
%   \definefontsynonym [Serif]        [SerifBold]
%   \definefontsynonym [SerifItalic]  [SerifBoldItalic]
%   \definefontsynonym [SerifSlanted] [SerifBoldSlanted]
%   \definefontsynonym [SerifCaps]    [SerifBold]
% \stopfontclass
%
% \setupbodyfont[palatino]

\def\startfontclass
  {\dosingleempty\dostartfontclass}

\def\dostartfontclass[#1]%
  {\pushmacro\fontclass
   \doifelse{#1}\v!each
     {\let\fontclass\empty}
     {\doifsomething{#1}{\def\fontclass{#1}}}}

\def\stopfontclass
  {\popmacro\fontclass}

%D \macros
%D   {tracedfontname}
%D
%D A goody:

\def\tracedfontname#1%
  {#1\ifcsname\??ff\fontclass#1\endcsname
     \@EA\tracedfontname\csname\??ff\fontclass#1\endcsname
   \else\ifcsname\??ff#1\endcsname
     \@EA\tracedfontname\csname\??ff#1\endcsname
   \fi\fi}

%D \macros
%D   {definefont}
%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:

\def\definefont
  {\dotripleempty\dodefinefont}

\def\dodefinefont[#1][#2][#3]% [name][spec][1.6 | line=10pt | setup_id]
  {\ifthirdargument
     \unexpanded\setvalue{#1}{\redodefinefont{#1}{#2}{#3}}%
   \else
     \unexpanded\setvalue{#1}{\dododefinefont{#1}{#2}}%
   \fi}

\def\redodefinefont#1#2#3%
  {\dododefinefont{#1}{#2}%
   \doifsetupselse{#3}
     {\setups[#3]} % don't forget to document this !
     {\setuplocalinterlinespace[#3]%
      \setupspacing}} % needed ?

\def\definefrozenfont
  {\dotripleempty\dodefinefrozenfont}

\def\dodefinefrozenfont[#1][#2][#3]%
  {\dodefinefont[#1][#2][#3]%
   \expandafter\let\csname\lastfontidentifier\expandafter\endcsname\csname\rawfontidentifier\endcsname}

%D The \type {*} makes the switch local, so that we can redefine a
%D logical name and/or change the size in between.

\newif\ifautofontsize \autofontsizetrue

\let\lastfontidentifier\empty

\def\rawfontidentifier{**\lastfontidentifier\fontsize\currentmathsize**}
\def\newfontidentifier{*\fontclass\lastfontidentifier\fontsize\currentmathsize*}

\let\oldrawfontidentifier\rawfontidentifier
\let\oldnewfontidentifier\newfontidentifier

\def\newfontidentifier{*\fontclass\lastfontidentifier\fontstyle\fontsize*}

\def\dododefinefont#1#2%
  {\edef\lastfontidentifier{#1}%
   \let\localrelativefontsize\defaultrelativefontsize
   \let\localabsolutefontsize\fontbody
   \lowleveldefinefont{#2}\rawfontidentifier
%    \let\localrelativefontsize\defaultrelativefontsize % not needed
   \csname\rawfontidentifier\endcsname
   \autofontsizefalse
   \setfontcharacteristics
   \the\everyfontswitch
   \let\rawfontidentifier\oldrawfontidentifier}

\def\xxdododefinefont#1#2#3#4% \autofontsizetrue is set by calling routine
  {\edef\lastfontidentifier{#3}%
   \ifcsname\newfontidentifier\endcsname\else
     \def\localrelativefontsize{#1}%
     \def\localabsolutefontsize{#2}%
     \lowleveldefinefont{#4}\newfontidentifier
%      \let\localrelativefontsize\defaultrelativefontsize % not needed
   \fi
   \csname\newfontidentifier\endcsname
   \autofontsizefalse
  %\edef\lastfontidentifier{#3}%
   \ifskipfontcharacteristics \else
     \setfontcharacteristics
     \the\everyfontswitch
   \fi
   \let\newfontidentifier\oldnewfontidentifier}

%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

\def\mapfontsize
  {\dodoubleargument\domapfontsize}

\def\domapfontsize[#1][#2]%
  {\setvalue{\??ft*\the\dimexpr#1\relax}{#2}}

\def\setmappedfontsize#1%
  {\ifcsname\??ft*#1\endcsname
     \csname\??ft*#1\endcsname
   \else
     #1%
   \fi}

%D \macros
%D   {getfontname}
%D
%D The names of the fonts can be called with the rather simple
%D macro \type{\getfontname}. When for instance we pass
%D \type{12ptrmtf} as argument, we get \getfontname{12ptrmtf}.

\def\getfontname#1%
  {\csname\??ft#1\endcsname}

%D To be documented.

\let\fontsizelist       \empty
\let\fontalternativelist\empty
\let\fontstylelist      \empty

\def\checkfontnamecombinations % we need to split math and text here ... todo (math only has mr and mb)
  {\def\docommand##1%
     {\def\dodocommand####1%
        {\def\dododocommand########1{\checkbodyfont{########1}{####1}{##1}}%
         \processcommacommand[\fontstylelist]\dododocommand}%
      \processcommacommand[\fontalternativelist]\dodocommand}%
   \processcommacommand[\fontsizelist]\docommand}

\def\definefontsize[#1]% sneller met toks
  {\addtocommalist{#1}\fontsizelist
   \checkfontnamecombinations}

\def\definefontalternative[#1]%
  {\addtocommalist{#1}\fontalternativelist
   \checkfontnamecombinations}

%D \macros
%D   {currentfontscale,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.

\def\currentfontscale
  {\csname\??ft\s!default
     \ifcsname\??ft\s!default\xfontsize\endcsname \xfontsize \else
     \ifcsname\??ft\s!default\s!text   \endcsname \s!text    \fi\fi
   \endcsname}

\def\currentfontbodyscale
  {\csname\??ft\s!default
     \ifcsname\??ft\s!default\fontsize\endcsname  \fontsize  \else
     \ifcsname\??ft\s!default\s!text  \endcsname  \s!text    \fi\fi
   \endcsname}

\setvalue{\??ft\s!default}{1}

%D Both alternatives use \type {\xfontsize}, a macro that
%D expands to the current size in terms of \type {a} \unknown
%D \type {d}, nothing, or \type {x} \unknown \type {xx}.

\def\xfontsize{\ifcase\currentxfontsize\fontsize\or\c!x\else\c!xx\fi}

%D A typical use of this command is in commands that switch
%D to another font bypassing the font mechanism:
%D
%D \starttyping
%D \font\myfont=\truefontname{MyFont} at \the\dimexpr\currentfontscale\bodyfontsize\relax
%D \stoptyping

%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 Due to the fact that \type{\c!text} and \type{\s!text} can
%D have a similar meaning, and therefore can lead to an
%D unwanted loop, we temporary redefine \type{\c!text}. For
%D the moment this in only place that some trickery is needed
%D to fool the multilingual interface.
%D
%D When instead of a size the keyword \type{unknown} is
%D passed, fractions (relations) are used instead of fixed
%D sizes.

\let\bodyfontenvironmentlist\empty

\newcount\@@fontdefhack % check if this is still needed

\def\@@beginfontdef
  {\ifcase\@@fontdefhack
     \let\k!savedtext     \k!text      \let\k!text      \s!text
     \let\k!k!savedtext   \k!k!text    \let\k!k!text    \!!plusone
     \let\k!saveddefault  \k!default   \let\k!default   \s!default
     \let\k!k!saveddefault\k!k!default \let\k!k!default \!!plusone
   \fi
   \advance\@@fontdefhack \plusone }

\def\@@endfontdef
  {\advance\@@fontdefhack \minusone
   \ifcase\@@fontdefhack
     \let\k!k!default\k!k!saveddefault
     \let\k!default  \k!saveddefault
     \let\k!k!text   \k!k!savedtext
     \let\k!text     \k!savedtext
   \fi}

\def\definebodyfontenvironment
  {\dotripleempty\dodefinebodyfontenvironment}

\def\dodefinebodyfontenvironment[#1][#2][#3]% class size settings
  {\ifthirdargument
     \@@beginfontdef
     \doifelse{#2}\s!default
       {\getparameters[\??ft\s!default][#3]}
       {\normalizebodyfontsize#2\to\tempbodyfontsize
        \addtocommalist\tempbodyfontsize\bodyfontenvironmentlist
        \@EA\dododefinebodyfontenvironment\@EA[\tempbodyfontsize][#1][#3]}%
     \@@endfontdef
   \else
     \ifx\fontclass\empty\else
       \writestatus\m!fonts{beware: fontclass ignored (if needed use: [fontclass][size][settings])}%
     \fi
     \pushmacro\fontclass
     \let\fontclass\empty
     \definebodyfontenvironment[\fontclass][#1][#2]% change */*
     \popmacro\fontclass
   \fi}

\def\dododefinebodyfontenvironment[#1][#2][#3]% size class settings
  {\@@beginfontdef % \s!text goes wrong in testing because the 12pt alternative will called when typesetting the test (or so)
   \ifcsname\??ft#2#1\c!em\endcsname
      % we test for em as we assume it to be set
   \else
     \def\docommand##1%
% fails: \def\checkbodyfontenvironment[#1]{! #1 ! \definebodyfontenvironment[\fontclass][#1][]} \setupbodyfont[8.5pt]
%        {\normalizebodyfontsize\csname\??ft\s!default##1\endcsname\dimexpr#1\relax\to\tempbodyfontsize
%         \letvalue{\??ft#2#1##1}\tempbodyfontsize}%
        {\scratchdimen\csname\??ft\s!default##1\endcsname\dimexpr#1\relax
         \normalizebodyfontsize\scratchdimen\to\tempbodyfontsize
         \letvalue{\??ft#2#1##1}\tempbodyfontsize}%
     \processcommacommand[\fontrelativesizelist]\docommand
     \copyparameters
       [\??ft#2#1][\??ft\s!default]
       [\c!interlinespace,\c!em]%
   \fi
   \getparameters[\??ft#2#1][#3]%
   \@@endfontdef
   % new code, see remark
   \ifloadingfonts
     % only runtime
   \else\ifcsname\@size@#1\endcsname
     % only once
   \else
     % prevent loop (hence \empty)
     \letvalue{\@size@#1}\empty
     \defineunknownfont{#1}%
   \fi\fi
   % so far
   \setvalue{\@size@#1}{\docompletefontswitch[#1]}}

%D {\bf Remark:} We need to cover the following cases,
%D otherwise users can 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 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.

\def\checkbodyfontenvironment[#1]%
  {\definebodyfontenvironment[\fontclass][#1][]}

\def\checkbodyfontenvironment[#1]%
  {\ifcsname\??ft\fontclass#1\c!em\endcsname
      % we test for em as we assume it to be set
   \else
      \definebodyfontenvironment[\fontclass][#1][]%
   \fi}

% this one already catches both define/setup

\def\setupbodyfontenvironment{\definebodyfontenvironment}

%D Just a couple of interface macros:

\def\bodyfontvariable#1%
  {\??ft\ifcsname\??ft\fontclass#1\endcsname\fontclass\fi#1}

\def\bodyfontinterlinespecs
  {\bodyfontvariable{\normalizedbodyfontsize\c!interlinespace}}

\def\bodyfontinterlinespace
  {\csname\bodyfontinterlinespecs\endcsname}

%D We default all parameters to the main bodyfont size (begin
%D \type{#1}), so the next setup is valid too:
%D
%D \starttyping
%D \definebodyfontenvironment[24pt]
%D \stoptyping
%D
%D All parameters can be redefined when needed, so one does
%D not have to 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.

\def\definebodyfont
  {\doquadrupleempty\redefinebodyfont}

\def\redefinebodyfont[#1][#2][#3][#4]%
  {\iffourthargument
     \processcommacommand[#1]{\reredefinebodyfont[#2][#3][#4]}%
   \else
     \dodefinebodyfont[#1][#2][#3]%
   \fi}

\def\reredefinebodyfont[#1][#2][#3]#4%
  {\pushmacro\fontclass
   \doifelse{#4}\s!default
     {\let\fontclass\empty}
     {\def\fontclass{#4}}%
   \definebodyfont[#1][#2][#3]%
   \popmacro\fontclass}

\def\dodefinebodyfont[#1][#2][#3]% body|identifier style defs|identifier
  {\ifthirdargument
     \doifnumberelse{#1}
       {\doifassignmentelse{#3}
          {% [12pt] [style] [settings]
           \ifcsname#2\endcsname\else\normalexpanded{\noexpand\definefontstyle[#2][#2]}\fi % new
           \processcommalist[#1]{\dododefinebodyfont{#2}{#3}}}
          {% [12pt] [style] [identifier]
           \dodefinedefaultbodyfont[#1][#2][#3]}} % body style identifier
       {% [identifier] [style] [settings] % see ***
        \setvalue{\s!default#1#2}##1##2{\normalexpanded{\noexpand\xdodefinebodyfont[##1][##2][#3]}}}%
   \else\ifsecondargument
     \definebodyfont[#1][\c!rm][#2]%
   \else
     % Maybe there are default dependencies defined which we can use ([unknown]) and
     % if not, then we have at least to make sure some basics are set up.
     \ifcsname\@size@#1\endcsname \else
       \defineunknownfont{#1}%
     \fi
     \ifcsname\@size@#1\endcsname \else
       \definebodyfont[#1][\c!rm][]%
     \fi
   \fi\fi}

\def\xdodefinebodyfont[#1][#2][#3]% body|identifier style defs|identifier
  {\checkrelativefontsize{#2}% rather new, inherit from other defs
   \ifcsname#2\endcsname\else\normalexpanded{\noexpand\definefontstyle[#2][#2]}\fi % new
   \processcommalist[#1]{\dododefinebodyfont{#2}{#3}}%
   \let\relativefontsize\defaultrelativefontsize}

\def\dododefinebodyfont#1#2#3% style defs body
  {\checkbodyfontenvironment[#3]% just to be sure.
   \processcommalist[#2]{\dodododefinebodyfont{#1}{#3}}}

\def\dodododefinebodyfont#1#2#3% style body def
  {\dododododefinebodyfont{#1}{#2}[#3]}

\def\dododododefinebodyfont
  {\ifx\fontclass\empty
     \expandafter\dododododefinebodyfontnop
   \else
     \expandafter\dododododefinebodyfontyes
   \fi}

\def\dododododefinebodyfontyes#1% style body def
  {\edef\askedbodyfontstyle{#1}%
   \ifx\askedbodyfontstyle\c!mm
     \expandafter\dodefinebodyfontyesmm
   \else
     \expandafter\dodefinebodyfontyesxx
   \fi\askedbodyfontstyle} % we can get rid of #1

\def\dododododefinebodyfontnop#1% style body def
  {\edef\askedbodyfontstyle{#1}%
   \ifx\askedbodyfontstyle\c!mm
     \expandafter\dodefinebodyfontnopmm
   \else
     \expandafter\dodefinebodyfontnopxx
   \fi\askedbodyfontstyle} % we can get rid of #1

\def\dodefinebodyfontnopxx#1#2[#3#4#5=#6]% style body def
  {\ifcsname#1#3#4#5\endcsname\else\checkbodyfont{#1}{#3#4}{#5}\fi% not \definefontsize[#5]
   \@EA\let\csname*#2#1#3#4#5*\endcsname\undefined
   \normalprotected\@EA\edef\csname#2#1#3#4#5\endcsname{\noexpand\xxdododefinefont{\number\relativefontsize}{#2}{#2#1#3#4#5}{\normalunexpanded{#6}}}}

\def\dodefinebodyfontyesxx#1#2[#3#4#5=#6]% style body def
  {\ifcsname#1#3#4#5\endcsname\else\checkbodyfont{#1}{#3#4}{#5}\fi% not \definefontsize[#5]
   \fcglobal\@EA\let\csname*\fontclass#2#1#3#4#5*\endcsname\undefined
   \normalprotected\@EA\fcxdef\csname\fontclass#2#1#3#4#5\endcsname{\noexpand\xxdododefinefont{\number\relativefontsize}{#2}{#2#1#3#4#5}{\normalunexpanded{#6}}}}

\def\dodefinebodyfontnopmm#1#2[#3#4#5=#6]% style body def
  {\ifcsname#1#3#4#5\endcsname\else\checkbodyfont{#1}{#3#4}{#5}\fi% not \definefontsize[#5]
   \@EA\let\csname*#2#1#3#4#51*\endcsname\undefined
   \@EA\let\csname*#2#1#3#4#52*\endcsname\undefined
   \@EA\let\csname*#2#1#3#4#53*\endcsname\undefined
   \normalprotected\@EA\edef\csname#2#1#3#4#51\endcsname{\noexpand\xxdododefinefont{\number\relativefontsize}{#2}{#2#1#3#4#51}{\normalunexpanded{#6}}}%
   \normalprotected\@EA\edef\csname#2#1#3#4#52\endcsname{\noexpand\xxdododefinefont{\number\relativefontsize}{#2}{#2#1#3#4#52}{\normalunexpanded{#6}}}%
   \normalprotected\@EA\edef\csname#2#1#3#4#53\endcsname{\noexpand\xxdododefinefont{\number\relativefontsize}{#2}{#2#1#3#4#53}{\normalunexpanded{#6}}}}

\def\dodefinebodyfontyesmm#1#2[#3#4#5=#6]% style body def
  {\ifcsname#1#3#4#5\endcsname\else\checkbodyfont{#1}{#3#4}{#5}\fi% not \definefontsize[#5]
   \fcglobal\@EA\let\csname*\fontclass#2#1#3#4#51*\endcsname\undefined
   \fcglobal\@EA\let\csname*\fontclass#2#1#3#4#52*\endcsname\undefined
   \fcglobal\@EA\let\csname*\fontclass#2#1#3#4#53*\endcsname\undefined
   \normalprotected\@EA\fcxdef\csname\fontclass#2#1#3#4#51\endcsname{\noexpand\xxdododefinefont{\number\relativefontsize}{#2}{#2#1#3#4#51}{\normalunexpanded{#6}}}%
   \normalprotected\@EA\fcxdef\csname\fontclass#2#1#3#4#52\endcsname{\noexpand\xxdododefinefont{\number\relativefontsize}{#2}{#2#1#3#4#52}{\normalunexpanded{#6}}}%
   \normalprotected\@EA\fcxdef\csname\fontclass#2#1#3#4#53\endcsname{\noexpand\xxdododefinefont{\number\relativefontsize}{#2}{#2#1#3#4#53}{\normalunexpanded{#6}}}}

\def\checkbodyfont#1% tests for ttsl mmbf
  {\edef\c!!mm{#1}%
   \ifx\c!!mm\c!mm % prevents \max and alike (re)defs
     \expandafter\checkmathbodyfont
   \else
     \expandafter\checktextbodyfont
   \fi{#1}} % no \c!!mm, not expanded later on

% some day we can do an auto-fam if needed

\def\checkmathbodyfont#1#2#3% style alt size / gdef % #3 can be empty
  {%\message{!m #1 #2 #3!}%
   % #1 #2 #3 = signal
   %unexpanded\setgvalue     {#2}{\setcurrentfontalternative         {#2}}%         \mr \mb
   \unexpanded\setgvalue     {#1}{\setcurrentfontstyle               {#1}}}%        \mm

\def\checktextbodyfont#1#2#3% style alt size / gdef % #3 can be empty
  {%\message{!t #1 #2 #3!}%
   \unexpanded\setgvalue   {#1#3}{\setcurrentfontstylesize           {#1}{#3}}%     \rma
   \unexpanded\setgvalue   {#2#3}{\setcurrentfontalternativesize     {#2}{#3}}%     \sla
   \unexpanded\setgvalue {#1#2#3}{\setcurrentfontstylealternativesize{#1}{#2}{#3}}% \rmsla
   \unexpanded\setgvalue     {#1}{\setcurrentfontstyle               {#1}}%         \rm
   \unexpanded\setgvalue     {#2}{\setcurrentfontalternative         {#2}}%         \sl
   \unexpanded\setgvalue {#1\c!x}{\setcurrentfontxstylealternative   {#1}}%         \rmx
   \unexpanded\setgvalue{#1\c!xx}{\setcurrentfontxxstylealternative  {#1}}%         \rmxx
   \unexpanded\setgvalue {#2\c!x}{\setcurrentfontxalternative        {#2}}%         \slx
   \unexpanded\setgvalue{#2\c!xx}{\setcurrentfontxxalternative       {#2}}%         \slxx
   \unexpanded\setgvalue   {#1#2}{\setcurrentfontstylealternative    {#1}{#2}}}%    \rmsl

\def\dodefinedefaultbodyfont[#1][#2][#3]% sizes styles identifier
  {\def\dododefinedefaultbodyfont##1%
     {\def\dodododefinedefaultbodyfont####1%
        {\def\dododododefinedefaultbodyfont########1%
           {\ifcsname\s!default########1####1\endcsname
              % [12pt] [style] [identifier]
              \csname\s!default########1####1\endcsname{##1}{####1}%
            \fi}%
         \processcommalist[#3]\dododododefinedefaultbodyfont}%
      \processcommalist[#2]\dodododefinedefaultbodyfont}%
   \processcommalist[#1]\dododefinedefaultbodyfont}

%D Unknown families are added to the family list! For the
%D moment we also set the direct calls here. Some day a better
%D solution will be implemented. The good news is that unknown
%D fonts are defined automatically.

\newif\ifdefiningunknownfont

\def\dodefineunknownfont#1#2%
  {\ifcsname\??ft\s!default#2\endcsname
     \donetrue
     \normalizebodyfontsize\csname\??ft\s!default#2\endcsname\dimexpr#1\relax\to\tempbodyfontsize
     \letvalue{\??ft#1#2}\tempbodyfontsize
   \fi}

\def\dodefineunknownbodyfont#1#2% see ***
  {\ifcsname\s!default\s!default#2\endcsname % somehow related to */*
     \donetrue
     \csname\s!default\s!default#2\endcsname{#1}{#2}%
   \fi}

\def\dodefineunknownsubfont#1#2%
  {\ifcsname\@size@\csname\??ft#1#2\endcsname\endcsname
   \else
     \donetrue
     \defineunknownfont{\csname\??ft#1#2\endcsname}%
   \fi}

\def\defineunknownfont#1%
  {\let\c!savedtext\c!text
   \let\c!text\s!text
   \donefalse
   \processcommacommand[\fontrelativesizelist]{\dodefineunknownfont{#1}}%
   \let\c!text\c!savedtext
   \ifdone
     \donefalse
     \processcommacommand
       [\fontstylelist]
       {\dodefineunknownbodyfont{#1}}%
     \ifdone
     \donefalse
       \setvalue{\@size@#1}{\docompletefontswitch[#1]}%
       \ifdefiningunknownfont \else
         \definingunknownfonttrue
         \processcommacommand[\fontrelativesizelist]{\dodefineunknownsubfont{#1}}%
         \definingunknownfontfalse
       \fi
     \fi
     \ifdone
       \showmessage\m!fonts{14}{#1}%
     \fi
   \fi}

%D These macros show that quite some definitions take place.
%D Fonts are not loaded yet! This means that at format
%D generation time, no font files are preloaded.

%D A previous implementation used:
%D
%D \starttyping
%D \type {\setvalue{name}{\donottest...}}
%D \stoptyping
%D
%D instead of the more memory hungry:
%D
%D \starttyping
%D \unexpanded\setvalue{name}{...}
%D \stoptyping
%D
%D The first alternative saves about 500 hash entries (about
%D 2.5\% of the total number of entries used. The second
%D alternative is currently used, because that one can more
%D easily be made \ETEX\ aware.

%D \macros
%D   {everybodyfont,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 At the system level one can initialize thing like:
%D
%D \starttyping
%D \appendtoks \setupspacing \to \everybodyfont
%D \stoptyping
%D
%D While users can add their own non standard commands like:
%D
%D \starttyping
%D \EveryBodyFont{\message{changing to bodyfont \the\bodyfontsize}}
%D \stoptyping
%D
%D Personnaly I never felt the need for such extensions, but
%D at least its possible.

%D \macros
%D   {globalbodyfontsize,localbodyfontsize}
%D
%D Next we'll do the tough job of font switching. Here we
%D have to distinguish between the global (overal) bodyfont
%D size and the local (sometimes in the textflow) size. We
%D store these dimensions in two \DIMENSION\ registers.

\ifdefined\globalbodyfontsize\else \newdimen\globalbodyfontsize \fi \globalbodyfontsize=12pt
\ifdefined\localbodyfontsize \else \newdimen\localbodyfontsize  \fi \localbodyfontsize =\globalbodyfontsize

%D \macros
%D   {bodyfontsize}
%D
%D These two registers are not to be misused in calculations.
%D For this purpose we keep a copy:

\newdimen\bodyfontsize  \bodyfontsize=\globalbodyfontsize

%D \macros
%D   {outputresolution}
%D
%D Sometimes (to be honest: not in this module) we need to
%D take the system resolution into account. Therefore we also
%D define a macro:

\def\outputresolution {600}

%D \macros
%D   {bodyfontfactor,bodyfontpoints}
%D
%D For multiplication purposes we keep an auxiliary counter
%D and macro (here the expansion is not explicitly needed):

\newcount\bodyfontpoints \dimensiontocount\bodyfontsize\bodyfontpoints

\edef\bodyfontfactor{\withoutpt\the\bodyfontsize}

%D When we assign for instance 12pt to a \DIMENSION\ register
%D the \type{\the}'d value comes out as 12.0pt, which is
%D often not the way users specify the bodyfont size. Therefore
%D we also store the normalized value.

\chardef\fontdigits=2 % was 1

\def\normalizebodyfontsize#1\to#2%
  {\@EA\@EA\@EA\donormalizedbodyfontsize\@EA\WITHOUTPT\the\dimexpr#1+\ifcase\fontdigits.5\or.05\or.005\fi\points\relax000\to#2}

\def\donormalizedbodyfontsize#1.#2#3#4#5\to#6% \points ?
  {\edef#6% not \ifcase#2\else due to \relax adding
     {#1%
      \ifcase\fontdigits
        \or   \ifcase#2     \else .#2\fi                                            % 1
        \or   \ifcase#2#3   \else .#2\ifcase#3                      \else  #3\fi\fi % 2
        \else \ifcase#2#3#4 \else .#2\ifcase#4 \ifcase#3 \else#3\fi \else#3#4\fi\fi % 3
      \fi
      \s!pt}}

% not faster, just less tracing
%
% \def\setfontdigits#1%
%   {\chardef\fontdigits\ifnum#1>\plusthree\plusthree\else#1\fi\relax
%    \@EA\let\@EA\normalizedbfs\csname normalizedbfs\number\fontdigits\endcsname}
%
% \def\normalizebodyfontsize#1\to#2%
%   {\@EA\@EA\@EA\normalizedbfs\@EA\WITHOUTPT\the\dimexpr#1+\ifcase\fontdigits.5\or.05\or.005\fi\points\relax000\to#2}
%
% \setvalue{normalizedbfs0}#1.#2\to      #3{\edef#3{#1\s!pt}}
% \setvalue{normalizedbfs1}#1.#2#3\to    #4{\edef#4{#1\ifcase#2 \else.#2\fi\s!pt}}
% \setvalue{normalizedbfs2}#1.#2#3#4\to  #5{\edef#5{#1\ifcase#2#3 \else.#2\ifcase#3 \else#3\fi\fi\s!pt}}
% \setvalue{normalizedbfs3}#1.#2#3#4#5\to#6{\edef#6{#1\ifcase#2#3#4 \else.#2\ifcase#4 \ifcase#3 \else#3\fi\else#3#4\fi\fi\s!pt}}
%
% \setfontdigits2

\normalizebodyfontsize\bodyfontsize\to\normalizedglobalbodyfontsize
\normalizebodyfontsize\bodyfontsize\to\normalizedlocalbodyfontsize
\normalizebodyfontsize\bodyfontsize\to\normalizedbodyfontsize

%D \macros
%D   {fontstyle,fontalternative,fontsize}
%D
%D Within a bodyfont, fonts can come in different sizes. For
%D instance \type{\tf} is accompanied by \type{\tfa},
%D \type{\tfb} etc. The first two characters denote the
%D alternative, while the third character in these sequences
%D represents the size. The actual size is saved in a macro
%D
%D The style, being roman (\type{\rm}), sans serif (\type{\ss})
%D etc. is also available in a macro in \type{rm}, \type{ss}
%D etc. form:

\let\defaultfontalternative = \c!tf
\let\defaultfontstyle       = \empty
\let\defaultfontsize        = \empty

\let\fontalternative = \defaultfontalternative
\let\fontstyle       = \defaultfontstyle
\let\fontsize        = \defaultfontsize

%D When \type {\loadfontfileoncetrue}, such files are
%D only loaded once! This permits redundant loading, but at
%D the same time forced grouping when we want continuously mix
%D all kind of font, which of course is a kind of
%D typographically sin. The \type{"} is made inactive if
%D needed to prevent problems with loading files that use this
%D character in numbers.

% can be made faster (only used internally now)

\def\doswitchpoints[#1]%
  {\normalexpanded{\dodoswitchpoints{#1}}}

\unexpanded \def\dodoswitchpoints#1%
  {\ifcsname\@size@#1\endcsname \else
     \defineunknownfont{#1}%
   \fi%
  %\defineunknownfontstyles{#1}%
   \ifcsname\@size@#1\endcsname
     \csname\@size@#1\endcsname
     \localbodyfontsize#1\relax
     \normalizebodyfontsize\localbodyfontsize\to\normalizedbodyfontsize
   % \edef\fontbody{\fontbody}% to be tested but we can clean up mkiv further
     \checkbodyfontenvironment[\normalizedbodyfontsize]%
   \else
     \showmessage\m!fonts4{#1}%
   \fi}

\unexpanded \def\doswitchstyle[#1]%
  {\ifcsname\@style@#1\endcsname
     \csname\@style@#1\endcsname
     \edef\fontstyle{#1}%
     \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{#1}%
   \fi}

%D \TEX\ loads font metric files like \type{cmr10.tfm} and
%D \type{tir.tfm} only once. In \PLAIN\ \TEX\ some font files
%D are {\em preloaded}. This means that the font files are
%D loaded, but not accessible yet by name. This is accomplished
%D by saying:
%D
%D \starttyping
%D \font\preloaded=cmr10 at 11pt
%D \stoptyping
%D
%D and using the name \type{\preloaded} again and again, so
%D fonts are indeed loaded, but unnamed, and therefore
%D unaccessible. In \CONTEXT\ we don't preload fonts, not even
%D the \PLAIN\ \TEX\ ones, although users can access them. Now
%D why is this done?

%D Defining fonts using \type{\definebodyfont} takes time, so we
%D prefer to predefine at least the Computer Modern Roman
%D fonts. However, loading all those fonts at definition time
%D would take both time and space. But even worse, once fonts
%D are loaded into memory, their encoding vector is fixed,
%D which is a handicap when we want to distribute the compact
%D \type{fmt} files. So what we want to do is defining fonts in
%D a way that postpones the loading. We accomplish this by only
%D loading the fonts when we switch to another bodyfont size.
%D Among the other alternatives, such as loading the font at
%D the moment of activation and redefining the activation
%D macro afterwards, this proved to be the most efficient
%D alternative.
%D
%D The next few macros take care of the one exeption on this
%D scheme. When at format generation time we load the default
%D font file, the one that defines the Computer Modern Fonts,
%D we don't want the fonts metrics to end up in the format
%D file, so we temporary prohibit loading. This means that at
%D runtime we have to load the default bodyfont size just before
%D we start typesetting.
%D
%D Therefore we have to signal the font switching macros that
%D we are preloading fonts. As long as the next boolean is,
%D true, no loading is done.

\newif\ifloadingfonts \loadingfontstrue

%D \macros
%D   {preloadfonts}
%D
%D Preloading is only called for once, during the startup
%D sequence of a session. After the loading job is done, the
%D macro relaxes itself and reset the signal.

% \appendtoks
% \to \everysetupdocument

\newconditional\fontsareloaded

\def\preloadfonts % never called, needs a clean up
  {\global\loadingfontsfalse
   \ifconditional\fontsareloaded \else
     \doifmodeelse {*nofonts}
       {\writestatus\m!fonts{latin modern fonts are not preloaded}}
       {\writestatus\m!fonts{preloading latin modern fonts}%
        \usetypescript[modern]%
        \setuptypeface[modern]%
        \showmessage\m!fonts6{\normalizedbodyfontsize\normalspace\fontstyle}}%
   \fi
   \global\let\preloadfonts\relax}

% maybe add this to \everystarttext
%
% \ifconditional\fontsareloaded\else
%   \usetypescript[modern]%
%   \setuptypeface[modern]%
% \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.

\def\dosetfont#1#2%  #1 = set/switch state
  {\doifelse{#2}\v!global
     {\restoreglobalbodyfont}
     {\processcommacommand[#2]{\dodosetfont{#1}}% ##1 get also passed
      \ifloadingfonts\else
        \global\settrue\fontsareloaded
        \doswitchpoints[\normalizedbodyfontsize]%
        \doswitchstyle[\fontstyle]%
        \ifx\defaultfontclass\empty
          \let\defaultfontclass\fontclass
        \fi
      \fi}%
   \chardef\currentxfontsize\zerocount}

\def\dodosetfont#1#2%  #1 = set/switch state | check fo rempty, else space
  {\doifsomething{#2}{\dododosetfont{#1}{#2}{\showmessage\m!fonts4{#2}}}}

% % % this can be retrofitted in mkii code % % %

% \def\normalizebodyfontsize#1\to#2%
%   {\@EA\@EA\@EA\donormalizedbodyfontsize\@EA\WITHOUTPT\the\dimexpr#1+\ifcase\fontdigits.5\or.05\or.005\fi\points\relax000\to#2}

\def\dododosetfont#1#2#3% #1 = set/switch state ! ! ! !could also be used for mkii
  {\doifnumberelse{#2}\dodododosetfont\redododosetfont{#1}{#2}{#3}}

\def\redododosetfont#1#2#3% #1 = set/switch state ! ! ! !could also be used for mkii
  {\edef\expandedfontthing{#2}%
   \def\interfacedfontsize{\normalizedbodyfontsize\interfaced\expandedfontthing}%
   \ifcsname\??ft\interfacedfontsize\endcsname
     \edef\fontstep{\csname\bodyfontvariable\interfacedfontsize\endcsname}%
     \normalexpanded{\noexpand\dodododosetfont{#1}{\fontstep}}{#3}%
   \else\ifx\expandedfontthing\v!reset
     \let\fontstyle\empty % new 31/7/2006
     \let\fontsize \empty
   \else
      \ifcsname\@style@\expandedfontthing\endcsname
        \let\fontstyle\expandedfontthing
      \else
        \setcurrentfontclass\expandedfontthing
        \ifcase#1\relax
          \let\globalfontclass\globalfontclass
        \else
          \let\globalfontclass\fontclass
        \fi
        \ifx\fontclass\empty
          \let\fontstyle\c!rm
        \else\ifcsname\??tf\fontclass\s!default\endcsname
          \edef\fontstyle{\csname\??tf\fontclass\s!default\endcsname}%
        \else
          \let\fontstyle\c!rm
        \fi\fi
      \fi
   \fi\fi}

\def\dodododosetfont#1#2#3% #1 = set/switch state
  {\normalizebodyfontsize#2\to\normalizedsetfont
   \ifcsname\@size@\normalizedsetfont\endcsname \else
     \defineunknownfont{#2}%
   \fi
   \ifcsname\@size@\normalizedsetfont\endcsname
     \localbodyfontsize\normalizedsetfont
     \let\normalizedbodyfontsize\normalizedsetfont
   \else
     #3\dosetsubstitutefont{#1}{#2}%
   \fi}

% % %

%D In the previous 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.

\chardef\currentxfontsize=0

%D When users specify for instance a 13 point bodyfont while no
%D such bodyfont is defined, the system automatically tries to
%D find a best fit, that is the nearest smaller defined
%D bodyfontzize. A smaller one is definitely better than a larger
%D one, simply because otherwise a lot of overfull box messages
%D are more probable to occur. By taking a value slightly
%D smaller than half a point, we can use the next method.

\def\dosetsubstitutefont#1#2% #1 = set/switch state
  {\scratchdimen#2\relax
   \advance\scratchdimen .499\points
   \dimensiontocount\scratchdimen\scratchcounter
   \advance\scratchcounter \minusone
   \ifnum\scratchcounter>\plusthree
     \dododosetfont{#1}{\the\scratchcounter\s!pt}{}%
   \fi}

% The following bunch of macros deals with the (run time)
% expansion of names onto the definitions made by \type
% {\definebodyfont}.

% \let\fontbody       \empty % ... 10pt 11pt 12pt ...
% \let\fontstyle      \empty % rm ss tt mm hw cg ...
% \let\fontalternative\empty % tf bf sl it bs bi sc ...
% \let\fontsize       \empty % xy-abcd ...

\def\defaultfontbody{\normalizedbodyfontsize}

\let\fontbody\defaultfontbody

\let\fontclass\empty \let\globalfontclass\fontclass

% we need to check the fontclass

\def\registerfontclass#1%
  {\letgvalue{\@fontclass@#1}\v!yes} % global ?

\def\setcurrentfontclass#1%
  {\ifcsname\@fontclass@#1\endcsname
     \edef\fontclass{#1}%
   \fi}

\let\defaultfontstyle       \c!rm
\let\defaultfontalternative \c!tf
\let\defaultfontsize        \empty

%D \macros
%D   {bigmath,nobigmath}
%D
%D We can inhibit this slow||downer with:

% these can best be combined

% 0=never 1=everymath 2=always

\chardef\synchronizebigmathflag=1

\appendtoks
  \ifcase\synchronizebigmathflag
    % never
  \or
    \synchronizebigmath
  \or
    % always
  \fi
\to \everymathematics

\def\nobigmath  {\chardef\synchronizebigmathflag\zerocount}
\def\autobigmath{\chardef\synchronizebigmathflag\plusone\synchronizebigmath}
\def\bigmath    {\chardef\synchronizebigmathflag\plustwo\synchronizebigmath}

\let\bigmathfontsize\empty

\def\synchronizebigmath
  {\ifx\bigmathfontsize\fontsize
     % already in sync
   \else
     \let\bigmathfontsize\fontsize
     \synchronizemath
   \fi}

\def\checkbigmathsynchronization
  {\ifcase\synchronizebigmathflag
     % never
   \or
     \ifmmode \synchronizebigmath \fi
   \or
     \synchronizebigmath
   \fi}

%D So far for synchronisation. (We can inline the following macros.)

\def\dosetcurrentfontsize#1%
  {\edef\fontsize{#1}%
   \checkbigmathsynchronization}

\def\dosetcurrentfontalternative#1%
  {\edef\fontalternative{#1}}

\def\setcurrentfont#1#2#3#4%
  {%\message{[1 #1 #2 #3 #4]}%
   \edef\fontbody{#1}%
   \edef\fontstyle{#2}%
   \dosetcurrentfontalternative{#3}%
   \dosetcurrentfontsize{#4}%
   \synchronizefont}

\def\setcurrentfontbody#1%
  {%\message{[2 #1]}%
   \edef\fontbody{#1}%
   \synchronizefont}

% For Taco: optional fall backs:

\ifx\checkfontclass\undefined \let\checkfontclass\gobbleoneargument \fi % implemented in type-ini

% \def\setcurrentfontstyle#1%
%   {%\message{[3 #1]}%
%    \checkfontclass{#1}%
%    \edef\fontstyle{#1}%
%    \ifmmode\mr\fi % otherwise \rm not downward compatible
%    \synchronizefont}

\def\setcurrentfontstyle#1%
  {%\message{[3 #1]}%
   \edef\fontstyle{#1}%
   \checkfontclass\fontstyle
   \ifmmode\mr\fi % otherwise \rm not downward compatible
   \synchronizefont}

\def\setcurrentfontbodyalternative#1#2%
  {%\message{[4 #1 #2]}%
   \edef\fontbody{#1}%
   \dosetcurrentfontalternative{#2}%
   \synchronizefont}

\def\setcurrentfontalternative#1%
  {%\message{[5 #1]}%
   \dosetcurrentfontalternative{#1}%
   \synchronizefont}

\def\setcurrentfontsize#1%
  {%\message{[6 #1]}%
   \dosetcurrentfontsize{#1}%
   \synchronizefont}

\def\setcurrentfontstylealternative#1#2% \rmsl
  {%\message{[7 #1 #2]}%
   \edef\fontstyle{#1}%
   \dosetcurrentfontalternative{#2}%
   \synchronizefont}

\def\setcurrentfontstylesize#1#2% \rmsla
  {%\message{[8 #1 #2]}%
   \edef\fontstyle{#1}%
   \dosetcurrentfontsize{#2}%
   \synchronizefont}

\def\setcurrentfontalternativesize#1#2% \sla
  {%\message{[9 #1 #2]}%
   \dosetcurrentfontalternative{#1}%
   \dosetcurrentfontsize{#2}%
   \synchronizefont}

\def\setcurrentfontstylealternativesize#1#2#3% \rmsla
  {%\message{[10 #1 #2 #3]}%
   \edef\fontstyle{#1}%
   \dosetcurrentfontalternative{#2}%
   \dosetcurrentfontsize{#3}%
   \synchronizefont}

%D In principle one can assign alternative fallback routines.
%D Some day we will.

\newtoks\fontstrategies
\newif\iftryingfont

\let\fontstrategy\relax

% \def\synchronizefont
%   {\tryingfonttrue
%    \ifx\fontclass\empty\else
%      \global\let\fontstrategy\dofontclassstrategy
%      \the\fontstrategies \relax % \relax still needed ?
%    \fi
%    \iftryingfont
%      \global\let\fontstrategy\dofontstrategy
%      \the\fontstrategies \relax % \relax still needed ?
%    \fi
%    \autofontsizefalse
%    \ifskipfontcharacteristics
%      \setfontcharacteristics
%      \the\everyfontswitch
%    \fi}

% \def\dofontstrategy#1#2#3#4#5%
%   {\ifcsname#2#3#4#5\endcsname
%      #1\csname#2#3#4#5\endcsname \tryingfontfalse
%    \fi}

% \def\dofontclassstrategy#1#2#3#4#5%
%   {\ifcsname\fontclass#2#3#4#5\endcsname
%      #1\csname\fontclass#2#3#4#5\endcsname \tryingfontfalse
%    \fi}

% \def\synchronizefont % we can have dups i.e. no need to let fontstrategy
%   {\tryingfonttrue
%    \ifx\fontclass\empty\else
%      \global\let\fontstrategy\dofontclassstrategy
%      \applyfontstrategies
%    \fi
%    \iftryingfont
%      \global\let\fontstrategy\dofontstrategy
%      \applyfontstrategies
%    \fi
%    \autofontsizefalse
%    \ifskipfontcharacteristics
%      \setfontcharacteristics
%      \the\everyfontswitch
%    \fi}

\def\synchronizefont % we can have dups i.e. no need to let fontstrategy
  {\tryingfonttrue
   \ifx\fontclass\empty
     \applyfontstrategies
   \else
     \applyfontclassstrategies
   \fi
   \autofontsizefalse
   \ifskipfontcharacteristics
     \setfontcharacteristics
     \the\everyfontswitch
   \fi}

% \appendtoks \iftryingfont \fontstrategy \autofontsizefalse % --- --- --- --- % pt tt bf a
%   \fontbody \fontstyle \fontalternative \fontsize
% \fi \to \fontstrategies
%
% \appendtoks \iftryingfont \fontstrategy \autofontsizetrue  % --- --- --- def % pt tt bf
%   \fontbody \fontstyle \fontalternative \defaultfontsize
% \fi \to \fontstrategies
%
% \appendtoks \iftryingfont \fontstrategy \autofontsizetrue  % --- --- def --- % pt tt tf a
%   \fontbody \fontstyle \defaultfontalternative \fontsize
% \fi \to \fontstrategies
%
% \appendtoks \iftryingfont \fontstrategy \autofontsizetrue  % --- --- def def % pt tt tf
%   \fontbody \fontstyle \defaultfontalternative \defaultfontsize
% \fi \to \fontstrategies
%
% \appendtoks \iftryingfont \fontstrategy \autofontsizefalse % --- def def def % pt rm tf
%   \fontbody \defaultfontstyle \defaultfontalternative \defaultfontsize
% \fi \to \fontstrategies
%
% \appendtoks \iftryingfont \fontstrategy \autofontsizetrue  % def def def def % rm tf
%   \defaultfontbody \defaultfontstyle \defaultfontalternative \defaultfontsize
% \fi \to \fontstrategies

% \def\fontstrategiesa % --- --- --- --- % pt tt bf a
%   {\fontstrategy \autofontsizefalse \fontbody \fontstyle \fontalternative \fontsize
%    \iftryingfont \fontstrategiesb \fi}
% \def\fontstrategiesb % --- --- --- def % pt tt bf
%   {\fontstrategy \autofontsizetrue  \fontbody \fontstyle \fontalternative \defaultfontsize
%    \iftryingfont \fontstrategiesc \fi}
% \def\fontstrategiesc % --- --- def --- % pt tt tf a
%   {\fontstrategy \autofontsizetrue \fontbody \fontstyle \defaultfontalternative \fontsize
%    \iftryingfont \fontstrategiesd \fi}
% \def\fontstrategiesd % --- --- def def % pt tt tf
%   {\fontstrategy \autofontsizetrue \fontbody \fontstyle \defaultfontalternative \defaultfontsize
%    \iftryingfont \fontstrategiese \fi}
% \def\fontstrategiese % --- def def def % pt rm tf
%   {\fontstrategy \autofontsizefalse \fontbody \defaultfontstyle \defaultfontalternative \defaultfontsize
%    \iftryingfont \fontstrategiesf \fi}
% \def\fontstrategiesf % def def def def % rm tf
%   {\fontstrategy \autofontsizetrue \defaultfontbody \defaultfontstyle \defaultfontalternative \defaultfontsize}

% \fontstrategies {\fontstrategiesa}
% \let\applyfontstrategies\fontstrategiesa

% \def\fontclassstrategiesa % --- --- --- --- % pt tt bf a
%   {\dofontclassstrategy \autofontsizefalse \fontbody \fontstyle \fontalternative \fontsize
%    \iftryingfont \fontclassstrategiesb \fi}
% \def\fontclassstrategiesb % --- --- --- def % pt tt bf
%   {\dofontclassstrategy \autofontsizetrue  \fontbody \fontstyle \fontalternative \defaultfontsize
%    \iftryingfont \fontclassstrategiesc \fi}
% \def\fontclassstrategiesc % --- --- def --- % pt tt tf a
%   {\dofontclassstrategy \autofontsizetrue \fontbody \fontstyle \defaultfontalternative \fontsize
%    \iftryingfont \fontclassstrategiesd \fi}
% \def\fontclassstrategiesd % --- --- def def % pt tt tf
%   {\dofontclassstrategy \autofontsizetrue \fontbody \fontstyle \defaultfontalternative \defaultfontsize
%    \iftryingfont \fontclassstrategiese \fi}
% \def\fontclassstrategiese % --- def def def % pt rm tf
%   {\dofontclassstrategy \autofontsizefalse \fontbody \defaultfontstyle \defaultfontalternative \defaultfontsize
%    \iftryingfont \fontclassstrategiesf \fi}
% \def\fontclassstrategiesf % def def def def % rm tf
%   {\dofontclassstrategy \autofontsizetrue \defaultfontbody \defaultfontstyle \defaultfontalternative \defaultfontsize}

\def\fontclassstrategiesa % --- --- --- --- % pt tt bf a
  {\ifcsname\fontclass\fontbody \fontstyle \fontalternative \fontsize\endcsname
     \autofontsizefalse
     \csname\fontclass\fontbody \fontstyle \fontalternative \fontsize\endcsname
   \else
     \expandafter\fontclassstrategiesb
   \fi}

\def\fontclassstrategiesb % --- --- --- def % pt tt bf
  {\ifcsname\fontclass\fontbody \fontstyle \fontalternative \defaultfontsize\endcsname
     \autofontsizetrue
     \csname\fontclass\fontbody \fontstyle \fontalternative \defaultfontsize\endcsname
   \else
     \expandafter\fontclassstrategiesc
   \fi}

\def\fontclassstrategiesc % --- --- def --- % pt tt tf a
  {\ifcsname\fontclass\fontbody \fontstyle \defaultfontalternative \fontsize\endcsname
     \autofontsizetrue
     \csname\fontclass\fontbody \fontstyle \defaultfontalternative \fontsize\endcsname
   \else
     \expandafter\fontclassstrategiesd
   \fi}

\def\fontclassstrategiesd % --- --- def def % pt tt tf
  {\ifcsname\fontclass\fontbody \fontstyle \defaultfontalternative \defaultfontsize\endcsname
     \autofontsizetrue
     \csname\fontclass\fontbody \fontstyle \defaultfontalternative \defaultfontsize\endcsname
   \else
     \expandafter\fontclassstrategiese
   \fi}

\def\fontclassstrategiese % --- def def def % pt rm tf
  {\ifcsname\fontclass\fontbody \defaultfontstyle \defaultfontalternative \defaultfontsize\endcsname
     \autofontsizefalse
     \csname\fontclass\fontbody \defaultfontstyle \defaultfontalternative \defaultfontsize\endcsname
   \else
     \expandafter\fontclassstrategiesf
   \fi}

\def\fontclassstrategiesf % def def def def % rm tf
  {\ifcsname\fontclass\defaultfontbody \defaultfontstyle \defaultfontalternative \defaultfontsize\endcsname
     \autofontsizetrue
     \csname\fontclass\defaultfontbody \defaultfontstyle \defaultfontalternative \defaultfontsize\endcsname
   \else
     \expandafter\fontstrategiesa
   \fi}

% no class

% \def\fontstrategiesa % --- --- --- --- % pt tt bf a
%   {\dofontstrategy \autofontsizefalse \fontbody \fontstyle \fontalternative \fontsize
%    \iftryingfont \fontstrategiesb \fi}
% \def\fontstrategiesb % --- --- --- def % pt tt bf
%   {\dofontstrategy \autofontsizetrue  \fontbody \fontstyle \fontalternative \defaultfontsize
%    \iftryingfont \fontstrategiesc \fi}
% \def\fontstrategiesc % --- --- def --- % pt tt tf a
%   {\dofontstrategy \autofontsizetrue \fontbody \fontstyle \defaultfontalternative \fontsize
%    \iftryingfont \fontstrategiesd \fi}
% \def\fontstrategiesd % --- --- def def % pt tt tf
%   {\dofontstrategy \autofontsizetrue \fontbody \fontstyle \defaultfontalternative \defaultfontsize
%    \iftryingfont \fontstrategiese \fi}
% \def\fontstrategiese % --- def def def % pt rm tf
%   {\dofontstrategy \autofontsizefalse \fontbody \defaultfontstyle \defaultfontalternative \defaultfontsize
%    \iftryingfont \fontstrategiesf \fi}
% \def\fontstrategiesf % def def def def % rm tf
%   {\dofontstrategy \autofontsizetrue \defaultfontbody \defaultfontstyle \defaultfontalternative \defaultfontsize}

\def\fontstrategiesa % --- --- --- --- % pt tt bf a
  {\ifcsname\fontbody \fontstyle \fontalternative \fontsize\endcsname
     \autofontsizefalse
     \csname\fontbody \fontstyle \fontalternative \fontsize\endcsname
   \else
     \expandafter\fontstrategiesb
   \fi}

\def\fontstrategiesb % --- --- --- --- % pt tt bf a
  {\ifcsname\fontbody \fontstyle \fontalternative \defaultfontsize\endcsname
     \autofontsizetrue
     \csname\fontbody \fontstyle \fontalternative \defaultfontsize\endcsname
   \else
     \expandafter\fontstrategiesc
   \fi}

\def\fontstrategiesc % --- --- --- --- % pt tt bf a
  {\ifcsname\fontbody \fontstyle \defaultfontalternative \fontsize\endcsname
     \autofontsizetrue
     \csname\fontbody \fontstyle \defaultfontalternative \fontsize\endcsname
   \else
     \expandafter\fontstrategiesd
   \fi}

\def\fontstrategiesd % --- --- --- --- % pt tt bf a
  {\ifcsname\fontbody \fontstyle \defaultfontalternative \defaultfontsize\endcsname
     \autofontsizetrue
     \csname\fontbody \fontstyle \defaultfontalternative \defaultfontsize\endcsname
   \else
     \expandafter\fontstrategiese
   \fi}

\def\fontstrategiese % --- --- --- --- % pt tt bf a
  {\ifcsname\fontbody \defaultfontstyle \defaultfontalternative \defaultfontsize\endcsname
     \autofontsizefalse
     \csname\fontbody \defaultfontstyle \defaultfontalternative \defaultfontsize\endcsname
   \else
     \expandafter\fontstrategiesf
   \fi}

\def\fontstrategiesf % --- --- --- --- % pt tt bf a
  {\ifcsname\defaultfontbody \defaultfontstyle \defaultfontalternative \defaultfontsize\endcsname
     \autofontsizetrue
     \csname\defaultfontbody \defaultfontstyle \defaultfontalternative \defaultfontsize\endcsname
   \fi}

\let\applyfontstrategies     \fontstrategiesa
\let\applyfontclassstrategies\fontclassstrategiesa

%D Let's synchronize:

\newif\ifsynchronizefonts \synchronizefontstrue

\prependtoks
  \ifsynchronizefonts
    \synchronizemath
    \synchronizefont % 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\dosetcurrentfontxxxalternative#1#2#3#4%
  {\chardef\currentxfontsize#2\relax
   \ifmmode
     #4%
   \else\ifcsname\bodyfontvariable{\normalizedbodyfontsize#3}\endcsname
     \setcurrentfontbodyalternative{\csname\bodyfontvariable\normalizedbodyfontsize#3\endcsname}{#1}%
   \fi\fi}

\def\setcurrentfontxalternative#1%
  {\dosetcurrentfontxxxalternative{#1}1\c!x\scriptstyle
   \let\tx\txx}

\def\setcurrentfontxxalternative#1%
  {\dosetcurrentfontxxxalternative{#1}2\c!xx\scriptscriptstyle
   \let\tx\empty
   \let\txx\empty}

\def\checknestedxfontsize % option
  {\ifcase\currentxfontsize\else\ifx\fontsize\empty\else
     \chardef\currentxfontsize\zeropoint
     \let\fontsize\empty
     \let\tx\normaltx
     \let\txx\normaltxx
   \fi\fi}

\def\setcurrentfontxalternative#1%
  {\checknestedxfontsize
   \dosetcurrentfontxxxalternative{#1}1\c!x\scriptstyle
   \let\tx\txx}

\def\setcurrentfontxxalternative#1%
  {\checknestedxfontsize
   \dosetcurrentfontxxxalternative{#1}2\c!xx\scriptscriptstyle
   \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\setcurrentfontxstylealternative #1{\csname#1\endcsname\tx}
\def\setcurrentfontxxstylealternative#1{\csname#1\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 \startvoorbeeld
%D \startlines
%D \getbuffer
%D \stoplines
%D \stopvoorbeeld
%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 {\setcurrentfontxalternative \fontalternative}
\unexpanded\def\txx{\setcurrentfontxxalternative\fontalternative}

\let\normaltx \tx
\let\normaltxx\txx

%D \macros
%D   {definefontstyle}
%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

\def\dodefinefontstyle[#1][#2]%
  {\rawdoifinsetelse{#2}{\fontstylelist}
     {%\debuggerinfo\m!fonts{unknown style #2}%
      }
     {%\debuggerinfo\m!fonts8{#2\space (#1)}%
      \addtocommalist{#2}\fontstylelist}%
   % check kan hier
   \def\docommand##1%
     {\setvalue{\@shortstyle@##1}{#2}%
      \setvalue{\@style@##1}{\csname#2\endcsname}}%
   \processcommalist[#1]\docommand}

\def\definefontstyle
  {\dodoubleargument\dodefinefontstyle}

\def\setfontstyle#1#2%  #1:name (roman, romaan)  #2:style (rm)
  {\edef\fontstyle{#1}%
   \checkfontnamecombinations
   \setcurrentfontstyle\normalizedbodyfontsize}

%D The previous macros show that it's is not always
%D neccessary to define the whole bunch of fonts, take for
%D instance the sequence:
%D
%D \starttyping
%D \setupbodyfont
%D   [ams]
%D
%D \definebodyfont [24pt] [mm]
%D   [ma=msam10 at 24pt,
%D    mb=msbm10 at 24pt]
%D
%D \switchtobodyfont
%D   [24pt]
%D
%D This is a 24pt $\blacktriangleleft$
%D \stoptyping
%D
%D Here we didn't define the 24 point bodyfont environment, so
%D it's defined automatically. Of course one can always use the
%D \TEX\ primitive \type{\font} to switch to whatever font
%D needed.

%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\dosetbodyfontface#1#2%
  {\edef#1{\csname\bodyfontvariable\normalizedbodyfontsize#2\endcsname}}

\def\docompletefontswitch[#1]%
  {\bodyfontsize#1\relax
   \dimensiontocount\bodyfontsize\bodyfontpoints % rounded, still used in m-chart
   \edef\bodyfontfactor{\withoutpt\the\bodyfontsize}%
   \normalizebodyfontsize\bodyfontsize\to\normalizedbodyfontsize
   \dosetbodyfontface \textface         \s!text
   \dosetbodyfontface \scriptface       \s!script
   \dosetbodyfontface \scriptscriptface \s!scriptscript}

\docompletefontswitch[12pt] % init

%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[cmr,ams,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

\chardef\bodyfontsetstate=0

\definecomplexorsimple\setupbodyfont

\def\simplesetupbodyfont
  {\restoreglobalbodyfont
   \saveinterlinespace}

\def\complexsetupbodyfont[#1]%
  {\doifsomething{#1}
     {\dosetfont1{#1}%
      \globalbodyfontsize\localbodyfontsize
      \normalizebodyfontsize\globalbodyfontsize\to\normalizedglobalbodyfontsize
      \let\globalfontstyle\fontstyle
      \ifloadingfonts\else
        \the\everybodyfont
        \the\everyglobalbodyfont
        \saveinterlinespace
      \fi}}

\unexpanded\def\switchtobodyfont[#1]%
  {\doifsomething{#1}
     {\ifcsname\??ft\normalizedbodyfontsize\interfaced{#1}\endcsname
        \setbodyfontstep{#1}% so we have a fast [small] switch
      \else
        \dosetfont0{#1}%
      \fi
      \the\everybodyfont}} % indeed needed in case nothing is executed

%D The following alternative is meant for math||to||text
%D switching and will be optimized.

\def\fastswitchtobodyfont#1%
  {\ifcsname\??ft\normalizedbodyfontsize#1\endcsname
     \edef\futurebodyfontsize{\csname\??ft\normalizedbodyfontsize#1\endcsname}%
     \ifcsname\@size@\futurebodyfontsize\endcsname
       \csname\@size@\futurebodyfontsize\endcsname
       \localbodyfontsize\futurebodyfontsize\relax
     \fi
   \fi
   \csname\@style@\fontstyle\endcsname
   \the\everybodyfont}

%D \starttyping
%D $\cases{& \ccaron}$ $x=\hbox{\ccaron $x=\hbox{\ccaron}$}$
%D \stoptyping

\def\setfontcharacteristics
  {\the\everyfont}

%D Predefined:

% \installfontfeature[otf][tlig]
% \installfontfeature[otf][trep]

%D tricky but ok:

\appendtoks\ctxlua{fonts.tfm.cleanup()}\to\everyshipout

%D Todo:

% \def\os{\groupedcommand{\setfontfeature{oldstyle}}{}}

%D Experimental:

\def\definefontfeature
  {\dotripleargument\dodefinefontfeature}

\def\dodefinefontfeature[#1][#2][#3]%
  {\global\expandafter\chardef\csname\??fq=#1\endcsname
     \ctxlua{tex.write(fonts.define.specify.preset_context("#1","#2","#3"))}\relax}

\definefontfeature
  [default]
  [%mode=node,%
   liga=yes,kern=yes,tlig=yes,trep=yes] % texligatures=yes,texquotes=yes

\definefontfeature
  [smallcaps]
  [%mode=node,%
   liga=yes,kern=yes,tlig=yes,trep=yes,smcp=yes] % texligatures=yes,texquotes=yes

\definefontfeature
  [oldstyle]
  [%mode=node,%
   liga=yes,kern=yes,tlig=yes,trep=yes,onum=yes] % texligatures=yes,texquotes=yes

\definefontfeature % can be used for type1 fonts
  [complete]
  [liga=yes,kern=yes,compose=yes,tlig=yes,trep=yes]

\definefontfeature
  [arabic]
  [mode=node,language=dflt,script=arab,ccmp=yes,
   init=yes,medi=yes,fina=yes,isol=yes,
   liga=yes,dlig=yes,rlig=yes,clig=yes,calt=yes,
   mark=yes,mkmk=yes,kern=yes,curs=yes]

\definefontfeature
  [none]
  [mode=none,features=off]

\definefontfeature
  [virtualmath]
  [mode=base,liga=yes,kern=yes,tlig=yes,trep=yes]

% for the moment here, this will change but we need it for mk.tex

\definefontfeature[math-text]        [virtualmath][ssty=no]
\definefontfeature[math-script]      [virtualmath][ssty=1,mathsize=yes]
\definefontfeature[math-scriptscript][virtualmath][ssty=2,mathsize=yes]

\definefontfeature [math-nostack-text]        [math-text]        [nostackmath=yes]
\definefontfeature [math-nostack-script]      [math-script]      [nostackmath=yes]
\definefontfeature [math-nostack-scriptscript][math-scriptscript][nostackmath=yes]

% \definefontfeature[mathtext]         [math-text]
% \definefontfeature[mathscript]       [math-script]
% \definefontfeature[mathscriptscript] [math-scriptscript]

%D Also new:

% handy for manuals

\def\otfchar#1{\ctxlua{fonts.otf.char("#1")}}

%D: We cannot yet inherit because no colors are predefined.

\definecolor[font:init][r=.75]
\definecolor[font:medi][g=.75]
\definecolor[font:fina][b=.75]
\definecolor[font:isol][r=.75,g=.75] % [y=.75]
\definecolor[font:mark][r=.75,b=.75] % [m=.75]
\definecolor[font:rest][g=.75,b=.75] % [c=.75]

%D Experimental!

\def\installfontfeature
  {\dodoubleargument\doinstallfontfeature}

\def\doinstallfontfeature[#1][#2]%
  {\writestatus\m!fonts{installing font features was experimental}} % \ctxlua{fonts.install_feature("#1","#2")}}

%D Not yet in \MKII.

\def\fontfeatureslist
  {\dodoubleargument\dofontfeatureslist}

\def\dofontfeatureslist[#1][#2]% todo: arg voor type
  {\ctxlua{tex.sprint(tex.ctxcatcodes,fonts.define.specify.context_tostring("#1","otf","\luaescapestring{#2}","yes","no",true,{"number"}))}}

\attribute\zerocount\zerocount % first in list, so fast match

\let\currentfeature\empty

% ! ! ! very experimental, some test code for idris advanced features ! ! !
%
% \startbuffer
% \definefontfeature[smallcaps][smallcaps][script=latn]
% \definefontfeature[oldstyle] [oldstyle] [script=latn]
%
% \definedfont[name:cambria at 15pt]
%
% Hello there {\setff{smallcaps}capped 123 \setff{oldstyle}123!}    \blank
% Hello there {\addff{smallcaps}capped 123 \addff{oldstyle}123!}    \blank
% Hello there {\addff{smallcaps}capped     \subff{smallcaps}normal} \blank
% \stopbuffer
%
% \typebuffer \getbuffer

\def\featureattribute#1{\ctxlua{tex.sprint(fonts.define.specify.context_number("#1"))}}
\def\setfontfeature  #1{\edef\currentfeature{#1}\attribute\zerocount\featureattribute{#1}\relax}
\def\resetfontfeature#1{\let\currentfeature\empty\attribute\zerocount\zerocount} % initial value

\def\addfontfeaturetoset        #1{\ctxlua{fonts.withset("#1", 1)}}
\def\subtractfontfeaturefromset #1{\ctxlua{fonts.withset("#1",-1)}}
\def\addfontfeaturetofont       #1{\ctxlua{fonts.withfnt("#1", 2)}}
\def\subtractfontfeaturefromfont#1{\ctxlua{fonts.withfnt("#1",-2)}}

\let\setff\setfontfeature
\let\addfs\addfontfeaturetoset
\let\subfs\subtractfontfeaturefromset
\let\addff\addfontfeaturetofont
\let\subff\subtractfontfeaturefromfont

%D The next auxilliary macro is an alternative to \type
%D {\fontname}.

% \def\purefontname#1{\expandafter\splitoffpurefontname\fontname#1 \\}
%
% extra level is needed:

\def\purefontname#1{\@EA\splitoffpurefontname\@EA{\@EA{\@EA\unstringed\fontname#1}} \\}

\def\splitoffpurefontname#1 #2\\{#1}

%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

\definecomplexorsimple\switchstyleonly

\def\simpleswitchstyleonly#1% stupid version
  {\complexswitchstyleonly[\checkedstrippedcsname#1]}

\def\complexswitchstyleonly[#1]% todo : check
  {\setcurrentfontstyle{\csname\@shortstyle@#1\endcsname}%
   \the\everybodyfont} % needed ?

%D \macros
%D   {os}
%D
%D In good old \TEX, the old style numerals were often taken
%D from the math fonts. No longer.

\definefontfeature
  [just-os]
  [mode=node,onum=yes]

% \def\sc{\setfontfeature{smallcaps}}
\def\os{\setfontfeature{just-os}}

%D Code for swithcing to fraktur and script has also been
%D changed. We now have an alphabet switcher.

\ifx\mathtext\undefined \let\mathtext\hbox \fi

%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, mainly
%D because \PLAIN\ \TEX\ is english anyway.

\def\dodefinebodyfontswitch[#1][#2]%
  {\def\docommand##1{\setvalue{##1}{\switchtobodyfont[#2]}}%
   \processcommalist[#1]\docommand}

\def\definebodyfontswitch
  {\dodoubleargument\dodefinebodyfontswitch}

%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.

\let\fontstep\empty % we can use \fontstep for tracing purposes

\def\setbodyfontstep#1%
  {\edef\fontstep{\csname\bodyfontvariable\normalizedbodyfontsize\interfaced{#1}\endcsname}%
   \doswitchpoints[\fontstep]%
   \doswitchstyle[\fontstyle]}

\unexpanded\def\setsmallbodyfont{\setbodyfontstep\v!small\the\everybodyfont}
\unexpanded\def\setbigbodyfont  {\setbodyfontstep\v!big  \the\everybodyfont}

\unexpanded\def\setmainbodyfont
  {\doswitchpoints[\normalizedbodyfontsize]%
   \doswitchstyle[\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:

\let\globalfontstyle\c!rm

\def\fullrestoreglobalbodyfont
  {\let\fontsize\defaultfontsize
   \let\fontbody\defaultfontbody
   \chardef\currentxfontsize\zerocount
   \let\fontclass\globalfontclass
   \doswitchpoints[\normalizedglobalbodyfontsize]%
   \doswitchstyle[\globalfontstyle]%
   \redoconvertfont % just in case a pagebreak occurs
   \tf
   \the\everybodyfont
   \the\everyglobalbodyfont
   \saveinterlinespace}

\def\partialrestoreglobalbodyfont
  {\let\fontsize\defaultfontsize
   \let\fontbody\defaultfontbody
   \chardef\currentxfontsize\zerocount
   \redoconvertfont
   \tf
   \saveinterlinespace}

\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 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]}.

%D \macros
%D   {rasterfont}
%D
%D There are (at the moment) two situations in which we want to
%D have fast access to a particular font. When we are using
%D \TEX\ to typeset rasters, we use small {\rasterfont.}'s
%D (a rather small period indeed), the same as \PICTEX\ uses
%D for drawing purposes.

\definefont [rasterfont] [Serif at 5pt]

%D \macros
%D   {infofont}
%D
%D The second situation occurs when we enable the info mode,
%D and put all kind of status information in the margin. We
%D don't want huge switches to the main bodyfont and style, so
%D here too we use a direct method.

\let\infofont\relax % satisfy dep checker

\definefont [infofont] [Mono at 6pt] % todo \the\everybodyfont

%D \macros
%D   {definealternativestyle}
%D
%D In the main modules we are going to implement lots of
%D parameterized commands and one of these parameters will
%D concern the font to use. To suit consistent use of fonts we
%D here implement a mechanism for defining the keywords that
%D present a particular style or alternative.
%D
%D \starttyping
%D \definealternativestyle [keywords] [\style] [\nostyle]
%D \stoptyping
%D
%D The first command is used in the normal textflow, while the
%D second command takes care of headings and alike. Consider
%D the next two definitions:
%D
%D \starttyping
%D \definealternativestyle [bold] [\bf]  []
%D \definealternativestyle [cap]  [\cap] [\cap]
%D \stoptyping
%D
%D A change \type{\bf} in a heading which is to be set in
%D \type{\tfd} does not look that well, so therefore we leave
%D the second argument of \type{\definealternativestyle} empty.
%D When we capatalize characters using the pseudo small cap
%D command \type{\cap}, we want this to take effect in both
%D text and headings, which is accomplished by assigning both
%D arguments.

\def\dodefinealternativestyle[#1][#2][#3]%
  {\def\docommand##1%
     {\ifcsname##1\endcsname\else\setvalue{##1}{\groupedcommand{#2}{}}\fi
      \setvalue{\@letter@  ##1}{#2}%
      \setvalue{\@noletter@##1}{#3}}%
   \processcommalist[#1]\docommand}

\def\definealternativestyle
  {\dotripleempty\dodefinealternativestyle}

\def\definestyle{\definealternativestyle}

%D Maybe too geneneric, but probably ok is the following. (Maybe one
%D day we will use a dedicated grouped command for styles.)

\appendtoks
  \let\groupedcommand\thirdofthreearguments
\to \simplifiedcommands

%D This command also defines the keyword as command. This means
%D that the example definition of \type{bold} we gave before,
%D results in a command \type{\bold} which can be used as:
%D
%D \startbuffer
%D He's a \bold{bold} man with a {\bold head}.
%D \stopbuffer
%D
%D \typebuffer
%D
%D or
%D
%D \startvoorbeeld
%D \definealternativestyle[bold][\bf][]\getbuffer
%D \stopvoorbeeld
%D
%D Such definitions are of course unwanted for \type{\cap}
%D because this would result in an endless recursive call.
%D Therefore we check on the existance of both the command and
%D the substitution. The latter is needed because for instance
%D \type{\type} is an entirely diferent command. That command
%D handles verbatim, while the style command would just switch
%D to teletype font. This is just an example of a tricky
%D naming coincidence.

%D \macros
%D   {doconvertfont,noconvertfont,
%D    dontconvertfont,redoconvertfont}
%D
%D After having defined such keywords, we can call for them by
%D using
%D
%D \starttyping
%D \doconvertfont{keyword}{text}
%D \stoptyping
%D
%D We deliberately pass an argument. This enables us to
%D assign converters that handle one argument, like
%D \type{\cap}.
%D
%D By default the first specification is used to set the style,
%D exept when we say \type{\dontconvertfont}, after which the
%D second specification is used. We can also directly call for
%D \type{\noconvertfont}. In nested calls, we can restore the
%D conversion by saying \type{\redoconvertfont}.

% subtle ... \expandafter is needed else problems with lookahead caps

\def\@@dodoconvertfont{\csname\@letter@  \p!defined\expandafter\endcsname\gobbleoneargument}
\def\@@donoconvertfont{\csname\@noletter@\p!defined\endcsname}
\def\@@redoconvertfont{\csname           \p!defined\expandafter\endcsname\gobbleoneargument}

% beware: p!defined can contain crap like \edef crap {...} and such
% so we need to pass #1 as well

\unexpanded\def\dodoconvertfont#1% #2% we need the protection
  {\edef\p!defined{#1}%
   \ifx\p!defined\empty\else
     \@EA\dododoconvertfont
   \fi{#1}}

\def\dododoconvertfont % #1
   {\ifcsname\@letter@\detokenize\@EA{\p!defined}\endcsname
      \@EA\@@dodoconvertfont
    \else\ifcsname\detokenize\@EA{\p!defined}\endcsname
      \@EAEAEA\@@redoconvertfont
    \else
      \@EAEAEA\firstofoneargument
    \fi\fi} % {#1}

\let\doconvertfont\dodoconvertfont

\unexpanded\def\noconvertfont#1% #2%
  {\edef\p!defined{#1}%
   \ifx\p!defined\empty
   \else
     \@EA\nononoconvertfont
   \fi}

\def\nononoconvertfont
  {\ifcsname\@noletter@\detokenize\@EA{\p!defined}\endcsname
     \@EA\@@donoconvertfont
   \fi}

%D Extras:

\unexpanded\def\dontconvertfont{\let\doconvertfont\noconvertfont}
\unexpanded\def\redoconvertfont{\let\doconvertfont\dodoconvertfont}

%D These commands are not grouped! Grouping is most probably
%D done by the calling macro's and would lead to unnecessary
%D overhead.

%D \macros
%D  {em,emphasistypeface,emphasisboldface}
%D
%D The next macro started as a copy of Donald Arseneau's
%D \type{\em} (\TUGNEWS\ Vol.~3, no.~1, 1994). His
%D implementation was a bit more sophisticated version of the
%D standard \LATEX\ one. We furter enhanced the macro, so now
%D it also adapts itself to boldface mode. Because we favor
%D {\sl slanted} type over {\it italic}, we made the emphasis
%D adaptable, for instance:
%D
%D \starttyping
%D \def\emphasistypeface {\it}
%D \def\emphasisboldface {\bi}
%D \stoptyping
%D
%D But we prefer:

\def\emphasistypeface {\sl}
\def\emphasisboldface {\bs}

%D or even better:

% \def\doemphasistypeface#1#2% slow
%   {\doifelsevalue{\??ft\fontclass\normalizedbodyfontsize\c!em}\v!slanted
%      {#1}%
%      {\doifelsevalue{\??ft\fontclass\normalizedbodyfontsize\c!em}\v!italic
%         {#2}%
%         {\doifelsevaluenothing{\??ft\fontclass\normalizedbodyfontsize\c!em}
%            {\doifelsevalue{\??ft\normalizedbodyfontsize\c!em}\v!slanted
%               {#1}%
%               {\doifelsevalue{\??ft\normalizedbodyfontsize\c!em}\v!italic
%                  {#2}%
%                  {\getvalue{\??ft\normalizedbodyfontsize\c!em}}}}
%            {\getvalue{\??ft\fontclass\normalizedbodyfontsize\c!em}}}}}

\def\doemphasistypeface#1#2%
  {\edef\emphasizedtypeface{\csname\??ft\fontclass\normalizedbodyfontsize\c!em\endcsname}%
   \ifx\emphasizedtypeface\v!slanted
     #1%
   \else\ifx\emphasizedtypeface\v!italic
     #2%
   \else\ifx\emphasizedtypeface\v!empty
     \edef\emphasizedtypeface{\csname\??ft\normalizedbodyfontsize\c!em\endcsname}%
     \ifx\emphasizedtypeface\v!slanted
       #1%
     \else\ifx\emphasizedtypeface\v!italic
       #2%
     \else
       \getvalue\emphasizedtypeface
     \fi\fi
   \else
     \getvalue\emphasizedtypeface
   \fi\fi\fi}

\def\emphasistypeface{\doemphasistypeface\sl\it}
\def\emphasisboldface{\doemphasistypeface\bs\bi}

%D To be set with the default body font environment: \type
%D {em} being \type {slanted} or \type {italic}.

\newconditional\emneeded

\newtoks\everyemphasized

\unexpanded\def\em
  {\relax
   \ifdim\slantperpoint>\zeropoint
     \settrue\emneeded
   \else
     \setfalse\emneeded
   \fi
   \setemphasisboldface % new
   \ifx\fontalternative\c!it
     \def\emphasistypeface{\it}\tf
   \else\ifx\fontalternative\c!sl
     \def\emphasistypeface{\sl}\tf
   \else\ifx\fontalternative\c!bf
     \emphasisboldface
   \else\ifx\fontalternative\c!bs
     \def\emphasisboldface{\bs}\bf
   \else\ifx\fontalternative\c!bi
     \def\emphasisboldface{\bi}\bf
   \else
     \emphasistypeface
   \fi\fi\fi\fi\fi
   \the\everyemphasized
   \ifconditional\emneeded\relax
   \else
     \expandafter\aftergroup
   \fi
   \emphasiscorrection}

% compare ...
%
% \appendtoks \red \to \everyemphasized
% \setupbodyfontenvironment [default] [em={\italic\color[red]}]

%D The next feature was not present in previous versions. It
%D takes care of \type {\em \bf ...} sitiations.

\def\setemphasisboldface
  {\let\normalbf\bf
   \let\setemphasisboldface\relax
   \unexpanded\def\bf
     {%\relax
      \let\bf\relax % new
      \ifx\fontalternative\c!it
        \bi
      \else\ifx\fontalternative\c!sl
        \bs
      \else
        \normalbf
      \fi\fi
      \let\bf\normalbf}}

%D Donald's (adapted) macros take the next character into
%D account when placing italic correction. As a bonus we also
%D look for something that looks like a dash, in which case we
%D don't correct.

\let\italiccorrection=\/ % tex primitive

\def\emphasiscorrection
  {\ifhmode
     \expandafter\emphasislook
   \fi}

% \def\emphasislook
%   {\begingroup
%    \beginrobusttest
%    \futurelet\next\emphasistest}

% \def\emphasistest
%   {\normalifcat\noexpand\next,%
%      \endrobusttest\expandafter\doemphasiscorrection
%    \normalelse
%      \endrobusttest\expandafter\dododoemphasiscorrection
%    \normalfi}

\def\emphasislook
  {\begingroup
   \futurelet\next\emphasistest}

\def\emphasistest
  {\ifcat\noexpand\next,% still ok?
     \expandafter\doemphasiscorrection
   \else
     \expandafter\dododoemphasiscorrection
   \fi}

\def\doemphasiscorrection
  {\futurelet\next\dodoemphasiscorrection}

\def\dodoemphasiscorrection
   {\setbox\scratchbox\hbox{\next}%
    \ifdim\ht\scratchbox=\zeropoint % probably a space
      \expandafter\dododoemphasiscorrection
    \else\ifdim\ht\scratchbox<.3ex
      \expandafter\expandafter\expandafter\endgroup
    \else
      \expandafter\expandafter\expandafter\dododoemphasiscorrection
    \fi\fi}

\def\dododoemphasiscorrection
  {\scratchskip\lastskip
   \ifdim\scratchskip=\zeropoint\relax % == \ifzeropt\scratchskip
     \italiccorrection\relax
   \else
     \unskip\italiccorrection\hskip\scratchskip
   \fi
   \endgroup}

%D We end with some examples which show the behavior when
%D some punctuation is met. We also show how the mechanism
%D adapts itself to bold, italic and slanted typing.
%D
%D \startbuffer
%D test {test}test       \par
%D test {\sl test}test   \par
%D test {\em test}test   \par
%D test {\em test}--test \par
%D
%D test {test}, test     \par
%D test {\em test}, test \par
%D
%D test {\em test {\em test {\em test} test} test} test \par
%D test {\bf test {\em test {\em test} test} test} test \par
%D test {\sl test {\em test {\em test} test} test} test \par
%D test {\it test {\em test {\em test} test} test} test \par
%D \stopbuffer
%D
%D \typebuffer
%D
%D We get:
%D
%D \startvoorbeeld
%D \startpacked
%D \getbuffer
%D \stoppacked
%D \stopvoorbeeld

%D \macros
%D   {emphbf,emphit,emphsl,emphtf}
%D
%D The next emphasis alternatives are for \THANH. They adapt
%D their style as good as possible.

\def\emphbf{\groupedcommand{\bf\def\emphit{\bi}\def\emphsl{\bs}}{}}
\def\emphit{\groupedcommand{\it\def\emphbf{\bi}\def\emphsl{\sl}}{}}
\def\emphsl{\groupedcommand{\sl\def\emphbf{\bs}\def\emphit{\it}}{}}
\def\emphtf{\groupedcommand{\tf\def\emphbf{\bf}\def\emphit{\it}\def\emphsl{\sl}}{}}

%D \startbuffer
%D TEXT {\emphbf text \emphit text  \emphtf text  \emphsl text}  TEXT
%D TEXT  \emphbf{text \emphit{text} \emphtf{text} \emphsl{text}} TEXT
%D \stopbuffer
%D
%D \typebuffer
%D \startlines
%D \getbuffer
%D \stoplines

%D \macros
%D   {setfont}
%D
%D Every now and then we want to define a font directly, for
%D instance when we typeset title pages. The next macro saves
%D some typing:

\def\setfont% geen \dosetfont mogelijk
  {\def\next{\nextfont\setupinterlinespace}%
   \afterassignment\next\font\nextfont=}

%D One can call this macro as:
%D
%D \starttyping
%D \setfont cmr10 at 60pt
%D \stoptyping
%D
%D After which the font is active and the baselines and
%D struts are set.

%D \macros
%D   {showbodyfont}
%D
%D One can call for a rather simple overview of a bodyfont and the
%D relations between its alternative fonts.
%D
%D \showsetup{showbodyfont}
%D
%D The current bodyfont (here we omitted the argument) looks like:
%D
%D \showbodyfont
%D
%D The implementation is rather straightforward in using
%D \type{\halign}.

\fetchruntimecommand \showbodyfont  {\f!fontprefix\s!run.mkii}

%D \macros
%D   {showfontstrip, testminimalbaseline, showminimalbaseline}
%D
%D The next command can come in handy when combining
%D different fonts into a collection (typeface) and
%D determining optimal baseline distances.
%D
%D \showfontstrip \blank \showminimalbaseline

\fetchruntimecommand \showfontstrip       {\f!fontprefix\s!run.mkii}
\fetchruntimecommand \testminimalbaseline {\f!fontprefix\s!run.mkii}
\fetchruntimecommand \showminimalbaseline {\f!fontprefix\s!run.mkii}

%D \macros
%D   {showkerning}
%D
%D A goody is:
%D
%D \showkerning{Can you guess what kerning is?}

\fetchruntimecommand \showkerning         {\f!fontprefix\s!run.mkii}

%D \macros
%D   {showbodyfontenvironment}
%D
%D The current bodyfontenvironment is:
%D
%D \showbodyfontenvironment
%D
%D This overview is generated using:
%D
%D \showsetup{showbodyfontenvironment}

\fetchruntimecommand \showbodyfontenvironment {\f!fontprefix\s!run.mkii}

%D \macros
%D   {showfont,showfontstyle,showligatures}
%D
%D The following command generates a fontmap:
%D
%D \startbuffer
%D \showfont[SansBold at 12pt]
%D \stopbuffer
%D
%D \typebuffer
%D \getbuffer

% to be internationalized

\fetchruntimecommand \showfont      {\f!fontprefix\s!run.mkii}
\fetchruntimecommand \showfontstyle {\f!fontprefix\s!run.mkii}
\fetchruntimecommand \showligature  {\f!fontprefix\s!run.mkii}
\fetchruntimecommand \showligatures {\f!fontprefix\s!run.mkii}
\fetchruntimecommand \showcharratio {\f!fontprefix\s!run.mkii}

%D \macros
%D   {getglyph, symbolicfont}
%D
%D Individual glyphs can be accessed by using
%D
%D \starttyping
%D \getglyph{fontname}{character}
%D \stoptyping
%D
%D This macro is used in for instance the symbol modules and
%D as one can see, it does obey the small and even smaller
%D sizes. The \type {\symbolicfont} macro can be used to
%D switch to a font named \type {fontname} (see \type
%D {cont-log} and \type {symb-eur} for examples of symbolic
%D definitions.

\def\fontstringA
  {\ifx\fontstyle\c!rm \s!Serif \else
   \ifx\fontstyle\c!ss \s!Sans  \else
   \ifx\fontstyle\c!tt \s!Mono  \else
                       \s!Serif \fi\fi\fi}

\def\fontstringB
  {\ifx\fontstyle\c!rm \s!Regular \else
   \ifx\fontstyle\c!ss \s!Support \else
   \ifx\fontstyle\c!tt \s!Type    \else
                       \s!Serif   \fi\fi\fi}

\def\fontstringC
  {\ifx\fontalternative\c!bf \s!Bold        \else
   \ifx\fontalternative\c!sl \s!Slanted     \else
   \ifx\fontalternative\c!it \s!Italic      \else
   \ifx\fontalternative\c!bs \s!BoldSlanted \else
   \ifx\fontalternative\c!bi \s!BoldItalic  \fi\fi\fi\fi\fi}

\def\fontstringD % default fontstyle
  {\expandafter\ifx\csname\??tf\fontclass\s!default\endcsname\c!rm \s!Serif \else
   \expandafter\ifx\csname\??tf\fontclass\s!default\endcsname\c!ss \s!Sans  \else
   \expandafter\ifx\csname\??tf\fontclass\s!default\endcsname\c!tt \s!Mono  \else
                                                                   \s!Serif \fi\fi\fi}

% potential generalization:

% \letvalue{\??ff:t:\c!rm}\s!Serif
% \letvalue{\??ff:t:\c!ss}\s!Sans
% \letvalue{\??ff:t:\c!tt}\s!Mono
%
% \letvalue{\??ff:s:\c!bf}\s!Bold
% \letvalue{\??ff:s:\c!sl}\s!Slanted
% \letvalue{\??ff:s:\c!it}\s!Italic
% \letvalue{\??ff:s:\c!bs}\s!BoldSlanted
% \letvalue{\??ff:s:\c!bi}\s!BoldItalic
%
% \letvalue{\??ff:a:\c!rm}\s!Regular
% \letvalue{\??ff:a:\c!ss}\s!Support
% \letvalue{\??ff:a:\c!tt}\s!Type
%
% \def\fontstringA{\executeifdefined{\??ff:t:\fontstyle}\s!Serif}
% \def\fontstringB{\executeifdefined{\??ff:a:\fontstyle}\s!Serif}
% \def\fontstringC{\executeifdefined{\??ff:s:\fontstyle}\empty}
% \def\fontstringD{\executeifdefined{\??ff:t:\csname\??tf\fontclass\s!default\endcsname}\s!Serif}

\def\glyphfontfile#1%
  {#1%
   \ifcsname\??ff#1\fontstringA\fontstringC\endcsname
     \fontstringA\fontstringC
   \else\ifcsname\??ff#1\fontstringB\fontstringC\endcsname
     \fontstringB\fontstringC
   \else\ifcsname\??ff#1\fontstringA\endcsname
     \fontstringA
   \else\ifcsname\??ff#1\fontstringB\endcsname
     \fontstringB
   \else\ifcsname\??ff#1\fontstringC\endcsname
     \fontstringC
   \fi\fi\fi\fi\fi}

%D The next macro can be used to make decisions based on the shape:

\def\doifitalicelse#1#2%
  {\ifx\fontalternative\c!sl#1\else
   \ifx\fontalternative\c!it#1\else
   \ifx\fontalternative\c!bs#1\else
   \ifx\fontalternative\c!bi#1\else#2\fi\fi\fi\fi}

%D For an example of usage of the following command,
%D see \type {cont-log.tex}.
%D
%D \starttyping
%D \def\symbolicfont#1{\definedfont[\glyphfontfile{#1} sa *]}
%D \stoptyping
%D
%D Since we know what scaling it to be applied, we can
%D implement a much faster alternative:

\let\thedefinedfont\relax

\def\symbolicsizedfont#1#2#3%
  {\scaledfontsize#1%
   \scaledfontsize#2\scaledfontsize
   \font\thedefinedfont=\truefontname{\glyphfontfile{#3}} at \currentfontbodyscale\scaledfontsize\relax
   \thedefinedfont}

\def\symbolicscaledfont
  {\symbolicsizedfont\fontbody}

\unexpanded\def\symbolicfont
  {\symbolicsizedfont\fontbody\plusone}

\unexpanded\def\getglyph#1#2% slow, faster, much faster
 %{{\definefont[\s!dummy][\glyphfontfile{#1} sa \currentfontscale]\dummy#2}}
 %{{\definefont[\s!dummy][\glyphfontfile{#1} sa *]\dummy#2}}
 %{{\symbolicfont{#1}#2}}
  {{\symbolicfont{#1}\doifnumberelse{#2}\char\donothing#2}}

\unexpanded\def\getscaledglyph#1#2#3%
  {{\symbolicscaledfont{#1}{#2}\doifnumberelse{#3}\char\donothing#3}}

\unexpanded\def\getrawglyph#1#2% for simple symbols
  {{\scaledfontsize\fontbody
    \font\thedefinedfont=#1 at \currentfontbodyscale\scaledfontsize\relax
    \thedefinedfont\doifnumberelse{#2}\char\donothing#2}}

%D The last implementation of \type {\getglyph} permits
%D definitions like:
%D
%D \starttyping
%D \definefontsynonym [EuroSans]            [eurose]
%D \definefontsynonym [EuroSansBold]        [euroseb]
%D \definefontsynonym [EuroSansItalic]      [eurosei]
%D \definefontsynonym [EuroSansSlanted]     [eurosei]
%D \definefontsynonym [EuroSansBoldItalic]  [eurosebi]
%D \definefontsynonym [EuroSansBoldSlanted] [eurosebi]
%D
%D \definesymbol [euro] [\getglyph{Euro}{\char160}]
%D
%D \def\euro{\symbol[euro]}
%D \stoptyping
%D
%D These definitions guarantee that the next calls work okay:
%D
%D \starttyping
%D \ss \tf\euro \bf\euro \sla\euro \itd\euro \bs\euro \bic\euro
%D \stoptyping
%D
%D The shape as well as the size is adapted to the current
%D environment.

%D \macros
%D   {ss, SS, sz}
%D
%D We are going to redefine \type{\ss} but for those wo still
%D want to have access to the german \SS, we save it's value in
%D \type{\SS}. Ok, I should have used \type{\sf} instead of
%D \type{\ss} in the first place.

\ifx\undefined\SS \let\SS=\ss \fi
\ifx\undefined\sz \let\sz=\ss \fi

%D Personally I think that using \TEX\ macro packages is
%D complicated by the way fonts are handled. Apart from the
%D many encodings, we also deal with different naming schemes.
%D Confronted with this problem, I decided to change the
%D definitions into:
%D
%D \starttyping
%D \definebodyfont [12pt] [rm] [tf=Times-Roman at 12pt]
%D \stoptyping
%D
%D combined with for instance:
%D
%D \starttyping
%D \definefontsynonym [Times-Roman] [tir]
%D \stoptyping

%D Now we're up to some definitions.

\definebodyfontenvironment
  [\s!default]
  [        \s!text=1.0,
         \s!script=0.7,
   \s!scriptscript=0.5,
              \c!a=1.200,
              \c!b=1.440,
              \c!c=1.728,
              \c!d=2.074,
                 *=\currentfontscale, % wildcard
              \c!x=0.8,
             \c!xx=0.6,
            \c!big=1.2,
          \c!small=0.8,
 \c!interlinespace=,
             \c!em=\v!slanted]

\definebodyfontenvironment
  [20.7pt]
  [        \s!text=20.7pt,
         \s!script=\!!fourteenpointfour,
   \s!scriptscript=\!!twelvepoint,
              \c!x=17.3pt,
             \c!xx=\!!fourteenpointfour,
            \c!big=20.7pt,    % !!!!
          \c!small=17.3pt]

\definebodyfontenvironment
  [17.3pt]
  [        \s!text=17.3pt,
         \s!script=\!!twelvepoint,
   \s!scriptscript=\!!tenpoint,
              \c!x=\!!fourteenpointfour,
             \c!xx=\!!twelvepoint,
            \c!big=20.7pt,
          \c!small=\!!fourteenpointfour]

\definebodyfontenvironment
  [\!!fourteenpointfour]
  [        \s!text=\!!fourteenpointfour,
         \s!script=\!!elevenpoint,
   \s!scriptscript=\!!ninepoint,
              \c!x=\!!twelvepoint,
             \c!xx=\!!tenpoint,
            \c!big=17.3pt,
          \c!small=\!!twelvepoint]

\definebodyfontenvironment
  [\!!twelvepoint]
  [        \s!text=\!!twelvepoint,
         \s!script=\!!ninepoint,
   \s!scriptscript=\!!sevenpoint,
              \c!x=\!!tenpoint,
             \c!xx=\!!eightpoint,
            \c!big=\!!fourteenpointfour,
          \c!small=\!!tenpoint]

\definebodyfontenvironment
  [\!!elevenpoint]
  [        \s!text=\!!elevenpoint,
         \s!script=\!!eightpoint,
   \s!scriptscript=\!!sixpoint,
              \c!x=\!!ninepoint,
             \c!xx=\!!sevenpoint,
            \c!big=\!!twelvepoint,
          \c!small=\!!ninepoint]

\definebodyfontenvironment
  [\!!tenpoint]
  [        \s!text=\!!tenpoint,
         \s!script=\!!sevenpoint,
   \s!scriptscript=\!!fivepoint,
              \c!x=\!!eightpoint,
             \c!xx=\!!sixpoint,
            \c!big=\!!twelvepoint,
          \c!small=\!!eightpoint]

\definebodyfontenvironment
  [\!!ninepoint]
  [        \s!text=\!!ninepoint,
         \s!script=\!!sevenpoint,
   \s!scriptscript=\!!fivepoint,
              \c!x=\!!sevenpoint,
             \c!xx=\!!fivepoint,
            \c!big=\!!elevenpoint,
          \c!small=\!!sevenpoint]

\definebodyfontenvironment
  [\!!eightpoint]
  [        \s!text=\!!eightpoint,
         \s!script=\!!sixpoint,
   \s!scriptscript=\!!fivepoint,
              \c!x=\!!sixpoint,
             \c!xx=\!!fivepoint,
            \c!big=\!!tenpoint,
          \c!small=\!!sixpoint]

\definebodyfontenvironment
  [\!!sevenpoint]
  [        \s!text=\!!sevenpoint,
         \s!script=\!!sixpoint,
   \s!scriptscript=\!!fivepoint,
              \c!x=\!!sixpoint,
             \c!xx=\!!fivepoint,
            \c!big=\!!ninepoint,
          \c!small=\!!fivepoint]

\definebodyfontenvironment
  [\!!sixpoint]
  [        \s!text=\!!sixpoint,
         \s!script=\!!fivepoint,
   \s!scriptscript=\!!fivepoint,
              \c!x=\!!fivepoint,
             \c!xx=\!!fivepoint,
            \c!big=\!!eightpoint,
          \c!small=\!!fivepoint]

\definebodyfontenvironment
  [\!!fivepoint]
  [        \s!text=\!!fivepoint,
         \s!script=\!!fivepoint,
   \s!scriptscript=\!!fivepoint,
              \c!x=\!!fivepoint,
             \c!xx=\!!fivepoint,
            \c!big=\!!sevenpoint,
          \c!small=\!!fivepoint]

\definebodyfontenvironment
  [\!!fourpoint]
  [        \s!text=\!!fourpoint,
         \s!script=\!!fourpoint,
   \s!scriptscript=\!!fourpoint,
              \c!x=\!!fourpoint,
             \c!xx=\!!fourpoint,
            \c!big=\!!sixpoint,
          \c!small=\!!fourpoint]

\definebodyfontswitch [fourteenpointfour] [\!!fourteenpointfour]
\definebodyfontswitch [twelvepoint]       [\!!twelvepoint]
\definebodyfontswitch [elevenpoint]       [\!!elevenpoint]
\definebodyfontswitch [tenpoint]          [\!!tenpoint]
\definebodyfontswitch [ninepoint]         [\!!ninepoint]
\definebodyfontswitch [eightpoint]        [\!!eightpoint]
\definebodyfontswitch [sevenpoint]        [\!!sevenpoint]
\definebodyfontswitch [sixpoint]          [\!!sixpoint]
\definebodyfontswitch [fivepoint]         [\!!fivepoint]
\definebodyfontswitch [fourpoint]         [\!!fourpoint]

% \definebodyfontswitch [xii]  [\!!twelvepoint]
% \definebodyfontswitch [xi]   [\!!elevenpoint]
% \definebodyfontswitch [x]    [\!!tenpoint]
% \definebodyfontswitch [ix]   [\!!ninepoint]
% \definebodyfontswitch [viii] [\!!eightpoint]
% \definebodyfontswitch [vii]  [\!!sevenpoint]
% \definebodyfontswitch [vi]   [\!!sixpoint]

%D So far.

\definefontstyle [\c!mm]                                 [\c!mm]
\definefontstyle [\c!rm,\v!roman,\v!serif,\v!regular]    [\c!rm]
\definefontstyle [\c!ss,\v!sansserif,\v!sans,\v!support] [\c!ss]
\definefontstyle [\c!tt,\v!teletype,\v!type,\v!mono]     [\c!tt]
\definefontstyle [\c!hw,\v!handwritten]                  [\c!hw]
\definefontstyle [\c!cg,\v!calligraphic]                 [\c!cg]

\definefontalternative[\c!tf]
\definefontalternative[\c!bf]
\definefontalternative[\c!it]
\definefontalternative[\c!sl]
\definefontalternative[\c!bs]
\definefontalternative[\c!bi]
\definefontalternative[\c!sc]

\definefontsize[\c!a] \definefontsize[\c!b]
\definefontsize[\c!c] \definefontsize[\c!d]

\definealternativestyle [\v!mediaeval]                            [\os]    []
\definealternativestyle [\v!normal]                               [\tf]    []
\definealternativestyle [\v!bold]                                 [\bf]    []
\definealternativestyle [\v!type]                                 [\tt]    []
\definealternativestyle [\v!mono]                                 [\tt]    []
\definealternativestyle [\v!slanted]                              [\sl]    []
\definealternativestyle [\v!italic]                               [\it]    []
\definealternativestyle [\v!boldslanted,\v!slantedbold]           [\bs]    []
\definealternativestyle [\v!bolditalic,\v!italicbold]             [\bi]    []
\definealternativestyle [\v!small,\v!smallnormal]                 [\tfx]   []
\definealternativestyle [\v!smallbold]                            [\bfx]   []
\definealternativestyle [\v!smalltype]                            [\ttx]   []
\definealternativestyle [\v!smallslanted]                         [\slx]   []
\definealternativestyle [\v!smallboldslanted,\v!smallslantedbold] [\bsx]   []
\definealternativestyle [\v!smallbolditalic,\v!smallitalicbold]   [\bix]   []

\definealternativestyle [\v!sans,\v!sansserif]                    [\ss]    []
\definealternativestyle [\v!sansbold]                             [\ss\bf] []

%D Slow but handy:

\definealternativestyle [\v!smallbodyfont] [\setsmallbodyfont] []
\definealternativestyle [\v!bigbodyfont]   [\setbigbodyfont]   []

%D We treat {\sc Small Caps} and \cap {Pseudo Caps} a bit
%D different. We also provide an \WORD {uppercase} style.

\definealternativestyle [\v!cap,\v!capital] [\smallcapped] [\smallcapped]
\definealternativestyle [\v!smallcaps]      [\sc]          [\sc]
\definealternativestyle [\v!WORD]           [\WORD]        [\WORD]

%D \macros
%D   {fontstylesuffix}
%D
%D The next macro is used to map non latin fontnames on
%D fonts. See \type {font-uni} for an example of its use.

\def\fontstylesuffix% why the \s!Regular ? see \getglyph
  {\ifx\fontalternative\c!tf     \s!Regular \else
   \ifx\fontalternative\c!bf        \s!Bold \else
   \ifx\fontalternative\c!sl     \s!Slanted \else
   \ifx\fontalternative\c!it      \s!Italic \else
   \ifx\fontalternative\c!bs \s!BoldSlanted \else
   \ifx\fontalternative\c!bi  \s!BoldItalic \else
   \ifx\fontalternative\c!sc        \s!Caps \else
                                 \s!Regular \fi\fi\fi\fi\fi\fi\fi}%

%D \macros
%D   {definefontvariant,fontvariant,variant}
%D
%D A slightly adapted version of Adam Lindsays variant patches:
%D
%D \starttyping
%D \usetypescriptfile[type-psc] \loadmapfile[texnansi-public-fpl]
%D \usetypescript[palatino][texnansi] \setupbodyfont[palatino]
%D
%D \definefontvariant [Serif][osf] [OsF]
%D
%D \startlines
%D {\sc abcdefgHIJKlmnop}
%D 123{\Var[osf]456}789
%D {\Var[osf] 123{\Var[reset]456}789}
%D {\it  123{\Var[osf]456}789
%D {\Var[osf]123{\Var[reset]456}789}}
%D {\tfb\bf 123{\Var[osf]456}789
%D {\Var[osf] 123{\Var[reset]456}789}}
%D {\sc  123{\Var[osf]456}789
%D {\Var[osf]  123{\Var[reset]456}789}}
%D \stoplines
%D \stoptyping

\def\definefontvariant
  {\dotripleargument\dodefinefontvariant}

\def\dodefinefontvariant[#1][#2][#3]%
  {\setvalue{\??fv#1#2}{#3}}

\def\fontvariant#1#2{\executeifdefined{\??fv#1#2}\empty}

\def\dosetscaledfont
  {\checkrelativefontsize\fontstyle
   \scaledfontsize\currentfontscale\bodyfontsize
   \scaledfontsize\relativefontsize\scaledfontsize}

\unexpanded\def\variant[#1]% slow
  {\dosetscaledfont
   \normalexpanded{\noexpand\definedfont[\fontstringA\fontstylesuffix\fontvariant\fontstringA{#1} at \the\dimexpr\scaledfontsize\relax]}%
   \ignoreimplicitspaces}

\ifx\Var\undefined \let\Var\variant \fi

%D By default we load the Computer Modern Roman fonts (but
%D not yet at this moment) and activate the 12pt roman
%D bodyfont. Sans serif and teletype are also available and
%D can be called for by \type{\ss} and \type{\tt}.

% \setupbodyfont [unk, rm]
% \setupbodyfont [rm]

%D Also needed is:

\definefont[tinyfont][Mono at 1ex]

% \tracinglostchars=1

% this needs some interfacing
%
% \setupfonts[check=...]

\def\checkcharactersinfont  {\ctxlua{fonts.checkers.enabled=true}}
\def\removemissingcharacters{\ctxlua{fonts.checkers.enabled=true fonts.checkers.delete=true}}

%D New commands (not yet interfaced):

\def\style[#1]% for inline usage, like \color
  {\groupedcommand{\ifcsname#1\endcsname\csname#1\endcsname\else\definedfont[#1]\fi}{}}

\def\startstyle[#1]%
  {\begingroup
   \ifcsname#1\endcsname\csname#1\endcsname\else\definedfont[#1]\fi}

\def\stopstyle
  {\endgroup}

%D Still experimental (might even go away).

% \definestylecollection[mine]

% \definestyleinstance[mine][default][sorry]
% \definestyleinstance[mine][tt][bs][ttbs:\rm\sl]
% \definestyleinstance[mine][tt][bf][ttbf:\rm\sl]
% \definestyleinstance[mine][bf][\sl]
% \definestyleinstance[mine][sl][\tt]

% {\bf test \mine test \sl test \mine test \bs oeps \mine oeps {\tt test \mine \bf test}}

\definesystemvariable{sx}

\def\definestylecollection
  {\dosingleargument\dodefinestylecollection}

\def\dodefinestylecollection[#1]%
  {\iffirstargument
     \unexpanded\setvalue{#1}{\styleinstance[#1]}%
     \def\docommand##1%
       {\def\dodocommand####1{\letbeundefined{\??sx##1:####1:\commalistelement}}%
        \processcommacommand[\fontalternativelist,\s!default]\dodocommand}%
     \processcommacommand[\fontstylelist,\s!default]\docommand
   \fi}

\def\definestyleinstance
  {\doquadrupleargument\dodefinestyleinstance}

\def\dodefinestyleinstance[#1][#2][#3][#4]% [name] [rm|ss|tt|..] [sl|bf|...] [whatever]
  {\iffirstargument
     \ifcsname#1\endcsname\else\definestylecollection[#1]\fi
   \fi
   \iffourthargument
     \setvalue{\??sx#1:#2:#3}{#4}%
   \else\ifthirdargument
     \setvalue{\??sx#1::#2}{#3}%
   \else\ifsecondargument
     \letvalue{\??sx#1::#2}\empty
   \fi\fi\fi}

\unexpanded\def\styleinstance[#1]% will be made faster
  {%\begingroup\normalexpanded{\noexpand\infofont[#1:\fontstyle:\fontalternative]}\endgroup
   \executeifdefined{\??sx#1:\fontstyle:\fontalternative}%
  {\executeifdefined{\??sx#1:\fontstyle:\s!default}%
  {\executeifdefined{\??sx#1::\fontalternative}
  {\getvalue        {\??sx#1::\s!default}}}}}

% \unexpanded\def\styleinstance[#1]%
%   {\csname\??sx#1%
%       \ifcsname:\fontstyle:\fontalternative\endcsname
%         :\fontstyle:\fontalternative
%       \else\ifcsname:\fontstyle:\s!default\endcsname
%         :\fontstyle:\s!default
%       \else\ifcsname::\fontalternative\endcsname
%         ::\fontalternative
%       \else\ifcsname::\s!default\endcsname
%         ::\s!default
%       \else
%         % nothing, \relax
%       \fi\fi\fi\fi
%     \endcsname}

\protect \endinput

% \startluacode
%     function commands.doifelsecurrentfonthasfeature(name)
%         local f = fonts.ids[font.current()]
%         f = f and f.shared
%         f = f and f.otfdata
%         f = f and f.luatex
%         f = f and f.features
%         commands.doifelse(f and (f.gpos[name] or f.gsub[name]))
%     end
% \stopluacode

% \def\doifelsecurrentfonthasfeature#1%
%   {\ctxlua{commands.doifelsecurrentfonthasfeature("#1")}}

% \doifelsecurrentfonthasfeature{smcp}{YES}{NO}
% \doifelsecurrentfonthasfeature{crap}{YES}{NO}
% \doifelsecurrentfonthasfeature{kern}{YES}{NO}
