%D \module %D [ file=font-ini, %D version=1998.09.11, % (second) %D version=2001.02.20, % (third) %D title=\CONTEXT\ Font Macros, %D subtitle=Initialization, %D author=Hans Hagen, %D date=\currentdate, %D copyright={PRAGMA ADE \& \CONTEXT\ Development Team}] %C %C This module is part of the \CONTEXT\ macro||package and is %C therefore copyrighted by \PRAGMA. See mreadme.pdf for %C details. %D Watch out: as we define inside macros in sometimes special ways, %D an occasional \type {\normaldef} is used in order to please the %D \MKVI\ parser. %D The \type {type-ini} and \type {font-ini} modules come as a pair %D and have mutual dependencies. %D Beware, we use s special set of parameters here: %D %D \starttabulate[|l|l|] %D \NC system variable (fixed) \NC \type {\s!text} \NC \NR %D \NC system variable (fixed) \NC \type {\s!script} \NC \NR %D \NC system variable (fixed) \NC \type {\s!scriptscript} \NC \NR %D \NC system variable (fixed) \NC \type {\s!x} \NC \NR %D \NC system variable (fixed) \NC \type {\s!xx} \NC \NR %D \NC variable (value) \NC \type {\v!big} \NC \NR %D \NC variable (value) \NC \type {\v!small} \NC \NR %D \NC constant (regular key) \NC \type {\c!interlinespace} \NC \NR %D \NC constant (regular key) \NC \type {\c!em} \NC \NR %D \stoptabulate %D %D The math related ones are similar to the ones used in \TEX\ itself, %D the size related ones show up as keywords in the user interface %D when switching sizes, and the two constants are used in key|/|value %D situations. % a few more names need to be _'d but best first make all mkvi so % that we can come up with more meaningful names % at some point fontclass will always have a value so that quite some % code can go away % todo: reconsider design sizes ... kick 'm out which removes the size % code and simplifies things considerably. After all, there will be no % lm math in sizes. % \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{font-log}{1.001} \registerctxluafile{font-con}{1.001} \registerctxluafile{font-enc}{1.001} %registerctxluafile{font-agl}{1.001} % loaded when needed, saves 100K in format \registerctxluafile{font-cid}{1.001} % cid maps \registerctxluafile{font-map}{1.001} \registerctxluafile{font-syn}{1.001} \registerctxluafile{font-tfm}{1.001} \registerctxluafile{font-afm}{1.001} \registerctxluafile{font-oti}{1.001} % otf initialization \registerctxluafile{font-ott}{1.001} % otf tables (first) \registerctxluafile{font-otf}{1.001} % otf main \registerctxluafile{font-otb}{1.001} % otf main base \registerctxluafile{node-inj}{1.001} % we might split it off \registerctxluafile{font-otn}{1.001} % otf main node \registerctxluafile{font-otd}{1.001} % otf dynamics (does an overload) \registerctxluafile{font-ota}{1.001} % otf analyzers (needs dynamics) \registerctxluafile{font-otp}{1.001} % otf pack \registerctxluafile{font-otc}{1.001} % otf context \registerctxluafile{font-oth}{1.001} % otf helpers \registerctxluafile{font-pat}{1.001} % patchers \registerctxluafile{node-fnt}{1.001} % here \registerctxluafile{font-lua}{1.001} \registerctxluafile{font-vf} {1.001} \registerctxluafile{font-enh}{1.001} \registerctxluafile{font-gds}{1.001} % currently only otf \registerctxluafile{font-def}{1.001} \registerctxluafile{font-ctx}{1.001} % after def as it overloads \registerctxluafile{font-ext}{1.001} \registerctxluafile{font-fbk}{1.001} \registerctxluafile{font-chk}{1.001} \registerctxluafile{font-aux}{1.001} \unprotect % \def\fontrange#criteria% % {\font_basics_fontrange{#criteria =\bodyfontsize}} % % \def\font_basics_fontrange#criteria% % {\font_basics_fontrange_grab#criteria \relax}% \v_font_string_a % % \def\font_basics_fontrange_grab#specification #criterium % % {\ifdim\bodyfontsize#criterium% % #specification\expandafter\gobbleuntilrelax % \else % \expandafter\font_basics_fontrange_grab % \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 \unexpanded\def\setfontparameters {\setfalse\c_font_synchronize \the\everybodyfont \settrue\c_font_synchronize} % handy \unexpanded\def\savefont {\edef\savedfont{\the\font}% gives \csname \pushmacro\savedfont} \unexpanded\def\restorefont {\popmacro\savedfont \savedfont} \unexpanded\def\pushcurrentfont {\edef\popcurrentfont {\def\noexpand\fontbody {\fontbody}% \def\noexpand\fontstyle {\fontstyle}% \def\noexpand\fontalternative{\fontalternative}% \def\noexpand\fontsize {\fontsize}% \font_helpers_check_big_math_synchronization \font_helpers_synchronize_font}} % \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 \let\thedefinedfont\relax \unexpanded\def\definedfont {\doifnextoptionalelse\font_basics_defined_font_yes\font_basics_defined_font_nop} \def\font_basics_defined_font_yes[#specification]% {\c_font_feature_inheritance_mode\c_font_feature_inheritance_fontonly %\definefont[thedefinedfont][#specification]% \font_basics_define_font_without_parameters{thedefinedfont}{#specification}% \thedefinedfont \the\everydefinedfont} \def\font_basics_defined_font_nop {\c_font_feature_inheritance_mode\c_font_feature_inheritance_fontonly \thedefinedfont \the\everydefinedfont} \unexpanded\def\startfont {\begingroup\definedfont} \unexpanded\def\stopfont {\endgroup} \unexpanded\def\doiffontcharelse#specification#unicode% this could be a direct lua call {\begingroup %\definedfont[#specification]% \font_basics_define_font_without_parameters{thedefinedfont}{#specification}% \iffontchar\font#unicode\relax \endgroup\expandafter\firstoftwoarguments \else \endgroup\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 \startexample %D \getbuffer %D \stopexample %D %D Maybe this mechanism isn't always as logic, but as said %D before, we tried to make it as intuitive as possible. %D %D So a specific kind of glyph can be characterized by: %D %D \startnarrower %D family (cmr) + bodyfont (12pt) + style (rm) + alternative (bf) + size (a) %D \stopnarrower %D %D The last component (the size) is optional. %D %D We introduced \type{\tf} as command to call for the current %D normally sized typeface. This commands results in roman, %D sans serif, teletype or whatever style is in charge. Such %D rather massive switches of style sometimes take more %D processing time than comfortable. Of course there is a %D workaround for this: we can call fonts directly by means of %D commands like: %D %D \starttyping %D \rmtf \sssl \tttf \rmbsa %D \stoptyping %D %D One should realize that this fast calls have limitations, %D they lack for instance automatic super- and subscript %D support. %D %D This leaves us two more commands: \type{\tx} and %D \type{\txx}. These activate a smaller and even more smaller %D font than the current one and adapt themselves to the %D current alternative, so when \type{\bf} is active, %D \type{\tx} gives a smaller boldface, which in turn can be %D called directly by \type{\bfx}. %D %D These two smaller alternatives are specified by the bodyfont %D environment and therefore not necessarily have similar sizes %D as \type{\scriptsize} and \type{\scriptscriptsize}. The main %D reason for this incompatibility (which can easily be undone) %D lays in the fact that we often want a bit bigger characters %D than in math mode. In \CONTEXT\ for instance the \type{\tx} %D and \type{\txx} commands are used for surrogate %D \cap{smallcaps} which support both nesting and alternatives, %D like in {\bf\cap{a \cap{small} world}}, which was typeset by %D %D \starttyping %D \bf\cap{a \cap{small} world} %D \stoptyping %D %D And compare $\rm \scriptstyle THIS$ with the slightly larger %D \cap{THIS}: \ruledhbox{$\rm \scriptstyle scriptstyle: THIS$} %D or \ruledhbox{\cap{x style: THIS}} makes a big difference. %D %D The \type{x..d} sizes should be used grouped. If you %D don't group them, i.e. call them in a row, \CONTEXT\ will %D not be able to sort out your intention (\type {x} inside %D \type {d} inside \type {x}. etc.). The following table %D demonstrates this: %D %D \def\FontState{\setstrut\ruledhbox{\strut Hello}} %D %D \starttabulate[|||||] %D \HL %D \NC \rlap{\quad\bf grouped} \NC \NC \type {\tx} \NC \type {\txx} \NC \NR %D \HL %D \NC \type{\tfx} \NC \tfx \FontState \NC \tfx \tx \FontState \NC \tfx \txx \FontState \NC \NR %D \NC \type{\tfxx} \NC \tfxx \FontState \NC \tfxx\tx \FontState \NC \tfxx\txx \FontState \NC \NR %D \NC \type{\tf} \NC \tf \FontState \NC \tf \tx \FontState \NC \tf \txx \FontState \NC \NR %D \NC \type{\tfa} \NC \tfa \FontState \NC \tfa \tx \FontState \NC \tfa \txx \FontState \NC \NR %D \NC \type{\tfb} \NC \tfb \FontState \NC \tfb \tx \FontState \NC \tfb \txx \FontState \NC \NR %D \NC \type{\tfc} \NC \tfc \FontState \NC \tfc \tx \FontState \NC \tfc \txx \FontState \NC \NR %D \NC \type{\tfd} \NC \tfd \FontState \NC \tfd \tx \FontState \NC \tfd \txx \FontState \NC \NR %D \NC \type{\tfx} \NC \tfx \FontState \NC \tfx \tx \FontState \NC \tfx \txx \FontState \NC \NR %D \NC \type{\tfxx} \NC \tfxx \FontState \NC \tfxx\tx \FontState \NC \tfxx\txx \FontState \NC \NR %D \HL %D \stoptabulate %D %D \blank %D %D \starttabulate[|||||] %D \HL %D \NC \rlap{\quad\bf stacked} \NC \NC \type {\tx} \NC \type {\txx} \NC \NR %D \HL %D \NC \type{\tfx} %D \NC \tfx \FontState %D \NC \tfx \tx \FontState %D \NC \tfx \txx \FontState %D \NC \NR %D \NC \type{\tfxx} %D \NC \tfx\tfxx \FontState %D \NC \tfx\tfxx \tx \FontState %D \NC \tfx\tfxx \txx \FontState %D \NC \NR %D \NC \type{\tf} %D \NC \tfx\tfxx\tf \FontState %D \NC \tfx\tfxx\tf \tx \FontState %D \NC \tfx\tfxx\tf \txx \FontState %D \NC \NR %D \NC \type{\tfa} %D \NC \tfx\tfxx\tf\tfa \FontState %D \NC \tfx\tfxx\tf\tfa \tx \FontState %D \NC \tfx\tfxx\tf\tfa \txx \FontState %D \NC \NR %D \NC \type{\tfb} %D \NC \tfx\tfxx\tf\tfa\tfb \FontState %D \NC \tfx\tfxx\tf\tfa\tfb \tx \FontState %D \NC \tfx\tfxx\tf\tfa\tfb \txx \FontState %D \NC \NR %D \NC \type{\tfc} %D \NC \tfx\tfxx\tf\tfa\tfb\tfc \FontState %D \NC \tfx\tfxx\tf\tfa\tfb\tfc \tx \FontState %D \NC \tfx\tfxx\tf\tfa\tfb\tfc \txx \FontState %D \NC \NR %D \NC \type{\tfd} %D \NC \tfx\tfxx\tf\tfa\tfb\tfd \FontState %D \NC \tfx\tfxx\tf\tfa\tfb\tfd \tx \FontState %D \NC \tfx\tfxx\tf\tfa\tfb\tfd \txx \FontState %D \NC \NR %D \NC \type{\tfx} %D \NC \tfx\tfxx\tf\tfa\tfb\tfc\tfx \FontState %D \NC \tfx\tfxx\tf\tfa\tfb\tfc\tfx \tx \FontState %D \NC \tfx\tfxx\tf\tfa\tfb\tfc\tfx \txx \FontState %D \NC \NR %D \NC \type{\tfxx} %D \NC \tfx\tfxx\tf\tfa\tfb\tfc\tfx\tfxx \FontState %D \NC \tfx\tfxx\tf\tfa\tfb\tfc\tfx\tfxx \tx \FontState %D \NC \tfx\tfxx\tf\tfa\tfb\tfc\tfx\tfxx \txx \FontState %D \NC \NR %D \HL %D \stoptabulate %D %D Remark: math support has changed a bit. \installcorenamespace {fontfile} % file synonyms \installcorenamespace {fontsize} % bodyfont size prefix (12pt etc) \installcorenamespace {fontstyle} % full style prefix (roman etc) \installcorenamespace {fontshortstyle} % short style prefix (rm etc) \installcorenamespace {fontclassyes} % fontclass \installcorenamespace {fontclassnop} % nofontclass %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 \def\fontclassname#class#name% {\ifcsname\??fontfile#class#name\endcsname \fontclassname{#class}{\csname\??fontfile#class#name\endcsname}% \else\ifcsname\??fontfile#name\endcsname \fontclassname{#class}{\csname\??fontfile#name\endcsname}% \else #2% \fi\fi} %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 \t_font_math_strategies \newconditional\c_font_synchronize_math_fonts \settrue\c_font_synchronize_math_fonts \unexpanded\def\font_helpers_synchronize_math % math stuff in mmode {\ifconditional\c_font_synchronize_math_fonts\the\t_font_math_strategies\fi} \unexpanded\def\textonly{\setfalse\c_font_synchronize_math_fonts} % 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. %D Because we want to keep mr=.. and mb=... settings (read: not %D break downward compatibility by enforcing mrlr etc) we need a %D bit more code that optimal. % todo: \c_font_fam_mr \let\c_font_fam_mr \zerocount % math regular \let\c_font_fam_mr_lr\plusone % math regular l2r \let\c_font_fam_mr_rl\plustwo % math regular r2l \let\c_font_fam_mb \plusthree % math bold \let\c_font_fam_mb_lr\plusfour % math bold l2r \let\c_font_fam_mb_rl\plusfive % math bold r2l \definesystemattribute[mathfamily][public] \newconditional\c_font_bidirectional_math_strategy % can be default, not that much overhead: \settrue\c_font_bidirectional_math_strategy \newconditional\c_font_complete_bold_math_strategy \settrue\c_font_complete_bold_math_strategy \def\mathtextsuffix {-text} \def\mathscriptsuffix {-script} \def\mathscriptscriptsuffix{-scriptscript} \let\currentmathsize\empty \def\mathsizesuffix{\ifcase0\currentmathsize\or\mathtextsuffix\or\mathscriptsuffix\or\mathscriptscriptsuffix\fi} % Beware: truefontname also does a fallback on defaultfontclass so there % can be some interference here, which is why we use a different method % for bold. \def\font_helpers_set_math_family_a {\ifcsname\fontclass \fontbody\s!mm\fontfamily\fontsize\currentmathsize\endcsname \setfalse\font_auto_font_size \csname\fontclass \fontbody\s!mm\fontfamily\fontsize\currentmathsize\endcsname \else \ifcsname\fontclass \fontbody\s!mm\fontfamily \currentmathsize\endcsname \settrue\font_auto_font_size \csname\fontclass \fontbody\s!mm\fontfamily \currentmathsize\endcsname \else \font_helpers_set_math_family_b \fi\fi} \def\font_helpers_set_math_family_b {\ifcsname\defaultfontclass\fontbody\s!mm\fontfamily\fontsize\currentmathsize\endcsname \setfalse\font_auto_font_size \csname\defaultfontclass\fontbody\s!mm\fontfamily\fontsize\currentmathsize\endcsname \else \ifcsname\defaultfontclass\fontbody\s!mm\fontfamily \currentmathsize\endcsname \settrue\font_auto_font_size \csname\defaultfontclass\fontbody\s!mm\fontfamily \currentmathsize\endcsname \else \font_helpers_set_math_family_c \fi\fi} \def\font_helpers_set_math_family_c {\ifcsname \fontbody\s!mm\fontfamily\fontsize\currentmathsize\endcsname \setfalse\font_auto_font_size \csname \fontbody\s!mm\fontfamily\fontsize\currentmathsize\endcsname \else \ifcsname \fontbody\s!mm\fontfamily \currentmathsize\endcsname \settrue\font_auto_font_size \csname \fontbody\s!mm\fontfamily \currentmathsize\endcsname \else \nullfont \settrue\font_auto_font_size \fi\fi} \def\font_helpers_set_math_family_indeed#mrtag#family% \currentmathsize etc are also used later on {\let\savedfontbody\fontbody \let\fontfamily#family% \let\currentmathsize\!!plusthree\let\fontbody\scriptscriptface\font_helpers_set_math_family_a\scriptscriptfont#mrtag\font \let\currentmathsize\!!plustwo \let\fontbody\scriptface \font_helpers_set_math_family_a\scriptfont #mrtag\font \let\currentmathsize\!!plusone \let\fontbody\textface \font_helpers_set_math_family_a\textfont #mrtag\font \let\currentmathsize\empty \let\fontbody\savedfontbody \setfalse\font_auto_font_size} \def\font_helpers_set_math_family_bold_a#font#mbfam#mrfam% {\ifcsname\fontclass\fontbody\s!mm\fontfamily\fontsize\currentmathsize\endcsname \setfalse\font_auto_font_size \csname\fontclass\fontbody\s!mm\fontfamily\fontsize\currentmathsize\endcsname #font#mbfam\font \else \ifcsname\fontclass\fontbody\s!mm\fontfamily \currentmathsize\endcsname \settrue\font_auto_font_size \csname\fontclass\fontbody\s!mm\fontfamily \currentmathsize\endcsname #font#mbfam\font \else #font#mbfam#font#mrfam% \fi\fi} \def\font_helpers_set_math_family_bold_indeed#mbfam#familytag#mrfam% \c_font_fam_mb \s!mb \c_font_fam_mr {\let\savedfontclass\defaultfontclass \let\defaultfontclass\fontclass % else truefontname falls back on the wrong one \let\savedfontbody\fontbody \let\fontfamily#familytag% \let\currentmathsize\!!plusthree\let\fontbody\scriptscriptface\font_helpers_set_math_family_bold_a\scriptscriptfont#mbfam#mrfam% \let\currentmathsize\!!plustwo \let\fontbody\scriptface \font_helpers_set_math_family_bold_a\scriptfont #mbfam#mrfam% \let\currentmathsize\!!plusone \let\fontbody\textface \font_helpers_set_math_family_bold_a\textfont #mbfam#mrfam% \let\currentmathsize\empty \let\fontbody\savedfontbody \let\defaultfontclass\savedfontclass \setfalse\font_auto_font_size} % optimized: math fonts are never changed (10K \bfa $x$: 3.2 => 2.5 (baseline 1.0)) % % sort of tricky: we cannot reset in \everybeforedefinetypeface as we don't know % all sizes so we postpone the optimization to the first starttext % % pitfall: we should reset 'm when a fontclass name is reused \newconditional\optimizemathfontdefinitions \settrue\optimizemathfontdefinitions \def\font_helpers_set_math_family#mrfam#familytag% {\ifconditional\optimizemathfontdefinitions \ifcsname*\fontclass\textface\s!mm#familytag1\fontsize1*\endcsname \font_helpers_preset_math_family_indeed#mrfam#familytag% \else \font_helpers_set_math_family_indeed#mrfam#familytag% \fi \else \font_helpers_set_math_family_indeed#mrfam#familytag% \fi} \def\font_helpers_set_math_family_bold#mbfam#familytag#mrfam% {\ifconditional\optimizemathfontdefinitions \ifcsname*\fontclass\textface\s!mm#familytag1\fontsize1*\endcsname \font_helpers_preset_math_family_indeed#mbfam#familytag% \else \font_helpers_set_math_family_bold_indeed#mbfam#familytag#mrfam% \fi \else \font_helpers_set_math_family_bold_indeed#mbfam#familytag#mrfam% \fi} \def\font_helpers_preset_math_family_indeed#fam#familytag% {\scriptscriptfont#fam\csname*\fontclass\scriptscriptface\s!mm#familytag3\fontsize3*\endcsname \scriptfont #fam\csname*\fontclass\scriptface \s!mm#familytag2\fontsize2*\endcsname \textfont #fam\csname*\fontclass\textface \s!mm#familytag1\fontsize1*\endcsname} \let\font_helpers_reset_fontclass_math_families\gobbleoneargument % It would be nice if characters could be defined in a neutral way (say fam 255) and % be mapped to a real family during noad list construction. However, this changes % tex in critical places so for the moment we simulate this using manipulation. % \appendtoks % \font_helpers_check_bodyfont_environment[\scriptscriptface]% pretty slow when many switches % \font_helpers_check_bodyfont_environment[\scriptface]% % \font_helpers_check_bodyfont_environment[\textface]% % \to \t_font_math_strategies % For tracing purposes we use three families but in l2r mode 1 and 2 are copies of 0 % while in rl mode 0 is a copy of 1. There is no real overhead involved in this. This % also permits different font definitions for normal and mixed. \let\m_font_class_direction\empty \let\m_font_class_features \empty \let\m_font_class_fallbacks\empty \let\m_font_class_goodies \empty \let\m_font_direction\empty \let\m_font_features \empty \let\m_font_fallbacks\empty \let\m_font_goodies \empty \appendtoks % can be analyzed once % why here .. \edef\m_font_class_direction{\ifcsname\??fontclass\fontclass\s!mm\s!direction\endcsname\csname\??fontclass\fontclass\s!mm\s!direction\endcsname\fi}% % ... \ifx\m_font_class_direction\v!both \settrue\c_font_bidirectional_math_strategy \else \setfalse\c_font_bidirectional_math_strategy \fi \to \t_font_math_strategies \def\font_helpers_bidirectional_mathstrategy_yes {\font_helpers_set_math_family\c_font_fam_mr_lr\s!mrlr \font_helpers_set_math_family\c_font_fam_mr_rl\s!mrrl \textfont \c_font_fam_mr\textfont \c_font_fam_mr_lr \scriptfont \c_font_fam_mr\scriptfont \c_font_fam_mr_lr \scriptscriptfont\c_font_fam_mr\scriptscriptfont\c_font_fam_mr_lr} \def\font_helpers_bidirectional_mathstrategy_nop {\font_helpers_set_math_family\c_font_fam_mr\s!mr \textfont \c_font_fam_mr_rl\textfont \c_font_fam_mr \scriptfont \c_font_fam_mr_rl\scriptfont \c_font_fam_mr \scriptscriptfont\c_font_fam_mr_rl\scriptscriptfont\c_font_fam_mr \textfont \c_font_fam_mr_lr\textfont \c_font_fam_mr \scriptfont \c_font_fam_mr_lr\scriptfont \c_font_fam_mr \scriptscriptfont\c_font_fam_mr_lr\scriptscriptfont\c_font_fam_mr} \appendtoks \ifconditional\c_font_bidirectional_math_strategy \font_helpers_bidirectional_mathstrategy_yes \else \font_helpers_bidirectional_mathstrategy_nop \fi \to \t_font_math_strategies \def\font_helpers_complete_bold_math_strategy_yes_bidi {\font_helpers_set_math_family_bold\c_font_fam_mb_lr\s!mblr\c_font_fam_mr_lr \font_helpers_set_math_family_bold\c_font_fam_mb_rl\s!mbrl\c_font_fam_mr_rl \textfont \c_font_fam_mb\textfont \c_font_fam_mb_lr \scriptfont \c_font_fam_mb\scriptfont \c_font_fam_mb_lr \scriptscriptfont\c_font_fam_mb\scriptscriptfont\c_font_fam_mb_lr} \def\font_helpers_complete_bold_math_strategy_yes {\font_helpers_set_math_family_bold\c_font_fam_mb\s!mb\c_font_fam_mr \textfont \c_font_fam_mb_rl\textfont \c_font_fam_mb \scriptfont \c_font_fam_mb_rl\scriptfont \c_font_fam_mb \scriptscriptfont\c_font_fam_mb_rl\scriptscriptfont\c_font_fam_mb \textfont \c_font_fam_mb_lr\textfont \c_font_fam_mb \scriptfont \c_font_fam_mb_lr\scriptfont \c_font_fam_mb \scriptscriptfont\c_font_fam_mb_lr\scriptscriptfont\c_font_fam_mb} \def\font_helpers_complete_bold_math_strategy_nop {\textfont \c_font_fam_mb \textfont \c_font_fam_mr \scriptfont \c_font_fam_mb \scriptfont \c_font_fam_mr \scriptscriptfont\c_font_fam_mb \scriptscriptfont\c_font_fam_mr \textfont \c_font_fam_mb_rl\textfont \c_font_fam_mr_rl \scriptfont \c_font_fam_mb_rl\scriptfont \c_font_fam_mr_rl \scriptscriptfont\c_font_fam_mb_rl\scriptscriptfont\c_font_fam_mr_rl \textfont \c_font_fam_mb_lr\textfont \c_font_fam_mr_lr \scriptfont \c_font_fam_mb_lr\scriptfont \c_font_fam_mr_lr \scriptscriptfont\c_font_fam_mb_lr\scriptscriptfont\c_font_fam_mr_lr} \def\font_helpers_apply_complete_bold_math_strategy {\ifconditional\c_font_complete_bold_math_strategy \ifconditional\c_font_bidirectional_math_strategy \font_helpers_complete_bold_math_strategy_yes_bidi \else \font_helpers_complete_bold_math_strategy_yes \fi \else \font_helpers_complete_bold_math_strategynop \fi} \appendtoks \font_helpers_apply_complete_bold_math_strategy \to \t_font_math_strategies \ifdefined\defaultmathfamily \else \setnewconstant\defaultmathfamily\zerocount \fi \appendtoks \fam\defaultmathfamily % all characters and symbols are in this family \to \everymathematics \unexpanded\def\font_helpers_synchronize_math_family_mr {\attribute\mathfamilyattribute\ifconditional\c_font_bidirectional_math_strategy \ifconditional\c_math_right_to_left \plustwo \else \plusone \fi \else \zerocount \fi} \unexpanded\def\font_helpers_synchronize_math_family_mb {\attribute\mathfamilyattribute\ifconditional\c_font_bidirectional_math_strategy \ifconditional\c_math_right_to_left \ifconditional\c_font_pseudo_bold_math_state\pluseight\else\plusfive\fi \else \ifconditional\c_font_pseudo_bold_math_state\plusseven\else\plusfour\fi \fi \else \ifconditional\c_font_pseudo_bold_math_state\plussix\else\plusthree\fi \fi} \installcorenamespace{fontmathsynchronizer} \installcorenamespace{fontmathstoredstrategy} \letvalue{\??fontmathsynchronizer\s!tf }\font_helpers_synchronize_math_family_mr \letvalue{\??fontmathsynchronizer\s!sl }\font_helpers_synchronize_math_family_mr \letvalue{\??fontmathsynchronizer\s!it }\font_helpers_synchronize_math_family_mr \letvalue{\??fontmathsynchronizer\s!bf }\font_helpers_synchronize_math_family_mb \letvalue{\??fontmathsynchronizer\s!bs }\font_helpers_synchronize_math_family_mb \letvalue{\??fontmathsynchronizer\s!bi }\font_helpers_synchronize_math_family_mb \letvalue{\??fontmathsynchronizer\empty}\font_helpers_synchronize_math_family_mr \def\font_helpers_synchronize_math_family {\csname\??fontmathsynchronizer\ifcsname\??fontmathsynchronizer\fontalternative\endcsname\fontalternative\fi\endcsname} \ifdefined \fontid % we need to keep this test for a while \appendtoks \ifnum\fontid\textfont\zerocount=\fontid\textfont\plusthree \letvalue{\??fontmathstoredstrategy\fontclass}\font_helpers_set_math_partial_bold_strategy \else \letvalue{\??fontmathstoredstrategy\fontclass}\font_helpers_set_math_full_bold_strategy \fi \to \t_font_math_strategies \else \appendtoks \edef\currentmathfontmr{\fontname\textfont\zerocount}% \edef\currentmathfontmb{\fontname\textfont\plusthree}% \ifx\currentmathfontmr\currentmathfontmb \letvalue{\??fontmathstoredstrategy\fontclass}\font_helpers_set_math_partial_bold_strategy \else \letvalue{\??fontmathstoredstrategy\fontclass}\font_helpers_set_math_full_bold_strategy \fi \to \t_font_math_strategies \fi \def\font_helpers_synchronize_math_bold_strategy{\csname\??fontmathstoredstrategy\fontclass\endcsname} \newconditional\c_font_pseudo_bold_math_state \def\font_helpers_set_math_partial_bold_strategy{\settrue \c_font_pseudo_bold_math_state} \def\font_helpers_set_math_full_bold_strategy {\setfalse\c_font_pseudo_bold_math_state} \appendtoks \font_helpers_synchronize_math_bold_strategy \to \everymathematics % Bold is somewhat special as we might want both full-bold-math mixed % regular-math, as well as automatic adaption to outer bold (in titles % and inline text bold) so we will need explicit switches as well as % an automatic one. (We will use lucida as an example.) \unexpanded\def\mr {\ifmmode \font_helpers_synchronize_math_family_mr \else \font_helpers_set_current_font_alternative\s!mr \fi} \unexpanded\def\mb {\ifmmode \font_helpers_synchronize_math_family_mb \else \font_helpers_set_current_font_alternative\s!mb \fi} \appendtoks \font_helpers_synchronize_math_family % auto bold \to \everymathematics %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\font_helpers_process_relative_size_list#command% {#command\s!text #command\s!script #command\s!scriptscript #command\s!x #command\s!xx #command\v!big #command\v!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. % \enableexperiments[fonts.autorscale] % % \starttypescript[mscore] % \definetypeface [mscore] [rm] [serif] [mscoretimes] [default] % \definetypeface [mscore] [ss] [sans] [mscorearial] [default] [rscale=auto] % 0.860] % \definetypeface [mscore] [tt] [mono] [mscorecourier] [default] [rscale=auto] % 1.065] % \definetypeface [mscore] [mm] [math] [times] [default] [rscale=auto] % 1.020] % \stoptypescript % % \starttext % \setupbodyfont[mscore,12pt] % \startTEXpage % test \ss test \tt test % \stopTEXpage % \stoptext \let\v_font_size_relative \plusone \def\v_font_size_absolute {\fontbody} \let\v_font_rscale_default\plusone \let\p_font_rscale \v_font_rscale_default \def\font_helpers_check_relative_font_id % can be plugged in later {\let\p_font_rscale\minusone \let\p_font_rscale\v_font_rscale_default} \def\font_helpers_check_relative_font_size#scale% {\edef\p_font_rscale {\ifcsname\??fontclass\fontclass#scale\s!rscale\endcsname \csname\??fontclass\fontclass#scale\s!rscale\endcsname \else\ifcsname\??fontclass\defaultfontclass#scale\s!rscale\endcsname \csname\??fontclass\defaultfontclass#scale\s!rscale\endcsname \else \v_font_rscale_default \fi\fi}% \ifx\p_font_rscale\v!auto \let\p_font_rscale\plusone \font_helpers_check_relative_font_id \else \let\relativefontid\minusone \fi} %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} \installcorenamespace{fonts} \def\safontscale{\number\dimexpr\v_font_size_absolute\relax} \def\mofontscale{\number\dimexpr\font_basics_set_mapped_fontsize\v_font_size_absolute\relax} \let\somefontname\s!unknown \let\somefontspec\s!unknown \let\somefontsize\zerocount \newcount\scaledfontmode % also used at the lua end \newcount\lastfontid % also used at the lua end / tex end \newtoks \everydefinefont \def\currentfontbodysize {\ifcsname\??fonts\s!default\somefontsize\endcsname \csname\??fonts\s!default\somefontsize\endcsname \else \somefontsize \fi} \let\relativefontid\empty % 0 = none % 1 = fontonly % 2 = classonly % 3 = fontfirst % 4 = classfirst \let\c_font_feature_inheritance_fontnone \zerocount \let\c_font_feature_inheritance_fontonly \plusone \let\c_font_feature_inheritance_classonly \plustwo \let\c_font_feature_inheritance_fontfirst \plusthree \let\c_font_feature_inheritance_classfirst\plusfour \let\c_font_feature_inheritance_default \c_font_feature_inheritance_fontfirst \setnewconstant\c_font_feature_inheritance_mode \c_font_feature_inheritance_default \newdimen\d_font_scaled_text_face \newdimen\d_font_scaled_font_size \unexpanded\def\font_helpers_low_level_define#specification#csname% {% we can now set more at the lua end \ctxcommand{definefont_one(\!!bs\luaescapestring{#specification}\!!es)}% the escapestring catches at \somedimen % sets \scaledfontmode and \somefontname and \somefontsize \ifcase\scaledfontmode\relax % none, avoid the designsize if possible \d_font_scaled_font_size-\plusthousand\scaledpoint \or % at \d_font_scaled_font_size\somefontsize \or % sa \d_font_scaled_font_size\v_font_size_absolute\relax \d_font_scaled_font_size\currentfontbodysize\d_font_scaled_font_size \or % mo \d_font_scaled_font_size\font_basics_set_mapped_fontsize\v_font_size_absolute \d_font_scaled_font_size\currentfontbodysize\d_font_scaled_font_size \or % scaled, don't use this one as it's unpredictable \d_font_scaled_font_size-\somefontsize\scaledpoint \fi \relax \d_font_scaled_font_size\v_font_size_relative\d_font_scaled_font_size \ifconditional\font_auto_font_size \d_font_scaled_font_size\currentfontbodyscale\d_font_scaled_font_size \d_font_scaled_text_face\currentfontbodyscale\dimexpr\textface\relax \else \d_font_scaled_text_face\textface \fi \edef\somefontspec{at \number\d_font_scaled_font_size sp}% \edef\somefontfile{\truefontname\somefontname}% \ifx\somefontfile\s!unknown \edef\somefontfile{\defaultfontfile}% \fi \ifx\somefontfile\s!unknown \edef\somefontfile{\defaultfontfile}% \fi \font_helpers_update_font_parameters \font_helpers_update_font_class_parameters \ctxcommand{definefont_two( \ifx\fontclass\empty false\else true\fi, "#csname", \!!bs\somefontfile\!!es, \number\d_font_scaled_font_size, \number\c_font_feature_inheritance_mode, "\m_font_class_features", "\m_font_features", "\m_font_class_fallbacks", "\m_font_fallbacks", 0\currentmathsize, \number\d_font_scaled_text_face, "\relativefontid", % experiment "\m_font_class_goodies", % experiment (not yet used) "\m_font_goodies" % experiment )}% \edef\somefontspec{at \number\d_font_scaled_font_size sp}% we need the resolved designsize (for fallbacks) \expandafter\let\expandafter\lastrawfontcall\csname#csname\endcsname \the\everydefinefont \c_font_feature_inheritance_mode\c_font_feature_inheritance_default} % Why these expanded and rscale not ... maybe not worth the trouble (delayed % expansion actually would be better i.e. macros in feature specs). Test % without pre-expansion. \def\font_helpers_update_font_class_parameters {\edef\m_font_class_direction{\ifcsname\??fontclass\fontclass\fontstyle\s!direction\endcsname\csname\??fontclass\fontclass\fontstyle\s!direction\endcsname\fi}% \edef\m_font_class_features {\ifcsname\??fontclass\fontclass\fontstyle\s!features \endcsname\csname\??fontclass\fontclass\fontstyle\s!features \endcsname\fi}% \edef\m_font_class_fallbacks{\ifcsname\??fontclass\fontclass\fontstyle\s!fallbacks\endcsname\csname\??fontclass\fontclass\fontstyle\s!fallbacks\endcsname\fi}% \edef\m_font_class_goodies {\ifcsname\??fontclass\fontclass\fontstyle\s!goodies \endcsname\csname\??fontclass\fontclass\fontstyle\s!goodies \endcsname\fi}} % resolve \def\font_helpers_set_features_yes#name% {\ifcsname\??fontfile\fontclass#name\s!features \endcsname\expandafter\let\expandafter\m_font_features \csname\??fontfile\fontclass#name\s!features \endcsname\else \ifcsname\??fontfile #name\s!features \endcsname\expandafter\let\expandafter\m_font_features \csname\??fontfile #name\s!features \endcsname\else \ifcsname\??fontfile\fontclass #name\endcsname\expandafter\font_helpers_set_features_yes \csname\??fontfile\fontclass #name\endcsname\else \ifcsname\??fontfile #name\endcsname\expandafter\font_helpers_set_features_yes \csname\??fontfile #name\endcsname\else \let\m_font_features\empty\fi\fi\fi\fi} \def\font_helpers_set_fallbacks_yes#name% {\ifcsname\??fontfile\fontclass#name\s!fallbacks\endcsname\expandafter\let\expandafter\m_font_fallbacks \csname\??fontfile\fontclass#name\s!fallbacks\endcsname\else \ifcsname\??fontfile #name\s!fallbacks\endcsname\expandafter\let\expandafter\m_font_fallbacks \csname\??fontfile #name\s!fallbacks\endcsname\else \ifcsname\??fontfile\fontclass #name\endcsname\expandafter\font_helpers_set_fallbacks_yes \csname\??fontfile\fontclass #name\endcsname\else \ifcsname\??fontfile #name\endcsname\expandafter\font_helpers_set_fallbacks_yes \csname\??fontfile #name\endcsname\else \let\m_font_fallbacks\empty\fi\fi\fi\fi} \def\font_helpers_set_goodies_yes#name% {\ifcsname\??fontfile\fontclass#name\s!goodies \endcsname\expandafter\let\expandafter\m_font_goodies \csname\??fontfile\fontclass#name\s!goodies \endcsname\else \ifcsname\??fontfile #name\s!goodies \endcsname\expandafter\let\expandafter\m_font_goodies \csname\??fontfile #name\s!goodies \endcsname\else \ifcsname\??fontfile\fontclass #name\endcsname\expandafter\font_helpers_set_goodies_yes \csname\??fontfile\fontclass #name\endcsname\else \ifcsname\??fontfile #name\endcsname\expandafter\font_helpers_set_goodies_yes \csname\??fontfile #name\endcsname\else \let\m_font_goodies\empty\fi\fi\fi\fi} \def\font_helpers_set_features_nop#name% {\ifcsname\??fontfile#name\s!features \endcsname\expandafter\let\expandafter\m_font_features \csname\??fontfile#name\s!features \endcsname\else \ifcsname\??fontfile #name\endcsname\expandafter\font_helpers_set_features_nop \csname\??fontfile #name\endcsname\else \let\m_font_features\empty\fi\fi} \def\font_helpers_set_fallbacks_nop#name% {\ifcsname\??fontfile#name\s!fallbacks\endcsname\expandafter\let\expandafter\m_font_fallbacks \csname\??fontfile#name\s!fallbacks\endcsname\else \ifcsname\??fontfile #name\endcsname\expandafter\font_helpers_set_fallbacks_nop \csname\??fontfile #name\endcsname\else \let\m_font_fallbacks\empty\fi\fi} \def\font_helpers_set_goodies_nop#name% {\ifcsname\??fontfile#name\s!goodies \endcsname\expandafter\let\expandafter\m_font_goodies \csname\??fontfile#name\s!goodies \endcsname\else \ifcsname\??fontfile #name\endcsname\expandafter\font_helpers_set_goodies_nop \csname\??fontfile #name\endcsname\else \let\m_font_goodies\empty\fi\fi} \def\font_helpers_update_font_parameters_yes {\font_helpers_set_features_yes \somefontname \font_helpers_set_fallbacks_yes\somefontname \font_helpers_set_goodies_yes \somefontname} \def\font_helpers_update_font_parameters_nop {\font_helpers_set_features_nop \somefontname \font_helpers_set_fallbacks_nop\somefontname \font_helpers_set_goodies_nop \somefontname} \def\font_helpers_update_font_parameters {\ifx\fontclass\empty\font_helpers_update_font_parameters_nop\else\font_helpers_update_font_parameters_yes\fi} \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[slanted] [default][slant=.25] % \definefontfeature[stretched][default][stretch=2] % % \start \definedfont[SerifBold*slanted at 20pt] \ruledhbox{Test!} \stop % \start \definedfont[SerifBold*stretched at 20pt] \ruledhbox{Test!} \stop % \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#class#name{#class#name} % \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. % % or nicer .. use parent chain \let\m_font_name\empty \let\m_font_file\empty \unexpanded\def\definefontsynonym[#name]#crap[#file]% {\edef\m_font_name{#name}% \edef\m_font_file{#file}% \ifx\fontclass\empty \expandafter\font_basics_define_font_synonym_nop \else \expandafter\font_basics_define_font_synonym_yes \fi} \def\font_basics_define_font_synonym_nop {\expandafter\let\csname\??fontfile\m_font_name\endcsname\m_font_file \doifnextoptionalelse\font_basics_define_font_synonym_nop_opt\font_basics_define_font_synonym_nop_nil} \def\font_basics_define_font_synonym_yes {\expandafter\let\csname\??fontfile\fontclass\m_font_name\endcsname\m_font_file \doifnextoptionalelse\font_basics_define_font_synonym_yes_opt\font_basics_define_font_synonym_yes_nil} \def\font_basics_define_font_synonym_nop_opt[#specification]% {\let\p_features \undefined \let\p_fallbacks\undefined \let\p_goodies \undefined \expandafter\font_basics_get_font_parameter_nop#specification,]=,} \def\font_basics_define_font_synonym_yes_opt[#specification]% {\let\p_features \undefined \let\p_fallbacks\undefined \let\p_goodies \undefined \expandafter\font_basics_get_font_parameter_yes#specification,]=,} \def\font_basics_get_font_parameter_nop#key=#value,% {\if]#key% \font_basics_get_font_parameter_nop_finish \else \expandafter\normaldef\csname p_#key\endcsname{#value}% \expandafter\font_basics_get_font_parameter_nop \fi} \def\font_basics_get_font_parameter_yes#key=#value,% {\if]#key% \font_basics_get_font_parameter_yes_finish \else \expandafter\normaldef\csname p_#key\endcsname{#value}% \expandafter\font_basics_get_font_parameter_yes \fi} % helpers, some day these will be toks and counts % \def\fntsetdefname {\global\let\somefontname\defaultfontfile} % \def\fntsetsomename{\gdef\somefontname} % takes argument % \def\fntsetnopsize {\let\somefontsize\empty} % \def\fntsetsomesize{\def\somefontsize} % takes argument % happens later, else mkvi parsing gets into troubles % end of helpers % we could collect them in one macro (but no expansion) \def\font_basics_define_font_synonym_nop_nil {\expandafter\let\csname\??fontfile\m_font_name\s!features \endcsname\undefined \expandafter\let\csname\??fontfile\m_font_name\s!fallbacks\endcsname\undefined \expandafter\let\csname\??fontfile\m_font_name\s!goodies \endcsname\undefined} \def\font_basics_define_font_synonym_yes_nil {\global\expandafter\let\csname\??fontfile\fontclass\m_font_name\s!features \endcsname\undefined \global\expandafter\let\csname\??fontfile\fontclass\m_font_name\s!fallbacks\endcsname\undefined \global\expandafter\let\csname\??fontfile\fontclass\m_font_name\s!goodies \endcsname\undefined} \def\font_basics_get_font_parameter_nop_finish {\expandafter\let\csname\??fontfile\m_font_name\s!features \endcsname\p_features \expandafter\let\csname\??fontfile\m_font_name\s!fallbacks\endcsname\p_fallbacks \expandafter\let\csname\??fontfile\m_font_name\s!goodies \endcsname\p_goodies} \def\font_basics_get_font_parameter_yes_finish {\global\expandafter\let\csname\??fontfile\fontclass\m_font_name\s!features \endcsname\p_features \global\expandafter\let\csname\??fontfile\fontclass\m_font_name\s!fallbacks\endcsname\p_fallbacks \global\expandafter\let\csname\??fontfile\fontclass\m_font_name\s!goodies \endcsname\p_goodies} %\definefontsynonym [KopFont] [\fontclassname{officina}{SerifBold}] % %\defineclassfontsynonym [KopFont] [officina] [SerifBold] \unexpanded\def\defineclassfontsynonym {\dotripleargument\font_basics_define_class_font_synonym} %\definefontsynonym[#tag][\fontclassname{#class}{#fileortag}]} \def\font_basics_define_class_font_synonym[#tag][#class][#fileortag]% needs testing {\expandafter\normaldef\csname\??fontfile\fontclass#tag\endcsname{\fontclassname{#class}{#fileortag}}% \font_basics_define_font_synonym_yes_nil} \let\definefontfile\definefontsynonym % dedicated to Taco Hoekwater \unexpanded\def\setupfontsynonym {\dodoubleempty\dosetupfontsynonym} \def\dosetupfontsynonym[#name][#settings]% not yet supported, will do when needed {} % todo: replace * by ... less messy with features \def\truefontname#name% {\expandafter\font_helpers_true_fontname#name*\empty*\relax} \def\font_helpers_true_fontname#name*#first#rest*#crap\relax {\ifcsname\??fontfile\fontclass#name\endcsname \ifx#first\empty \expandafter\truefontname\csname\??fontfile\fontclass#name\endcsname \else \expandafter\font_helpers_true_fontname_check\csname\??fontfile\fontclass#name\endcsname*#first#rest% \fi \else\ifcsname\??fontfile\defaultfontclass#name\endcsname \ifx#first\empty \expandafter\truefontname\csname\??fontfile\defaultfontclass#name\endcsname \else \expandafter\font_helpers_true_fontname_check\csname\??fontfile\defaultfontclass#name\endcsname*#first#rest% \fi \else\ifcsname\??fontfile#name\endcsname \ifx#first\empty \expandafter\truefontname\csname\??fontfile#name\endcsname \else \expandafter\font_helpers_true_fontname_check\csname\??fontfile#name\endcsname*#first#rest% \fi \else #name\ifx#first\empty\else*#first#rest\fi \fi\fi\fi} \def\font_helpers_true_fontname_check#name% {\expandafter\font_helpers_true_fontname_check_indeed#name*\relax} \def\font_helpers_true_fontname_check_indeed#name*#crap\relax {\ifcsname\??fontfile\fontclass#name\endcsname \expandafter\font_helpers_true_fontname_check\csname\??fontfile\fontclass#name\endcsname \else\ifcsname\??fontfile\defaultfontclass#name\endcsname \expandafter\font_helpers_true_fontname_check\csname\??fontfile\defaultfontclass#name\endcsname \else\ifcsname\??fontfile#name\endcsname \expandafter\font_helpers_true_fontname_check\csname\??fontfile#name\endcsname \else #name% \fi\fi\fi} \def\expandfontsynonym#command#name% one level expansion {\ifcsname\??fontfile\fontclass#name\endcsname \expandafter\normaldef\expandafter#command\expandafter{\csname\??fontfile\fontclass#name\endcsname}% \else\ifcsname\??fontfile\defaultfontclass#2\endcsname \expandafter\normaldef\expandafter#command\expandafter{\csname\??fontfile\defaultfontclass#name\endcsname}% \fi\fi} \def\doifelsefontsynonym#name% {\ifcsname\??fontfile\fontclass#name\endcsname \singleexpandafter\firstoftwoarguments \else\ifcsname\??fontfile\defaultfontclass#name\endcsname \doubleexpandafter\firstoftwoarguments \else \doubleexpandafter\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] \unexpanded\def\startfontclass {\dosingleempty\font_basics_start_font_class} \def\font_basics_start_font_class[#class]% {\pushmacro\fontclass \doifelse{#class}\v!each {\let\fontclass\empty} {\doifsomething{#class}{\def\fontclass{#class}}}} \unexpanded\def\stopfontclass {\popmacro\fontclass} %D \macros %D {tracedfontname} %D %D A goody: \def\tracedfontname#name% {#name\ifcsname\??fontfile\fontclass#name\endcsname \expandafter\tracedfontname\csname\??fontfile\fontclass#name\endcsname \else\ifcsname\??fontfile#name\endcsname \expandafter\tracedfontname\csname\??fontfile#name\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: % \unexpanded\def\definefont % {\dotripleempty\font_basics_define_font} % % \def\font_basics_define_font[#name][#specification][#settings]% [name][spec][1.6 | line=10pt | setup_id] % {\ifthirdargument % \setuvalue{#name}{\font_basics_define_font_with_parameters{#name}{#specification}{#settings}}% % \else % \setuvalue{#name}{\font_basics_define_font_without_parameters{#name}{#specification}}% % \fi} % % \def\font_basics_define_font_with_parameters#name#specification#settings% % {\font_basics_define_font_without_parameters{#name}{#specification}% % \doifsetupselse{#settings} % {\setups[#settings]} % don't forget to document this ! % {\setuplocalinterlinespace[#settings]% % \setupspacing}} % needed ? \unexpanded\def\definefont % [name][spec][1.6 | line=10pt | setup_id] {\dotripleempty\font_basics_define_font} \def\font_basics_define_font {\ifthirdargument \expandafter\font_basics_define_font_a \else \expandafter\font_basics_define_font_b \fi} \def\font_basics_define_font_a[#name][#specification][#settings]% [name][spec][1.6 | line=10pt | setup_id] {\doifsetupselse{#settings}% {\setuvalue{#name}{\font_basics_define_font_with_setups {#name}{#specification}{#settings}}} {\setuvalue{#name}{\font_basics_define_font_with_parameters{#name}{#specification}{#settings}}}} \def\font_basics_define_font_b[#name][#specification][#dummy]% {\setuvalue{#name}{\font_basics_define_font_without_parameters{#name}{#specification}}} \def\font_basics_define_font_with_parameters#name#specification#settings% {\font_basics_define_font_without_parameters{#name}{#specification}% \setuplocalinterlinespace[#settings]% \setupspacing\relax} % is this really needed ? \def\font_basics_define_font_with_setups#name#specification#settings% {\font_basics_define_font_without_parameters{#name}{#specification}% \setups[#settings]} % Beware, currently no settings are supported ... might happen some day \unexpanded\def\definefrozenfont {\dotripleempty\font_basics_define_frozen_font} \def\font_basics_define_frozen_font[#name][#specification][#settings]% {\begingroup \font_basics_define_font[#name][#specification][#settings]% \csname#name\endcsname \expandafter\endgroup\expandafter\let\csname#name\endcsname\lastrawfontcall} %D The \type {*} makes the switch local, so that we can redefine a %D logical name and/or change the size in between. % todo: now mathsize twice in name (so it can go here) % todo: check when mathsize is needed \installcorenamespace {fontsbasic} \installcorenamespace {fontsclass} \newconditional\font_auto_font_size \settrue\font_auto_font_size \let\lastfontidentifier\empty \def\v_font_identifier_basic{\??fontsbasic \lastfontidentifier\fontsize\currentmathsize} \def\v_font_identifier_class{\??fontsclass\fontclass\lastfontidentifier\fontsize\currentmathsize} \def\v_font_identifier_basic{\??fontsbasic \lastfontidentifier\fontsize\currentmathsize} \def\v_font_identifier_class{\??fontsclass\fontclass\lastfontidentifier\fontsize\currentmathsize} \let\v_font_identifier_basic_saved\v_font_identifier_basic \let\v_font_identifier_class_saved\v_font_identifier_class % \def\v_font_identifier_class{*\fontclass\lastfontidentifier\fontstyle\fontsize*} % no \currentmathsize \def\font_basics_define_font_without_parameters#identifier#2% {\c_font_feature_inheritance_mode\c_font_feature_inheritance_fontonly \edef\lastfontidentifier{#identifier}% \let\v_font_size_relative\v_font_rscale_default \let\v_font_size_absolute\fontbody \font_helpers_low_level_define{#2}\v_font_identifier_basic \csname\v_font_identifier_basic\endcsname \setfalse\font_auto_font_size \setfontcharacteristics \the\everyfontswitch \let\v_font_identifier_basic\v_font_identifier_basic_saved} \unexpanded\def\font_helpers_trigger#identifier% {\edef\lastfontidentifier{#identifier}% \ifcsname\v_font_identifier_class\endcsname \expandafter\font_helpers_trigger_reuse \else \expandafter\font_helpers_trigger_define \fi} \def\font_helpers_trigger_define#relative#absolute#specification% {\def\v_font_size_relative{#relative}% \def\v_font_size_absolute{#absolute}% \font_helpers_low_level_define{#specification}\v_font_identifier_class \csname\v_font_identifier_class\endcsname \setfalse\font_auto_font_size \ifskipfontcharacteristics \else \setfontcharacteristics \the\everyfontswitch \fi \let\v_font_identifier_class\v_font_identifier_class_saved} \def\font_helpers_trigger_reuse#relative#absolute#specification% {\csname\v_font_identifier_class\endcsname \setfalse\font_auto_font_size \ifskipfontcharacteristics \else \setfontcharacteristics \the\everyfontswitch \fi \let\v_font_identifier_class\v_font_identifier_class_saved} %D \macros %D {mapfontsize} %D %D For special purposes, like in math, you may want to use %D slightly different sizes than the ones given. This happens %D for instance with the Math Times fonts. Mapped font sizes %D can be specified by using the \type {mo} key instead of %D \type {sa} in font definitions. %D %D \startbuffer %D \mapfontsize[10pt][11pt] %D \mapfontsize[11pt][12pt] %D \mapfontsize[12pt][13pt] %D %D \definefont[test][Serif]\test TEST \par %D \definefont[test][Serif sa 5]\test TEST \par %D \definefont[test][Serif mo 5]\test TEST \par %D \definefont[test][Serif sa d]\test TEST \par %D \definefont[test][Serif at 60pt]\test TEST \par %D \definefont[test][Serif scaled 6000]\test TEST \par %D \stopbuffer %D %D \typebuffer %D %D \startpacked %D \getbuffer %D \stoppacked \installcorenamespace{mappedfontsize} \unexpanded\def\mapfontsize {\dodoubleargument\font_basics_map_fontsize} \def\font_basics_map_fontsize[#from][#to]% {\setvalue{\??mappedfontsize\the\dimexpr#from\relax}{#to}} \def\font_basics_set_mapped_fontsize#from% {\ifcsname\??mappedfontsize\the\dimexpr#from\relax\endcsname \csname\??mappedfontsize\the\dimexpr#from\relax\endcsname\else#from% \fi} %D To be documented. \let\fontsizelist \empty \let\fontalternativelist\empty \let\fontstylelist \empty % if we really need it we can make a toks \def\font_helpers_check_fontname_combinations_indeed#size% {\def\font_helpers_check_fontname_combinations_indeed_a#alternative% {\def\font_helpers_check_fontname_combinations_indeed_b#style{\font_basics_check_bodyfont{#style}{#alternative}{#size}}% \processcommacommand[\fontstylelist]\font_helpers_check_fontname_combinations_indeed_b}% \processcommacommand[\fontalternativelist]\font_helpers_check_fontname_combinations_indeed_a} \unexpanded\def\font_helpers_check_fontname_combinations % we need to split math and text here ... todo (math only has mr and mb) {\processcommacommand[\fontsizelist]\font_helpers_check_fontname_combinations_indeed} \unexpanded\def\definefontsize[#size]% sneller met toks {\addtocommalist{#size}\fontsizelist \font_helpers_check_fontname_combinations} \unexpanded\def\definefontalternative[#alternative]% {\addtocommalist{#alternative}\fontalternativelist \font_helpers_check_fontname_combinations} %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\??fonts\s!default \ifcsname\??fonts\s!default\xfontsize\endcsname \xfontsize \else \ifcsname\??fonts\s!default\s!text \endcsname \s!text \fi\fi \endcsname} \def\currentfontbodyscale {\csname\??fonts\s!default \ifcsname\??fonts\s!default\fontsize\endcsname \fontsize \else \ifcsname\??fonts\s!default\s!text \endcsname \s!text \fi\fi \endcsname} \setvalue{\??fonts\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}. %D In the following macros we use \type{\currentxfontsize} to %D hold the current x||size of the font. This enables us to %D support for instance \type{\sl} inside a \type{\tx} switch. \newconstant\currentxfontsize \def\xfontsize{\ifcase\currentxfontsize\fontsize\or\s!x\else\s!xx\fi} %D 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 When instead of a size the keyword \type{unknown} is %D passed, fractions (relations) are used instead of fixed %D sizes. %D {\bf Remark:} We need to cover the following cases, otherwise users can %D get confused: %D %D \starttyping %D \setupbodyfont[23pt] %D %D \definebodyfontenvironment[23pt] %D \setupbodyfont[23pt] %D %D \definebodyfontenvironment[23pt] %D \definebodyfont[23pt][rm,ss,tt][default] %D \setupbodyfont[23pt] %D \stoptyping %D %D Beware: while some font defs can be global, the bodyfont %D environment checks local. This means that multiple local %D checks resulting in definitions are not that efficient. %D So, apart from an occasional switch, one should define an %D environment at the outer level. \letvalue\??fonts\empty % so we default to empty \def\bodyfontvariable#parameter% {\csname\??fonts \ifcsname\??fonts\fontclass\normalizedbodyfontsize#parameter\endcsname\fontclass\normalizedbodyfontsize#parameter\else \ifcsname\??fonts\fontclass #parameter\endcsname\fontclass #parameter\else \ifcsname\??fonts \normalizedbodyfontsize#parameter\endcsname \normalizedbodyfontsize#parameter\else \ifcsname\??fonts\s!default #parameter\endcsname\s!default #parameter\fi\fi\fi\fi \endcsname} \def\bodyfontsizevariable#size#parameter% {\csname\??fonts \ifcsname\??fonts\fontclass#size#parameter\endcsname\fontclass#size#parameter\else \ifcsname\??fonts\fontclass #parameter\endcsname\fontclass #parameter\else \ifcsname\??fonts #size#parameter\endcsname #size#parameter\else \ifcsname\??fonts\s!default #parameter\endcsname\s!default #parameter\fi\fi\fi\fi \endcsname} \def\bodyfontinterlinespace{\bodyfontvariable\c!interlinespace} % used elsewhere \def\bodyfontdimension#class#size#parameter#body% {\the\dimexpr \ifcsname\??fonts#class #size#parameter\endcsname \csname\??fonts#class #size#parameter\endcsname \else \ifcsname\??fonts#class\s!default#parameter\endcsname \csname\??fonts#class\s!default#parameter\endcsname\dimexpr#body\relax \else % factor \ifcsname\??fonts #size#parameter\endcsname \csname\??fonts #size#parameter\endcsname \else \csname\??fonts \s!default#parameter\endcsname\dimexpr#body\relax \fi\fi\fi % factor \relax} \let\bodyfontenvironmentlist\empty % used in font-run \unexpanded\def\definebodyfontenvironment {\dotripleempty\font_basics_define_body_font_environment} \let\setupbodyfontenvironment\definebodyfontenvironment % the lookup order is: % % [class] [dimension] [parameters] % [class] [default] [parameters] % factors % [dimension] [parameters] % [default] [parameters] % factors % % with defaults providing factors % todo: class:size % todo: make assignments global \installcorenamespace{fontsteps} % fast cache \let\m_font_body \empty \let\m_font_body_normalized\empty \def\font_basics_define_body_font_environment {\ifthirdargument \singleexpandafter\font_basics_define_body_font_environment_class \else\ifsecondargument \doubleexpandafter\font_basics_define_body_font_environment_empty \fi\fi} % First we handle the class specific case. Beware: you can change values before % a bodyfont is loaded but changing them afterwards can be sort of tricky as % values are not consulted afterwards. \def\font_basics_define_body_font_environment_class[#class][#body][#settings]% {\edef\m_font_body{#body}% \ifx\m_font_body\s!default % these are the last resort within a class \getrawparameters[\??fonts#class\s!default][#settings]% \else \edef\m_font_body_normalized{\thenormalizedbodyfontsize\m_font_body}% \addtocommalist\m_font_body_normalized\bodyfontenvironmentlist \font_basics_define_body_font_environment_size[#class][\m_font_body_normalized][#settings]% \letvalue{\??fonts#class#body\s!check}\empty % a signal that we have defined this one \fi} \def\font_basics_define_body_font_environment_size[#class][#body][#settings]% normalized body {\getrawparameters[\??fonts#class#body][#settings]% % don't check too soon as we can refer to later definitions % \font_helpers_process_relative_size_list{\font_basics_define_body_font_environment_size_step{#class}{#body}{#body}}% \ifproductionrun \ifcsname\??fontsize#body\endcsname % only once \else % \empty prevents loop \letvalueempty{\??fontsize#body}% \pushmacro\fontclass \edef\fontclass{#class}% \font_helpers_define_unknown_font{#body}% \popmacro\fontclass \fi \fi % so far \setevalue{\??fontsize#body}{\font_basics_complete_switch[#body]}} \def\font_basics_define_body_font_environment_size_step_normal#class#size#body#step% {\expandafter\normaledef\csname\??fontsteps#class#size#step\endcsname {\thenormalizedbodyfontsize{\bodyfontdimension{#class}{#size}{#step}{#body}}}} \def\font_basics_define_body_font_environment_size_step_traced#class#size#body#step% {\font_basics_define_body_font_environment_size_step_normal{#class}{#size}{#body}{#step}% \writestatus{size mapping}{#class #size #step => \csname\??fontsteps#class#size#step\endcsname}} \let\font_basics_define_body_font_environment_size_step\font_basics_define_body_font_environment_size_step_normal \unexpanded\def\tracefontsizemapping % todo, \enabletextracker {\let\font_basics_define_body_font_environment_size_step\font_basics_define_body_font_environment_size_step_traced} % \tracefontsizemapping % The empty case uses the same code but needs to ignore the current class % settings (just to be sure, as it's not really needed). \def\font_basics_define_body_font_environment_empty[#body][#settings][#dummy]% {\pushmacro\fontclass \let\fontclass\empty \font_basics_define_body_font_environment_class[][#body][#settings]% \popmacro\fontclass} % Checking \def\font_helpers_check_bodyfont_environment[#size]% {\ifcsname\??fonts\fontclass#size\s!check\endcsname \else \font_helpers_check_bodyfont_environment_indeed{#size}% \fi} \def\font_helpers_check_bodyfont_environment_indeed#size% class size (simplified version of definebodyfontenvironment) {\edef\m_font_body_normalized{\thenormalizedbodyfontsize{#size}}% \addtocommalist\m_font_body_normalized\bodyfontenvironmentlist \font_helpers_process_relative_size_list{\font_basics_define_body_font_environment_size_step\fontclass\m_font_body_normalized\fontbody}% \letvalue{\??fonts\fontclass#size\s!check}\empty \ifcsname\??fontsize\m_font_body_normalized\endcsname \else \letvalue{\??fontsize\m_font_body_normalized}\empty % prevent loop \normalexpanded{\font_helpers_define_unknown_font{\m_font_body_normalized}}% we can also inherit here \fi \setevalue{\??fontsize\fontclass}{\font_basics_complete_switch[\fontclass]}} %D We default all parameters to the main bodyfont size, so the %D 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. %D If we move design size info to the lfg file (after all only lm %D has design sizes) we can get rid of much code .. 2012 or so. \installcorenamespace{fontdefaults} \unexpanded\def\definebodyfont {\doquadrupleempty\font_basics_define_body_font} \def\font_basics_define_body_font[#1][#2][#3][#4]% {\iffourthargument \processcommacommand[#1]{\font_basics_define_body_font_by_class[#2][#3][#4]}% \else \font_basics_define_body_font_indeed[#1][#2][#3]% \fi} \def\font_basics_define_body_font_by_class[#1][#2][#3]#4% {\pushmacro\fontclass \doifelse{#4}\s!default {\let\fontclass\empty} {\def\fontclass{#4}}% \definebodyfont[#1][#2][#3]% \popmacro\fontclass} \def\font_basics_define_body_font_indeed {\ifthirdargument \singleexpandafter\font_basics_define_body_font_indeed_a \else\ifsecondargument \doubleexpandafter\font_basics_define_body_font_indeed_b \else \doubleexpandafter\font_basics_define_body_font_indeed_c \fi\fi} \def\font_basics_define_body_font_indeed_a[#body][#style][#specification]% body|identifier style defs|identifier {\doifnumberelse{#body} {\doifassignmentelse{#specification} {% [12pt] [style] [settings] \ifcsname#style\endcsname\else\normalexpanded{\definefontstyle[#style][#style]}\fi % new \processcommalist[#1]{\font_basics_define_body_font_styles{#style}{#specification}}} {% [12pt] [style] [identifier] \font_basics_define_default_bodyfont[#body][#style][#specification]}} % body style identifier {% [identifier] [style] [settings] % see *** ... normalexpanded \setevalue{\??fontdefaults#body#style}{\font_basics_define_body_font_default{#specification}}}} % takes two extra arguments \def\font_basics_define_body_font_indeed_b[#body][#specification][#dummy]% body|identifier defs|identifier {\font_basics_define_body_font_indeed_a[#body][\s!rm][#specification]} \def\font_basics_define_body_font_indeed_c[#body][#dummya][#dummyb]% body|identifier {% 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\??fontsize#1\endcsname \else \font_helpers_define_unknown_font{#body}% \fi \ifcsname\??fontsize#1\endcsname \else \font_basics_define_body_font_indeed_a[#body][\s!rm][]% \fi} \unexpanded\def\font_basics_define_body_font_default#specification#body#style% {\font_helpers_check_relative_font_size{#style}% rather new, inherit from other defs \ifcsname#style\endcsname\else\normalexpanded{\definefontstyle[#style][#style]}\fi % new \processcommalist[#body]{\font_basics_define_body_font_styles{#style}{#specification}}% \let\p_font_rscale\v_font_rscale_default} \def\font_basics_define_body_font_styles#1#2#3% style defs body {\font_helpers_check_bodyfont_environment[#3]% just to be sure; can probably be omited now \processcommalist[#2]{\font_basics_define_body_font_defs{#1}{#3}}} \def\font_basics_define_body_font_defs#1#2#3% style body def {\font_basics_define_body_font_defs_indeed{#1}{#2}[#3]} \def\font_basics_define_body_font_defs_indeed {\ifx\fontclass\empty \expandafter\font_basics_define_body_font_defs_nop \else \expandafter\font_basics_define_body_font_defs_yes \fi} \def\font_basics_define_body_font_defs_yes#style% style body def {\edef\askedbodyfontstyle{#style}% \ifx\askedbodyfontstyle\s!mm \expandafter\font_basics_define_body_font_yes_mm \else \expandafter\font_basics_define_body_font_yes_xx \fi\askedbodyfontstyle} \def\font_basics_define_body_font_defs_nop#style% style body def {\edef\askedbodyfontstyle{#style}% \ifx\askedbodyfontstyle\s!mm \expandafter\font_basics_define_body_font_nop_mm \else \expandafter\font_basics_define_body_font_nop_xx \fi\askedbodyfontstyle} % we split into two characters (first part of spec) and the rest \def\font_basics_define_body_font_nop_xx#style#body[#one#two#rest=#value]% {\ifcsname#style#one#two#rest\endcsname\else\font_basics_check_bodyfont{#style}{#one#two}{#rest}\fi \expandafter\let\csname*#body#style#one#two#rest*\endcsname\undefined \unexpanded\expandafter\normaledef\csname#body#style#one#two#rest\endcsname{\font_helpers_trigger{#body#style#one#two#rest}{\number\p_font_rscale}{#body}{\normalunexpanded{#value}}}} \def\font_basics_define_body_font_yes_xx#style#body[#one#two#rest=#value]% {\ifcsname#style#one#two#rest\endcsname\else\font_basics_check_bodyfont{#style}{#one#two}{#rest}\fi \global\expandafter\let\csname*\fontclass#body#style#one#two#rest*\endcsname\undefined \unexpanded\expandafter\normalxdef\csname\fontclass#body#style#one#two#rest\endcsname{\font_helpers_trigger{#body#style#one#two#rest}{\number\p_font_rscale}{#body}{\normalunexpanded{#value}}}} \def\font_basics_define_body_font_nop_mm#style#body[#one#two#rest=#value]% {\ifcsname#style#one#two#rest\endcsname\else\font_basics_check_bodyfont{#style}{#one#two}{#rest}\fi \expandafter\let\csname*#body#style#one#two#rest1*\endcsname\undefined \expandafter\let\csname*#body#style#one#two#rest2*\endcsname\undefined \expandafter\let\csname*#body#style#one#two#rest3*\endcsname\undefined \unexpanded\expandafter\normaledef\csname#body#style#one#two#rest1\endcsname{\font_helpers_trigger{#body#style#one#two#rest1}{\number\p_font_rscale}{#body}{\normalunexpanded{#value}}}% \unexpanded\expandafter\normaledef\csname#body#style#one#two#rest2\endcsname{\font_helpers_trigger{#body#style#one#two#rest2}{\number\p_font_rscale}{#body}{\normalunexpanded{#value}}}% \unexpanded\expandafter\normaledef\csname#body#style#one#two#rest3\endcsname{\font_helpers_trigger{#body#style#one#two#rest3}{\number\p_font_rscale}{#body}{\normalunexpanded{#value}}}} \def\font_basics_define_body_font_yes_mm#style#body[#one#two#rest=#value]% {\ifcsname#style#one#two#rest\endcsname\else\font_basics_check_bodyfont{#style}{#one#two}{#rest}\fi \global\expandafter\let\csname*\fontclass#body#style#one#two#rest1*\endcsname\undefined \global\expandafter\let\csname*\fontclass#body#style#one#two#rest2*\endcsname\undefined \global\expandafter\let\csname*\fontclass#body#style#one#two#rest3*\endcsname\undefined \unexpanded\expandafter\normalxdef\csname\fontclass#body#style#one#two#rest1\endcsname{\font_helpers_trigger{#body#style#one#two#rest1}{\number\p_font_rscale}{#body}{\normalunexpanded{#value}}}% \unexpanded\expandafter\normalxdef\csname\fontclass#body#style#one#two#rest2\endcsname{\font_helpers_trigger{#body#style#one#two#rest2}{\number\p_font_rscale}{#body}{\normalunexpanded{#value}}}% \unexpanded\expandafter\normalxdef\csname\fontclass#body#style#one#two#rest3\endcsname{\font_helpers_trigger{#body#style#one#two#rest3}{\number\p_font_rscale}{#body}{\normalunexpanded{#value}}}} \let\m_font_mm\empty \def\font_basics_check_bodyfont#style% tests for ttsl mmbf {\edef\m_font_mm{#style}% \ifx\m_font_mm\s!mm % prevents \max and alike (re)defs \expandafter\font_basics_check_math_bodyfont \else \expandafter\font_basics_check_text_bodyfont \fi{#style}} % no \m_font_mm, not expanded later on % nb: We define the commands globally in the next two macros. After % all they are part of the formal font interface once defined. % % The size can be empty (so checking is needed as \bf is already % defined) \def\font_basics_check_math_bodyfont#style#alternative#size% {%setugvalue{#alternative}{\font_helpers_set_current_font_alternative{#alternative}}% \mr \mb \setugvalue{#style}{\font_helpers_set_current_font_style{#style}}}% \mm \def\font_basics_check_text_bodyfont#style#alternative#size% nb: gdef % size can be empty (checking needed as \bf is already defined) {\setugvalue{#style#size}{\font_helpers_set_current_font_style_size{#style}{#size}}% \rma \setugvalue{#alternative#size}{\font_helpers_set_current_font_alternative_size{#alternative}{#size}}% \sla \setugvalue{#style#alternative#size}{\font_helpers_set_current_font_style_alternative_size{#style}{#alternative}{#size}}% \rmsla \ifcsname\s!normal#style\endcsname % text/math check \expandafter\let\csname#style\expandafter\endcsname\csname\s!normal#style\endcsname \else \setugvalue{#style}{\font_helpers_set_current_font_style{#style}}% \rm \fi \ifcsname\s!normal#alternative\endcsname % text/math check \expandafter\let\csname#alternative\expandafter\endcsname\csname\s!normal#alternative\endcsname \else \setugvalue{#alternative}{\font_helpers_set_current_font_alternative{#alternative}}% \sl \fi \setugvalue{#style\s!x}{\font_helpers_set_current_font_x_style_alternative{#style}}% \rmx \setugvalue{#style\s!xx}{\font_helpers_set_current_font_xx_style_alternative{#style}}% \rmxx \setugvalue{#alternative\s!x}{\font_helpers_set_current_font_x_alternative{#alternative}}% \slx \setugvalue{#alternative\s!xx}{\font_helpers_set_current_font_xx_alternative{#alternative}}% \slxx \setugvalue{#style#alternative}{\font_helpers_set_current_font_style_alternative{#style}{#alternative}}}% \rmsl \def\font_basics_define_default_bodyfont[#sizes][#styles][#specification]% {\def\font_basics_define_default_bodyfont_a#size% {\def\font_basics_define_default_bodyfont_b#style% {\def\font_basics_define_default_bodyfont_c#spec% {\ifcsname\??fontdefaults#spec#style\endcsname % [12pt] [style] [identifier] \csname\??fontdefaults#spec#style\endcsname{#size}{#style}% \fi}% \processcommalist[#specification]\font_basics_define_default_bodyfont_c}% \processcommalist[#styles]\font_basics_define_default_bodyfont_b}% \processcommalist[#sizes]\font_basics_define_default_bodyfont_a} \newconditional\c_font_defining_unknown \newconditional\c_font_defining_state \def\font_helpers_define_unknown_font_indeed#body#relativesize% {\ifcsname\??fonts\s!default#relativesize\endcsname \settrue\c_font_defining_state \edef\m_font_body_normalized{\thenormalizedbodyfontsize{\csname\??fonts\s!default#relativesize\endcsname\dimexpr#body\relax}}% \letvalue{\??fonts#body#relativesize}\m_font_body_normalized \fi} \def\font_helpers_define_unknown_bodyfont_indeed#body#style% see *** {\ifcsname\??fontdefaults\s!default#style\endcsname % somehow related to */* \settrue\c_font_defining_state \csname\??fontdefaults\s!default#style\endcsname{#body}{#style}% \fi} \def\font_helpers_define_unknown_sub_font#body#relativesize% {\ifcsname\??fontsize\csname\??fonts#body#relativesize\endcsname\endcsname \else \settrue\c_font_defining_state \font_helpers_define_unknown_font{\csname\??fonts#body#relativesize\endcsname}% \fi} \unexpanded\def\font_helpers_define_unknown_font#body% {\setfalse\c_font_defining_state \font_helpers_process_relative_size_list{\font_helpers_define_unknown_font_indeed{#body}}% \ifconditional\c_font_defining_state \setfalse\c_font_defining_state \processcommacommand [\fontstylelist] {\font_helpers_define_unknown_bodyfont_indeed{#body}}% \ifconditional\c_font_defining_state \setfalse\c_font_defining_state \setevalue{\??fontsize#body}{\font_basics_complete_switch[#body]}% \ifconditional\c_font_defining_unknown \else \settrue\c_font_defining_unknown \font_helpers_process_relative_size_list{\font_helpers_define_unknown_sub_font{#body}}% \setfalse\c_font_defining_unknown \fi \fi \ifconditional\c_font_defining_state \showmessage\m!fonts{14}{#body}% \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 \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 {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. \setnewconstant\fontdigits\plustwo % was 1 \def\normalizebodyfontsize#body\to#macro% {\edef#macro{\ctxcommand{nbfs(\number\dimexpr#body\relax,\number\fontdigits)}}} \def\thenormalizedbodyfontsize#body% {\ctxcommand{nbfs(\number\dimexpr#body\relax,\number\fontdigits)}} \edef\normalizedglobalbodyfontsize{\thenormalizedbodyfontsize\bodyfontsize} \edef\normalizedlocalbodyfontsize {\thenormalizedbodyfontsize\bodyfontsize} \edef\normalizedbodyfontsize {\thenormalizedbodyfontsize\bodyfontsize} %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 = \s!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\font_basics_switch_points#body% % {\normalexpanded{\font_basics_switch_points_indeed{#body}}} % % \unexpanded\def\font_basics_switch_points_indeed#body% % % is expanded still handy here? \unexpanded\def\font_basics_switch_points#body% {\ifcsname\??fontsize#body\endcsname \else \font_helpers_define_unknown_font{#body}% \fi% \ifcsname\??fontsize#body\endcsname \csname\??fontsize#body\endcsname \localbodyfontsize#body\relax \edef\normalizedbodyfontsize{\thenormalizedbodyfontsize\localbodyfontsize}% \font_helpers_check_bodyfont_environment[\normalizedbodyfontsize]% \else \showmessage\m!fonts4{#body}% \fi} \unexpanded\def\font_basics_switch_style#style% {\ifcsname\??fontstyle#style\endcsname \csname\??fontstyle#style\endcsname \edef\fontstyle{#style}% \ifmmode\mr\fi % in order to be compatible with \rm in math mode % \the\everybodyfont % cleaner, in setting size as well as style \else \showmessage\m!fonts5{#style}% \fi} %D 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. %D %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. \fontslantperpoint \nullfont 0\scaledpoint \fontinterwordspace \nullfont 256377\scaledpoint \fontinterwordstretch\nullfont 128188\scaledpoint \fontinterwordshrink \nullfont 85459\scaledpoint \fontexheight \nullfont 338952\scaledpoint \fontemwidth \nullfont 786432\scaledpoint \fontextraspace \nullfont 85459\scaledpoint \fetchruntimecommand \showfontparameters {\f!fontprefix\s!run} \def\font_preloads_reset_nullfont % this is needed because some macro packages (tikz) misuse \nullfont {%\dorecurse7{\fontdimen\recurselevel\nullfont\zeropoint}% keep en eye on this as: \ctxcommand{resetnullfont()}% in luatex 0.70 this will also do the previous \globallet\font_preloads_reset_nullfont\relax} \def\font_preload_default_fonts {\font_preloads_reset \setupbodyfont[modern,\fontstyle,\fontbody]% \showmessage\m!fonts6{fallback modern \fontstyle\normalspace\normalizedbodyfontsize}} \def\font_preload_default_fonts_mm {\writestatus\m!fonts{preloading latin modern fonts (math)}% \definetypeface[\fontclass][\s!mm][\s!math][modern][\s!default]% \showmessage\m!fonts6{fallback modern mm \normalizedbodyfontsize}} \def\font_preload_default_fonts_tt {\writestatus\m!fonts{preloading latin modern fonts (mono)}% \definetypeface[\fontclass][\s!tt][\s!mono][modern][\s!default]% \showmessage\m!fonts6{fallback modern tt \normalizedbodyfontsize}} \def\font_preloads_reset {\glet\font_preload_default_fonts \relax %\glet\font_preload_default_fonts_tt\relax %\glet\font_preload_default_fonts_mm\relax \glet\font_preloads_zero_stage \relax \glet\font_preloads_first_stage \relax \glet\font_preloads_second_stage \relax %\glet\font_preloads_third_stage \relax \glet\fourthstagepreloadfonts \relax \global\everyhbox\emptytoks \global\everyvbox\emptytoks \font_preloads_reset_nullfont} \def\font_preloads_reset_checked {\glet\font_preload_default_fonts_tt\relax \glet\font_preload_default_fonts_mm\relax \glet\font_preloads_third_stage \relax} \def\font_preloads_zero_stage_indeed {\definedfont[\s!file:lmmono10-regular sa 1]} \unexpanded\def\font_preloads_zero_stage {\writestatus\m!fonts{beware: no fonts are loaded yet, using 'lm mono' in box}% \glet\font_preloads_zero_stage\font_preloads_zero_stage_indeed \font_preloads_zero_stage} \unexpanded\def\font_preloads_first_stage % % *nofonts -> *preloadfonts {\doifmodeelse{*preloadfonts} {\font_preload_default_fonts \writestatus\m!fonts{preloading latin modern fonts (first stage)}} {\writestatus\m!fonts{latin modern fonts are not preloaded}}} \unexpanded\def\font_preloads_second_stage {\writestatus\m!fonts{preloading latin modern fonts (second stage)}% \font_preload_default_fonts} \unexpanded\def\font_preloads_third_stage % always {\ifx\fontclass\empty \writestatus\m!fonts{preloading latin modern fonts (third stage)}% \font_preload_default_fonts \else \font_preloads_reset \pushmacro\fontstyle \ifcsname\??fontclass\fontclass\s!mm\s!features\endcsname \else \font_preload_default_fonts_mm \fi \ifcsname\??fontclass\fontclass\s!tt\s!features\endcsname \else \font_preload_default_fonts_tt \fi \popmacro\fontstyle \font_preloads_reset_checked % reset third, mm and tt \setupbodyfont[\fontstyle]% \fi} \unexpanded\def\font_preloads_fourth_stage {\begingroup %ifzeropt\fontcharwd\font\number`!\relax \setbox\scratchbox\hbox{context}% \ifzeropt\wd\scratchbox \writeline \writestatus\m!fonts{!! No bodyfont has been defined and no defaults have been}% \writestatus\m!fonts{!! loaded (maybe due to a missing \string\starttext).}% \writeline \fi \font_preloads_reset \endgroup} \appendtoks \everyhbox{\font_preloads_zero_stage} \everyvbox{\font_preloads_zero_stage} \to \everydump \def\font_preloads_at_every_job {\font_preloads_first_stage } \def\font_preloads_at_start_text{\font_preloads_second_stage} \def\font_preloads_at_stop_text {\font_preloads_fourth_stage} %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\font_helpers_set_font#method#specification% {\doifelse{#specification}\v!global {\restoreglobalbodyfont} {\processcommacommand[#specification]{\font_helpers_set_font_check_size}% \processcommacommand[#specification]{\font_helpers_set_font_set_font{#method}}% \ifproductionrun \font_preloads_third_stage \font_basics_switch_points\normalizedbodyfontsize \font_basics_switch_style\fontstyle \ifx\defaultfontclass\empty \let\defaultfontclass\fontclass \fi \fi}% \currentxfontsize\zerocount} \def\font_helpers_set_font_check_size#option% {\doifnumberelse{#option}{\font_helpers_check_bodyfont_environment[#option]}\donothing} \def\font_helpers_set_font_set_font#method#option% method=1: set, method=2: switch {\doifsomething{#option}{\font_helpers_set_font_set_font_option{#method}{#option}}} \def\font_helpers_set_font_set_font_option#method#option% {\doifnumberelse{#option}% \font_helpers_set_font_set_font_option_body \font_helpers_set_font_set_font_option_keyword {#method}{#option}{#option}} \let\m_font_keyword\empty \unexpanded\def\font_helpers_set_font_set_font_option_keyword#method#keyword#message% {\edef\m_font_keyword{#keyword}% \ifcsname\??fonts\normalizedbodyfontsize\m_font_keyword\endcsname \edef\m_font_step{\bodyfontvariable\m_font_keyword}% \normalexpanded{\font_helpers_set_font_set_font_option_body{#method}{\m_font_step}{#message}}% \else\ifx\m_font_keyword\v!reset \let\fontstyle\empty % new 31/7/2006 \let\fontsize \empty \else\ifcsname\??fontstyle\m_font_keyword\endcsname \let\fontstyle\m_font_keyword \else \setcurrentfontclass\m_font_keyword \ifcase#method\relax \let\globalfontclass\globalfontclass \else \let\globalfontclass\fontclass \fi \font_helpers_set_fontstyle_of_fontclass \fi\fi\fi} % \unexpanded\def\font_helpers_set_font_set_font_option_keyword#method#keyword#message% % {\edef\m_font_keyword{#keyword}% % \ifx\m_font_keyword\v!reset % \let\fontstyle\empty % new 31/7/2006 % \let\fontsize \empty % \else\ifcsname\??fontstyle\m_font_keyword\endcsname % \let\fontstyle\m_font_keyword % \else % \edef\m_font_step{\bodyfontvariable\m_font_keyword}% % \ifx\m_font_step\empty % \setcurrentfontclass\m_font_keyword % \ifcase#method\relax % \let\globalfontclass\globalfontclass % \else % \let\globalfontclass\fontclass % \fi % \font_helpers_set_fontstyle_of_fontclass % \else % \normalexpanded{\font_helpers_set_font_set_font_option_body{#method}{\m_font_step}{#message}}% we can have a simple one for this % \fi % \fi\fi} \def\font_helpers_set_fontstyle_of_fontclass % will be overloaded later {\let\fontstyle\s!rm} \unexpanded\def\font_helpers_set_font_set_font_option_body#method#body#message% {\edef\normalizedsetfont{\thenormalizedbodyfontsize{#body}}% redundant for some calls \ifcsname\??fontsize\normalizedsetfont\endcsname \else \font_helpers_define_unknown_font{#body}% \fi \ifcsname\??fontsize\normalizedsetfont\endcsname \localbodyfontsize\normalizedsetfont \let\normalizedbodyfontsize\normalizedsetfont \else \showmessage\m!fonts4{#message}% \font_helpers_set_font_set_font_option_body_fallbacks{#method}{#body}% \fi} %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\font_helpers_set_font_set_font_option_body_fallbacks#method#body% {\scratchdimen#body\relax \advance\scratchdimen .499\points \dimensiontocount\scratchdimen\scratchcounter \advance\scratchcounter \minusone \ifnum\scratchcounter>\plusthree %\font_helpers_set_font_set_font_option{#method}{\the\scratchcounter\s!pt}% \font_helpers_set_font_set_font_option_body{#method}{\the\scratchcounter\s!pt}\empty \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#class% {\letgvalue{\??fontclassyes#class}\v!yes} % global ? \def\setcurrentfontclass#class% {\ifcsname\??fontclassyes#class\endcsname \edef\fontclass{#class}% \else\ifcsname\??fontclassnop#class\endcsname % already tried \else % too messy: \ifcase\currentgrouplevel % (unpredictable) \trycurrentfontclass{#class}% \fi\fi} % \fi} % no prefix ? \installcorenamespace{fontclass} \unexpanded\def\savefontclassparameters#style#rscale#features#fallbacks#goodies#direction% {\setxvalue{\??fontclass\fontclass#style\s!rscale }{#rscale}% \setxvalue{\??fontclass\fontclass#style\s!features }{#features}% \setxvalue{\??fontclass\fontclass#style\s!fallbacks}{#fallbacks}% \setxvalue{\??fontclass\fontclass#style\s!goodies }{#goodies}% \setxvalue{\??fontclass\fontclass#style\s!direction}{#direction}} \settrue\autotypescripts \unexpanded\def\trycurrentfontclass#typeface% {\ifconditional\autotypescripts \usetypescript[#typeface]% \ifcsname\??fontclassyes#typeface\endcsname \edef\fontclass{#typeface}% \else \usetypescriptfile[\f!typeprefix#typeface]% \usetypescript[#typeface]% \ifcsname\??fontclassyes#typeface\endcsname \edef\fontclass{#typeface}% \else % todo: message \letvalueempty{\??fontclassnop#typeface}% \fi \fi \else % todo: message \letvalueempty{\??fontclassnop#typeface}% \fi} \let\defaultfontstyle \s!rm \let\defaultfontalternative\s!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 \setnewconstant\synchronizebigmathflag\plusone \appendtoks \ifcase\synchronizebigmathflag % never \or \synchronizebigmath \or % always \fi \to \everymathematics \unexpanded\def\nobigmath {\synchronizebigmathflag\zerocount} \unexpanded\def\autobigmath{\synchronizebigmathflag\plusone\synchronizebigmath} \unexpanded\def\bigmath {\synchronizebigmathflag\plustwo\synchronizebigmath} \let\bigmathfontsize\empty \unexpanded\def\synchronizebigmath {\ifx\bigmathfontsize\fontsize % already in sync \else \let\bigmathfontsize\fontsize \font_helpers_synchronize_math \fi} \unexpanded\def\font_helpers_check_big_math_synchronization {\ifcase\synchronizebigmathflag % never \or \ifmmode \synchronizebigmath \fi \or \synchronizebigmath \fi} %D So far for synchronisation. (We can inline the following macros.) \unexpanded\def\setcurrentfont#body#style#alternative#size% {\edef\fontbody {#body}% \edef\fontstyle {#style}% \edef\fontalternative{#alternative}% \edef\fontsize {#size}% \font_helpers_check_big_math_synchronization \font_helpers_synchronize_font} \unexpanded\def\setcurrentfontbody#body% {\edef\fontbody{#body}% \font_helpers_synchronize_font} % For Taco: optional fall backs: \ifdefined\font_typescripts_inherit_check \else \let\font_typescripts_inherit_check\gobbleoneargument % implemented in type-ini \fi \unexpanded\def\font_helpers_set_current_font_style#style% {\edef\fontstyle{#style}% \font_typescripts_inherit_check\fontstyle \ifmmode\mr\fi % otherwise \rm not downward compatible ... not adapted yet \font_helpers_synchronize_font} \unexpanded\def\font_helpers_set_current_fontbody_alternative#body#alternative% {\edef\fontbody {#body}% \edef\fontalternative{#alternative}% \font_helpers_synchronize_font} \unexpanded\def\font_helpers_set_current_font_alternative#alternative% {\edef\fontalternative{#alternative}% \font_helpers_synchronize_font} \unexpanded\def\font_helpers_set_current_font_size#size% {\edef\fontsize{#size}% \font_helpers_check_big_math_synchronization \font_helpers_synchronize_font} \unexpanded\def\font_helpers_set_current_font_style_alternative#style#alternative% \rmsl {\edef\fontstyle {#style}% \edef\fontalternative{#alternative}% \font_helpers_synchronize_font} \unexpanded\def\font_helpers_set_current_font_style_size#style#size% \rma {\edef\fontstyle{#style}% \edef\fontsize {#size}% \font_helpers_check_big_math_synchronization \font_helpers_synchronize_font} \unexpanded\def\font_helpers_set_current_font_alternative_size#alternative#size% \sla {\edef\fontalternative{#alternative}% \edef\fontsize {#size}% \font_helpers_check_big_math_synchronization \font_helpers_synchronize_font} \unexpanded\def\font_helpers_set_current_font_style_alternative_size#style#alternative#size% \rmsla {\edef\fontstyle {#style}% \edef\fontalternative{#alternative}% \edef\fontsize {#size}% \font_helpers_check_big_math_synchronization \font_helpers_synchronize_font} \unexpanded\def\font_helpers_synchronize_font % we can have dups i.e. no need to let fontstrategy {\ifx\fontclass\empty \applyfontstrategies \else \applyfontclassstrategies \fi \setfalse\font_auto_font_size \ifskipfontcharacteristics \setfontcharacteristics \the\everyfontswitch \fi} \def\font_helpers_check_strategy_class_a % --- --- --- --- % pt tt bf a {\ifcsname\fontclass\fontbody \fontstyle \fontalternative \fontsize\endcsname \setfalse\font_auto_font_size \csname\fontclass\fontbody \fontstyle \fontalternative \fontsize\endcsname \else \expandafter\font_helpers_check_strategy_class_b \fi} \def\font_helpers_check_strategy_class_b % --- --- --- def % pt tt bf {\ifcsname\fontclass\fontbody \fontstyle \fontalternative \defaultfontsize\endcsname \settrue\font_auto_font_size \csname\fontclass\fontbody \fontstyle \fontalternative \defaultfontsize\endcsname \else \expandafter\font_helpers_check_strategy_class_c \fi} \def\font_helpers_check_strategy_class_c % --- --- def --- % pt tt tf a {\ifcsname\fontclass\fontbody \fontstyle \defaultfontalternative \fontsize\endcsname \settrue\font_auto_font_size \csname\fontclass\fontbody \fontstyle \defaultfontalternative \fontsize\endcsname \else \expandafter\font_helpers_check_strategy_class_d \fi} \def\font_helpers_check_strategy_class_d % --- --- def def % pt tt tf {\ifcsname\fontclass\fontbody \fontstyle \defaultfontalternative \defaultfontsize\endcsname \settrue\font_auto_font_size \csname\fontclass\fontbody \fontstyle \defaultfontalternative \defaultfontsize\endcsname \else \expandafter\font_helpers_check_strategy_class_e \fi} \def\font_helpers_check_strategy_class_e % --- def def def % pt rm tf {\ifcsname\fontclass\fontbody \defaultfontstyle \defaultfontalternative \defaultfontsize\endcsname \setfalse\font_auto_font_size \csname\fontclass\fontbody \defaultfontstyle \defaultfontalternative \defaultfontsize\endcsname \else \expandafter\font_helpers_check_strategy_class_f \fi} \def\font_helpers_check_strategy_class_f % def def def def % rm tf {\ifcsname\fontclass\defaultfontbody \defaultfontstyle \defaultfontalternative \defaultfontsize\endcsname \settrue\font_auto_font_size \csname\fontclass\defaultfontbody \defaultfontstyle \defaultfontalternative \defaultfontsize\endcsname \else \expandafter\font_helpers_check_strategy_a \fi} % no class \def\font_helpers_check_strategy_a % --- --- --- --- % pt tt bf a {\ifcsname\fontbody \fontstyle \fontalternative \fontsize\endcsname \setfalse\font_auto_font_size \csname\fontbody \fontstyle \fontalternative \fontsize\endcsname \else \expandafter\font_helpers_check_strategy_b \fi} \def\font_helpers_check_strategy_b % --- --- --- --- % pt tt bf a {\ifcsname\fontbody \fontstyle \fontalternative \defaultfontsize\endcsname \settrue\font_auto_font_size \csname\fontbody \fontstyle \fontalternative \defaultfontsize\endcsname \else \expandafter\font_helpers_check_strategy_c \fi} \def\font_helpers_check_strategy_c % --- --- --- --- % pt tt bf a {\ifcsname\fontbody \fontstyle \defaultfontalternative \fontsize\endcsname \settrue\font_auto_font_size \csname\fontbody \fontstyle \defaultfontalternative \fontsize\endcsname \else \expandafter\font_helpers_check_strategy_d \fi} \def\font_helpers_check_strategy_d % --- --- --- --- % pt tt bf a {\ifcsname\fontbody \fontstyle \defaultfontalternative \defaultfontsize\endcsname \settrue\font_auto_font_size \csname\fontbody \fontstyle \defaultfontalternative \defaultfontsize\endcsname \else \expandafter\font_helpers_check_strategy_e \fi} \def\font_helpers_check_strategy_e % --- --- --- --- % pt tt bf a {\ifcsname\fontbody \defaultfontstyle \defaultfontalternative \defaultfontsize\endcsname \setfalse\font_auto_font_size \csname\fontbody \defaultfontstyle \defaultfontalternative \defaultfontsize\endcsname \else \expandafter\font_helpers_check_strategy_f \fi} \def\font_helpers_check_strategy_f % --- --- --- --- % pt tt bf a {\ifcsname\defaultfontbody \defaultfontstyle \defaultfontalternative \defaultfontsize\endcsname \settrue\font_auto_font_size \csname\defaultfontbody \defaultfontstyle \defaultfontalternative \defaultfontsize\endcsname \fi} \let\applyfontstrategies \font_helpers_check_strategy_a \let\applyfontclassstrategies\font_helpers_check_strategy_class_a %D Let's synchronize: \newconditional\c_font_synchronize \settrue\c_font_synchronize \prependtoks \ifconditional\c_font_synchronize \font_helpers_synchronize_math \font_helpers_synchronize_font % problem: syncs last font \fi \to \everybodyfont %D Setting the normal sizes as well as the x and xx smaller %D sizes is accomplished by the next set of macros. When in %D math mode, the commands \type{\tx} and \type{\txx} are %D just a switch to the script and double script styles, but %D in text mode the values defined by the bodyfontenvironment are %D used. Here we also set \type{\currentxfontsize}. \def\font_helpers_set_current_font_xxx_alternative#alternative#size#xsize#scriptstyle% {\currentxfontsize#size\relax \ifmmode #scriptstyle% \else\ifcsname\??fontsteps\fontclass\fontbody#xsize\endcsname \expandafter\font_helpers_set_current_fontbody_alternative\csname\??fontsteps\fontclass\fontbody#xsize\endcsname{#alternative}% \else % some error: check is not done correctly \fi\fi} \def\font_helpers_set_current_font_x_alternative#alternative% {\font_helpers_set_current_font_xxx_alternative{#alternative}1\s!x\scriptstyle \let\tx\txx} \def\font_helpers_set_current_font_xx_alternative#alternative% {\font_helpers_set_current_font_xxx_alternative{#alternative}2\s!xx\scriptscriptstyle \let\tx\empty \let\txx\empty} \def\font_helpers_check_nested_x_fontsize % option {\ifcase\currentxfontsize\else\ifx\fontsize\empty\else \currentxfontsize\zerocount \let\fontsize\empty \let\tx\normaltx \let\txx\normaltxx \fi\fi} \def\font_helpers_set_current_font_x_alternative#alternative% {\font_helpers_check_nested_x_fontsize \font_helpers_set_current_font_xxx_alternative{#alternative}1\s!x\scriptstyle \let\tx\txx} \def\font_helpers_set_current_font_xx_alternative#alternative% {\font_helpers_check_nested_x_fontsize \font_helpers_set_current_font_xxx_alternative{#alternative}2\s!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\font_helpers_set_current_font_x_style_alternative #alternative{\csname#alternative\endcsname\tx} \def\font_helpers_set_current_font_xx_style_alternative#alternative{\csname#alternative\endcsname\txx} %D These macros also show us that when we call for \type{\tx}, %D this macro is redefined to be \type{\txx}. Therefore calls %D like: %D %D \startbuffer %D {small \tx is \tx beautiful} %D {small \tx is \txx beautiful} %D {small \txx is \tx beautiful} %D {small \txx is \txx beautiful} %D \stopbuffer %D %D \typebuffer %D %D result in: %D %D \startlines %D \getbuffer %D \stoplines %D %D Setting the main size involves the style list and therefore %D takes a bit more time. Keep in mind that the fontsize is %D represented by a character or empty. \unexpanded\def\tx {\font_helpers_set_current_font_x_alternative \fontalternative} \unexpanded\def\txx{\font_helpers_set_current_font_xx_alternative\fontalternative} \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 \unexpanded\def\definefontstyle {\dodoubleargument\font_basics_define_fontstyle} \def\font_basics_define_fontstyle[#commands][#style]% {\rawdoifinsetelse{#style}{\fontstylelist}{}{\addtocommalist{#style}\fontstylelist}% \processcommalist[#commands]{\font_basics_define_fontstyle_indeed{#style}}} \def\font_basics_define_fontstyle_indeed#style#command% {\setvalue{\??fontshortstyle#command}{#style}% \setvalue{\??fontstyle #command}{\csname#style\endcsname}} %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} \unexpanded\def\font_basics_complete_switch[#size]% {\bodyfontsize#size\relax \dimensiontocount\bodyfontsize\bodyfontpoints % rounded, still used in m-chart \edef\bodyfontfactor{\withoutpt\the\bodyfontsize}% \edef\normalizedbodyfontsize{\thenormalizedbodyfontsize\bodyfontsize}% \edef\textface {\bodyfontvariable\s!text }% \edef\scriptface {\bodyfontvariable\s!script }% \edef\scriptscriptface{\bodyfontvariable\s!scriptscript}} % \font_basics_complete_switch[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[modern,12pt,roman] %D \stoptyping %D %D This command affects the document as a whole: text, headers %D and footers. The second macro however affects only the text: %D %D \starttyping %D \switchtobodyfont[10pt] %D \stoptyping %D %D So we've got: %D %D \showsetup{setupbodyfont} %D \showsetup{switchtobodyfont} %D %D Both macros look alike. The second one also has to take %D all kind of keywords into account. \ifx\saveinterlinespace \undefined \let\saveinterlinespace \relax \fi \ifx\restoreinterlinespace\undefined \let\restoreinterlinespace\relax \fi % \newtoks \everysetupbodyfont % \newtoks \everyswitchtobodyfont \unexpanded\def\setupbodyfont {\doifnextoptionalelse\font_basics_setupbodyfont_yes\font_basics_setupbodyfont_nop} \def\font_basics_setupbodyfont_nop {\restoreglobalbodyfont \saveinterlinespace} \def\font_basics_setupbodyfont_yes[#specification]% {\doifsomething{#specification} {\font_helpers_set_font\plusone{#specification}% \globalbodyfontsize\localbodyfontsize \edef\normalizedglobalbodyfontsize{\thenormalizedbodyfontsize\globalbodyfontsize}% \let\globalfontstyle\fontstyle \ifproductionrun \the\everybodyfont \the\everyglobalbodyfont \saveinterlinespace \fi \the\everysetupbodyfont}} % \unexpanded\def\switchtobodyfont[#specification]% % {\doifsomething{#specification} % {\ifcsname\??fonts\normalizedbodyfontsize#specification\endcsname % \font_helpers_set_bodyfont_step{#specification}% so we have a fast [small] switch % \else % \font_helpers_set_font\zerocount{#specification}% % \fi % \the\everybodyfont % \the\everyswitchtobodyfont}} \unexpanded\def\switchtobodyfont[#specification]% {\doifsomething{#specification} {\edef\m_font_step{\bodyfontvariable{#specification}}% \ifx\m_font_step\empty \font_helpers_set_font\zerocount{#specification}% \else \font_helpers_switch_bodyfont_step % so we have a fast [small] switch \fi \the\everybodyfont \the\everyswitchtobodyfont}} \def\font_helpers_switch_bodyfont_step {\font_basics_switch_points\m_font_step \font_basics_switch_style \fontstyle} %D The following alternative is meant for math||to||text %D switching and will be optimized. \unexpanded\def\fastswitchtobodyfont#name% {\ifcsname\??fonts\normalizedbodyfontsize#name\endcsname \edef\futurebodyfontsize{\csname\??fonts\normalizedbodyfontsize#name\endcsname}% \ifcsname\??fontsize\futurebodyfontsize\endcsname \csname\??fontsize\futurebodyfontsize\endcsname \localbodyfontsize\futurebodyfontsize\relax \fi \fi \csname\??fontstyle\fontstyle\endcsname \the\everybodyfont} %D \starttyping %D $\cases{& \ccaron}$ $x=\hbox{\ccaron $x=\hbox{\ccaron}$}$ %D \stoptyping \def\setfontcharacteristics {\the\everyfont} %D Handy for manuals: \unexpanded\def\fontchar#character% {\ctxcommand{fontchar("#character")}} %D Feature management. \unexpanded\def\definefontfeature {\dotripleargument\font_basics_define_font_feature} \def\font_basics_define_font_feature[#featureset][#parent][#settings]% {\ctxcommand{definefontfeature("#featureset","#parent","#settings")}} \unexpanded\def\fontfeatureslist {\dodoubleargument\font_basics_features_list} \def\font_basics_features_list[#name][#separator]% todo: arg voor type {\cldcommand{featurelist("#name","otf","\luaescapestring{#separator}","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 \unexpanded\def\featureattribute#feature{\ctxcommand{featureattribute("#feature")}} \unexpanded\def\setfontfeature #feature{\ctxcommand{setfontfeature("#feature")}\edef\currentfeature{#feature}} %unexpanded\def\resetfontfeature {\ctxcommand{resetfontfeature()}\let\currentfeature\empty} % initial value \unexpanded\def\resetfontfeature {\attribute\zerocount\zerocount \let\currentfeature\empty} % initial value \unexpanded\def\addfontfeaturetoset #feature{\ctxcommand{addfs("#feature")}} % merge \unexpanded\def\subtractfontfeaturefromset #feature{\ctxcommand{subfs("#feature")}} % merge \unexpanded\def\addfontfeaturetofont #feature{\ctxcommand{addff("#feature")}} % overload \unexpanded\def\subtractfontfeaturefromfont#feature{\ctxcommand{subff("#feature")}} % overload \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#font{\ctxlua{file.basename("\fontname#font"}} % will be function using id %D \macros %D {switchstyleonly} %D %D For switching a style but keeping the alternative, there %D is: %D %D \starttyping %D {\bf text \switchstyleonly\ss text} %D {\bf text \switchstyleonly[ss]text} %D {\sl text \switchstyleonly[sansserif]text} %D \stoptyping \unexpanded\def\switchstyleonly {\doifnextoptionalelse\font_basics_switch_style_only_opt\font_basics_switch_style_only_arg} \def\font_basics_switch_style_only_arg#name% stupid version {\font_helpers_set_current_font_style{\csname\??fontshortstyle\checkedstrippedcsname#name\endcsname}% \the\everybodyfont} % needed ? \def\font_basics_switch_style_only_opt[#name]% todo : check {\font_helpers_set_current_font_style{\csname\??fontshortstyle#name\endcsname}% \the\everybodyfont} % needed ? %D \macros %D {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] %unexpanded\def\sc{\setfontfeature{smallcaps}} \unexpanded\def\os{\setfontfeature{just-os}} %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. \unexpanded\def\definebodyfontswitch {\dodoubleargument\font_basics_define_bodyfont_switch} \def\font_basics_define_bodyfont_switch[#command][#specification]% no longer a commalist (not useful) {\setvalue{#command}{\switchtobodyfont[#specification]}}% %D \macros %D {setsmallbodyfont,setmainbodyfont,setbigbodyfont} %D %D When we're typesetting at for instance 10pt, we can call for %D the \type{small} as well as the \type{big} alternative, %D related to this main size, using \type{\switchtobodyfont[small]}. %D The three alternatives can be activated by the next three %D system calls and are defined by the bodyfontenvironment. \let\m_font_step\empty \def\font_helpers_set_bodyfont_step#step% {\edef\m_font_step{\bodyfontvariable{#step}}% not always \cs \font_basics_switch_points\m_font_step \font_basics_switch_style \fontstyle} \unexpanded\def\setsmallbodyfont{\font_helpers_set_bodyfont_step\v!small\the\everybodyfont} \unexpanded\def\setbigbodyfont {\font_helpers_set_bodyfont_step\v!big \the\everybodyfont} \unexpanded\def\setmainbodyfont {\font_basics_switch_points\normalizedbodyfontsize \font_basics_switch_style\fontstyle \the\everybodyfont \the\everyglobalbodyfont \saveinterlinespace} %D \macros %D {restoreglobalbodyfont} %D %D Users can set whatever font available while typesetting text. %D Pagenumbers, footers, headers etc. however must be typeset %D in the main bodyfont and style of the document. Returning to %D the global state can be done with the next macro: \let\globalfontstyle\s!rm \def\fullrestoreglobalbodyfont {\let\fontsize\defaultfontsize \let\fontbody\defaultfontbody \currentxfontsize\zerocount \let\fontclass\globalfontclass \font_basics_switch_points\normalizedglobalbodyfontsize \font_basics_switch_style\globalfontstyle \redoconvertfont % just in case a pagebreak occurs \tf \the\everybodyfont \the\everyglobalbodyfont \saveinterlinespace} \def\partialrestoreglobalbodyfont {\let\fontsize\defaultfontsize \let\fontbody\defaultfontbody \currentxfontsize\zerocount \redoconvertfont \tf \the\everybodyfont % indeed needed \the\everyglobalbodyfont % indeed needed \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 {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. \installcorenamespace{alternativestyles} \setnewconstant \c_font_current_alternative_style_index \plusone \unexpanded\def\definealternativestyle {\dotripleempty\font_basics_define_alternative_style} \def\font_basics_define_alternative_style[#commands][#variantone][#varianttwo]% {\processcommalist[#commands]{\font_basics_define_alternative_style_indeed{#variantone}{#varianttwo}}} \let\definestyle\definealternativestyle % later redefined \def\font_basics_define_alternative_style_indeed#variantone#varianttwo#command% {\ifcsname#command\endcsname % no redefinition \else \setuvalue{#command}{\groupedcommand{#variantone}{}}% \fi \setvalue{\??alternativestyles#command}{\font_helpers_apply_alternative_style{#variantone}{#varianttwo}}}% \def\font_helpers_apply_alternative_style {\ifcase\c_font_current_alternative_style_index \expandafter\gobbletwoarguments \or \expandafter\firstoftwoarguments \or \expandafter\secondoftwoarguments \else \expandafter\firstoftwoarguments \fi} \def\applyalternativestyle#name% public {\ifcsname\??alternativestyles#name\endcsname\csname\??alternativestyles#name\expandafter\endcsname\fi} %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 \startexample %D \definealternativestyle[bold][\bf][]\getbuffer %D \stopexample %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}. %D These commands are not grouped! Grouping is most probably %D done by the calling macro's and would lead to unnecessary %D overhead. \let\m_current_convert_font \empty \let\m_current_convert_font_dt\empty \unexpanded\def\doconvertfont#specification% takes second argument / this command is obsolete {\edef\m_current_convert_font{#specification}% \ifx\m_current_convert_font\empty %\expandafter\firstofoneargument \else \expandafter\font_helpers_do_convert_font \fi} \def\font_helpers_do_convert_font {\edef\m_current_convert_font_dt{\detokenize\expandafter{\m_current_convert_font}}% \ifcsname\??alternativestyles\m_current_convert_font_dt\endcsname \csname\??alternativestyles\m_current_convert_font_dt\expandafter\endcsname \else\ifcsname\m_current_convert_font_dt\endcsname \csname\m_current_convert_font_dt\expandafter\endcsname \else \doubleexpandafter\m_current_convert_font \fi\fi} %D Low level switches (downward compatible): \unexpanded\def\dontconvertfont{\c_font_current_alternative_style_index\plustwo} % needs checking in usage \unexpanded\def\redoconvertfont{\c_font_current_alternative_style_index\plusone} % needs checking in usage %D The new one: \unexpanded\def\dousestyleparameter#value% {\edef\currentstyleparameter{#value}% \ifx\currentstyleparameter\empty\else \expandafter\dousecurrentstyleparameter \fi} \unexpanded\def\dousestylehashparameter#hash#parameter% {\ifcsname#hash#parameter\endcsname \expandafter\dousestyleparameter\csname#hash#parameter\endcsname \fi} \unexpanded\def\dousecurrentstyleparameter % empty check outside here {\edef\detokenizedstyleparameter{\detokenize\expandafter{\currentstyleparameter}}% \settrue\fontattributeisset % reset is done elsewhere \ifcsname\??alternativestyles\detokenizedstyleparameter\endcsname \csname\??alternativestyles\detokenizedstyleparameter\endcsname \else\ifcsname\detokenizedstyleparameter\endcsname \csname\detokenizedstyleparameter\endcsname \else \currentstyleparameter \fi\fi} \let\dosetfontattribute\dousestylehashparameter % for a while %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: \unexpanded\def\setfont% geen \font_helpers_set_font mogelijk {\afterassignment\font_basics_set_font\font\nextfont=} \def\font_basics_set_font {\nextfont\setupinterlinespace}% hm, we need to use \setuplocalinterlinespace %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} %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} \fetchruntimecommand \testminimalbaseline {\f!fontprefix\s!run} \fetchruntimecommand \showminimalbaseline {\f!fontprefix\s!run} %D \macros %D {showkerning} %D %D A goody is: %D %D \showkerning{Can you guess what kerning is?} \fetchruntimecommand \showkerning {\f!fontprefix\s!run} %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} %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} \fetchruntimecommand \showfontstyle {\f!fontprefix\s!run} \fetchruntimecommand \showligature {\f!fontprefix\s!run} \fetchruntimecommand \showligatures {\f!fontprefix\s!run} \fetchruntimecommand \showcharratio {\f!fontprefix\s!run} %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\v_font_string_a {\ifx\fontstyle\s!rm \s!Serif \else \ifx\fontstyle\s!ss \s!Sans \else \ifx\fontstyle\s!tt \s!Mono \else \s!Serif \fi\fi\fi} \def\v_font_string_b {\ifx\fontstyle\s!rm \s!Regular \else \ifx\fontstyle\s!ss \s!Support \else \ifx\fontstyle\s!tt \s!Type \else \s!Serif \fi\fi\fi} \def\v_font_string_c {\ifx\fontalternative\s!bf \s!Bold \else \ifx\fontalternative\s!sl \s!Slanted \else \ifx\fontalternative\s!it \s!Italic \else \ifx\fontalternative\s!bs \s!BoldSlanted \else \ifx\fontalternative\s!bi \s!BoldItalic \fi\fi\fi\fi\fi} \let\v_font_string_d\s!Serif % default fontstyle (will be redefined in type-ini) % potential generalization: % % \letvalue{\??fontfile:t:\s!rm}\s!Serif % \letvalue{\??fontfile:t:\s!ss}\s!Sans % \letvalue{\??fontfile:t:\s!tt}\s!Mono % % \letvalue{\??fontfile:a:\s!rm}\s!Regular % \letvalue{\??fontfile:a:\s!ss}\s!Support % \letvalue{\??fontfile:a:\s!tt}\s!Type % % \letvalue{\??fontfile:s:\s!bf}\s!Bold % \letvalue{\??fontfile:s:\s!sl}\s!Slanted % \letvalue{\??fontfile:s:\s!it}\s!Italic % \letvalue{\??fontfile:s:\s!bs}\s!BoldSlanted % \letvalue{\??fontfile:s:\s!bi}\s!BoldItalic % % \def\v_font_string_a{\executeifdefined{\??fontfile:t:\fontstyle}\s!Serif} % \def\v_font_string_a{\executeifdefined{\??fontfile:t:\fontstyle}\s!Serif} % \def\v_font_string_b{\executeifdefined{\??fontfile:a:\fontstyle}\s!Serif} % \def\v_font_string_c{\executeifdefined{\??fontfile:s:\fontstyle}\empty} % \def\v_font_string_d{\executeifdefined{\??fontfile:t:\csname\??typescriptdefaultstyles\fontclass\endcsname}\s!Serif} %D \macros %D {fontstylesuffix} %D %D The next macro is used to map non latin fontnames on fonts. See \type %D {font-uni} for an example of its use. \def\fontstylesuffix% why the \s!Regular ? see \getglyph {\ifx\fontalternative\s!tf \s!Regular \else \ifx\fontalternative\s!bf \s!Bold \else \ifx\fontalternative\s!sl \s!Slanted \else \ifx\fontalternative\s!it \s!Italic \else \ifx\fontalternative\s!bs \s!BoldSlanted \else \ifx\fontalternative\s!bi \s!BoldItalic \else \ifx\fontalternative\s!sc \s!Caps \else \s!Regular \fi\fi\fi\fi\fi\fi\fi}% \def\glyphfontfile#base% appends {#base% \ifcsname\??fontfile#base\v_font_string_a\v_font_string_c\endcsname \v_font_string_a\v_font_string_c \else\ifcsname\??fontfile#base\v_font_string_b\v_font_string_c\endcsname \v_font_string_b\v_font_string_c \else\ifcsname\??fontfile#base\v_font_string_a\endcsname \v_font_string_a \else\ifcsname\??fontfile#base\v_font_string_b\endcsname \v_font_string_b \else\ifcsname\??fontfile#base\v_font_string_c\endcsname \v_font_string_c \fi\fi\fi\fi\fi} %D The next macro can be used to make decisions based on the shape: \def\doifitalicelse#yes#nop% {\ifx\fontalternative\s!sl#yes\else \ifx\fontalternative\s!it#yes\else \ifx\fontalternative\s!bs#yes\else \ifx\fontalternative\s!bi#yes\else#nop\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#specification{\definedfont[\glyphfontfile{#specification} sa *]} %D \stoptyping %D %D Since we know what scaling it to be applied, we can %D implement a much faster alternative: \installcorenamespace {symbolfont} \let\thedefinedfont\relax \def\setscaledstyledsymbolicfont#1#2#3% quite a slowdown, glyphfontfile {\edef\askedsymbolfont{\truefontname{\glyphfontfile{#3}} at \the\dimexpr#2\dimexpr\currentfontbodyscale\dimexpr#1}% \ifcsname\??symbolfont\askedsymbolfont\endcsname \csname\??symbolfont\askedsymbolfont\endcsname \else \font_basics_define_symbolic_font \fi} \def\setscaleddirectsymbolicfont#1#2#3% quite a slowdown, glyphfontfile {\edef\askedsymbolfont{\truefontname{#3} at \the\dimexpr#2\dimexpr\currentfontbodyscale\dimexpr#1}% \ifcsname\??symbolfont\askedsymbolfont\endcsname \csname\??symbolfont\askedsymbolfont\endcsname \else \font_basics_define_symbolic_font \fi} \def\setstyledsymbolicfont#fontname% quite a slowdown, glyphfontfile {\edef\askedsymbolfont{\truefontname{\glyphfontfile{#fontname}} at \the\dimexpr\currentfontbodyscale\dimexpr\fontbody}% \ifcsname\??symbolfont\askedsymbolfont\endcsname \csname\??symbolfont\askedsymbolfont\endcsname \else \font_basics_define_symbolic_font \fi} \def\setdirectsymbolicfont#fontname% {\edef\askedsymbolfont{\truefontname{#fontname} at \the\dimexpr\currentfontbodyscale\dimexpr\fontbody}% \ifcsname\??symbolfont\askedsymbolfont\endcsname \csname\??symbolfont\askedsymbolfont\endcsname \else \font_basics_define_symbolic_font \fi} \def\font_basics_define_symbolic_font {\definefont[currentsymbolfont][\askedsymbolfont]% \currentsymbolfont \global\expandafter\let\csname\??symbolfont\askedsymbolfont\endcsname\lastrawfontcall} \unexpanded\def\getnamedglyphstyled#fontname#character{{\setstyledsymbolicfont{#fontname}\ctxcommand{fontchar("#character")}}} \unexpanded\def\getnamedglyphdirect#fontname#character{{\setdirectsymbolicfont{#fontname}\ctxcommand{fontchar("#character")}}} \unexpanded\def\getglyphstyled #fontname#character{{\setstyledsymbolicfont{#fontname}\doifnumberelse{#character}\char\donothing#2}} \unexpanded\def\getglyphdirect #fontname#character{{\setdirectsymbolicfont{#fontname}\doifnumberelse{#character}\char\donothing#2}} % this one is wrong: \unexpanded\def\getscaledglyph#scale#name#content% {{\setscaledstyledsymbolicfont\fontbody{#scale}{#name}\doifnumberelse{#content}\char\donothing#content}} \let\getglyph \getglyphstyled % old \let\getrawglyph \getglyphdirect % old \let\symbolicsizedfont\setscaledstyledsymbolicfont % old \let\symbolicfont \setstyledsymbolicfont % old \unexpanded\def\symbolicscaledfont{\setsscaledstyledsymbolicfont\fontbody} \unexpanded\def\symbolicscaledfont{\setscaledstyledsymbolicfont\fontbody} %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 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 % this needs some interfacing % % \setupfonts[check=...] \unexpanded\def\checkcharactersinfont {\ctxcommand{checkcharactersinfont }} \unexpanded\def\removemissingcharacters{\ctxcommand{removemissingcharacters}} %D New commands (not yet interfaced): %D %D \startbuffer %D \definestyle[one][style=bold,color=darkblue] %D %D test \one{test} test %D test \style[one]{test} test %D test \style[color=red]{test} test %D test \style[Serif at 20pt]{test} test %D \stopbuffer %D %D \typebuffer \startlines \getbuffer \stoplines % definitions .. no tagging here \installcorenamespace{style} \installcorenamespace{stylecheck} \installcommandhandler \??style {style} \??style \appendtoks \letvalue{\??stylecheck\currentstyle}\relax \setuevalue{\e!start\currentstyle}{\font_styles_apply_start{\currentstyle}}% \setuevalue{\e!stop \currentstyle}{\font_styles_apply_stop}% \setuevalue {\currentstyle}{\font_styles_apply_grouped{\currentstyle}}% no longer groupedcommand here \to \everydefinestyle \unexpanded\def\font_styles_apply_start#name% {\begingroup \font_styles_use_defined{#name}} \unexpanded\def\font_styles_apply_stop {\endgroup} \unexpanded\def\font_styles_apply_grouped#name% assumes that the next is { or \bgroup {\bgroup \def\g_style{\font_styles_use_defined{#name}}% \afterassignment\g_style \let\nexttoken} \unexpanded\def\font_styles_use_defined#name% {\edef\currentstyle{#name}% \usestylestyleandcolor\c!style\c!color} \unexpanded\def\font_styles_use_generic#specification% {\let\currentstyle\s!unknown % reasonable generic tag \setupcurrentstyle[\c!style=,\c!color=,#specification]% \usestylestyleandcolor\c!style\c!color} % commands \installcorenamespace{styleargument} \unexpanded\def\style[#name]% as this is can be a switch we use groupedcommand {\csname\??styleargument \ifcsname#name\endcsname1\else\ifcsname\??stylecheck#name\endcsname2\else3\fi\fi \endcsname{#name}} \setvalue{\??styleargument1}#name% {\csname#name\endcsname} \setvalue{\??styleargument2}#name% {\groupedcommand{\font_styles_use_defined{#name}}{}} \setvalue{\??styleargument3}#specification% {\doifassignmentelse{#specification}\font_styles_assignment\font_styles_direct{#specification}} \def\font_styles_assignment#specification{\groupedcommand{\font_styles_use_generic{#specification}}{}} \def\font_styles_direct #specification{\groupedcommand{\definedfont[#specification]}{}} % environments \installcorenamespace{styleenvironment} \unexpanded\def\startstyle[#name]% {\begingroup \csname\??styleenvironment \ifcsname#name\endcsname1\else\ifcsname\??stylecheck#name\endcsname2\else3\fi\fi \endcsname{#name}} \unexpanded\def\stopstyle {\endgroup \autoinsertnextspace} % will be configurable, maybe also in \definestartstop \setvalue{\??styleenvironment1}#name% {\csname#name\endcsname} \setvalue{\??styleenvironment2}#name% {\font_styles_use_defined{#name}} \setvalue{\??styleenvironment3}#specification% {\doifassignmentelse{#specification}\font_styles_start_assignment\font_styles_start_direct{#specification}} \def\font_styles_start_assignment#specification{\usegenericstyle{#specification}} \def\font_styles_start_direct #specification{\definedfont[#specification]\relax} %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}} \installcorenamespace{stylecollection} \unexpanded\def\definestylecollection {\dosingleargument\font_styles_define_style_collection} \def\font_styles_define_style_collection[#name]% {\iffirstargument \setuvalue{#name}{\styleinstance[#name]}% \def\font_styles_define_style_collection_a#style% {\def\font_styles_define_style_collection_b#alternative{\letbeundefined{\??stylecollection#name:#style:#alternative}}% \processcommacommand[\fontalternativelist,\s!default]\font_styles_define_style_collection_b}% \processcommacommand[\fontstylelist,\s!default]\font_styles_define_style_collection_a \fi} \unexpanded\def\definestyleinstance {\doquadrupleargument\font_styles_define_style_instance} \def\font_styles_define_style_instance[#instance][#2][#3][#4]% [name] [rm|ss|tt|..] [sl|bf|...] [whatever] {\iffirstargument \ifcsname#1\endcsname\else\font_styles_define_style_collection[#instance]\fi \fi \iffourthargument \setvalue{\??stylecollection#instance:#2:#3}{#4}% \else\ifthirdargument \setvalue{\??stylecollection#instance::#2}{#3}% \else\ifsecondargument \letvalueempty{\??stylecollection#instance::#2}% \fi\fi\fi} \unexpanded\def\styleinstance[#instance]% will be made faster {%\begingroup\normalexpanded{\noexpand\infofont[#1:\fontstyle:\fontalternative]}\endgroup \executeifdefined{\??stylecollection#instance:\fontstyle:\fontalternative}% {\executeifdefined{\??stylecollection#instance:\fontstyle:\s!default}% {\executeifdefined{\??stylecollection#instance::\fontalternative} {\getvalue {\??stylecollection#instance::\s!default}}}}} % \unexpanded\def\styleinstance[#instance]% % {\csname\??stylecollection#instance% % \ifcsname\??stylecollection#instance:\fontstyle:\fontalternative\endcsname % :\fontstyle:\fontalternative % \else\ifcsname\??stylecollection#instance:\fontstyle:\s!default\endcsname % :\fontstyle:\s!default % \else\ifcsname\??stylecollection#instance::\fontalternative\endcsname % ::\fontalternative % \else % \ifcsname\??stylecollection#instance::\s!default\endcsname % ::\s!default % % \else % % % nothing, \relax % \fi\fi\fi % \fi % \endcsname} %D goodies: \unexpanded\def\showchardata#character{\ctxcommand{showchardata("#character")}} \unexpanded\def\showfontdata {\ctxcommand{showfontparameters()}} %D some low level helpers %D %D \starttyping %D \def\TestLookup#specification% %D {\dolookupfontbyspec{#specification} %D pattern: #specification, found: \dolookupnoffound %D \blank %D \dorecurse {\dolookupnoffound} {% %D \recurselevel:~\dolookupgetkeyofindex{fontname}{\recurselevel}\quad %D }% %D \blank} %D %D \TestLookup{familyname=helveticaneue} %D \TestLookup{familyname=helveticaneue,weight=bold} %D \TestLookup{familyname=helveticaneue,weight=bold,style=italic} %D \stoptyping % we can also move the lookups to the fonts.namespace (of commands) % these will be renamed but it needs synchronization with WS \def\dolookupfontbyspec #1{\ctxcommand{fontlookupinitialize("#1")}} \def\dolookupnoffound {\ctxcommand{fontlookupnoffound()}} \def\dolookupgetkeyofindex#1#2{\ctxcommand{fontlookupgetkeyofindex("#1",#2)}} \def\dolookupgetkey #1{\ctxcommand{fontlookupgetkey("#1")}} \def\cleanfontname #1{\ctxcommand{cleanfontname("#1")}} % \doifelsecurrentfonthasfeature{smcp}{YES}{NO} % \doifelsecurrentfonthasfeature{crap}{YES}{NO} % \doifelsecurrentfonthasfeature{kern}{YES}{NO} \def\doifelsecurrentfonthasfeature#feature% {\ctxcommand{doifelsecurrentfonthasfeature("#feature")}} %D variant selectors %D %D \starttyping %D \mathematics {\vsone{\utfchar{"2229}}} %D \mathematics {\utfchar{"2229}\vsone{}} %D \stoptyping \unexpanded\edef\vsone#character{#character\utfchar{"FE00}} % used \unexpanded\edef\vstwo#character{#character\utfchar{"FE01}} % not used but handy for testing % new: \unexpanded\def\setfontofid#1{\ctxcommand{setfontofid(#1)}} %D Watch the \type {\normal} hackery: this makes the mkvi parser happy. \normaldef\fntsetdefname {\global\let\somefontname\defaultfontfile} \normaldef\fntsetsomename{\normalgdef\somefontname} % takes argument \normaldef\fntsetnopsize {\let\somefontsize\empty} \normaldef\fntsetsomesize{\normaldef\somefontsize} % takes argument \protect \endinput