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