%D \module %D [ file=font-xtx, %D version=2004.09.11, %D title=\CONTEXT\ Font Macros, %D subtitle=\XETEX\ Hacks, %D author=Hans Hagen, %D date=\currentdate, %D copyright={PRAGMA ADE \& \CONTEXT\ Development Team}] %C %C This module is part of the \CONTEXT\ macro||package and is %C therefore copyrighted by \PRAGMA. See mreadme.pdf for %C details. \ifnum\texengine=\xetexengine \writestatus{loading}{ConTeXt Font Macros / XeTeX Hacks} \else \endinput \fi \unprotect %D Features: % \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 \def\definefontfeature {\dotripleargument\dodefinefontfeature} \def\dododefinefontfeature#1% {\edef\!!stringa{\ifx\!!stringa\empty\else\!!stringa,\fi\executeifdefined{\??fa#1}\empty}} \def\dodefinefontfeature[#1][#2][#3]% {\doifassignmentelse{#2} {\setevalue{\??fa#1}{#2}} {\let\!!stringa\empty \processcommalist[#2]\dododefinefontfeature \setevalue{\??fa#1}{\ifx\!!stringa\empty\else\!!stringa,\fi#3}}} \definefontfeature [default] [liga=yes,kern=yes,tlig=yes,trep=yes] % texligatures=yes,texquotes=yes \definefontfeature [smallcaps] [liga=yes,kern=yes,tlig=yes,trep=yes,smcp=yes] % texligatures=yes,texquotes=yes \definefontfeature [oldstyle] [liga=yes,kern=yes,tlig=yes,trep=yes,onum=yes] % texligatures=yes,texquotes=yes \definefontfeature % no calt [arabic] [language=dflt,script=arab, init=yes,medi=yes,fina=yes,isol=yes, liga=yes,dlig=yes,rlig=yes,clig=yes, mark=yes,mkmk=yes,kern=yes,curs=yes] \definefontfeature [none] [features=no] %D Overloaded: \def\getfontfileparameters#1% can be simpler for mkii (no features) {\edef\@@truefontname{\truefontname{#1}}% \edef\currentfontfileencoding{\truefontdata\@@truefontname\s!encoding}% \edef\currentfontfilemapping {\truefontdata\@@truefontname\s!mapping }% \edef\currentfontfilehandling{\truefontdata\@@truefontname\s!handling}% \edef\currentfontfilefeatures{\truefontdata\@@truefontname\s!features}} \def\updatefontparameters {\edef\@@fontencoding{\truefontdata\fontfile \s!encoding}% \edef\@@fontmapping {\truefontdata\fontfile \s!mapping }% \edef\@@fonthandling{\truefontdata\somefontname\s!handling}% \edef\@@fontfeatures{\truefontdata\fontfile \s!features}% \edef\@@fontskewchar{\truefontdata\fontfile \s!skewchar}} %D Loading: %D %D for some reason xetex does not support [filename] for tfm files and %D quotes also behave kind of strange " vs ' vs [ vs ... %D %D \starttyping %D \font\myfont = msam7 % ok %D \font\myfont = "msam7" % also ok %D \font\myfont = "msam7" at 8pt % error %D \stoptyping \newconditional\tracexetexfonts %D Because \XETEX\ is not that fast on locating fonts we cache lookups so %D that we minimize the test. It saves a little bit of runtime, depending %D on the number of fonts loaded (which is normally not that much). \def\doiffoundXTXfontelse#1#2% {\ifcsname xtx@fnt@#2\somefontspec\endcsname \ifconditional\tracexetexfonts \writestatus\m!fonts{already checked #1: #2\somefontspec\space (state: \number\csname xtx@fnt@#2\somefontspec\endcsname)}% \fi \else \suppressfontnotfounderror\plusone \font\xetextempfont=#2\somefontspec\relax \suppressfontnotfounderror\zerocount \edef\xetextempfont{\fontname\xetextempfont}% \global\expandafter\chardef\csname xtx@fnt@#2\somefontspec\endcsname \ifx\xetextempfont\nullfontname \zerocount \ifconditional\tracexetexfonts \writestatus\m!fonts{not found #1: #2\somefontspec}% \fi \else \plusone \ifconditional\tracexetexfonts \writestatus\m!fonts{found #1: #2\somefontspec}% \fi \fi \fi \ifcase\csname xtx@fnt@#2\somefontspec\endcsname \expandafter\secondoftwoarguments \else \expandafter\firstoftwoarguments \fi} \def\docheckfontfilenameprefix#1:#2:#3#4\relax {\edef\!!stringa{#1}% \edef\!!stringb{#2}% \ifx\!!stringb\empty % no prefix \let\checkedfontfile\!!stringa \doiffoundXTXfontelse{1a}{\checkedfontfile\checkedfontfeatures} {\edef\checkedfontfile{\checkedfontfile\checkedfontfeatures}} {\doiffoundXTXfontelse{1b}{"\checkedfontfile\checkedfontfeatures"} {\edef\checkedfontfile{"\checkedfontfile\checkedfontfeatures"}} {\doiffoundXTXfontelse{1c}{"[\checkedfontfile]\checkedfontfeatures"} {\edef\checkedfontfile{"[\checkedfontfile]\checkedfontfeatures"}} {}}}% \else\ifx\!!stringa\v!file % force file, only file check when no spaces \let\checkedfontfile\!!stringb \doiffoundXTXfontelse{2a}{"[\checkedfontfile]\checkedfontfeatures"} {\edef\checkedfontfile{"[\checkedfontfile]\checkedfontfeatures"}} {\doiffoundXTXfontelse{2b}{"\checkedfontfile\checkedfontfeatures"} {\edef\checkedfontfile{"\checkedfontfile\checkedfontfeatures"}} {}}% \else\ifx\!!stringa\v!name % force name, always lookup by xetex itself, "" forces otf/ttf/type1 \edef\checkedfontfile{"\!!stringb\checkedfontfeatures"}% \ifconditional\tracexetexfonts \writestatus\m!fonts{no checking 3a: \checkedfontfile}% \fi \else % whatever, maybe even xetex spec, forget about features \edef\checkedfontfile{"\!!stringa\!!stringb"}% \ifconditional\tracexetexfonts \writestatus\m!fonts{no checking 3b: \checkedfontfile}% \fi \fi\fi\fi} \newconditional\enabledfontfeatures \def\checkfontfilename% -- todo: integrate so that we call do.. directly {\expandafter\docheckfontfilename\fontfile*\empty*\relax} \def\docheckfontfilename#1*#2#3*#4\relax % class overrules file {\settrue\enabledfontfeatures \edef\checkedfontfeatures {\expandafter\ifx\csname\fontclass\s!features\endcsname\empty \ifx\@@fontfeatures\empty\ifx#2\empty\else#2#3\fi\else\@@fontfeatures\fi \else\expandafter\ifx\csname\fontclass\s!features\endcsname\relax % redundant, will go away \ifx\@@fontfeatures\empty\ifx#2\empty\else#2#3\fi\else\@@fontfeatures\fi \else \csname\fontclass\s!features\endcsname \fi\fi}% \ifx\checkedfontfeatures\empty % done \else \edef\checkedfontfeatures{\executeifdefined{\??fa\checkedfontfeatures}\empty}% \ifx\checkedfontfeatures\empty % done \else \let\convertedfontfeatures\empty \processcommacommand[\checkedfontfeatures]\doconvertfontfeatures % raw \ifx\convertedfontfeatures\empty \let\checkedfontfeatures\empty \else\ifconditional\enabledfontfeatures \edef\checkedfontfeatures{:\convertedfontfeatures}% \else \let\checkedfontfeatures\empty \fi\fi \fi \fi \docheckfontfilenameprefix#1:\empty:\empty\relax \doshowcheckedfontfeatures} \edef\@@fontfeaturesareno {features\v!no} \edef\@@fontfeaturesareoff{features\v!off} \def\dodoconvertfontfeatures#1=#2#3=#4\relax {\ifx#2\empty % invalid feature \else\ifcsname @xtx@#1@#2#3\endcsname \expandafter\ifx\csname @xtx@#1@#2#3\endcsname\empty\else \edef\convertedfontfeatures{\convertedfontfeatures\csname @xtx@#1@#2#3\endcsname;}% \fi \else \edef\!!stringa{#1}% \edef\!!stringb{#2#3}% \edef\!!stringc{#1#2#3}% \ifx\!!stringc\@@fontfeaturesareoff \setfalse\enabledfontfeatures \else\ifx\!!stringc\@@fontfeaturesareno \setfalse\enabledfontfeatures \else \edef\convertedfontfeatures {\convertedfontfeatures \ifx\!!stringb\v!yes +\!!stringa \else\ifx\!!stringb\v!on +\!!stringa \else\ifx\!!stringb\v!no -\!!stringa \else\ifx\!!stringb\v!off -\!!stringa \else \!!stringa=\!!stringb \fi\fi\fi\fi;}% \fi\fi \fi\fi} \def\doconvertfontfeatures#1% {\dodoconvertfontfeatures#1=\empty=\relax} \def\remapfontfeature #1 #2 #3 {\setevalue{@xtx@#1@#2}{#3}} % this may move to another file, maybe font-xtx \remapfontfeature tlig yes mapping=tlig %remapfontfeature tlig no mapping= \remapfontfeature trep yes {} \remapfontfeature trep no {} \remapfontfeature texligatures yes mapping=tlig %remapfontfeature texligatures no mapping= %remapfontfeature texquotes yes mapping=tex-text %remapfontfeature texquotes no mapping= %D Variants: \unexpanded\def\variant[#1]% {\dosetscaledfont \font\variantfont\truefontname{\fontstringA\fontstylesuffix\fontvariant\fontstringA{#1}} at \scaledfont \variantfont} %D Possible optimizations: % \def\updatefontparameters % {\edef\@@fontfeatures{\truefontdata\fontfile\s!features}% % \edef\@@fontskewchar{\truefontdata\fontfile\s!skewchar}} % \def\setfontcharacteristics % {\updatefontparameters % redundant, will go away, faster too % \the\everyfont} % \let\synchronizepatternswithfont\relax %D Names: % We need to move the feature into the filename else it may be % overloaded by another reference. For instance the definition of % a regular and caps variant can use the same font. % We could use an indirect method ... store in 'array' and refer to % slot. \def\definefontsynonym[#1]#2[#3]% {\edef\@@fontname{#1}% \edef\@@fontfile{#3}% \doifnextoptionalelse\dodefinefontsynonym\nodefinefontsynonym} \def\nodefinefontsynonym {\@EA\let\csname\??ff\fontclass\@@fontname\endcsname\@@fontfile % \@EA\let\csname\??ff\@@fontfile\s!features\endcsname\undefined } \def\dodefinefontsynonym[#1]% {\edef\@@fontdata{#1}% \ifx\@@fontdata\empty \nodefinefontsynonym \else \ifx\fontclass\empty \getfontparameters \else \getglobalfontparameters \fi \ifcsname\??ff\@@fontfile\s!features\endcsname \@EA\edef\csname\??ff\fontclass\@@fontname\endcsname{\@@fontfile*\csname\??ff\@@fontfile\s!features\endcsname}% \@EA\let\csname\??ff\@@fontfile\s!features\endcsname\undefined \else \nodefinefontsynonym \fi \fi} \let\definefontfile\definefontsynonym % dedicated to Taco Hoekwater % simple version % % \def\truefontname#1% % {\@EA\dotruefontname#1*\relax} % % \def\dotruefontname#1*#2\relax % {\ifcsname\??ff\fontclass#1\endcsname % \@EA\truefontname\csname\??ff\fontclass#1\endcsname % \else\ifcsname\??ff#1\endcsname % \@EA\truefontname\csname\??ff#1\endcsname % \else % #1% % \fi\fi} % % last counts % % \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\truefontname\csname\??ff\fontclass#1\endcsname*#2#3% % \fi % \else\ifcsname\??ff#1\endcsname % \ifx#2\empty % \@EA\truefontname\csname\??ff#1\endcsname % \else % \@EA\truefontname\csname\??ff#1\endcsname*#2#3% % \fi % \else % \ifx#2\empty % #1% % \else % #1*#2#3% % \fi % \fi\fi} % % first counts \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#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} \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#1\endcsname \@EA\redotruefontname\csname\??ff#1\endcsname \else #1% \fi\fi} %D Default: \def\defaultfontfile{file:lmmono10-regular} %D Maybe: % \def\updatefontparameters % {\edef\@@fontfeatures{\truefontdata\fontfile \s!features}% % \edef\@@fontskewchar{\truefontdata\fontfile \s!skewchar}} % \def\setfontcharacteristics % {%\updatefontparameters % redundant, will go away, faster too % \the\everyfont % \synchronizepatternswithfont} \protect \endinput % \starttypescript[serif] [myzhfont] % \definefontsynonym [Serif] [file:SimSun] % \definefontsynonym [SerifBold] [file:SimSun] % \definefontsynonym [SerifItalic] [file:SimSun] % \definefontsynonym [SerifBoldItalic] [file:SimSun] % \stoptypescript % \starttypescript[sans] [myzhfont] % \definefontsynonym [Sans] [file:SimSun] % \definefontsynonym [SansBold] [file:SimSun] % \definefontsynonym [SansItalic] [file:SimSun] % \definefontsynonym [SansBoldItalic] [file:SimSun] % \stoptypescript % \starttypescript[mono] [myzhfont] % \definefontsynonym [Mono] [file:SimSun] % \definefontsynonym [MonoBold] [file:SimSun] % \definefontsynonym [MonoItalic] [file:SimSun] % \definefontsynonym [MonoBoldItalic] [file:SimSun] % \stoptypescript % \definetypeface [myzhfont] [rm] [serif][myzhfont] [default] % \definetypeface [myzhfont] [ss] [sans] [myzhfont] [default] % \definetypeface [myzhfont] [tt] [mono] [myzhfont] [default] % \starttext % % on windows: make sure fonts.conf has no cache mentioned % % % % 64 sec xetex, 11 sec luatex (56 sec xetex when \nobigmath) % % % \setupbodyfont[myzhfont] \dorecurse{10000}{{hello {\switchtobodyfont[myzhfont] 你好}}\par} % % % % 67 sec xetex, 11.5 sec luatex % % % % \dorecurse{10000}{{hello {\switchtobodyfont[myzhfont] 你好}}\par} % % % % 5 sec xetex, 7 sec luatex % % % % \setupbodyfont[myzhfont] \dorecurse{10000}{{hello {你好}}\par} % % % % 5 sec xetex, 7 sec luatex % % % % \setupbodyfont[myzhfont] \dorecurse{10000}{{\bf hello {你好}}\par} % \stoptext