%D \module %D [ file=font-ini, %D version=1998.09.11, % (second) %D version=2001.02.20, % (third) %D title=\CONTEXT\ Font Macros, %D subtitle=Initialization, %D author=Hans Hagen, %D date=\currentdate, %D copyright={PRAGMA / Hans Hagen \& Ton Otten}] %C %C This module is part of the \CONTEXT\ macro||package and is %C therefore copyrighted by \PRAGMA. See mreadme.pdf for %C details. % runtime commands will move to modules % simplification ... we no longer deal with specific mmtfa specifications % todo: always fontclass, then less testing % \definefontfeature[smallcaps][smcp=yes,script=latn] % \definefontfeature[smallcaps][SmallCapitals=yes,script=latn] % \definefontfeature[smallcaps][Small Capitals=yes,script=latn] % \definefontfeature[smallcaps][small capitals=yes,script=latn] % \definefontfeature[smallcaps][smallcapitals=yes,script=latn] % % \definedfont[cambria*smallcaps] test % \starttext % \definefontfeature[basekerned][default][mode=base] % \definefontfeature[nodekerned][default][mode=node] % \definefontfeature[nonekerned][default][mode=base,kern=no] % \setupcolors[state=start] % \startoverlay % {\vbox{\red \definedfont[Serif*nonekerned at 12pt]\input tufte }} % {\vbox{\blue \definedfont[Serif*basekerned at 12pt]\input tufte }} % {\vbox{\green\definedfont[Serif*nodekerned at 12pt]\input tufte }} % \stopoverlay % \stoptext % \enabletrackers[otf.kerns] % % \definefontfeature[withkern][default][mode=node] % \definefontfeature[nokern] [default][mode=node,kern=no] % \definefontfeature[single] [default][mode=node,cpsp=yes] % \definefontfeature[simple] [default][mode=node,cpsp=yes,kern=no] % % {\definedfont[Serif*default] [FGFGFGFGFGFGFGFGFGFGFGFGFG ABCDEFGHIJKLMNOPQRSTUVWXYZ] \par} % {\definedfont[Serif*nokern] [FGFGFGFGFGFGFGFGFGFGFGFGFG ABCDEFGHIJKLMNOPQRSTUVWXYZ] \par} % {\definedfont[Serif*single] [FGFGFGFGFGFGFGFGFGFGFGFGFG ABCDEFGHIJKLMNOPQRSTUVWXYZ] \par} % {\definedfont[Serif*simple] [FGFGFGFGFGFGFGFGFGFGFGFGFG ABCDEFGHIJKLMNOPQRSTUVWXYZ] \par} % figure out why \fontbody is not expanded \writestatus{loading}{ConTeXt Font Macros / Initialization} \registerctxluafile{font-ini}{1.001} \registerctxluafile{node-fnt}{1.001} % here \registerctxluafile{font-enc}{1.001} \registerctxluafile{font-map}{1.001} \registerctxluafile{font-syn}{1.001} \registerctxluafile{font-log}{1.001} \registerctxluafile{font-tfm}{1.001} \registerctxluafile{font-enh}{1.001} \registerctxluafile{font-afm}{1.001} \registerctxluafile{font-cid}{1.001} % cid maps \registerctxluafile{font-ott}{1.001} % otf tables \registerctxluafile{font-otf}{1.001} % otf main \registerctxluafile{font-otd}{1.001} % otf dynamics \registerctxluafile{font-oti}{1.001} % otf initialization \registerctxluafile{font-otb}{1.001} % otf main base \registerctxluafile{font-otn}{1.001} % otf main node \registerctxluafile{font-ota}{1.001} % otf analyzers \registerctxluafile{font-otp}{1.001} % otf pack \registerctxluafile{font-otc}{1.001} % otf context \registerctxluafile{font-vf} {1.001} \registerctxluafile{font-def}{1.001} \registerctxluafile{font-ctx}{1.001} \registerctxluafile{font-xtx}{1.001} \registerctxluafile{font-fbk}{1.001} \registerctxluafile{font-gds}{1.001} \registerctxluafile{font-ext}{1.001} \registerctxluafile{font-pat}{1.001} \registerctxluafile{font-chk}{1.001} \registerctxluafile{font-agl}{1.001} \unprotect % \def\fontrange#1% % {\dofontrange{#1 =\bodyfontsize}} % % \def\dofontrange#1% % {\dodofontrange#1 \relax}% \fontstringA % % \def\dodofontrange#1 #2 % % {\ifdim\bodyfontsize#2% % #1\expandafter\gobbleuntilrelax % \else % \expandafter\dodofontrange % \fi} % % \definefont % [crap] % [\fontrange % {Regular <10pt % RegularBold <12pt % RegularSlanted <15pt % Regular} sa 1] % % may be better: % % \definefontrange % [crap] % [Regular <10pt % RegularBold <12pt % RegularSlanted <15pt] % [Regular sa 1] % % % \dostepwiserecurse{2}{15}{1} % {{\switchtobodyfont[\recurselevel pt]\crap test}\endgraf} % adapted, else wrong interlinespace \def\setfontparameters {\synchronizefontsfalse \the\everybodyfont \synchronizefontstrue} % handy \newcounter\pushedfont \def\savefont {\edef\savedfont{\the\font}% \pushmacro\savedfont} \def\restorefont {\popmacro\savedfont \savedfont} \def\pushcurrentfont {\edef\popcurrentfont {\noexpand\def\noexpand\fontbody{\fontbody}% \noexpand\def\noexpand\fontstyle{\fontstyle}% \noexpand\dosetcurrentfontalternative{\fontalternative}% \noexpand\dosetcurrentfontsize{\fontsize}% \noexpand\synchronizefont}} % \definetypeface[one][rm][serif][computer-roman][default] % \definetypeface[two][rm][serif][computer-roman][default][rscale=.9] % % {\one \bf test \two test} % {\one \bf test \pushcurrentfont \two \popcurrentfont test} %D \macros %D {definedfont,startfont,doiffontcharelse} %D %D A couple of relatively new macros: % \newtoks \everydefinedfont % not ot be confused with \everydefinefont \def\dodefinedfont[#1]% {\iffirstargument\definefont[thedefinedfont][#1]\fi % we can speed this one up \csname thedefinedfont\endcsname \the\everydefinedfont} \unexpanded\def\definedfont {\dosingleempty\dodefinedfont} \unexpanded\def\startfont {\bgroup\definedfont} \unexpanded\def\stopfont {\egroup} \def\doiffontcharelse#1#2% {\bgroup \definedfont[#1]% \iffontchar\font#2\relax \egroup\expandafter\firstoftwoarguments \else \egroup\expandafter\secondoftwoarguments \fi} %D For more detailed (and historic information) we refer to the file %D \type {font-ini.mkii}. Here we have a much simplified lower level %D implementation due to a different approach to math. Also the chapter %D on fonts in the reference manual explains a lot. %D \macros %D {rm,ss,tt,hw,cg} %D %D Fonts are defined in separate files. When we define a font, %D we distinguish between several styles. In most cases we will %D use: %D %D \startlinecorrection %D \starttable[|l||] %D \HL %D \NC roman regular serif \NC \type{\rm} \NC\FR %D \NC sansserif sans support \NC \type{\ss} \NC\MR %D \NC type teletype mono \NC \type{\tt} \NC\LR %D \HL %D \stoptable %D \stoplinecorrection %D %D The number of styles is not limited to these three. When %D using Lucida Bright we can for instance also define: %D %D \startlinecorrection %D \starttable[|l||] %D \HL %D \NC handwritten \NC \type{\hw} \NC\FR %D \NC calligraphic \NC \type{\cg} \NC\LR %D \HL %D \stoptable %D \stoplinecorrection %D %D Within such a font set (\type{cmr}) and style (\type{\rm}) %D we can define a number of text font alternatives: %D %D \startlinecorrection %D \starttable[|l||] %D \HL %D \NC typeface \NC \type{\tf} \NC\FR %D \NC boldface \NC \type{\bf} \NC\MR %D \NC slanted \NC \type{\sl} \NC\MR %D \NC italic \NC \type{\it} \NC\MR %D \NC boldslanted \NC \type{\bs} \NC\MR %D \NC bolditalic \NC \type{\bi} \NC\MR %D \NC smallcaps \NC \type{\sc} \NC\LR %D \HL %D \stoptable %D \stoplinecorrection %D %D Internally fonts are stored as combination of size, style %D and alternative, e.g. \type{12pt}+\type{\ss}+\type{\bf}. %D Users are not confronted with sizes, but use the style or %D style+alternative to activate them. %D %D During the definition of a bodyfont one can also declare the %D available larger alternatives: %D %D \starttyping %D \tf \tfa \tfb \tfc ... %D \bf \bfa \bfb \bfc ... %D \sl \sla \slb \slc ... %D \stoptyping %D %D The smaller ones are automatically supplied and derived from %D the the bodyfont environment. %D %D \starttyping %D \tfx \tfxx %D \bfx \bfxx %D \slx \slxx %D \stoptyping %D %D There are only two smaller alternatives per style. The %D larger alternatives on the other hand have no limitations. %D %D These larger alternatives are mostly used in chapter and %D section titles or on title pages. When one switches to a %D larger alternative, the bold an other ones automatically %D adapt themselves: %D %D \startbuffer %D \tfd Hi \bf there\sl, here \tfb I \bf am %D \stopbuffer %D %S \startnarrower %D \typebuffer %S \stopnarrower %D %D therefore becomes: %D %D \startvoorbeeld %D \getbuffer %D \stopvoorbeeld %D %D Maybe this mechanism isn't always as logic, but as said %D before, we tried to make it as intuitive as possible. %D %D So a specific kind of glyph can be characterized by: %D %D \startnarrower %D family (cmr) + bodyfont (12pt) + style (rm) + alternative (bf) + size (a) %D \stopnarrower %D %D The last component (the size) is optional. %D %D We introduced \type{\tf} as command to call for the current %D normally sized typeface. This commands results in roman, %D sans serif, teletype or whatever style is in charge. Such %D rather massive switches of style sometimes take more %D processing time than comfortable. Of course there is a %D workaround for this: we can call fonts directly by means of %D commands like: %D %D \starttyping %D \rmtf \sssl \tttf \rmbsa %D \stoptyping %D %D One should realize that this fast calls have limitations, %D they lack for instance automatic super- and subscript %D support. %D %D This leaves us two more commands: \type{\tx} and %D \type{\txx}. These activate a smaller and even more smaller %D font than the current one and adapt themselves to the %D current alternative, so when \type{\bf} is active, %D \type{\tx} gives a smaller boldface, which in turn can be %D called directly by \type{\bfx}. %D %D These two smaller alternatives are specified by the bodyfont %D environment and therefore not necessarily have similar sizes %D as \type{\scriptsize} and \type{\scriptscriptsize}. The main %D reason for this incompatibility (which can easily be undone) %D lays in the fact that we often want a bit bigger characters %D than in math mode. In \CONTEXT\ for instance the \type{\tx} %D and \type{\txx} commands are used for surrogate %D \cap{smallcaps} which support both nesting and alternatives, %D like in {\bf\cap{a \cap{small} world}}, which was typeset by %D %D \starttyping %D \bf\cap{a \cap{small} world} %D \stoptyping %D %D And compare $\rm \scriptstyle THIS$ with the slightly larger %D \cap{THIS}: \ruledhbox{$\rm \scriptstyle scriptstyle: THIS$} %D or \ruledhbox{\cap{x style: THIS}} makes a big difference. %D %D The \type{x..d} sizes should be used grouped. If you %D don't group them, i.e. call them in a row, \CONTEXT\ will %D not be able to sort out your intention (\type {x} inside %D \type {d} inside \type {x}. etc.). The following table %D demonstrates this: %D %D \def\FontState{\setstrut\ruledhbox{\strut Hello}} %D %D \starttabulate[|||||] %D \HL %D \NC \rlap{\quad\bf grouped} \NC \NC \type {\tx} \NC \type {\txx} \NC \NR %D \HL %D \NC \type{\tfx} \NC \tfx \FontState \NC \tfx \tx \FontState \NC \tfx \txx \FontState \NC \NR %D \NC \type{\tfxx} \NC \tfxx \FontState \NC \tfxx\tx \FontState \NC \tfxx\txx \FontState \NC \NR %D \NC \type{\tf} \NC \tf \FontState \NC \tf \tx \FontState \NC \tf \txx \FontState \NC \NR %D \NC \type{\tfa} \NC \tfa \FontState \NC \tfa \tx \FontState \NC \tfa \txx \FontState \NC \NR %D \NC \type{\tfb} \NC \tfb \FontState \NC \tfb \tx \FontState \NC \tfb \txx \FontState \NC \NR %D \NC \type{\tfc} \NC \tfc \FontState \NC \tfc \tx \FontState \NC \tfc \txx \FontState \NC \NR %D \NC \type{\tfd} \NC \tfd \FontState \NC \tfd \tx \FontState \NC \tfd \txx \FontState \NC \NR %D \NC \type{\tfx} \NC \tfx \FontState \NC \tfx \tx \FontState \NC \tfx \txx \FontState \NC \NR %D \NC \type{\tfxx} \NC \tfxx \FontState \NC \tfxx\tx \FontState \NC \tfxx\txx \FontState \NC \NR %D \HL %D \stoptabulate %D %D \blank %D %D \starttabulate[|||||] %D \HL %D \NC \rlap{\quad\bf stacked} \NC \NC \type {\tx} \NC \type {\txx} \NC \NR %D \HL %D \NC \type{\tfx} %D \NC \tfx \FontState %D \NC \tfx \tx \FontState %D \NC \tfx \txx \FontState %D \NC \NR %D \NC \type{\tfxx} %D \NC \tfx\tfxx \FontState %D \NC \tfx\tfxx \tx \FontState %D \NC \tfx\tfxx \txx \FontState %D \NC \NR %D \NC \type{\tf} %D \NC \tfx\tfxx\tf \FontState %D \NC \tfx\tfxx\tf \tx \FontState %D \NC \tfx\tfxx\tf \txx \FontState %D \NC \NR %D \NC \type{\tfa} %D \NC \tfx\tfxx\tf\tfa \FontState %D \NC \tfx\tfxx\tf\tfa \tx \FontState %D \NC \tfx\tfxx\tf\tfa \txx \FontState %D \NC \NR %D \NC \type{\tfb} %D \NC \tfx\tfxx\tf\tfa\tfb \FontState %D \NC \tfx\tfxx\tf\tfa\tfb \tx \FontState %D \NC \tfx\tfxx\tf\tfa\tfb \txx \FontState %D \NC \NR %D \NC \type{\tfc} %D \NC \tfx\tfxx\tf\tfa\tfb\tfc \FontState %D \NC \tfx\tfxx\tf\tfa\tfb\tfc \tx \FontState %D \NC \tfx\tfxx\tf\tfa\tfb\tfc \txx \FontState %D \NC \NR %D \NC \type{\tfd} %D \NC \tfx\tfxx\tf\tfa\tfb\tfd \FontState %D \NC \tfx\tfxx\tf\tfa\tfb\tfd \tx \FontState %D \NC \tfx\tfxx\tf\tfa\tfb\tfd \txx \FontState %D \NC \NR %D \NC \type{\tfx} %D \NC \tfx\tfxx\tf\tfa\tfb\tfc\tfx \FontState %D \NC \tfx\tfxx\tf\tfa\tfb\tfc\tfx \tx \FontState %D \NC \tfx\tfxx\tf\tfa\tfb\tfc\tfx \txx \FontState %D \NC \NR %D \NC \type{\tfxx} %D \NC \tfx\tfxx\tf\tfa\tfb\tfc\tfx\tfxx \FontState %D \NC \tfx\tfxx\tf\tfa\tfb\tfc\tfx\tfxx \tx \FontState %D \NC \tfx\tfxx\tf\tfa\tfb\tfc\tfx\tfxx \txx \FontState %D \NC \NR %D \HL %D \stoptabulate %D %D Remark: math support has changed a bit. %D \macros %D {uchar} %D %D This macro prepares \CONTEXT\ for \UNICODE\ support. By %D defining it here, we have at least an safeguard for utility %D file reading. \ifdefined\uchar\else \unexpanded\def\uchar#1#2{[#1,#2]} \fi %D We define some (very private) constants to improve speed, %D memory usage and consistency. \def\@size@ {@f@si@} % bodyfont size prefix (12pt etc) \def\@style@ {@f@st@} % full style prefix (roman etc) \def\@shortstyle@ {@f@sh@} % short style prefix (rm etc) \def\@letter@ {@f@le@} % first alternative typeface \def\@noletter@ {@f@no@} % second alternative typeface \def\@fontclass@ {@f@cl@} % fontclass %D \macros %D {fontclass, defaultfontclass} %D %D The fontclass model was introduced a while after we implement %D the basic font model and at that time we still defaulted to %D no model at all. Nowadays we default to the \type {modern} %D fontclass. \let\fontclass \empty \let\defaultfontclass\empty %D \macros %D {textonly} %D %D Traditionally math has a big impact on font definitions, mainly %D because we need to define alphabet variants using families and %D fonts. This means that one can easily get 10 fonts loaded per %D math size. In \MKIV\ we use a different approach: one family %D which has either a virtual font made of traditional fonts, or %D an \OPENTYPE\ font that has it all. %D %D We currently use only one math family but in the future we %D might consider using a second one for bold math. For the %D moment we keep the \MKII\ method of using a token register %D for definitions but we already dropped the text and symbols %D ones since they now live in the same family. \newtoks \mathstrategies \newif\ifsynchronizemathfonts \synchronizemathfontstrue \def\synchronizemath % math stuff in mmode {\ifsynchronizemathfonts\the\mathstrategies\fi} \def\textonly{\synchronizemathfontsfalse} % document this %D The main math font definer. We have removed some optimized %D code simply because we now always have a fontclass. We could %D check for fontclass being default or empty and save a few %D tests but it does not help us when no math is defined. \chardef\mrfam\zerocount % math regular \chardef\mbfam\plusone % math bold \unexpanded\def\mr{\ifmmode\fam\zerocount\else\setcurrentfontalternative\c!mr\fi} % \fam\csname\c!mr fam\endcsname \unexpanded\def\mb{\ifmmode\fam\plusone \else\setcurrentfontalternative\c!mb\fi} % \fam\csname\c!mb fam\endcsname \def\mathtextsuffix {-text} \def\mathscriptsuffix {-script} \def\mathscriptscriptsuffix{-scriptscript} % \let\mathsizesuffix\empty \let\currentmathsize\empty \def\mathsizesuffix{\ifcase0\currentmathsize\or\mathtextsuffix\or\mathscriptsuffix\or\mathscriptscriptsuffix\fi} \def\dodosetmathfamily#1#2% {\ifcsname\fontclass \fontbody\c!mm\fontfamily\fontsize\currentmathsize\endcsname \autofontsizefalse \csname\fontclass \fontbody\c!mm\fontfamily\fontsize\currentmathsize\endcsname \else \ifcsname\fontclass \fontbody\c!mm\fontfamily \currentmathsize\endcsname \autofontsizetrue \csname\fontclass \fontbody\c!mm\fontfamily \currentmathsize\endcsname \else \dodosetmathfamilyx#1#2% \fi\fi #1#2\font} \def\dodosetmathfamilyx#1#2% {\ifcsname\defaultfontclass\fontbody\c!mm\fontfamily\fontsize\currentmathsize\endcsname \autofontsizefalse \csname\defaultfontclass\fontbody\c!mm\fontfamily\fontsize\currentmathsize\endcsname \else \ifcsname\defaultfontclass\fontbody\c!mm\fontfamily \currentmathsize\endcsname \autofontsizetrue \csname\defaultfontclass\fontbody\c!mm\fontfamily \currentmathsize\endcsname \else \dodosetmathfamilyxx#1#2% \fi\fi} \def\dodosetmathfamilyxx#1#2% {\ifcsname \fontbody\c!mm\fontfamily\fontsize\currentmathsize\endcsname \autofontsizefalse \csname \fontbody\c!mm\fontfamily\fontsize\currentmathsize\endcsname \else \ifcsname \fontbody\c!mm\fontfamily \currentmathsize\endcsname \autofontsizetrue \csname \fontbody\c!mm\fontfamily \currentmathsize\endcsname \else \nullfont \autofontsizetrue \fi\fi} \def\dosetmathfamily#1#2% {\let\savedfontbody\fontbody % op hoger plan \let\fontfamily#2% \let\currentmathsize\!!plusthree\let\fontbody\scriptscriptface\dodosetmathfamily\scriptscriptfont#1% \let\currentmathsize\!!plustwo \let\fontbody\scriptface \dodosetmathfamily\scriptfont #1% \let\currentmathsize\!!plusone \let\fontbody\textface \dodosetmathfamily\textfont #1% \let\currentmathsize\empty \let\fontbody\savedfontbody \autofontsizefalse} \appendtoks \dosetmathfamily\mrfam\c!mr \to \mathstrategies % not official ! \chardef\boldmathmode\zerocount % might change ... maybe \mathfontsupport 1 (normal) 2 (bold too) \def\enableboldmath {\chardef\boldmathmode\plusone } % todo: \setupbodyfont[boldmath,...] \def\disableboldmath{\chardef\boldmathmode\zerocount} \appendtoks \ifcase\boldmathmode\or\dosetmathfamily\mbfam\c!mb\fi \to \mathstrategies % \chardef\msfam\plustwo % math symbol % % \def\c!ms{ms} % % \unexpanded\def\ms{\ifmmode\fam\plustwo\else\setcurrentfontalternative\c!ms\fi} % % \chardef\symbolmathmode\zerocount % % \def\enablesymbolmath {\chardef\symbolmathmode\plusone } % \def\disablesymbolmath{\chardef\symbolmathmode\zerocount} % % \appendtoks % \ifcase\symbolmathmode\or\dosetmathfamily\msfam\c!ms\fi % \to \mathstrategies %D All used styles, like rm, ss and tt, are saved in a comma %D separated list. Appart from practical limitations one can %D define as many styles as needed. \def\fontrelativesizelist{\s!text,\s!script,\s!scriptscript,\c!x,\c!xx,\c!big,\c!small} %D There are several ways to specify a font. Three of them are %D pure \TeX\ ones, the fourth one is new: %D %D \starttyping %D \font\name=cmr12 %D \font\name=cmr12 at 10pt %D \font\name=cmr12 scaled 2 %D \font\name=cmr12 sa 1.440 %D \stoptyping %D %D The non||\TEX\ alternative \type{sa} stands for {\em scaled %D at}. This means as much as: scale the bodyfontsize with this %D factor. The scaled option is not that useful as one needs to %D know the design size. %D %D Because \type {sa} (scaled at) and \type {mo} (mapped on) %D are not low level \TEX\ supported alternatives, we have to %D test for it ourselves. In doing so, we need an auxiliary %D \DIMENSION. We cannot use \type{\scratchdimen} because font %D loading can happen at any moment due to postponed loading. %D We could instead have used dirty grouping tricks, but this %D one works too. % \enableexperiments[fonts.autorscale] % % \starttypescript[mscore] % \definetypeface [mscore] [rm] [serif] [mscoretimes] [default] % \definetypeface [mscore] [ss] [sans] [mscorearial] [default] [rscale=auto] % 0.860] % \definetypeface [mscore] [tt] [mono] [mscorecourier] [default] [rscale=auto] % 1.065] % \definetypeface [mscore] [mm] [math] [times] [default] [rscale=auto] % 1.020] % \stoptypescript % % \starttext % \setupbodyfont[mscore,12pt] % \startTEXpage % test \ss test \tt test % \stopTEXpage % \stoptext \let\defaultrelativefontsize \plusone \let\localrelativefontsize \plusone \def\localabsolutefontsize {\fontbody} \let\relativefontsize \defaultrelativefontsize % \def\saverelativefontsize#1#2% #1=rm|ss|.. #2=waarde % {\setxvalue{\fontclass#1\s!rscale}{#2}} \def\checkrelativefontid {\ifcsname\??tf\fontclass\s!rname\endcsname \@EA\let\@EA\relativefontid\csname\??tf\fontclass\s!rname\endcsname \else \@EA\xdef\csname\??tf\fontclass\s!rname\endcsname{\the\lastfontid}% \let\relativefontid\empty \fi} \def\checkrelativefontsize#1% {\edef\relativefontsize {\ifcsname\fontclass#1\s!rscale\endcsname \csname\fontclass#1\s!rscale\endcsname \else\ifcsname\defaultfontclass#1\s!rscale\endcsname \csname\defaultfontclass#1\s!rscale\endcsname \else \defaultrelativefontsize \fi\fi}% \ifx\relativefontsize\v!auto \let\relativefontsize\plusone \checkrelativefontid \else \let\relativefontid\minusone \fi} %D Scaling macros: %D %D This system is somewhat complicated by two (possible conflicting) %D demands: %D %D \startitemize %D \item We support wildcards like \type {sa *} which will adapt %D to the current size. This is also the default specification. %D \item We support named scales like \type {sa d}; beware: \type %D {x} and \type {xx} are valid scales but they are not alway %D the same as the ones used in for instance \type {\bfx} because %D there the sized come from the bodyfont environment. In the %D future there maybe a switch that also honors the environment %D in named scales. %D \stopitemize %D Keep in mind that the smaller sizes are just for text super and %D subscripts while larger sizes can be used in titles where for %D instance math follows the size. % b:x{\definedfont[SerifBold sa b]x}{\bfb x $x^x$}\par % 1:x{\definedfont[SerifBold sa 1]x}{\bf x $x^x$}\par % x:x{\definedfont[SerifBold sa x]x}{\bfx x $x^x$}\par % xx:x{\definedfont[SerifBold sa xx]x}{\bfxx x $x^x$}\par % % *:x{\definedfont[Serif sa *]x}\par % 1:x{\definedfont[Serif sa 1]x}\par % 2:x{\definedfont[Serif sa 2]x}\par % 3:x{\definedfont[Serif sa 3]x}\par % 4:x{\definedfont[Serif sa 4]x}\par % 5:x{\definedfont[Serif sa 5]x}\par % % {\definedfont[cmbx10 at 10pt]x\definedfont[cmbx8 at 10pt]x} \def\safontscale{\number\dimexpr\localabsolutefontsize\relax} \def\mofontscale{\number\dimexpr\setmappedfontsize\localabsolutefontsize\relax} \let\somefontname\s!unknown \let\somefontspec\s!unknown \let\somefontsize\zerocount \newcount\scaledfontmode \newdimen\scaledfontsize \newtoks \everydefinefont \newcount\lastfontid \def\currentfontbodysize {\ifcsname\??ft\s!default\somefontsize\endcsname \csname\??ft\s!default\somefontsize\endcsname \else \somefontsize \fi} \let\relativefontid\empty \def\lowleveldefinefont#1#2% #2 = cs {% \ctxlua{fonts.define.command_1("\luaescapestring{#1}")}% the escapestring catches at \somedimen % sets \scaledfontmode and \somefontname and \somefontsize \ifcase\scaledfontmode\relax % none, avoid the designsize if possible \scaledfontsize-1000\scaledpoint \or % at \scaledfontsize\somefontsize \or % sa \scaledfontsize\localabsolutefontsize\relax \scaledfontsize\currentfontbodysize\scaledfontsize \or % mo \scaledfontsize\setmappedfontsize\localabsolutefontsize \scaledfontsize\currentfontbodysize\scaledfontsize \or % scaled, don't use this one as it's unpredictable \scaledfontsize-\somefontsize\scaledpoint \fi \scaledfontsize\localrelativefontsize\scaledfontsize \ifautofontsize \scaledfontsize\currentfontbodyscale\scaledfontsize \fi \edef\somefontspec{at \number\scaledfontsize sp}% \edef\somefontfile{\truefontname\somefontname}% \ifx\somefontfile\s!unknown \edef\somefontfile{\defaultfontfile}% \fi \updatefontparameters \updatefontclassparameters \ctxlua{fonts.define.command_2( \ifx\fontclass\empty false\else true\fi, "#2", % cs, trailing % is gone "\somefontfile", \number\scaledfontsize, "\@@fontclassfeatures", "\@@fontfeatures", "\@@fontclassfallbacks", "\@@fontfallbacks", 0\currentmathsize, \number\dimexpr\textface\relax, "\relativefontid" % experiment )}% \edef\somefontspec{at \somefontsize}% we need the resolved designsize (for fallbacks) \expandafter\let\expandafter\lastrawfontcall\csname#2\endcsname \the\everydefinefont} \def\updatefontclassparameters {\edef\@@fontclassfeatures {\ifcsname\fontclass\fontstyle\s!features \endcsname\csname\fontclass\fontstyle\s!features \endcsname\fi}% \edef\@@fontclassfallbacks{\ifcsname\fontclass\fontstyle\s!fallbacks\endcsname\csname\fontclass\fontstyle\s!fallbacks\endcsname\fi}} % resolve \def\@@thefeaturesyes#1% {\ifcsname\??ff\fontclass#1\s!features \endcsname\@EA\let\@EA\@@fontfeatures \csname\??ff\fontclass#1\s!features \endcsname\else \ifcsname\??ff #1\s!features \endcsname\@EA\let\@EA\@@fontfeatures \csname\??ff #1\s!features \endcsname\else \ifcsname\??ff\fontclass #1\endcsname\@EA \@@thefeaturesyes \csname\??ff\fontclass #1\endcsname\else \ifcsname\??ff #1\endcsname\@EA \@@thefeaturesyes \csname\??ff #1\endcsname\else \let \@@fontfeatures \empty \fi\fi\fi\fi} \def\@@thefallbacksyes#1% {\ifcsname\??ff\fontclass#1\s!fallbacks\endcsname\@EA\let\@EA\@@fontfallbacks \csname\??ff\fontclass#1\s!fallbacks\endcsname\else \ifcsname\??ff #1\s!fallbacks\endcsname\@EA\let\@EA\@@fontfallbacks \csname\??ff #1\s!fallbacks\endcsname\else \ifcsname\??ff\fontclass #1\endcsname\@EA \@@thefallbacksyes\csname\??ff\fontclass #1\endcsname\else \ifcsname\??ff #1\endcsname\@EA \@@thefallbacksyes\csname\??ff #1\endcsname\else \let \@@fontfallbacks \empty \fi\fi\fi\fi} \def\@@thefeaturesnop#1% {\ifcsname\??ff#1\s!features \endcsname\@EA\let\@EA\@@fontfeatures \csname\??ff#1\s!features \endcsname\else \ifcsname\??ff #1\endcsname\@EA \@@thefeaturesnop \csname\??ff #1\endcsname\else \let \@@fontfeatures \empty \fi\fi} \def\@@thefallbacksnop#1% {\ifcsname\??ff#1\s!fallbacks\endcsname\@EA\let\@EA\@@fontfallbacks \csname\??ff#1\s!fallbacks\endcsname\else \ifcsname\??ff #1\endcsname\@EA \@@thefallbacksnop\csname\??ff #1\endcsname\else \let \@@fontfallbacks \empty \fi\fi} \def\updatefontparametersyes {\@@thefeaturesyes \somefontname \@@thefallbacksyes\somefontname} \def\updatefontparametersnop {\@@thefeaturesnop \somefontname \@@thefallbacksnop\somefontname} \def\updatefontparameters {\ifx\fontclass\empty\updatefontparametersnop\else\updatefontparametersyes\fi} \let\@@fontclassfeatures \empty \let\@@fontclassfallbacks\empty \let\@@fontfallbacks\empty \let\@@fontfeatures \empty \let\@@hyphenchar \empty % todo, will go to encoding %D This brings down maps processing from 466 to 309 seconds %D ($-33$\%) and mfonts from 42 to 34 seconds ($-15$\%). \newif\ifskipfontcharacteristics \skipfontcharacteristicstrue %D When fontclasses are used, we define the font global, %D since namespaces are used. Otherwise we parse the specs %D each time. \let\fontfile\s!unknown % \definefontfeature[slanted] [default][slant=.25] % \definefontfeature[stretched][default][stretch=2] % % \start \definedfont[SerifBold*slanted at 20pt] \ruledhbox{Test!} \stop % \start \definedfont[SerifBold*stretched at 20pt] \ruledhbox{Test!} \stop % \definefontfeature[default] [liga=yes,texligatures=yes,texquotes=yes] % \definefontfeature[default-caps][liga=yes,texligatures=yes,texquotes=yes,smcp=yes,script=latn] % % \starttypescript [serif] [palatino-nova-regular] [name] % \definefontsynonym[Serif] [palatinonova-regular][features=default] % \definefontsynonym[SerifCaps][palatinonova-regular][features=default-caps] % also sets Serif % \stoptypescript % % \starttypescript [serif] [palatino-nova-regular] [name] % \definefontsynonym[Serif] [palatinonova-regular*default] % \definefontsynonym[SerifCaps] [palatinonova-regular*default-caps] % \stoptypescript % \definetypeface[mainface][rm][serif][palatino-nova-regular][default] \setupbodyfont[mainface] % % \starttext % ``Test'' -- --- ff fi fl \sc ``Test'' -- --- ff fi fl % \stoptext % \starttext % \definefont % [blabla] % [name:Latin Modern Something] % \definefont % [blabla] % [file:texnansi-lmr10] % \blabla test % \definefont % [blabla] % [texnansi-lmtt10] % \blabla test % \stoptext % \starttext % % \setupcolors[state=start] % % \definefontfeature % [default-base] % [script=latn,language=dflt,liga=yes,kern=yes,tlig=yes,trep=yes] % \definefontfeature % [default-node] % [script=latn,language=dflt,liga=yes,kern=yes,tlig=yes,trep=yes,mode=node] % \definefontfeature % [default-none] % [script=latn,language=dflt,liga=yes,kern=no, tlig=yes,trep=yes] % % \startoverlay % {\vtop{\color[red] {\font\test=name:lmroman12regular*default-node \test \input ward \input zapf \input linden }}} % {\vtop{\color[green]{\font\test=name:lmroman12regular*default-base \test \input ward \input zapf \input linden }}} % {\vtop{\color[blue] {\font\test=name:lmroman12regular*default-none \test \input ward \input zapf \input linden }}} % \stopoverlay % % \blank % % \startoverlay % {\vtop{\color[red] {\font\test=name:texgyrepagella*default-node \test \input ward \input zapf \input linden }}} % {\vtop{\color[green]{\font\test=name:texgyrepagella*default-base \test \input ward \input zapf \input linden }}} % {\vtop{\color[blue] {\font\test=name:texgyrepagella*default-none \test \input ward \input zapf \input linden }}} % \stopoverlay % % \blank % % \startoverlay % {\vtop{\color[red] {\font\test=name:palatinonovaregular*default-node \test \input ward \input zapf \input linden }}} % {\vtop{\color[green]{\font\test=name:palatinonovaregular*default-base \test \input ward \input zapf \input linden }}} % {\vtop{\color[blue] {\font\test=name:palatinonovaregular*default-none \test \input ward \input zapf \input linden }}} % \stopoverlay % % \startoverlay % {\vtop{\color[red] {\font\test=name:OfficinaSerifBookITC*default-node \test \input ward \input zapf \input linden }}} % {\vtop{\color[green]{\font\test=name:OfficinaSerifBookITC*default-base \test \input ward \input zapf \input linden }}} % {\vtop{\color[blue] {\font\test=name:OfficinaSerifBookITC*default-none \test \input ward \input zapf \input linden }}} % \stopoverlay % % \definefontfeature[superdefault][default][compose=yes] % % {\font\oeps=name:lmroman10regular*default at 30pt \oeps test \char7683} % {\font\oeps=name:lmroman10regular*superdefault at 30pt \oeps test \char7683} % % \stoptext \def \defaultfontfile{\truefontname{Normal}} % was cmtt10, but that one is gone \edef\nullfontname {\fontname\nullfont} %D \macros %D {everyfont,everyfontswitch} %D %D For special purposes, we provide a hook. % \newevery \everyfont \relax % \newevery \everyfontswitch \relax %D We also accept \type{sa a}||\type{sa d} as specification. %D \macros %D {definefontsynonym, doifelsefontsynonym, %D expandfontsynonym, truefontname, truefontdata} %D %D While looking for fonts, fontsynonyms are used for accessing %D the files! %D %D \starttyping %D \definefontsynonym[Serif][Lucida-Bright] %D \definefontsynonym[Lucida-Bright][lbr][encoding=texnansi] %D \stoptyping \def\classfont#1#2{#1#2} % \definefont[whatever][\classfont{xx}{yy} at 10pt] % We need to move the feature into the filename else it may be % overloaded by another reference. For instance the definition of % a regular and caps variant can use the same font. % We could use an indirect method ... store in 'array' and refer to % slot. \unexpanded\def\definefontsynonym[#1]#2[#3]% {\edef\@@fontname{#1}% \edef\@@fontfile{#3}% \ifx\fontclass\empty \expandafter\dodefinefontsynonymnop \else \expandafter\dodefinefontsynonymyes \fi} \def\dodefinefontsynonymnop {\@EA\let\csname\??ff\@@fontname\endcsname\@@fontfile % maybe just #1 #3, saves expansion \doifnextoptionalelse\dododefinefontsynonymnop\nonodefinefontsynonymnop} \def\dodefinefontsynonymyes {\@EA\let\csname\??ff\fontclass\@@fontname\endcsname\@@fontfile % maybe just #1 #3, saves expansion \doifnextoptionalelse\dododefinefontsynonymyes\nonodefinefontsynonymyes} \def\dododefinefontsynonymnop[#1]% {\let\@@ff@@features \undefined \let\@@ff@@fallbacks\undefined \expandafter\dogetfontparameternop#1,]=,} \def\dododefinefontsynonymyes[#1]% {\let\@@ff@@features \undefined \let\@@ff@@fallbacks\undefined \expandafter\dogetfontparameteryes#1,]=,} \def\dogetfontparameternop#1=#2,% {\if]#1% \dodododefinefontsynonymnop \else \expandafter\def\csname @@ff@@#1\endcsname{#2}% \expandafter\dogetfontparameternop \fi} \def\dogetfontparameteryes#1=#2,% {\if]#1% \dodododefinefontsynonymyes \else \expandafter\def\csname @@ff@@#1\endcsname{#2}% \expandafter\dogetfontparameteryes \fi} % hm, was wrong, class/global reversed \let\fcglobal\global \let\fcxdef \xdef \let\fcglet \glet \def\nonodefinefontsynonymnop {\@EA\let\csname\??ff\@@fontname\s!features \endcsname\undefined \@EA\let\csname\??ff\@@fontname\s!fallbacks\endcsname\undefined} \def\nonodefinefontsynonymyes {\fcglobal\@EA\let\csname\??ff\fontclass\@@fontname\s!features \endcsname\undefined \fcglobal\@EA\let\csname\??ff\fontclass\@@fontname\s!fallbacks\endcsname\undefined} \def\dodododefinefontsynonymnop {\@EA\let\csname\??ff\@@fontname\s!features \endcsname\@@ff@@features \@EA\let\csname\??ff\@@fontname\s!fallbacks\endcsname\@@ff@@fallbacks} \def\dodododefinefontsynonymyes {\fcglobal\@EA\let\csname\??ff\fontclass\@@fontname\s!features \endcsname\@@ff@@features \fcglobal\@EA\let\csname\??ff\fontclass\@@fontname\s!fallbacks\endcsname\@@ff@@fallbacks} \let\definefontfile\definefontsynonym % dedicated to Taco Hoekwater \unexpanded\def\setupfontsynonym {\dodoubleempty\dosetupfontsynonym} \def\dosetupfontsynonym[#1][#2]% not yet supported, will do when needed {} \def\truefontname#1% {\@EA\dotruefontname#1*\empty*\relax} \def\dotruefontname#1*#2#3*#4\relax {\ifcsname\??ff\fontclass#1\endcsname \ifx#2\empty \@EA\truefontname\csname\??ff\fontclass#1\endcsname \else \@EA\redotruefontname\csname\??ff\fontclass#1\endcsname*#2#3% \fi \else\ifcsname\??ff\defaultfontclass#1\endcsname \ifx#2\empty \@EA\truefontname\csname\??ff\defaultfontclass#1\endcsname \else \@EA\redotruefontname\csname\??ff\defaultfontclass#1\endcsname*#2#3% \fi \else\ifcsname\??ff#1\endcsname \ifx#2\empty \@EA\truefontname\csname\??ff#1\endcsname \else \@EA\redotruefontname\csname\??ff#1\endcsname*#2#3% \fi \else #1\ifx#2\empty\else*#2#3\fi \fi\fi\fi} \def\redotruefontname#1% {\@EA\dodotruefontname#1*\relax} \def\dodotruefontname#1*#2\relax {\ifcsname\??ff\fontclass#1\endcsname \@EA\redotruefontname\csname\??ff\fontclass#1\endcsname \else\ifcsname\??ff\defaultfontclass#1\endcsname \@EA\redotruefontname\csname\??ff\defaultfontclass#1\endcsname \else\ifcsname\??ff#1\endcsname \@EA\redotruefontname\csname\??ff#1\endcsname \else #1% \fi\fi\fi} \def\expandfontsynonym#1#2% #2 := onelevelexpansion(#1) {\ifcsname\??ff\fontclass#2\endcsname \expandafter\def\expandafter#1\expandafter{\csname\??ff\fontclass#2\endcsname}% \else\ifcsname\??ff\defaultfontclass#2\endcsname \expandafter\def\expandafter#1\expandafter{\csname\??ff\defaultfontclass#2\endcsname}% \fi\fi} \def\doifelsefontsynonym#1% {\ifcsname\??ff\fontclass#1\endcsname \@EA\firstoftwoarguments \else\ifcsname\??ff\defaultfontclass#1\endcsname \@EAEAEA\firstoftwoarguments \else \@EAEAEA\secondoftwoarguments \fi\fi} % \definetypeface[palatino][rm][serif][palatino,allbold][default] % % \startfontclass[palatino] % \definefontsynonym [Serif] [SerifBold] % \definefontsynonym [SerifItalic] [SerifBoldItalic] % \definefontsynonym [SerifSlanted] [SerifBoldSlanted] % \definefontsynonym [SerifCaps] [SerifBold] % \stopfontclass % % \setupbodyfont[palatino] \unexpanded\def\startfontclass {\dosingleempty\dostartfontclass} \def\dostartfontclass[#1]% {\pushmacro\fontclass \doifelse{#1}\v!each {\let\fontclass\empty} {\doifsomething{#1}{\def\fontclass{#1}}}} \unexpanded\def\stopfontclass {\popmacro\fontclass} %D \macros %D {tracedfontname} %D %D A goody: \def\tracedfontname#1% {#1\ifcsname\??ff\fontclass#1\endcsname \@EA\tracedfontname\csname\??ff\fontclass#1\endcsname \else\ifcsname\??ff#1\endcsname \@EA\tracedfontname\csname\??ff#1\endcsname \fi\fi} %D \macros %D {definefont} %D %D Before we implement the main definition macro, we first show %D one for local use: %D %D \starttyping %D \definefont[Some][LucidaBright at 100pt] \Some some %D \definefont[More][LucidaBright scaled 3000] \More more %D \definefont[Nice][LucidaBright mo 2] \Nice nice %D \definefont[Text][LucidaBright sa 5.4] \Text last %D \stoptyping %D %D The implementation looks as follows: \unexpanded\def\definefont {\dotripleempty\dodefinefont} \def\dodefinefont[#1][#2][#3]% [name][spec][1.6 | line=10pt | setup_id] {\ifthirdargument \setuvalue{#1}{\redodefinefont{#1}{#2}{#3}}% \else \setuvalue{#1}{\dododefinefont{#1}{#2}}% \fi} \def\redodefinefont#1#2#3% {\dododefinefont{#1}{#2}% \doifsetupselse{#3} {\setups[#3]} % don't forget to document this ! {\setuplocalinterlinespace[#3]% \setupspacing}} % needed ? \unexpanded\def\definefrozenfont {\dotripleempty\dodefinefrozenfont} \def\dodefinefrozenfont[#1][#2][#3]% {\dodefinefont[#1][#2][#3]% \expandafter\let\csname\lastfontidentifier\expandafter\endcsname\csname\rawfontidentifier\endcsname} %D The \type {*} makes the switch local, so that we can redefine a %D logical name and/or change the size in between. \newif\ifautofontsize \autofontsizetrue \let\lastfontidentifier\empty \def\rawfontidentifier{**\lastfontidentifier\fontsize\currentmathsize**} \def\newfontidentifier{*\fontclass\lastfontidentifier\fontsize\currentmathsize*} \let\oldrawfontidentifier\rawfontidentifier \let\oldnewfontidentifier\newfontidentifier \def\newfontidentifier{*\fontclass\lastfontidentifier\fontstyle\fontsize*} \def\dododefinefont#1#2% {\edef\lastfontidentifier{#1}% \let\localrelativefontsize\defaultrelativefontsize \let\localabsolutefontsize\fontbody \lowleveldefinefont{#2}\rawfontidentifier \csname\rawfontidentifier\endcsname \autofontsizefalse \setfontcharacteristics \the\everyfontswitch \let\rawfontidentifier\oldrawfontidentifier} \def\xxdododefinefont#1#2#3#4% \autofontsizetrue is set by calling routine {\edef\lastfontidentifier{#3}% \ifcsname\newfontidentifier\endcsname\else \def\localrelativefontsize{#1}% \def\localabsolutefontsize{#2}% \lowleveldefinefont{#4}\newfontidentifier \fi \csname\newfontidentifier\endcsname \autofontsizefalse %\edef\lastfontidentifier{#3}% \ifskipfontcharacteristics \else \setfontcharacteristics \the\everyfontswitch \fi \let\newfontidentifier\oldnewfontidentifier} %D \macros %D {mapfontsize} %D %D For special purposes, like in math, you may want to use %D slightly different sizes than the ones given. This happens %D for instance with the Math Times fonts. Mapped font sizes %D can be specified by using the \type {mo} key instead of %D \type {sa} in font definitions. %D %D \startbuffer %D \mapfontsize[10pt][11pt] %D \mapfontsize[11pt][12pt] %D \mapfontsize[12pt][13pt] %D %D \definefont[test][Serif]\test TEST \par %D \definefont[test][Serif sa 5]\test TEST \par %D \definefont[test][Serif mo 5]\test TEST \par %D \definefont[test][Serif sa d]\test TEST \par %D \definefont[test][Serif at 60pt]\test TEST \par %D \definefont[test][Serif scaled 6000]\test TEST \par %D \stopbuffer %D %D \typebuffer %D %D \startpacked %D \getbuffer %D \stoppacked \def\mapfontsize {\dodoubleargument\domapfontsize} \def\domapfontsize[#1][#2]% {\setvalue{\??ft*\the\dimexpr#1\relax}{#2}} \def\setmappedfontsize#1% {\ifcsname\??ft*#1\endcsname \csname\??ft*#1\endcsname \else #1% \fi} %D \macros %D {getfontname} %D %D The names of the fonts can be called with the rather simple %D macro \type{\getfontname}. When for instance we pass %D \type{12ptrmtf} as argument, we get \getfontname{12ptrmtf}. \def\getfontname#1% {\csname\??ft#1\endcsname} %D To be documented. \let\fontsizelist \empty \let\fontalternativelist\empty \let\fontstylelist \empty \def\checkfontnamecombinations % we need to split math and text here ... todo (math only has mr and mb) {\def\docommand##1% {\def\dodocommand####1% {\def\dododocommand########1{\checkbodyfont{########1}{####1}{##1}}% \processcommacommand[\fontstylelist]\dododocommand}% \processcommacommand[\fontalternativelist]\dodocommand}% \processcommacommand[\fontsizelist]\docommand} \unexpanded\def\definefontsize[#1]% sneller met toks {\addtocommalist{#1}\fontsizelist \checkfontnamecombinations} \unexpanded\def\definefontalternative[#1]% {\addtocommalist{#1}\fontalternativelist \checkfontnamecombinations} %D \macros %D {currentfontscale,currentfontbodyscale} %D %D Sometimes we need to have access to the font scale %D including the \type{a}||\type{d} sizes. The next macro %D returns the current scaling factor. Take a look at %D \type {cont-log.tex} for an example of its use. \def\currentfontscale {\csname\??ft\s!default \ifcsname\??ft\s!default\xfontsize\endcsname \xfontsize \else \ifcsname\??ft\s!default\s!text \endcsname \s!text \fi\fi \endcsname} \def\currentfontbodyscale {\csname\??ft\s!default \ifcsname\??ft\s!default\fontsize\endcsname \fontsize \else \ifcsname\??ft\s!default\s!text \endcsname \s!text \fi\fi \endcsname} \setvalue{\??ft\s!default}{1} %D Both alternatives use \type {\xfontsize}, a macro that %D expands to the current size in terms of \type {a} \unknown %D \type {d}, nothing, or \type {x} \unknown \type {xx}. \def\xfontsize{\ifcase\currentxfontsize\fontsize\or\c!x\else\c!xx\fi} %D A typical use of this command is in commands that switch %D to another font bypassing the font mechanism: %D %D \starttyping %D \font\myfont=\truefontname{MyFont} at \the\dimexpr\currentfontscale\bodyfontsize\relax %D \stoptyping %D Now we enter the area of font switching. The switching %D mechanism has to take care of several situations, like: %D %D \startitemize[packed] %D \item changing the overal document fonts (including margins, %D headers and footers) %D \item changing local fonts (only the running text) %D \item smaller and even more smaller alternatives (super- %D and subscripts) %D \stopitemize %D %D \TEX\ offers a powerfull family mechanism for super- and %D subscripts in math mode. In text mode however, we don't use %D families for the smaller alternatives, and therefore have %D to take care of it otherwise. %D \macros %D {definebodyfontenvironment,setupbodyfontenvironment} %D %D The relationship between the several sizes of a font, is %D defined by: %D %D \showsetup{definebodyfontenvironment} %D %D Later on we will see how these parameters are used, so for %D the moment we stick with an example: %D %D \starttyping %D \definebodyfontenvironment %D [12pt] %D [ text=12pt, %D script=9pt, %D scriptscript=7pt, %D x=10pt, %D xx=8pt, %D big=12pt, %D small=10pt] %D \stoptyping %D %D The first argument specifies the bodyfont size to which the %D settings apply. All second parameters are specified in %D dimensions and tell us more about related sizes. %D %D Afterwards, one can change values with %D %D \showsetup{setupbodyfontenvironment} %D %D Due to the fact that \type{\c!text} and \type{\s!text} can %D have a similar meaning, and therefore can lead to an %D unwanted loop, we temporary redefine \type{\c!text}. For %D the moment this in only place that some trickery is needed %D to fool the multilingual interface. However, long ago %D we decided to stick to \s!text in definitions as it closely %D relates to the math model where text, script and scriptscript %D are used untranslated. Also, we are now english at the low %D level so it cannot go wrong anymore. %D %D When instead of a size the keyword \type{unknown} is %D passed, fractions (relations) are used instead of fixed %D sizes. \let\bodyfontenvironmentlist\empty \newcount\@@fontdefhack % check if this is still needed \def\@@beginfontdef {\ifcase\@@fontdefhack \let\k!savedtext \k!text \let\k!text \s!text \let\k!k!savedtext \k!k!text \let\k!k!text \!!plusone \let\k!saveddefault \k!default \let\k!default \s!default \let\k!k!saveddefault\k!k!default \let\k!k!default \!!plusone \fi \advance\@@fontdefhack \plusone } \def\@@endfontdef {\advance\@@fontdefhack \minusone \ifcase\@@fontdefhack \let\k!k!default\k!k!saveddefault \let\k!default \k!saveddefault \let\k!k!text \k!k!savedtext \let\k!text \k!savedtext \fi} \unexpanded\def\definebodyfontenvironment {\dotripleempty\dodefinebodyfontenvironment} \def\dodefinebodyfontenvironment[#1][#2][#3]% class size settings {\ifthirdargument \@@beginfontdef \doifelse{#2}\s!default {\getparameters[\??ft\s!default][#3]} {\normalizebodyfontsize#2\to\tempbodyfontsize \addtocommalist\tempbodyfontsize\bodyfontenvironmentlist \@EA\dododefinebodyfontenvironment\@EA[\tempbodyfontsize][#1][#3]}% \@@endfontdef \else \ifx\fontclass\empty\else \writestatus\m!fonts{beware: fontclass ignored (if needed use: [fontclass][size][settings])}% \fi \pushmacro\fontclass \let\fontclass\empty \definebodyfontenvironment[\fontclass][#1][#2]% change */* \popmacro\fontclass \fi} \def\dododefinebodyfontenvironment[#1][#2][#3]% size class settings {\@@beginfontdef % \s!text goes wrong in testing because the 12pt alternative will called when typesetting the test (or so) \ifcsname\??ft#2#1\c!em\endcsname % we test for em as we assume it to be set \else \def\docommand##1% {\scratchdimen\csname\??ft\s!default##1\endcsname\dimexpr#1\relax \normalizebodyfontsize\scratchdimen\to\tempbodyfontsize \letvalue{\??ft#2#1##1}\tempbodyfontsize}% \processcommacommand[\fontrelativesizelist]\docommand \copyparameters [\??ft#2#1][\??ft\s!default] [\c!interlinespace,\c!em]% \fi \getparameters[\??ft#2#1][#3]% \@@endfontdef % new code, see remark \ifloadingfonts % only runtime \else\ifcsname\@size@#1\endcsname % only once \else % prevent loop (hence \empty) \letvalue{\@size@#1}\empty \pushmacro\fontclass % new per 26102009 \edef\fontclass{#2}% % new per 26102009 \defineunknownfont{#1}% \popmacro\fontclass % new per 26102009 \fi\fi % so far \setvalue{\@size@#1}{\docompletefontswitch[#1]}} %D {\bf Remark:} We need to cover the following cases, %D otherwise users can get confused: %D %D \starttyping %D \setupbodyfont[23pt] %D %D \definebodyfontenvironment[23pt] %D \setupbodyfont[23pt] %D %D \definebodyfontenvironment[23pt] %D \definebodyfont[23pt][rm,ss,tt][default] %D \setupbodyfont[23pt] %D \stoptyping %D Beware: while some font defs can be global, the bodyfont %D environment checks local. This means that multiple local %D checks resulting in definitions are not that efficient. %D So, apart from an occasional switch, one should define an %D environment at the outer level. \def\checkbodyfontenvironment[#1]% {\definebodyfontenvironment[\fontclass][#1][]} \def\checkbodyfontenvironment[#1]% {\ifcsname\??ft\fontclass#1\c!em\endcsname % we test for em as we assume it to be set \else \definebodyfontenvironment[\fontclass][#1][]% \fi} % this one already catches both define/setup \let\setupbodyfontenvironment\definebodyfontenvironment %D Just a couple of interface macros: \def\bodyfontvariable#1% {\??ft\ifcsname\??ft\fontclass#1\endcsname\fontclass\fi#1} \def\bodyfontinterlinespecs {\bodyfontvariable{\normalizedbodyfontsize\c!interlinespace}} \def\bodyfontinterlinespace {\csname\bodyfontinterlinespecs\endcsname} %D We default all parameters to the main bodyfont size (begin %D \type{#1}), so the next setup is valid too: %D %D \starttyping %D \definebodyfontenvironment[24pt] %D \stoptyping %D %D All parameters can be redefined when needed, so one does %D not have to stick to the default ones. %D \macros %D {definebodyfont} %D %D The next step in defining a bodyfont involves the actual font %D files, which can be recognized by their extension %D \type{tfm}. Installing those file is often beyond the %D scope of the user and up to the system administrator. %D %D \showsetup{definebodyfont} %D %D This commands takes three arguments: a (series of) bodyfont %D size(s), the style group to which the definitions belong, %D and an alternative, as specified by the \TEX\ (math) families, %D extended with~a, b~\unknown. %D %D We show two examples, that show all the alternative %D scaling options. The \type{\tfa} alternatives can be %D extended with \type{\bfa}, \type{\slb}, etc. or even %D \type{e} and higher alternatives. The magic scaled %D values are derived from plain \TEX's \type {\magstep}: %D %D \starttyping %D \definebodyfont [12pt] [rm] %D [tf=cmr12, %D bf=cmbx12, %D it=cmti12, %D sl=cmsl12, %D bi=cmbxti10 at 12pt, %D bs=cmbxsl10 at 12pt, %D tfa=cmr12 scaled 1.200, %D tfb=cmr12 scaled 1.440, %D tfc=cmr12 scaled 1.728, %D tfd=cmr12 scaled 2.074, %D sc=cmcsc10 at 12pt] %D %D \definebodyfont [12pt,11pt,10pt,9pt,8pt] [rm] %D [tf=lbr sa 1, %D bf=lbd sa 1, %D it=lbi sa 1, %D sl=lbsl sa 1, %D bi=lbdi sa 1, %D bs=lbdi sa 1, %D tfa=lbr sa 1.200, %D tfb=lbr sa 1.440, %D tfc=lbr sa 1.728, %D tfd=lbr sa 2.074, %D sc=lbr sa 0.833] %D \stoptyping %D %D The second example shows that we can define more sizes at %D once. The main difference between these examples is that the %D Computer Modern Roman come in many design sizes. This means %D that there we cannot define them in bulk using \type{sa}. %D Instead of \type{rm} (roman) one can define \type{ss} (sans %D serif), \type{tt} (teletype), \type{hw} (hand written), %D \type{cg} (calygraphic) and whatever styles. %D %D The first argument may be a comma separated list. This, %D combined with specifications using \type{sa} can save a lot %D of typing. Although all arguments should be specified, we %D treat the second argument as optional. %D %D Defining a bodyfont involves two actions: defining the %D specific style related alternatives, like \type{\rma}, %D \type{\bfa} and \type{\rmsla}, and storing the definitions %D of their bodyfont size related fonts. The first step is %D bodyfont independant but executed every time. This permits %D user definitions like \type{\tfw} or \type{\bfq} for real %D large alternatives. \unexpanded\def\definebodyfont {\doquadrupleempty\redefinebodyfont} \def\redefinebodyfont[#1][#2][#3][#4]% {\iffourthargument \processcommacommand[#1]{\reredefinebodyfont[#2][#3][#4]}% \else \dodefinebodyfont[#1][#2][#3]% \fi} \def\reredefinebodyfont[#1][#2][#3]#4% {\pushmacro\fontclass \doifelse{#4}\s!default {\let\fontclass\empty} {\def\fontclass{#4}}% \definebodyfont[#1][#2][#3]% \popmacro\fontclass} \def\dodefinebodyfont[#1][#2][#3]% body|identifier style defs|identifier {\ifthirdargument \doifnumberelse{#1} {\doifassignmentelse{#3} {% [12pt] [style] [settings] \ifcsname#2\endcsname\else\normalexpanded{\noexpand\definefontstyle[#2][#2]}\fi % new \processcommalist[#1]{\dododefinebodyfont{#2}{#3}}} {% [12pt] [style] [identifier] \dodefinedefaultbodyfont[#1][#2][#3]}} % body style identifier {% [identifier] [style] [settings] % see *** \setvalue{\s!default#1#2}##1##2{\normalexpanded{\noexpand\xdodefinebodyfont[##1][##2][#3]}}}% \else\ifsecondargument \definebodyfont[#1][\c!rm][#2]% \else % Maybe there are default dependencies defined which we can use ([unknown]) and % if not, then we have at least to make sure some basics are set up. \ifcsname\@size@#1\endcsname \else \defineunknownfont{#1}% \fi \ifcsname\@size@#1\endcsname \else \definebodyfont[#1][\c!rm][]% \fi \fi\fi} \def\xdodefinebodyfont[#1][#2][#3]% body|identifier style defs|identifier {\checkrelativefontsize{#2}% rather new, inherit from other defs \ifcsname#2\endcsname\else\normalexpanded{\noexpand\definefontstyle[#2][#2]}\fi % new \processcommalist[#1]{\dododefinebodyfont{#2}{#3}}% \let\relativefontsize\defaultrelativefontsize} \def\dododefinebodyfont#1#2#3% style defs body {\checkbodyfontenvironment[#3]% just to be sure. \processcommalist[#2]{\dodododefinebodyfont{#1}{#3}}} \def\dodododefinebodyfont#1#2#3% style body def {\dododododefinebodyfont{#1}{#2}[#3]} \def\dododododefinebodyfont {\ifx\fontclass\empty \expandafter\dododododefinebodyfontnop \else \expandafter\dododododefinebodyfontyes \fi} \def\dododododefinebodyfontyes#1% style body def {\edef\askedbodyfontstyle{#1}% \ifx\askedbodyfontstyle\c!mm \expandafter\dodefinebodyfontyesmm \else \expandafter\dodefinebodyfontyesxx \fi\askedbodyfontstyle} % we can get rid of #1 \def\dododododefinebodyfontnop#1% style body def {\edef\askedbodyfontstyle{#1}% \ifx\askedbodyfontstyle\c!mm \expandafter\dodefinebodyfontnopmm \else \expandafter\dodefinebodyfontnopxx \fi\askedbodyfontstyle} % we can get rid of #1 \def\dodefinebodyfontnopxx#1#2[#3#4#5=#6]% style body def {\ifcsname#1#3#4#5\endcsname\else\checkbodyfont{#1}{#3#4}{#5}\fi% not \definefontsize[#5] \@EA\let\csname*#2#1#3#4#5*\endcsname\undefined \unexpanded\@EA\edef\csname#2#1#3#4#5\endcsname{\noexpand\xxdododefinefont{\number\relativefontsize}{#2}{#2#1#3#4#5}{\normalunexpanded{#6}}}} \def\dodefinebodyfontyesxx#1#2[#3#4#5=#6]% style body def {\ifcsname#1#3#4#5\endcsname\else\checkbodyfont{#1}{#3#4}{#5}\fi% not \definefontsize[#5] \fcglobal\@EA\let\csname*\fontclass#2#1#3#4#5*\endcsname\undefined \unexpanded\@EA\fcxdef\csname\fontclass#2#1#3#4#5\endcsname{\noexpand\xxdododefinefont{\number\relativefontsize}{#2}{#2#1#3#4#5}{\normalunexpanded{#6}}}} \def\dodefinebodyfontnopmm#1#2[#3#4#5=#6]% style body def {\ifcsname#1#3#4#5\endcsname\else\checkbodyfont{#1}{#3#4}{#5}\fi% not \definefontsize[#5] \@EA\let\csname*#2#1#3#4#51*\endcsname\undefined \@EA\let\csname*#2#1#3#4#52*\endcsname\undefined \@EA\let\csname*#2#1#3#4#53*\endcsname\undefined \unexpanded\@EA\edef\csname#2#1#3#4#51\endcsname{\noexpand\xxdododefinefont{\number\relativefontsize}{#2}{#2#1#3#4#51}{\normalunexpanded{#6}}}% \unexpanded\@EA\edef\csname#2#1#3#4#52\endcsname{\noexpand\xxdododefinefont{\number\relativefontsize}{#2}{#2#1#3#4#52}{\normalunexpanded{#6}}}% \unexpanded\@EA\edef\csname#2#1#3#4#53\endcsname{\noexpand\xxdododefinefont{\number\relativefontsize}{#2}{#2#1#3#4#53}{\normalunexpanded{#6}}}} \def\dodefinebodyfontyesmm#1#2[#3#4#5=#6]% style body def {\ifcsname#1#3#4#5\endcsname\else\checkbodyfont{#1}{#3#4}{#5}\fi% not \definefontsize[#5] \fcglobal\@EA\let\csname*\fontclass#2#1#3#4#51*\endcsname\undefined \fcglobal\@EA\let\csname*\fontclass#2#1#3#4#52*\endcsname\undefined \fcglobal\@EA\let\csname*\fontclass#2#1#3#4#53*\endcsname\undefined \unexpanded\@EA\fcxdef\csname\fontclass#2#1#3#4#51\endcsname{\noexpand\xxdododefinefont{\number\relativefontsize}{#2}{#2#1#3#4#51}{\normalunexpanded{#6}}}% \unexpanded\@EA\fcxdef\csname\fontclass#2#1#3#4#52\endcsname{\noexpand\xxdododefinefont{\number\relativefontsize}{#2}{#2#1#3#4#52}{\normalunexpanded{#6}}}% \unexpanded\@EA\fcxdef\csname\fontclass#2#1#3#4#53\endcsname{\noexpand\xxdododefinefont{\number\relativefontsize}{#2}{#2#1#3#4#53}{\normalunexpanded{#6}}}} \def\checkbodyfont#1% tests for ttsl mmbf {\edef\c!!mm{#1}% \ifx\c!!mm\c!mm % prevents \max and alike (re)defs \expandafter\checkmathbodyfont \else \expandafter\checktextbodyfont \fi{#1}} % no \c!!mm, not expanded later on % some day we can do an auto-fam if needed \def\checkmathbodyfont#1#2#3% style alt size / gdef % #3 can be empty {%\message{!m #1 #2 #3!}% % #1 #2 #3 = signal %setugvalue {#2}{\setcurrentfontalternative {#2}}% \mr \mb \setugvalue {#1}{\setcurrentfontstyle {#1}}}% \mm \def\checktextbodyfont#1#2#3% style alt size / gdef % #3 can be empty {%\message{!t #1 #2 #3!}% \setugvalue {#1#3}{\setcurrentfontstylesize {#1}{#3}}% \rma \setugvalue {#2#3}{\setcurrentfontalternativesize {#2}{#3}}% \sla \setugvalue {#1#2#3}{\setcurrentfontstylealternativesize{#1}{#2}{#3}}% \rmsla \setugvalue {#1}{\setcurrentfontstyle {#1}}% \rm \setugvalue {#2}{\setcurrentfontalternative {#2}}% \sl \setugvalue {#1\c!x}{\setcurrentfontxstylealternative {#1}}% \rmx \setugvalue{#1\c!xx}{\setcurrentfontxxstylealternative {#1}}% \rmxx \setugvalue {#2\c!x}{\setcurrentfontxalternative {#2}}% \slx \setugvalue{#2\c!xx}{\setcurrentfontxxalternative {#2}}% \slxx \setugvalue {#1#2}{\setcurrentfontstylealternative {#1}{#2}}}% \rmsl \def\dodefinedefaultbodyfont[#1][#2][#3]% sizes styles identifier {\def\dododefinedefaultbodyfont##1% {\def\dodododefinedefaultbodyfont####1% {\def\dododododefinedefaultbodyfont########1% {\ifcsname\s!default########1####1\endcsname % [12pt] [style] [identifier] \csname\s!default########1####1\endcsname{##1}{####1}% \fi}% \processcommalist[#3]\dododododefinedefaultbodyfont}% \processcommalist[#2]\dodododefinedefaultbodyfont}% \processcommalist[#1]\dododefinedefaultbodyfont} %D Unknown families are added to the family list! For the %D moment we also set the direct calls here. Some day a better %D solution will be implemented. The good news is that unknown %D fonts are defined automatically. \newif\ifdefiningunknownfont \def\dodefineunknownfont#1#2% {\ifcsname\??ft\s!default#2\endcsname \donetrue \normalizebodyfontsize\csname\??ft\s!default#2\endcsname\dimexpr#1\relax\to\tempbodyfontsize \letvalue{\??ft#1#2}\tempbodyfontsize \fi} \def\dodefineunknownbodyfont#1#2% see *** {\ifcsname\s!default\s!default#2\endcsname % somehow related to */* \donetrue \csname\s!default\s!default#2\endcsname{#1}{#2}% \fi} \def\dodefineunknownsubfont#1#2% {\ifcsname\@size@\csname\??ft#1#2\endcsname\endcsname \else \donetrue \defineunknownfont{\csname\??ft#1#2\endcsname}% \fi} \unexpanded\def\defineunknownfont#1% {\let\c!savedtext\c!text \let\c!text\s!text \donefalse \processcommacommand[\fontrelativesizelist]{\dodefineunknownfont{#1}}% \let\c!text\c!savedtext \ifdone \donefalse \processcommacommand [\fontstylelist] {\dodefineunknownbodyfont{#1}}% \ifdone \donefalse \setvalue{\@size@#1}{\docompletefontswitch[#1]}% \ifdefiningunknownfont \else \definingunknownfonttrue \processcommacommand[\fontrelativesizelist]{\dodefineunknownsubfont{#1}}% \definingunknownfontfalse \fi \fi \ifdone \showmessage\m!fonts{14}{#1}% \fi \fi} %D These macros show that quite some definitions take place. %D Fonts are not loaded yet! This means that at format %D generation time, no font files are preloaded. %D \macros %D {everybodyfont,Everybodyfont,everyglobalbodyfont} %D %D Every change in bodyfont size has conseqences for the baseline %D distance and skips between paragraphs. These are initialized %D in other modules. Here we only provide the hooks that %D garantees their handling. %D At the system level one can initialize thing like: %D %D \starttyping %D \appendtoks \setupspacing \to \everybodyfont %D \stoptyping %D %D While users can add their own non standard commands like: %D %D \starttyping %D \EveryBodyFont{\message{changing to bodyfont \the\bodyfontsize}} %D \stoptyping %D %D Personnaly I never felt the need for such extensions, but %D at least its possible. %D \macros %D {globalbodyfontsize,localbodyfontsize} %D %D Next we'll do the tough job of font switching. Here we %D have to distinguish between the global (overal) bodyfont %D size and the local (sometimes in the textflow) size. We %D store these dimensions in two \DIMENSION\ registers. \ifdefined\globalbodyfontsize\else \newdimen\globalbodyfontsize \fi \globalbodyfontsize=12pt \ifdefined\localbodyfontsize \else \newdimen\localbodyfontsize \fi \localbodyfontsize =\globalbodyfontsize %D \macros %D {bodyfontsize} %D %D These two registers are not to be misused in calculations. %D For this purpose we keep a copy: \newdimen\bodyfontsize \bodyfontsize=\globalbodyfontsize %D \macros %D {bodyfontfactor,bodyfontpoints} %D %D For multiplication purposes we keep an auxiliary counter %D and macro (here the expansion is not explicitly needed): \newcount\bodyfontpoints \dimensiontocount\bodyfontsize\bodyfontpoints \edef\bodyfontfactor{\withoutpt\the\bodyfontsize} %D When we assign for instance 12pt to a \DIMENSION\ register %D the \type{\the}'d value comes out as 12.0pt, which is %D often not the way users specify the bodyfont size. Therefore %D we also store the normalized value. \chardef\fontdigits=2 % was 1 % \def\normalizebodyfontsize#1\to#2% % {\@EA\@EA\@EA\donormalizedbodyfontsize\@EA\WITHOUTPT\the\dimexpr#1+\ifcase\fontdigits.5\or.05\or.005\fi\points\relax000\to#2} % % \def\donormalizedbodyfontsize#1.#2#3#4#5\to#6% \points ? % {\edef#6% not \ifcase#2\else due to \relax adding % {#1% % \ifcase\fontdigits % \or \ifcase#2 \else .#2\fi % 1 % \or \ifcase#2#3 \else .#2\ifcase#3 \else #3\fi\fi % 2 % \else \ifcase#2#3#4 \else .#2\ifcase#4 \ifcase#3 \else#3\fi \else#3#4\fi\fi % 3 % \fi % \s!pt}} \def\normalizebodyfontsize#1\to#2% {\edef#2{\ctxlua{fonts.nbfs(\number\dimexpr#1\relax,\number\fontdigits)}}} \def\thenormalizedbodyfontsize#1% {\ctxlua{fonts.nbfs(\number\dimexpr#1\relax,\number\fontdigits)}} \normalizebodyfontsize\bodyfontsize\to\normalizedglobalbodyfontsize \normalizebodyfontsize\bodyfontsize\to\normalizedlocalbodyfontsize \normalizebodyfontsize\bodyfontsize\to\normalizedbodyfontsize %D \macros %D {fontstyle,fontalternative,fontsize} %D %D Within a bodyfont, fonts can come in different sizes. For %D instance \type{\tf} is accompanied by \type{\tfa}, %D \type{\tfb} etc. The first two characters denote the %D alternative, while the third character in these sequences %D represents the size. The actual size is saved in a macro %D %D The style, being roman (\type{\rm}), sans serif (\type{\ss}) %D etc. is also available in a macro in \type{rm}, \type{ss} %D etc. form: \let\defaultfontalternative = \c!tf \let\defaultfontstyle = \empty \let\defaultfontsize = \empty \let\fontalternative = \defaultfontalternative \let\fontstyle = \defaultfontstyle \let\fontsize = \defaultfontsize %D When \type {\loadfontfileoncetrue}, such files are %D only loaded once! This permits redundant loading, but at %D the same time forced grouping when we want continuously mix %D all kind of font, which of course is a kind of %D typographically sin. The \type{"} is made inactive if %D needed to prevent problems with loading files that use this %D character in numbers. % can be made faster (only used internally now) \def\doswitchpoints[#1]% {\normalexpanded{\dodoswitchpoints{#1}}} \unexpanded \def\dodoswitchpoints#1% {\ifcsname\@size@#1\endcsname \else \defineunknownfont{#1}% \fi% %\defineunknownfontstyles{#1}% \ifcsname\@size@#1\endcsname \csname\@size@#1\endcsname \localbodyfontsize#1\relax \normalizebodyfontsize\localbodyfontsize\to\normalizedbodyfontsize % \edef\fontbody{\fontbody}% to be tested but we can clean up mkiv further \checkbodyfontenvironment[\normalizedbodyfontsize]% \else \showmessage\m!fonts4{#1}% \fi} \unexpanded \def\doswitchstyle[#1]% {\ifcsname\@style@#1\endcsname \csname\@style@#1\endcsname \edef\fontstyle{#1}% \ifmmode\mr\fi % in order to be compatible with \rm in math mode % \the\everybodyfont % cleaner, in setting size as well as style \else \showmessage\m!fonts5{#1}% \fi} %D \TEX\ loads font metric files like \type{cmr10.tfm} and %D \type{tir.tfm} only once. In \PLAIN\ \TEX\ some font files %D are {\em preloaded}. This means that the font files are %D loaded, but not accessible yet by name. This is accomplished %D by saying: %D %D \starttyping %D \font\preloaded=cmr10 at 11pt %D \stoptyping %D %D and using the name \type{\preloaded} again and again, so %D fonts are indeed loaded, but unnamed, and therefore %D unaccessible. In \CONTEXT\ we don't preload fonts, not even %D the \PLAIN\ \TEX\ ones, although users can access them. Now %D why is this done? %D Defining fonts using \type{\definebodyfont} takes time, so we %D prefer to predefine at least the Computer Modern Roman %D fonts. However, loading all those fonts at definition time %D would take both time and space. But even worse, once fonts %D are loaded into memory, their encoding vector is fixed, %D which is a handicap when we want to distribute the compact %D \type{fmt} files. So what we want to do is defining fonts in %D a way that postpones the loading. We accomplish this by only %D loading the fonts when we switch to another bodyfont size. %D Among the other alternatives, such as loading the font at %D the moment of activation and redefining the activation %D macro afterwards, this proved to be the most efficient %D alternative. %D %D The next few macros take care of the one exeption on this %D scheme. When at format generation time we load the default %D font file, the one that defines the Computer Modern Fonts, %D we don't want the fonts metrics to end up in the format %D file, so we temporary prohibit loading. This means that at %D runtime we have to load the default bodyfont size just before %D we start typesetting. %D %D Therefore we have to signal the font switching macros that %D we are preloading fonts. As long as the next boolean is, %D true, no loading is done. \newif\ifloadingfonts \loadingfontstrue %D \macros %D {preloadfonts} %D %D Preloading is only called for once, during the startup %D sequence of a session. After the loading job is done, the %D macro relaxes itself and reset the signal. % \appendtoks % \to \everysetupdocument \newconditional\fontsareloaded \def\preloadfonts % never called, needs a clean up {\global\loadingfontsfalse \ifconditional\fontsareloaded \else \doifmodeelse {*nofonts} {\writestatus\m!fonts{latin modern fonts are not preloaded}} {\writestatus\m!fonts{preloading latin modern fonts}% \usetypescript[modern]% \setuptypeface[modern]% \showmessage\m!fonts6{\normalizedbodyfontsize\normalspace\fontstyle}}% \fi \global\let\preloadfonts\relax} % maybe add this to \everystarttext % % \ifconditional\fontsareloaded\else % \usetypescript[modern]% % \setuptypeface[modern]% % \fi %D Here comes the main font switching macros. These macros %D handle changes in size as well as returning to the global %D bodyfont size. \def\dosetfont#1#2% #1 = set/switch state {\doifelse{#2}\v!global {\restoreglobalbodyfont} {\processcommacommand[#2]{\dodosetfont{#1}}% ##1 get also passed \ifloadingfonts\else \global\settrue\fontsareloaded \doswitchpoints[\normalizedbodyfontsize]% \doswitchstyle[\fontstyle]% \ifx\defaultfontclass\empty \let\defaultfontclass\fontclass \fi \fi}% \chardef\currentxfontsize\zerocount} \def\dodosetfont#1#2% #1 = set/switch state | check fo rempty, else space {\doifsomething{#2}{\dododosetfont{#1}{#2}{\showmessage\m!fonts4{#2}}}} % % % this can be retrofitted in mkii code % % % % \def\normalizebodyfontsize#1\to#2% % {\@EA\@EA\@EA\donormalizedbodyfontsize\@EA\WITHOUTPT\the\dimexpr#1+\ifcase\fontdigits.5\or.05\or.005\fi\points\relax000\to#2} \def\dododosetfont#1#2#3% #1 = set/switch state ! ! ! !could also be used for mkii {\doifnumberelse{#2}\dodododosetfont\redododosetfont{#1}{#2}{#3}} \def\redododosetfont#1#2#3% #1 = set/switch state ! ! ! !could also be used for mkii {\edef\expandedfontthing{#2}% \def\interfacedfontsize{\normalizedbodyfontsize\interfaced\expandedfontthing}% \ifcsname\??ft\interfacedfontsize\endcsname \edef\fontstep{\csname\bodyfontvariable\interfacedfontsize\endcsname}% \normalexpanded{\noexpand\dodododosetfont{#1}{\fontstep}}{#3}% \else\ifx\expandedfontthing\v!reset \let\fontstyle\empty % new 31/7/2006 \let\fontsize \empty \else \ifcsname\@style@\expandedfontthing\endcsname \let\fontstyle\expandedfontthing \else \setcurrentfontclass\expandedfontthing \ifcase#1\relax \let\globalfontclass\globalfontclass \else \let\globalfontclass\fontclass \fi \ifx\fontclass\empty \let\fontstyle\c!rm \else\ifcsname\??tf\fontclass\s!default\endcsname \edef\fontstyle{\csname\??tf\fontclass\s!default\endcsname}% \else \let\fontstyle\c!rm \fi\fi \fi \fi\fi} \def\dodododosetfont#1#2#3% #1 = set/switch state {\normalizebodyfontsize#2\to\normalizedsetfont \ifcsname\@size@\normalizedsetfont\endcsname \else \defineunknownfont{#2}% \fi \ifcsname\@size@\normalizedsetfont\endcsname \localbodyfontsize\normalizedsetfont \let\normalizedbodyfontsize\normalizedsetfont \else #3\dosetsubstitutefont{#1}{#2}% \fi} % % % %D In the previous macros we use \type{\currentxfontsize} to %D hold the current x||size of the font. This enables us to %D support for instance \type{\sl} inside a \type{\tx} switch. \chardef\currentxfontsize=0 %D When users specify for instance a 13 point bodyfont while no %D such bodyfont is defined, the system automatically tries to %D find a best fit, that is the nearest smaller defined %D bodyfontzize. A smaller one is definitely better than a larger %D one, simply because otherwise a lot of overfull box messages %D are more probable to occur. By taking a value slightly %D smaller than half a point, we can use the next method. \def\dosetsubstitutefont#1#2% #1 = set/switch state {\scratchdimen#2\relax \advance\scratchdimen .499\points \dimensiontocount\scratchdimen\scratchcounter \advance\scratchcounter \minusone \ifnum\scratchcounter>\plusthree \dododosetfont{#1}{\the\scratchcounter\s!pt}{}% \fi} % The following bunch of macros deals with the (run time) % expansion of names onto the definitions made by \type % {\definebodyfont}. % \let\fontbody \empty % ... 10pt 11pt 12pt ... % \let\fontstyle \empty % rm ss tt mm hw cg ... % \let\fontalternative\empty % tf bf sl it bs bi sc ... % \let\fontsize \empty % xy-abcd ... \def\defaultfontbody{\normalizedbodyfontsize} \let\fontbody\defaultfontbody \let\fontclass\empty \let\globalfontclass\fontclass % we need to check the fontclass \def\registerfontclass#1% {\letgvalue{\@fontclass@#1}\v!yes} % global ? \edef\@no@fontclass@{\@fontclass@:?:} \def\setcurrentfontclass#1% {\ifcsname\@fontclass@#1\endcsname \edef\fontclass{#1}% \else\ifcsname\@no@fontclass@#1\endcsname % already tried \else\ifcase\currentgrouplevel \trycurrentfontclass{#1}% \fi\fi\fi} \def\savefontclassparameters#1#2#3#4% #1=rm|ss|.. rscale features fallbacks {\setxvalue{\fontclass#1\s!rscale }{#2}% \setxvalue{\fontclass#1\s!features }{#3}% \setxvalue{\fontclass#1\s!fallbacks}{#4}} \settrue\autotypescripts % \def\trycurrentfontclass#1% % {\ifconditional\autotypescripts % \usetypescript[#1]% % \ifcsname\@fontclass@#1\endcsname % \edef\fontclass{#1}% % \else % \letvalue{\@no@fontclass@#1}\empty % \fi % \else % \letvalue{\@no@fontclass@#1}\empty % \fi} \def\trycurrentfontclass#1% {\ifconditional\autotypescripts % try to load typescript #1 \usetypescript[#1]% \ifcsname\@fontclass@#1\endcsname \edef\fontclass{#1}% \else % try to load type-#1.mkiv \usetypescriptfile[\f!typeprefix#1]% % try to load typescript #1 \usetypescript[#1]% \ifcsname\@fontclass@#1\endcsname \edef\fontclass{#1}% \else % todo: message \letvalue{\@no@fontclass@#1}\empty \fi \fi \else % todo: message \letvalue{\@no@fontclass@#1}\empty \fi} \let\defaultfontstyle \c!rm \let\defaultfontalternative \c!tf \let\defaultfontsize \empty %D \macros %D {bigmath,nobigmath} %D %D We can inhibit this slow||downer with: % these can best be combined % 0=never 1=everymath 2=always \chardef\synchronizebigmathflag=1 \appendtoks \ifcase\synchronizebigmathflag % never \or \synchronizebigmath \or % always \fi \to \everymathematics \def\nobigmath {\chardef\synchronizebigmathflag\zerocount} \def\autobigmath{\chardef\synchronizebigmathflag\plusone\synchronizebigmath} \def\bigmath {\chardef\synchronizebigmathflag\plustwo\synchronizebigmath} \let\bigmathfontsize\empty \def\synchronizebigmath {\ifx\bigmathfontsize\fontsize % already in sync \else \let\bigmathfontsize\fontsize \synchronizemath \fi} \def\checkbigmathsynchronization {\ifcase\synchronizebigmathflag % never \or \ifmmode \synchronizebigmath \fi \or \synchronizebigmath \fi} %D So far for synchronisation. (We can inline the following macros.) \def\dosetcurrentfontsize#1% {\edef\fontsize{#1}% \checkbigmathsynchronization} \def\dosetcurrentfontalternative#1% {\edef\fontalternative{#1}} \def\setcurrentfont#1#2#3#4% {%\message{[1 #1 #2 #3 #4]}% \edef\fontbody{#1}% \edef\fontstyle{#2}% \dosetcurrentfontalternative{#3}% \dosetcurrentfontsize{#4}% \synchronizefont} \def\setcurrentfontbody#1% {%\message{[2 #1]}% \edef\fontbody{#1}% \synchronizefont} % For Taco: optional fall backs: \ifx\checkfontclass\undefined \let\checkfontclass\gobbleoneargument \fi % implemented in type-ini % \def\setcurrentfontstyle#1% % {%\message{[3 #1]}% % \checkfontclass{#1}% % \edef\fontstyle{#1}% % \ifmmode\mr\fi % otherwise \rm not downward compatible % \synchronizefont} \def\setcurrentfontstyle#1% {%\message{[3 #1]}% \edef\fontstyle{#1}% \checkfontclass\fontstyle \ifmmode\mr\fi % otherwise \rm not downward compatible \synchronizefont} \def\setcurrentfontbodyalternative#1#2% {%\message{[4 #1 #2]}% \edef\fontbody{#1}% \dosetcurrentfontalternative{#2}% \synchronizefont} \def\setcurrentfontalternative#1% {%\message{[5 #1]}% \dosetcurrentfontalternative{#1}% \synchronizefont} \def\setcurrentfontsize#1% {%\message{[6 #1]}% \dosetcurrentfontsize{#1}% \synchronizefont} \def\setcurrentfontstylealternative#1#2% \rmsl {%\message{[7 #1 #2]}% \edef\fontstyle{#1}% \dosetcurrentfontalternative{#2}% \synchronizefont} \def\setcurrentfontstylesize#1#2% \rmsla {%\message{[8 #1 #2]}% \edef\fontstyle{#1}% \dosetcurrentfontsize{#2}% \synchronizefont} \def\setcurrentfontalternativesize#1#2% \sla {%\message{[9 #1 #2]}% \dosetcurrentfontalternative{#1}% \dosetcurrentfontsize{#2}% \synchronizefont} \def\setcurrentfontstylealternativesize#1#2#3% \rmsla {%\message{[10 #1 #2 #3]}% \edef\fontstyle{#1}% \dosetcurrentfontalternative{#2}% \dosetcurrentfontsize{#3}% \synchronizefont} %D In principle one can assign alternative fallback routines. %D Some day we will. \newtoks\fontstrategies \newif\iftryingfont \let\fontstrategy\relax \def\synchronizefont % we can have dups i.e. no need to let fontstrategy {\tryingfonttrue \ifx\fontclass\empty \applyfontstrategies \else \applyfontclassstrategies \fi \autofontsizefalse \ifskipfontcharacteristics \setfontcharacteristics \the\everyfontswitch \fi} \def\fontclassstrategiesa % --- --- --- --- % pt tt bf a {\ifcsname\fontclass\fontbody \fontstyle \fontalternative \fontsize\endcsname \autofontsizefalse \csname\fontclass\fontbody \fontstyle \fontalternative \fontsize\endcsname \else \expandafter\fontclassstrategiesb \fi} \def\fontclassstrategiesb % --- --- --- def % pt tt bf {\ifcsname\fontclass\fontbody \fontstyle \fontalternative \defaultfontsize\endcsname \autofontsizetrue \csname\fontclass\fontbody \fontstyle \fontalternative \defaultfontsize\endcsname \else \expandafter\fontclassstrategiesc \fi} \def\fontclassstrategiesc % --- --- def --- % pt tt tf a {\ifcsname\fontclass\fontbody \fontstyle \defaultfontalternative \fontsize\endcsname \autofontsizetrue \csname\fontclass\fontbody \fontstyle \defaultfontalternative \fontsize\endcsname \else \expandafter\fontclassstrategiesd \fi} \def\fontclassstrategiesd % --- --- def def % pt tt tf {\ifcsname\fontclass\fontbody \fontstyle \defaultfontalternative \defaultfontsize\endcsname \autofontsizetrue \csname\fontclass\fontbody \fontstyle \defaultfontalternative \defaultfontsize\endcsname \else \expandafter\fontclassstrategiese \fi} \def\fontclassstrategiese % --- def def def % pt rm tf {\ifcsname\fontclass\fontbody \defaultfontstyle \defaultfontalternative \defaultfontsize\endcsname \autofontsizefalse \csname\fontclass\fontbody \defaultfontstyle \defaultfontalternative \defaultfontsize\endcsname \else \expandafter\fontclassstrategiesf \fi} \def\fontclassstrategiesf % def def def def % rm tf {\ifcsname\fontclass\defaultfontbody \defaultfontstyle \defaultfontalternative \defaultfontsize\endcsname \autofontsizetrue \csname\fontclass\defaultfontbody \defaultfontstyle \defaultfontalternative \defaultfontsize\endcsname \else \expandafter\fontstrategiesa \fi} % no class \def\fontstrategiesa % --- --- --- --- % pt tt bf a {\ifcsname\fontbody \fontstyle \fontalternative \fontsize\endcsname \autofontsizefalse \csname\fontbody \fontstyle \fontalternative \fontsize\endcsname \else \expandafter\fontstrategiesb \fi} \def\fontstrategiesb % --- --- --- --- % pt tt bf a {\ifcsname\fontbody \fontstyle \fontalternative \defaultfontsize\endcsname \autofontsizetrue \csname\fontbody \fontstyle \fontalternative \defaultfontsize\endcsname \else \expandafter\fontstrategiesc \fi} \def\fontstrategiesc % --- --- --- --- % pt tt bf a {\ifcsname\fontbody \fontstyle \defaultfontalternative \fontsize\endcsname \autofontsizetrue \csname\fontbody \fontstyle \defaultfontalternative \fontsize\endcsname \else \expandafter\fontstrategiesd \fi} \def\fontstrategiesd % --- --- --- --- % pt tt bf a {\ifcsname\fontbody \fontstyle \defaultfontalternative \defaultfontsize\endcsname \autofontsizetrue \csname\fontbody \fontstyle \defaultfontalternative \defaultfontsize\endcsname \else \expandafter\fontstrategiese \fi} \def\fontstrategiese % --- --- --- --- % pt tt bf a {\ifcsname\fontbody \defaultfontstyle \defaultfontalternative \defaultfontsize\endcsname \autofontsizefalse \csname\fontbody \defaultfontstyle \defaultfontalternative \defaultfontsize\endcsname \else \expandafter\fontstrategiesf \fi} \def\fontstrategiesf % --- --- --- --- % pt tt bf a {\ifcsname\defaultfontbody \defaultfontstyle \defaultfontalternative \defaultfontsize\endcsname \autofontsizetrue \csname\defaultfontbody \defaultfontstyle \defaultfontalternative \defaultfontsize\endcsname \fi} \let\applyfontstrategies \fontstrategiesa \let\applyfontclassstrategies\fontclassstrategiesa %D Let's synchronize: \newif\ifsynchronizefonts \synchronizefontstrue \prependtoks \ifsynchronizefonts \synchronizemath \synchronizefont % problem: syncs last font \fi \to \everybodyfont %D Setting the normal sizes as well as the x and xx smaller %D sizes is accomplished by the next set of macros. When in %D math mode, the commands \type{\tx} and \type{\txx} are %D just a switch to the script and double script styles, but %D in text mode the values defined by the bodyfontenvironment are %D used. Here we also set \type{\currentxfontsize}. \def\dosetcurrentfontxxxalternative#1#2#3#4% {\chardef\currentxfontsize#2\relax \ifmmode #4% \else\ifcsname\bodyfontvariable{\normalizedbodyfontsize#3}\endcsname \setcurrentfontbodyalternative{\csname\bodyfontvariable\normalizedbodyfontsize#3\endcsname}{#1}% \fi\fi} \def\setcurrentfontxalternative#1% {\dosetcurrentfontxxxalternative{#1}1\c!x\scriptstyle \let\tx\txx} \def\setcurrentfontxxalternative#1% {\dosetcurrentfontxxxalternative{#1}2\c!xx\scriptscriptstyle \let\tx\empty \let\txx\empty} \def\checknestedxfontsize % option {\ifcase\currentxfontsize\else\ifx\fontsize\empty\else \chardef\currentxfontsize\zeropoint \let\fontsize\empty \let\tx\normaltx \let\txx\normaltxx \fi\fi} \def\setcurrentfontxalternative#1% {\checknestedxfontsize \dosetcurrentfontxxxalternative{#1}1\c!x\scriptstyle \let\tx\txx} \def\setcurrentfontxxalternative#1% {\checknestedxfontsize \dosetcurrentfontxxxalternative{#1}2\c!xx\scriptscriptstyle \let\tx\empty \let\txx\empty} % This alterative is not really needed, but for old time's sake % we keep it there. We can speed it up when needed. \def\setcurrentfontxstylealternative #1{\csname#1\endcsname\tx} \def\setcurrentfontxxstylealternative#1{\csname#1\endcsname\txx} %D These macros also show us that when we call for \type{\tx}, %D this macro is redefined to be \type{\txx}. Therefore calls %D like: %D %D \startbuffer %D {small \tx is \tx beautiful} %D {small \tx is \txx beautiful} %D {small \txx is \tx beautiful} %D {small \txx is \txx beautiful} %D \stopbuffer %D %D \typebuffer %D %D result in: %D %D \startvoorbeeld %D \startlines %D \getbuffer %D \stoplines %D \stopvoorbeeld %D %D Setting the main size involves the style list and therefore %D takes a bit more time. Keep in mind that the fontsize is %D represented by a character or empty. \unexpanded\def\tx {\setcurrentfontxalternative \fontalternative} \unexpanded\def\txx{\setcurrentfontxxalternative\fontalternative} \let\normaltx \tx \let\normaltxx\txx %D \macros %D {definefontstyle} %D %D When setting of switching the overall style we can use the %D short identifier like rm and ss, but when defined we can %D also use more verbose names like roman or sansserif. Such %D names are defined by: %D %D \starttyping %D \definefontstyle [serif,rm] [rm] %D \definefontstyle [sansserif,ss] [ss] %D \stoptyping \def\dodefinefontstyle[#1][#2]% {\rawdoifinsetelse{#2}{\fontstylelist} {%\debuggerinfo\m!fonts{unknown style #2}% } {%\debuggerinfo\m!fonts8{#2\space (#1)}% \addtocommalist{#2}\fontstylelist}% % check kan hier \def\docommand##1% {\setvalue{\@shortstyle@##1}{#2}% \setvalue{\@style@##1}{\csname#2\endcsname}}% \processcommalist[#1]\docommand} \unexpanded\def\definefontstyle {\dodoubleargument\dodefinefontstyle} \def\setfontstyle#1#2% #1:name (roman, romaan) #2:style (rm) {\edef\fontstyle{#1}% \checkfontnamecombinations \setcurrentfontstyle\normalizedbodyfontsize} %D When asking for a complete font switch, for instance from 10 %D to 12~points, the next macro does the job. First we %D normalize the size, next we define the current range of %D text, script and scriptscript sizes, then we set the text %D fonts and the math families and finally we activate the %D default typeface and also set the font specific parameters %D assigned to \type{\everybodyfont} \def\dosetbodyfontface#1#2% {\edef#1{\csname\bodyfontvariable\normalizedbodyfontsize#2\endcsname}} \def\docompletefontswitch[#1]% {\bodyfontsize#1\relax \dimensiontocount\bodyfontsize\bodyfontpoints % rounded, still used in m-chart \edef\bodyfontfactor{\withoutpt\the\bodyfontsize}% \normalizebodyfontsize\bodyfontsize\to\normalizedbodyfontsize \dosetbodyfontface \textface \s!text \dosetbodyfontface \scriptface \s!script \dosetbodyfontface \scriptscriptface \s!scriptscript} \docompletefontswitch[12pt] % init %D \macros %D {setupbodyfont,switchtobodyfont} %D %D The next two macros are user ones. With \type{\setupbodyfont} %D one can set the document bodyfont size, font family, style %D and/or options defined in files, for example: %D %D \starttyping %D \setupbodyfont[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 \chardef\bodyfontsetstate=0 \definecomplexorsimple\setupbodyfont \def\simplesetupbodyfont {\restoreglobalbodyfont \saveinterlinespace} \def\complexsetupbodyfont[#1]% {\doifsomething{#1} {\dosetfont1{#1}% \globalbodyfontsize\localbodyfontsize \normalizebodyfontsize\globalbodyfontsize\to\normalizedglobalbodyfontsize \let\globalfontstyle\fontstyle \ifloadingfonts\else \the\everybodyfont \the\everyglobalbodyfont \saveinterlinespace \fi \the\everysetupbodyfont}} \unexpanded\def\switchtobodyfont[#1]% {\doifsomething{#1} {\ifcsname\??ft\normalizedbodyfontsize\interfaced{#1}\endcsname \setbodyfontstep{#1}% so we have a fast [small] switch \else \dosetfont0{#1}% \fi \the\everybodyfont \the\everyswitchtobodyfont}} %D The following alternative is meant for math||to||text %D switching and will be optimized. \def\fastswitchtobodyfont#1% {\ifcsname\??ft\normalizedbodyfontsize#1\endcsname \edef\futurebodyfontsize{\csname\??ft\normalizedbodyfontsize#1\endcsname}% \ifcsname\@size@\futurebodyfontsize\endcsname \csname\@size@\futurebodyfontsize\endcsname \localbodyfontsize\futurebodyfontsize\relax \fi \fi \csname\@style@\fontstyle\endcsname \the\everybodyfont} %D \starttyping %D $\cases{& \ccaron}$ $x=\hbox{\ccaron $x=\hbox{\ccaron}$}$ %D \stoptyping \def\setfontcharacteristics {\the\everyfont} %D Predefined: % \installfontfeature[otf][tlig] % \installfontfeature[otf][trep] %D tricky but ok: \appendtoks\ctxlua{fonts.tfm.cleanup()}\to\everyshipout %D Todo: % \def\os{\groupedcommand{\setfontfeature{oldstyle}}{}} %D Experimental: \unexpanded\def\definefontfeature {\dotripleargument\dodefinefontfeature} \def\dodefinefontfeature[#1][#2][#3]% {\global\expandafter\chardef\csname\??fq=#1\endcsname % beware () needed as we get two values returned \ctxlua{tex.write((fonts.define.specify.preset_context("#1","#2","#3")))}\relax} \definefontfeature [default] [%mode=node, liga=yes,kern=yes,tlig=yes,trep=yes] % texligatures=yes,texquotes=yes \definefontfeature [smallcaps] [%mode=node,liga=yes, smcp=yes,kern=yes,tlig=yes,trep=yes] % texligatures=yes,texquotes=yes \definefontfeature [oldstyle] [%mode=node, onum=yes,liga=yes,kern=yes,tlig=yes,trep=yes] % texligatures=yes,texquotes=yes \definefontfeature % == default unless redefined [ligatures] [%mode=node, liga=yes,kern=yes,tlig=yes,trep=yes] \definefontfeature % can be used for type1 fonts [complete] [liga=yes,kern=yes,compose=yes,tlig=yes,trep=yes] \definefontfeature [arabic] [mode=node,language=dflt,script=arab,ccmp=yes, init=yes,medi=yes,fina=yes,isol=yes, liga=yes,dlig=yes,rlig=yes,clig=yes,calt=yes, mark=yes,mkmk=yes,kern=yes,curs=yes] \definefontfeature [none] [mode=none,features=no] \definefontfeature [virtualmath] [mode=base,liga=yes,kern=yes,tlig=yes,trep=yes] % for the moment here, this will change but we need it for mk.tex \definefontfeature[math-text] [virtualmath][ssty=no] \definefontfeature[math-script] [virtualmath][ssty=1,mathsize=yes] \definefontfeature[math-scriptscript][virtualmath][ssty=2,mathsize=yes] \definefontfeature [math-nostack-text] [math-text] [nostackmath=yes] \definefontfeature [math-nostack-script] [math-script] [nostackmath=yes] \definefontfeature [math-nostack-scriptscript][math-scriptscript][nostackmath=yes] % \definefontfeature[mathtext] [math-text] % \definefontfeature[mathscript] [math-script] % \definefontfeature[mathscriptscript] [math-scriptscript] %D Also new, handy for manuals: \unexpanded\def\fontchar#1{\ctxlua{fonts.char("#1")}} \let\otfchar\fontchar % will disappear, for compatibility only \let\afmchar\fontchar % will disappear, for compatibility only %D: We cannot yet inherit because no colors are predefined. \definecolor[font:init][r=.75] \definecolor[font:medi][g=.75] \definecolor[font:fina][b=.75] \definecolor[font:isol][r=.75,g=.75] % [y=.75] \definecolor[font:mark][r=.75,b=.75] % [m=.75] \definecolor[font:rest][g=.75,b=.75] % [c=.75] %D Experimental! \def\installfontfeature {\dodoubleargument\doinstallfontfeature} \def\doinstallfontfeature[#1][#2]% {\writestatus\m!fonts{installing font features was experimental}} % \ctxlua{fonts.install_feature("#1","#2")}} %D Not yet in \MKII. \def\fontfeatureslist {\dodoubleargument\dofontfeatureslist} \def\dofontfeatureslist[#1][#2]% todo: arg voor type {\ctxlua{tex.sprint(tex.ctxcatcodes,fonts.define.specify.context_tostring("#1","otf","\luaescapestring{#2}","yes","no",true,{"number"}))}} \attribute\zerocount\zerocount % first in list, so fast match \let\currentfeature\empty % ! ! ! very experimental, some test code for idris advanced features ! ! ! % % \startbuffer % \definefontfeature[smallcaps][smallcaps][script=latn] % \definefontfeature[oldstyle] [oldstyle] [script=latn] % % \definedfont[name:cambria at 15pt] % % Hello there {\setff{smallcaps}capped 123 \setff{oldstyle}123!} \blank % Hello there {\addff{smallcaps}capped 123 \addff{oldstyle}123!} \blank % Hello there {\addff{smallcaps}capped \subff{smallcaps}normal} \blank % \stopbuffer % % \typebuffer \getbuffer \def\featureattribute#1{\ctxlua{tex.sprint(fonts.define.specify.context_number("#1"))}} \def\setfontfeature #1{\edef\currentfeature{#1}\attribute\zerocount\featureattribute{#1}\relax} \def\resetfontfeature#1{\let\currentfeature\empty\attribute\zerocount\zerocount} % initial value \def\addfontfeaturetoset #1{\ctxlua{fonts.withset("#1", 1)}} % merge \def\subtractfontfeaturefromset #1{\ctxlua{fonts.withset("#1",-1)}} % merge \def\addfontfeaturetofont #1{\ctxlua{fonts.withfnt("#1", 2)}} % overload \def\subtractfontfeaturefromfont#1{\ctxlua{fonts.withfnt("#1",-2)}} % overload \let\setff\setfontfeature \let\addfs\addfontfeaturetoset \let\subfs\subtractfontfeaturefromset \let\addff\addfontfeaturetofont \let\subff\subtractfontfeaturefromfont %D The next auxilliary macro is an alternative to \type %D {\fontname}. \def\purefontname#1{\ctxlua{file.basename("\fontname#1"}} % will be function using id %D \macros %D {switchstyleonly} %D %D For switching a style but keeping the alternative, there %D is: %D %D \starttyping %D {\bf text \switchstyleonly\ss text} %D {\bf text \switchstyleonly[ss]text} %D {\sl text \switchstyleonly[sansserif]text} %D \stoptyping \definecomplexorsimple\switchstyleonly \def\simpleswitchstyleonly#1% stupid version {\complexswitchstyleonly[\checkedstrippedcsname#1]} \def\complexswitchstyleonly[#1]% todo : check {\setcurrentfontstyle{\csname\@shortstyle@#1\endcsname}% \the\everybodyfont} % needed ? %D \macros %D {os} %D %D In good old \TEX, the old style numerals were often taken %D from the math fonts. No longer. \definefontfeature [just-os] [mode=node,onum=yes] % \def\sc{\setfontfeature{smallcaps}} \unexpanded\def\os{\setfontfeature{just-os}} %D Code for switching to fraktur and script has also been %D changed. We now have an alphabet switcher. \ifx\mathtext\undefined \let\mathtext\hbox \fi %D \macros %D {definebodyfontswitch} %D %D \PLAIN\ \TEX\ defines some macro's like \type{\tenpoint} %D to switch to a specific bodyfontsize. Just for the sake of %D compatibility we can define them like: %D %D \starttyping %D \definebodyfontswitch [twelvepoint] [12pt] %D \stoptyping %D %D We don't support language specific synonyms here, mainly %D because \PLAIN\ \TEX\ is english anyway. \def\dodefinebodyfontswitch[#1][#2]% {\def\docommand##1{\setvalue{##1}{\switchtobodyfont[#2]}}% \processcommalist[#1]\docommand} \unexpanded\def\definebodyfontswitch {\dodoubleargument\dodefinebodyfontswitch} %D \macros %D {setsmallbodyfont,setmainbodyfont,setbigbodyfont} %D %D When we're typesetting at for instance 10pt, we can call for %D the \type{small} as well as the \type{big} alternative, %D related to this main size, using \type{\switchtobodyfont[small]}. %D The three alternatives can be activated by the next three %D system calls and are defined by the bodyfontenvironment. \let\fontstep\empty % we can use \fontstep for tracing purposes \def\setbodyfontstep#1% {\edef\fontstep{\csname\bodyfontvariable\normalizedbodyfontsize\interfaced{#1}\endcsname}% \doswitchpoints[\fontstep]% \doswitchstyle[\fontstyle]} \unexpanded\def\setsmallbodyfont{\setbodyfontstep\v!small\the\everybodyfont} \unexpanded\def\setbigbodyfont {\setbodyfontstep\v!big \the\everybodyfont} \unexpanded\def\setmainbodyfont {\doswitchpoints[\normalizedbodyfontsize]% \doswitchstyle[\fontstyle]% \the\everybodyfont \the\everyglobalbodyfont \saveinterlinespace} %D \macros %D {restoreglobalbodyfont} %D %D Users can set whatever font available while typesetting text. %D Pagenumbers, footers, headers etc. however must be typeset %D in the main bodyfont and style of the document. Returning to %D the global state can be done with the next macro: \let\globalfontstyle\c!rm \def\fullrestoreglobalbodyfont {\let\fontsize\defaultfontsize \let\fontbody\defaultfontbody \chardef\currentxfontsize\zerocount \let\fontclass\globalfontclass \doswitchpoints[\normalizedglobalbodyfontsize]% \doswitchstyle[\globalfontstyle]% \redoconvertfont % just in case a pagebreak occurs \tf \the\everybodyfont \the\everyglobalbodyfont \saveinterlinespace} \def\partialrestoreglobalbodyfont {\let\fontsize\defaultfontsize \let\fontbody\defaultfontbody \chardef\currentxfontsize\zerocount \redoconvertfont \tf \the\everybodyfont % indeed needed \the\everyglobalbodyfont % indeed needed \saveinterlinespace} \def\restoreglobalbodyfont % ook style etc {\ifx\fontclass\globalfontclass \ifx\fontstyle\globalfontstyle \ifx\normalizedbodyfontsize\normalizedglobalbodyfontsize \partialrestoreglobalbodyfont \else \fullrestoreglobalbodyfont \fi \else \fullrestoreglobalbodyfont \fi \else \fullrestoreglobalbodyfont \fi} % in case of troubles: \let\restorebodyfont\fullrestoreglobalbodyfont %D This macro has to be called when entering the pagebody %D handling routine as well as the footnote insert routine. %D Users can access this feature |<|for instance when one wants %D to typeset tables and alike in the main bodyfont and style %D while the running text is temporary set to a smaller one|>| %D by saying \type{\switchtobodyfont[global]}. %D \macros %D {rasterfont} %D %D There are (at the moment) two situations in which we want to %D have fast access to a particular font. When we are using %D \TEX\ to typeset rasters, we use small {\rasterfont.}'s %D (a rather small period indeed), the same as \PICTEX\ uses %D for drawing purposes. \definefont [rasterfont] [Serif at 5pt] %D \macros %D {infofont} %D %D The second situation occurs when we enable the info mode, %D and put all kind of status information in the margin. We %D don't want huge switches to the main bodyfont and style, so %D here too we use a direct method. \let\infofont\relax % satisfy dep checker \definefont [infofont] [Mono at 6pt] % todo \the\everybodyfont %D \macros %D {definealternativestyle} %D %D In the main modules we are going to implement lots of %D parameterized commands and one of these parameters will %D concern the font to use. To suit consistent use of fonts we %D here implement a mechanism for defining the keywords that %D present a particular style or alternative. %D %D \starttyping %D \definealternativestyle [keywords] [\style] [\nostyle] %D \stoptyping %D %D The first command is used in the normal textflow, while the %D second command takes care of headings and alike. Consider %D the next two definitions: %D %D \starttyping %D \definealternativestyle [bold] [\bf] [] %D \definealternativestyle [cap] [\cap] [\cap] %D \stoptyping %D %D A change \type{\bf} in a heading which is to be set in %D \type{\tfd} does not look that well, so therefore we leave %D the second argument of \type{\definealternativestyle} empty. %D When we capatalize characters using the pseudo small cap %D command \type{\cap}, we want this to take effect in both %D text and headings, which is accomplished by assigning both %D arguments. \def\dodefinealternativestyle[#1][#2][#3]% {\def\docommand##1% {\ifcsname##1\endcsname\else\setuvalue{##1}{\groupedcommand{#2}{}}\fi \setvalue{\@letter@ ##1}{#2}% \setvalue{\@noletter@##1}{#3}}% \processcommalist[#1]\docommand} \unexpanded\def\definealternativestyle {\dotripleempty\dodefinealternativestyle} \unexpanded\def\definestyle{\definealternativestyle} %D Maybe too geneneric, but probably ok is the following. (Maybe one %D day we will use a dedicated grouped command for styles.) \appendtoks \let\groupedcommand\thirdofthreearguments \to \simplifiedcommands %D This command also defines the keyword as command. This means %D that the example definition of \type{bold} we gave before, %D results in a command \type{\bold} which can be used as: %D %D \startbuffer %D He's a \bold{bold} man with a {\bold head}. %D \stopbuffer %D %D \typebuffer %D %D or %D %D \startvoorbeeld %D \definealternativestyle[bold][\bf][]\getbuffer %D \stopvoorbeeld %D %D Such definitions are of course unwanted for \type{\cap} %D because this would result in an endless recursive call. %D Therefore we check on the existance of both the command and %D the substitution. The latter is needed because for instance %D \type{\type} is an entirely diferent command. That command %D handles verbatim, while the style command would just switch %D to teletype font. This is just an example of a tricky %D naming coincidence. %D \macros %D {doconvertfont,noconvertfont, %D dontconvertfont,redoconvertfont} %D %D After having defined such keywords, we can call for them by %D using %D %D \starttyping %D \doconvertfont{keyword}{text} %D \stoptyping %D %D We deliberately pass an argument. This enables us to %D assign converters that handle one argument, like %D \type{\cap}. %D %D By default the first specification is used to set the style, %D exept when we say \type{\dontconvertfont}, after which the %D second specification is used. We can also directly call for %D \type{\noconvertfont}. In nested calls, we can restore the %D conversion by saying \type{\redoconvertfont}. % subtle ... \expandafter is needed else problems with lookahead caps \def\@@dodoconvertfont{\csname\@letter@ \p!defined\expandafter\endcsname\gobbleoneargument} \def\@@donoconvertfont{\csname\@noletter@\p!defined\endcsname} \def\@@redoconvertfont{\csname \p!defined\expandafter\endcsname\gobbleoneargument} % beware: p!defined can contain crap like \edef crap {...} and such % so we need to pass #1 as well \unexpanded\def\dodoconvertfont#1% #2% we need the protection {\edef\p!defined{#1}% \ifx\p!defined\empty\else \@EA\dododoconvertfont \fi{#1}} \def\dododoconvertfont % #1 {\ifcsname\@letter@\detokenize\@EA{\p!defined}\endcsname \@EA\@@dodoconvertfont \else\ifcsname\detokenize\@EA{\p!defined}\endcsname \@EAEAEA\@@redoconvertfont \else \@EAEAEA\firstofoneargument \fi\fi} % {#1} \let\doconvertfont\dodoconvertfont \unexpanded\def\noconvertfont#1% #2% {\edef\p!defined{#1}% \ifx\p!defined\empty \else \@EA\nononoconvertfont \fi} \def\nononoconvertfont {\ifcsname\@noletter@\detokenize\@EA{\p!defined}\endcsname \@EA\@@donoconvertfont \fi} %D Extras: \unexpanded\def\dontconvertfont{\let\doconvertfont\noconvertfont} \unexpanded\def\redoconvertfont{\let\doconvertfont\dodoconvertfont} %D These commands are not grouped! Grouping is most probably %D done by the calling macro's and would lead to unnecessary %D overhead. %D \macros %D {em,emphasistypeface,emphasisboldface} %D %D The next macro started as a copy of Donald Arseneau's %D \type{\em} (\TUGNEWS\ Vol.~3, no.~1, 1994). His %D implementation was a bit more sophisticated version of the %D standard \LATEX\ one. We furter enhanced the macro, so now %D it also adapts itself to boldface mode. Because we favor %D {\sl slanted} type over {\it italic}, we made the emphasis %D adaptable, for instance: %D %D \starttyping %D \def\emphasistypeface {\it} %D \def\emphasisboldface {\bi} %D \stoptyping %D %D But we prefer: \def\emphasistypeface {\sl} \def\emphasisboldface {\bs} %D or even better: \def\doemphasistypeface#1#2% {\edef\emphasizedtypeface{\csname\??ft\fontclass\normalizedbodyfontsize\c!em\endcsname}% \ifx\emphasizedtypeface\v!slanted #1% \else\ifx\emphasizedtypeface\v!italic #2% \else\ifx\emphasizedtypeface\v!empty \edef\emphasizedtypeface{\csname\??ft\normalizedbodyfontsize\c!em\endcsname}% \ifx\emphasizedtypeface\v!slanted #1% \else\ifx\emphasizedtypeface\v!italic #2% \else \getvalue\emphasizedtypeface \fi\fi \else \getvalue\emphasizedtypeface \fi\fi\fi} \def\emphasistypeface{\doemphasistypeface\sl\it} \def\emphasisboldface{\doemphasistypeface\bs\bi} %D To be set with the default body font environment: \type %D {em} being \type {slanted} or \type {italic}. \newconditional\emneeded \newtoks\everyemphasized \unexpanded\def\em {\relax \ifdim\slantperpoint>\zeropoint \settrue\emneeded \else \setfalse\emneeded \fi \setemphasisboldface % new \ifx\fontalternative\c!it \def\emphasistypeface{\it}\tf \else\ifx\fontalternative\c!sl \def\emphasistypeface{\sl}\tf \else\ifx\fontalternative\c!bf \emphasisboldface \else\ifx\fontalternative\c!bs \def\emphasisboldface{\bs}\bf \else\ifx\fontalternative\c!bi \def\emphasisboldface{\bi}\bf \else \emphasistypeface \fi\fi\fi\fi\fi \the\everyemphasized \ifconditional\emneeded\relax \else \expandafter\aftergroup \fi \emphasiscorrection} % compare ... % % \appendtoks \red \to \everyemphasized % \setupbodyfontenvironment [default] [em={\italic\color[red]}] %D The next feature was not present in previous versions. It %D takes care of \type {\em \bf ...} sitiations. \def\setemphasisboldface {\let\savedemphasisboldface\bf \let\setemphasisboldface\relax \unexpanded\def\bf {%\relax \let\bf\relax % new \ifx\fontalternative\c!it \bi \else\ifx\fontalternative\c!sl \bs \else \savedemphasisboldface \fi\fi \let\bf\savedemphasisboldface}} %D Donald's (adapted) macros take the next character into %D account when placing italic correction. As a bonus we also %D look for something that looks like a dash, in which case we %D don't correct. \let\italiccorrection=\/ % tex primitive \def\emphasiscorrection {\ifhmode \expandafter\emphasislook \fi} \def\emphasislook {\begingroup \futurelet\next\emphasistest} \def\emphasistest {\ifcat\noexpand\next,% still ok? \expandafter\doemphasiscorrection \else \expandafter\dododoemphasiscorrection \fi} \def\doemphasiscorrection {\futurelet\next\dodoemphasiscorrection} \def\dodoemphasiscorrection {\setbox\scratchbox\hbox{\next}% \ifdim\ht\scratchbox=\zeropoint % probably a space \expandafter\dododoemphasiscorrection \else\ifdim\ht\scratchbox<.3ex \expandafter\expandafter\expandafter\endgroup \else \expandafter\expandafter\expandafter\dododoemphasiscorrection \fi\fi} \def\dododoemphasiscorrection {\scratchskip\lastskip \ifdim\scratchskip=\zeropoint\relax % == \ifzeropt\scratchskip \italiccorrection\relax \else \unskip\italiccorrection\hskip\scratchskip \fi \endgroup} %D We end with some examples which show the behavior when %D some punctuation is met. We also show how the mechanism %D adapts itself to bold, italic and slanted typing. %D %D \startbuffer %D test {test}test \par %D test {\sl test}test \par %D test {\em test}test \par %D test {\em test}--test \par %D %D test {test}, test \par %D test {\em test}, test \par %D %D test {\em test {\em test {\em test} test} test} test \par %D test {\bf test {\em test {\em test} test} test} test \par %D test {\sl test {\em test {\em test} test} test} test \par %D test {\it test {\em test {\em test} test} test} test \par %D \stopbuffer %D %D \typebuffer %D %D We get: %D %D \startvoorbeeld %D \startpacked %D \getbuffer %D \stoppacked %D \stopvoorbeeld %D \macros %D {emphbf,emphit,emphsl,emphtf} %D %D The next emphasis alternatives are for \THANH. They adapt %D their style as good as possible. \def\emphbf{\groupedcommand{\bf\def\emphit{\bi}\def\emphsl{\bs}}{}} \def\emphit{\groupedcommand{\it\def\emphbf{\bi}\def\emphsl{\sl}}{}} \def\emphsl{\groupedcommand{\sl\def\emphbf{\bs}\def\emphit{\it}}{}} \def\emphtf{\groupedcommand{\tf\def\emphbf{\bf}\def\emphit{\it}\def\emphsl{\sl}}{}} %D \startbuffer %D TEXT {\emphbf text \emphit text \emphtf text \emphsl text} TEXT %D TEXT \emphbf{text \emphit{text} \emphtf{text} \emphsl{text}} TEXT %D \stopbuffer %D %D \typebuffer %D \startlines %D \getbuffer %D \stoplines %D \macros %D {setfont} %D %D Every now and then we want to define a font directly, for %D instance when we typeset title pages. The next macro saves %D some typing: \def\setfont% geen \dosetfont mogelijk {\def\next{\nextfont\setupinterlinespace}% hm, we need to use \setuplocalinterlinespace \afterassignment\next\font\nextfont=} %D One can call this macro as: %D %D \starttyping %D \setfont cmr10 at 60pt %D \stoptyping %D %D After which the font is active and the baselines and %D struts are set. %D \macros %D {showbodyfont} %D %D One can call for a rather simple overview of a bodyfont and the %D relations between its alternative fonts. %D %D \showsetup{showbodyfont} %D %D The current bodyfont (here we omitted the argument) looks like: %D %D \showbodyfont %D %D The implementation is rather straightforward in using %D \type{\halign}. \fetchruntimecommand \showbodyfont {\f!fontprefix\s!run.mkiv} %D \macros %D {showfontstrip, testminimalbaseline, showminimalbaseline} %D %D The next command can come in handy when combining %D different fonts into a collection (typeface) and %D determining optimal baseline distances. %D %D \showfontstrip \blank \showminimalbaseline \fetchruntimecommand \showfontstrip {\f!fontprefix\s!run.mkiv} \fetchruntimecommand \testminimalbaseline {\f!fontprefix\s!run.mkiv} \fetchruntimecommand \showminimalbaseline {\f!fontprefix\s!run.mkiv} %D \macros %D {showkerning} %D %D A goody is: %D %D \showkerning{Can you guess what kerning is?} \fetchruntimecommand \showkerning {\f!fontprefix\s!run.mkiv} %D \macros %D {showbodyfontenvironment} %D %D The current bodyfontenvironment is: %D %D \showbodyfontenvironment %D %D This overview is generated using: %D %D \showsetup{showbodyfontenvironment} \fetchruntimecommand \showbodyfontenvironment {\f!fontprefix\s!run.mkiv} %D \macros %D {showfont,showfontstyle,showligatures} %D %D The following command generates a fontmap: %D %D \startbuffer %D \showfont[SansBold at 12pt] %D \stopbuffer %D %D \typebuffer %D \getbuffer % to be internationalized \fetchruntimecommand \showfont {\f!fontprefix\s!run.mkiv} \fetchruntimecommand \showfontstyle {\f!fontprefix\s!run.mkiv} \fetchruntimecommand \showligature {\f!fontprefix\s!run.mkiv} \fetchruntimecommand \showligatures {\f!fontprefix\s!run.mkiv} \fetchruntimecommand \showcharratio {\f!fontprefix\s!run.mkiv} %D \macros %D {getglyph, symbolicfont} %D %D Individual glyphs can be accessed by using %D %D \starttyping %D \getglyph{fontname}{character} %D \stoptyping %D %D This macro is used in for instance the symbol modules and %D as one can see, it does obey the small and even smaller %D sizes. The \type {\symbolicfont} macro can be used to %D switch to a font named \type {fontname} (see \type %D {cont-log} and \type {symb-eur} for examples of symbolic %D definitions. \def\fontstringA {\ifx\fontstyle\c!rm \s!Serif \else \ifx\fontstyle\c!ss \s!Sans \else \ifx\fontstyle\c!tt \s!Mono \else \s!Serif \fi\fi\fi} \def\fontstringB {\ifx\fontstyle\c!rm \s!Regular \else \ifx\fontstyle\c!ss \s!Support \else \ifx\fontstyle\c!tt \s!Type \else \s!Serif \fi\fi\fi} \def\fontstringC {\ifx\fontalternative\c!bf \s!Bold \else \ifx\fontalternative\c!sl \s!Slanted \else \ifx\fontalternative\c!it \s!Italic \else \ifx\fontalternative\c!bs \s!BoldSlanted \else \ifx\fontalternative\c!bi \s!BoldItalic \fi\fi\fi\fi\fi} \def\fontstringD % default fontstyle {\expandafter\ifx\csname\??tf\fontclass\s!default\endcsname\c!rm \s!Serif \else \expandafter\ifx\csname\??tf\fontclass\s!default\endcsname\c!ss \s!Sans \else \expandafter\ifx\csname\??tf\fontclass\s!default\endcsname\c!tt \s!Mono \else \s!Serif \fi\fi\fi} % potential generalization: % \letvalue{\??ff:t:\c!rm}\s!Serif % \letvalue{\??ff:t:\c!ss}\s!Sans % \letvalue{\??ff:t:\c!tt}\s!Mono % % \letvalue{\??ff:s:\c!bf}\s!Bold % \letvalue{\??ff:s:\c!sl}\s!Slanted % \letvalue{\??ff:s:\c!it}\s!Italic % \letvalue{\??ff:s:\c!bs}\s!BoldSlanted % \letvalue{\??ff:s:\c!bi}\s!BoldItalic % % \letvalue{\??ff:a:\c!rm}\s!Regular % \letvalue{\??ff:a:\c!ss}\s!Support % \letvalue{\??ff:a:\c!tt}\s!Type % % \def\fontstringA{\executeifdefined{\??ff:t:\fontstyle}\s!Serif} % \def\fontstringB{\executeifdefined{\??ff:a:\fontstyle}\s!Serif} % \def\fontstringC{\executeifdefined{\??ff:s:\fontstyle}\empty} % \def\fontstringD{\executeifdefined{\??ff:t:\csname\??tf\fontclass\s!default\endcsname}\s!Serif} \def\glyphfontfile#1% {#1% \ifcsname\??ff#1\fontstringA\fontstringC\endcsname \fontstringA\fontstringC \else\ifcsname\??ff#1\fontstringB\fontstringC\endcsname \fontstringB\fontstringC \else\ifcsname\??ff#1\fontstringA\endcsname \fontstringA \else\ifcsname\??ff#1\fontstringB\endcsname \fontstringB \else\ifcsname\??ff#1\fontstringC\endcsname \fontstringC \fi\fi\fi\fi\fi} %D The next macro can be used to make decisions based on the shape: \def\doifitalicelse#1#2% {\ifx\fontalternative\c!sl#1\else \ifx\fontalternative\c!it#1\else \ifx\fontalternative\c!bs#1\else \ifx\fontalternative\c!bi#1\else#2\fi\fi\fi\fi} %D For an example of usage of the following command, %D see \type {cont-log.tex}. %D %D \starttyping %D \def\symbolicfont#1{\definedfont[\glyphfontfile{#1} sa *]} %D \stoptyping %D %D Since we know what scaling it to be applied, we can %D implement a much faster alternative: \let\thedefinedfont\relax \def\symbolicsizedfont#1#2#3% {\scaledfontsize#1% \scaledfontsize#2\scaledfontsize \font\thedefinedfont=\truefontname{\glyphfontfile{#3}} at \currentfontbodyscale\scaledfontsize\relax \thedefinedfont} \def\symbolicscaledfont {\symbolicsizedfont\fontbody} \unexpanded\def\symbolicfont {\symbolicsizedfont\fontbody\plusone} \unexpanded\def\getglyph#1#2% slow, faster, much faster %{{\definefont[\s!dummy][\glyphfontfile{#1} sa \currentfontscale]\dummy#2}} %{{\definefont[\s!dummy][\glyphfontfile{#1} sa *]\dummy#2}} %{{\symbolicfont{#1}#2}} {{\symbolicfont{#1}\doifnumberelse{#2}\char\donothing#2}} \unexpanded\def\getscaledglyph#1#2#3% {{\symbolicscaledfont{#1}{#2}\doifnumberelse{#3}\char\donothing#3}} \unexpanded\def\getrawglyph#1#2% for simple symbols {{\scaledfontsize\fontbody \font\thedefinedfont=#1 at \currentfontbodyscale\scaledfontsize\relax \thedefinedfont\doifnumberelse{#2}\char\donothing#2}} %D The last implementation of \type {\getglyph} permits %D definitions like: %D %D \starttyping %D \definefontsynonym [EuroSans] [eurose] %D \definefontsynonym [EuroSansBold] [euroseb] %D \definefontsynonym [EuroSansItalic] [eurosei] %D \definefontsynonym [EuroSansSlanted] [eurosei] %D \definefontsynonym [EuroSansBoldItalic] [eurosebi] %D \definefontsynonym [EuroSansBoldSlanted] [eurosebi] %D %D \definesymbol [euro] [\getglyph{Euro}{\char160}] %D %D \def\euro{\symbol[euro]} %D \stoptyping %D %D These definitions guarantee that the next calls work okay: %D %D \starttyping %D \ss \tf\euro \bf\euro \sla\euro \itd\euro \bs\euro \bic\euro %D \stoptyping %D %D The shape as well as the size is adapted to the current %D environment. %D \macros %D {ss, SS, sz} %D %D We are going to redefine \type{\ss} but for those wo still %D want to have access to the german \SS, we save it's value in %D \type{\SS}. Ok, I should have used \type{\sf} instead of %D \type{\ss} in the first place. \ifx\undefined\SS \let\SS=\ss \fi \ifx\undefined\sz \let\sz=\ss \fi %D Personally I think that using \TEX\ macro packages is %D complicated by the way fonts are handled. Apart from the %D many encodings, we also deal with different naming schemes. %D Confronted with this problem, I decided to change the %D definitions into: %D %D \starttyping %D \definebodyfont [12pt] [rm] [tf=Times-Roman at 12pt] %D \stoptyping %D %D combined with for instance: %D %D \starttyping %D \definefontsynonym [Times-Roman] [tir] %D \stoptyping %D Now we're up to some definitions. \definebodyfontenvironment [\s!default] [ \s!text=1.0, \s!script=0.7, \s!scriptscript=0.5, \c!a=1.200, \c!b=1.440, \c!c=1.728, \c!d=2.074, *=\currentfontscale, % wildcard \c!x=0.8, \c!xx=0.6, \c!big=1.2, \c!small=0.8, \c!interlinespace=, \c!em=\v!slanted] \definebodyfontenvironment [20.7pt] [ \s!text=20.7pt, \s!script=\!!fourteenpointfour, \s!scriptscript=\!!twelvepoint, \c!x=17.3pt, \c!xx=\!!fourteenpointfour, \c!big=20.7pt, % !!!! \c!small=17.3pt] \definebodyfontenvironment [17.3pt] [ \s!text=17.3pt, \s!script=\!!twelvepoint, \s!scriptscript=\!!tenpoint, \c!x=\!!fourteenpointfour, \c!xx=\!!twelvepoint, \c!big=20.7pt, \c!small=\!!fourteenpointfour] \definebodyfontenvironment [\!!fourteenpointfour] [ \s!text=\!!fourteenpointfour, \s!script=\!!elevenpoint, \s!scriptscript=\!!ninepoint, \c!x=\!!twelvepoint, \c!xx=\!!tenpoint, \c!big=17.3pt, \c!small=\!!twelvepoint] \definebodyfontenvironment [\!!twelvepoint] [ \s!text=\!!twelvepoint, \s!script=\!!ninepoint, \s!scriptscript=\!!sevenpoint, \c!x=\!!tenpoint, \c!xx=\!!eightpoint, \c!big=\!!fourteenpointfour, \c!small=\!!tenpoint] \definebodyfontenvironment [\!!elevenpoint] [ \s!text=\!!elevenpoint, \s!script=\!!eightpoint, \s!scriptscript=\!!sixpoint, \c!x=\!!ninepoint, \c!xx=\!!sevenpoint, \c!big=\!!twelvepoint, \c!small=\!!ninepoint] \definebodyfontenvironment [\!!tenpoint] [ \s!text=\!!tenpoint, \s!script=\!!sevenpoint, \s!scriptscript=\!!fivepoint, \c!x=\!!eightpoint, \c!xx=\!!sixpoint, \c!big=\!!twelvepoint, \c!small=\!!eightpoint] \definebodyfontenvironment [\!!ninepoint] [ \s!text=\!!ninepoint, \s!script=\!!sevenpoint, \s!scriptscript=\!!fivepoint, \c!x=\!!sevenpoint, \c!xx=\!!fivepoint, \c!big=\!!elevenpoint, \c!small=\!!sevenpoint] \definebodyfontenvironment [\!!eightpoint] [ \s!text=\!!eightpoint, \s!script=\!!sixpoint, \s!scriptscript=\!!fivepoint, \c!x=\!!sixpoint, \c!xx=\!!fivepoint, \c!big=\!!tenpoint, \c!small=\!!sixpoint] \definebodyfontenvironment [\!!sevenpoint] [ \s!text=\!!sevenpoint, \s!script=\!!sixpoint, \s!scriptscript=\!!fivepoint, \c!x=\!!sixpoint, \c!xx=\!!fivepoint, \c!big=\!!ninepoint, \c!small=\!!fivepoint] \definebodyfontenvironment [\!!sixpoint] [ \s!text=\!!sixpoint, \s!script=\!!fivepoint, \s!scriptscript=\!!fivepoint, \c!x=\!!fivepoint, \c!xx=\!!fivepoint, \c!big=\!!eightpoint, \c!small=\!!fivepoint] \definebodyfontenvironment [\!!fivepoint] [ \s!text=\!!fivepoint, \s!script=\!!fivepoint, \s!scriptscript=\!!fivepoint, \c!x=\!!fivepoint, \c!xx=\!!fivepoint, \c!big=\!!sevenpoint, \c!small=\!!fivepoint] \definebodyfontenvironment [\!!fourpoint] [ \s!text=\!!fourpoint, \s!script=\!!fourpoint, \s!scriptscript=\!!fourpoint, \c!x=\!!fourpoint, \c!xx=\!!fourpoint, \c!big=\!!sixpoint, \c!small=\!!fourpoint] \definebodyfontswitch [fourteenpointfour] [\!!fourteenpointfour] \definebodyfontswitch [twelvepoint] [\!!twelvepoint] \definebodyfontswitch [elevenpoint] [\!!elevenpoint] \definebodyfontswitch [tenpoint] [\!!tenpoint] \definebodyfontswitch [ninepoint] [\!!ninepoint] \definebodyfontswitch [eightpoint] [\!!eightpoint] \definebodyfontswitch [sevenpoint] [\!!sevenpoint] \definebodyfontswitch [sixpoint] [\!!sixpoint] \definebodyfontswitch [fivepoint] [\!!fivepoint] \definebodyfontswitch [fourpoint] [\!!fourpoint] % \definebodyfontswitch [xii] [\!!twelvepoint] % \definebodyfontswitch [xi] [\!!elevenpoint] % \definebodyfontswitch [x] [\!!tenpoint] % \definebodyfontswitch [ix] [\!!ninepoint] % \definebodyfontswitch [viii] [\!!eightpoint] % \definebodyfontswitch [vii] [\!!sevenpoint] % \definebodyfontswitch [vi] [\!!sixpoint] %D So far. \definefontstyle [\c!mm] [\c!mm] \definefontstyle [\c!rm,\v!roman,\v!serif,\v!regular] [\c!rm] \definefontstyle [\c!ss,\v!sansserif,\v!sans,\v!support] [\c!ss] \definefontstyle [\c!tt,\v!teletype,\v!type,\v!mono] [\c!tt] \definefontstyle [\c!hw,\v!handwritten] [\c!hw] \definefontstyle [\c!cg,\v!calligraphic] [\c!cg] \definefontalternative[\c!tf] \definefontalternative[\c!bf] \definefontalternative[\c!it] \definefontalternative[\c!sl] \definefontalternative[\c!bs] \definefontalternative[\c!bi] \definefontalternative[\c!sc] \definefontsize[\c!a] \definefontsize[\c!b] \definefontsize[\c!c] \definefontsize[\c!d] \definealternativestyle [\v!mediaeval] [\os] [] \definealternativestyle [\v!normal] [\tf] [] \definealternativestyle [\v!bold] [\bf] [] \definealternativestyle [\v!type] [\tt] [] \definealternativestyle [\v!mono] [\tt] [] \definealternativestyle [\v!slanted] [\sl] [] \definealternativestyle [\v!italic] [\it] [] \definealternativestyle [\v!boldslanted,\v!slantedbold] [\bs] [] \definealternativestyle [\v!bolditalic,\v!italicbold] [\bi] [] \definealternativestyle [\v!small,\v!smallnormal] [\tfx] [] \definealternativestyle [\v!smallbold] [\bfx] [] \definealternativestyle [\v!smalltype] [\ttx] [] \definealternativestyle [\v!smallslanted] [\slx] [] \definealternativestyle [\v!smallboldslanted,\v!smallslantedbold] [\bsx] [] \definealternativestyle [\v!smallbolditalic,\v!smallitalicbold] [\bix] [] \definealternativestyle [\v!sans,\v!sansserif] [\ss] [] \definealternativestyle [\v!sansbold] [\ss\bf] [] %D Slow but handy: \definealternativestyle [\v!smallbodyfont] [\setsmallbodyfont] [] \definealternativestyle [\v!bigbodyfont] [\setbigbodyfont] [] %D We treat {\sc Small Caps} and \cap {Pseudo Caps} a bit %D different. We also provide an \WORD {uppercase} style. \definealternativestyle [\v!cap,\v!capital] [\smallcapped] [\smallcapped] \definealternativestyle [\v!smallcaps] [\sc] [\sc] \definealternativestyle [\v!WORD] [\WORD] [\WORD] %D \macros %D {fontstylesuffix} %D %D The next macro is used to map non latin fontnames on %D fonts. See \type {font-uni} for an example of its use. \def\fontstylesuffix% why the \s!Regular ? see \getglyph {\ifx\fontalternative\c!tf \s!Regular \else \ifx\fontalternative\c!bf \s!Bold \else \ifx\fontalternative\c!sl \s!Slanted \else \ifx\fontalternative\c!it \s!Italic \else \ifx\fontalternative\c!bs \s!BoldSlanted \else \ifx\fontalternative\c!bi \s!BoldItalic \else \ifx\fontalternative\c!sc \s!Caps \else \s!Regular \fi\fi\fi\fi\fi\fi\fi}% %D \macros %D {definefontvariant,fontvariant,variant} %D %D This command is obsolete in \MKIV\ as we have features. It might %D come back using the local features handlers. \unexpanded\def\definefontvariant{\dotripleargument\dodefinefontvariant} \def\dodefinefontvariant[#1][#2][#3]{} \def\variant [#1]{} \ifdefined\Var\else \let\Var\variant \fi %D By default we load the Computer Modern Roman fonts (but %D not yet at this moment) and activate the 12pt roman %D bodyfont. Sans serif and teletype are also available and %D can be called for by \type{\ss} and \type{\tt}. Loading %D takes place elsewhere. %D %D For tracing purposes we define: \definefont[tinyfont][Mono at 1ex] % \tracinglostchars=1 % this needs some interfacing % % \setupfonts[check=...] \def\checkcharactersinfont {\ctxlua{fonts.checkers.enable()}} \def\removemissingcharacters{\ctxlua{fonts.checkers.enable(true)}} %D New commands (not yet interfaced): \def\style[#1]% for inline usage, like \color {\groupedcommand{\ifcsname#1\endcsname\csname#1\endcsname\else\definedfont[#1]\fi}{}} \unexpanded\def\startstyle[#1]% {\begingroup \ifcsname#1\endcsname\csname#1\endcsname\else\definedfont[#1]\fi} \unexpanded\def\stopstyle {\endgroup} %D Still experimental (might even go away). % \definestylecollection[mine] % \definestyleinstance[mine][default][sorry] % \definestyleinstance[mine][tt][bs][ttbs:\rm\sl] % \definestyleinstance[mine][tt][bf][ttbf:\rm\sl] % \definestyleinstance[mine][bf][\sl] % \definestyleinstance[mine][sl][\tt] % {\bf test \mine test \sl test \mine test \bs oeps \mine oeps {\tt test \mine \bf test}} \unexpanded\def\definestylecollection {\dosingleargument\dodefinestylecollection} \def\dodefinestylecollection[#1]% {\iffirstargument \setuvalue{#1}{\styleinstance[#1]}% \def\docommand##1% {\def\dodocommand####1{\letbeundefined{\??sx##1:####1:\commalistelement}}% \processcommacommand[\fontalternativelist,\s!default]\dodocommand}% \processcommacommand[\fontstylelist,\s!default]\docommand \fi} \unexpanded\def\definestyleinstance {\doquadrupleargument\dodefinestyleinstance} \def\dodefinestyleinstance[#1][#2][#3][#4]% [name] [rm|ss|tt|..] [sl|bf|...] [whatever] {\iffirstargument \ifcsname#1\endcsname\else\definestylecollection[#1]\fi \fi \iffourthargument \setvalue{\??sx#1:#2:#3}{#4}% \else\ifthirdargument \setvalue{\??sx#1::#2}{#3}% \else\ifsecondargument \letvalue{\??sx#1::#2}\empty \fi\fi\fi} \unexpanded\def\styleinstance[#1]% will be made faster {%\begingroup\normalexpanded{\noexpand\infofont[#1:\fontstyle:\fontalternative]}\endgroup \executeifdefined{\??sx#1:\fontstyle:\fontalternative}% {\executeifdefined{\??sx#1:\fontstyle:\s!default}% {\executeifdefined{\??sx#1::\fontalternative} {\getvalue {\??sx#1::\s!default}}}}} % \unexpanded\def\styleinstance[#1]% % {\csname\??sx#1% % \ifcsname:\fontstyle:\fontalternative\endcsname % :\fontstyle:\fontalternative % \else\ifcsname:\fontstyle:\s!default\endcsname % :\fontstyle:\s!default % \else\ifcsname::\fontalternative\endcsname % ::\fontalternative % \else\ifcsname::\s!default\endcsname % ::\s!default % \else % % nothing, \relax % \fi\fi\fi\fi % \endcsname} %D goodies: \def\showchardata#1{\ctxlua{fonts.show_char_data("#1")}} \def\showfontdata {\ctxlua{fonts.show_font_parameters()}} %D some low level helpers %D %D \starttyping %D \def\TestLookup#1% %D {\dolookupfontbyspec{#1} %D pattern: #1, found: \dolookupnoffound %D \blank %D \dorecurse {\dolookupnoffound} {% %D \recurselevel:~\dolookupgetkeyofindex{fontname}{\recurselevel}\quad %D }% %D \blank} %D %D \TestLookup{familyname=helveticaneue} %D \TestLookup{familyname=helveticaneue,weight=bold} %D \TestLookup{familyname=helveticaneue,weight=bold,style=italic} %D \stoptyping % we can also move the lookups to the fonts.namespace (of commands) \def\dolookupfontbyspec #1{\ctxlua{fonts.names.lookup("#1")}} \def\dolookupnoffound {\ctxlua{tex.write(fonts.names.noflookups())}} \def\dolookupgetkeyofindex#1#2{\ctxlua{tex.write(fonts.names.getlookupkey("#1",#2))}} \def\dolookupgetkey #1{\ctxlua{tex.write(fonts.names.getlookupkey("#1"))}} \def\cleanfontname #1{\ctxlua{fonts.cleanname("#1")}} \protect \endinput % \startluacode % function commands.doifelsecurrentfonthasfeature(name) % local f = fonts.ids[font.current()] % f = f and f.shared % f = f and f.otfdata % f = f and f.luatex % f = f and f.features % commands.doifelse(f and (f.gpos[name] or f.gsub[name])) % end % \stopluacode % \def\doifelsecurrentfonthasfeature#1% % {\ctxlua{commands.doifelsecurrentfonthasfeature("#1")}} % \doifelsecurrentfonthasfeature{smcp}{YES}{NO} % \doifelsecurrentfonthasfeature{crap}{YES}{NO} % \doifelsecurrentfonthasfeature{kern}{YES}{NO}