%% This is part of the OpTeX project, see http://petr.olsak.net/optex \_codedecl \setfontsize {Font resizing macros <2020-04-17>} % preloaded in format \_doc ----------------------------- The \`\setfontsize` `{}` saves the `` to the \`\_sizespec` macro. The \`\_optsize` value is calculated from the ``. If the `` is in the `mag` format then the contents of the `\_sizespec` macro is re-calculated to the `at` format using previous `\_optsize` value. \par \goodbreak \_cod ----------------------------- \_newdimen \_optsize \_optsize=10pt \_newdimen \_defaultoptsize \_defaultoptsize=10pt \_newdimen\_lastmagsize \_def\_setfontsize #1{% \_edef\_sizespec{#1}% \_ea \_setoptsize \_sizespec\_relax \_reloading } \_def\_setoptsize {\_isnextchar a{\_setoptsizeA} {\_isnextchar m{\_setoptsizeC}{\_setoptsizeB}}} \_def\_setoptsizeA at#1\_relax{\_optsize=#1\_relax\_lastmagsize=\_optsize} % at \_def\_setoptsizeB scaled#1\_relax{\_optsize=\_defaultoptsize\_relax} % scaled \_def\_setoptsizeC mag#1\_relax{% \_ifdim\_lastmagsize>\_zo \_optsize=\_lastmagsize \_else \_optsize=\_pdffontsize\_font \_fi \_optsize=#1\_optsize \_lastmagsize=\_optsize \_edef\_sizespec{at\_the\_optsize}% } \_public \setfontsize \defaultoptsize ; \_doc ----------------------------- \`\_resizefont` `{}\`, for example `\resizefont{bf}\_tenbf` resizes the font given by the variant. The variant `XX` have its font switch `\_tenXX`. The \`\_doresizefont``\fontswitch` is used. It works in TFM mode (\`\_doresizetfmfont`) or OTF mode (\^`\_doresizeunifont`). In both modes, it does \begtt \catcode`\<=13 \_font \_tenXX = \_sizespec \endtt The `` is generated by the `\fontname` \TeX/ primitive where \`\_rfontskipat` removes the `at` part of the `\_fontname` output. The `` is generated differently in OTF mode, see \^`\_doresizeunifont` macro.\nl The \`\_whatresize` is defined as ``. \_cod ----------------------------- \_def\_resizefont#1#2{% \_edef\_whatresize{#1}% \_ifx \_fontselector \_undefined \_doresizefont#2% \_else \_ea \_doresizefont \_fontselector \_fi \_lastmagsize=\_zo \_slet{_tryload#1}{_relax}% } \_def\_doresizetfmfont#1{\_logfont{#1}% \_ea\_font\_ea#1\_ea\_rfontskipat \_fontname \_cs{_ten\_whatresize} \_relax\_space \_sizespec \_relax } \_let\_doresizefont=\_doresizetfmfont \_def\_logfont#1{} % default is no logging of used fonts \_def\_rfontskipat#1{\_ifx#1"\_ea\_rfskipatX \_else\_ea\_rfskipatN\_ea#1\_fi} \_def\_rfskipatX #1" #2\_relax{"\_whichtfm{#1}"} \_def\_rfskipatN #1 #2\_relax{\_whichtfm{#1}} \_doc ----------------------------- \`\fontdef` `{}` opens group, runs `` (i.e.\ it runs `#2` parameter). The font switch `#1` saved in the \`\_fontselector` macro is re-declared because the variant selector runs the \^`\_resizefont`. Now, we need to keep the current meaning of the font switch `#1` but we must leave the opened group. This is done by the \`\_keepmeaning` macro. \nl \`\fontlet` ` ` does \begtt \catcode`\<=13 \font = \endtt The `` is extracted using the primitive command `\_fontname `. \_cod ----------------------------- \_def \_fontdef #1#2{\_begingroup \_ifx\_fontselector\_undefined \_def\_fontselector{#1}\_fi \_reloading #2% \_ea \_keepmeaning \_fontselector \_endgroup } \_def\_fontlet#1#2{\_ifx #2=\_ea\_fontlet \_ea#1\_else \_ea\_font\_ea#1\_ea\_rfontskipat\_fontname#2 \_relax\_space \_fi } \_def \_keepmeaning #1#2{\_global\_let\_keepmeaningdata=#1% #2\_let#1=\_keepmeaningdata \_global\_let\_keepmeaningdata=\_undefined } \_public \fontdef \fontlet ; \_doc ----------------------------- \`\newcurrfontsize` `` sets current font size to the `` It is implemented by \^`\fontlet`. The font switch of the current font is extracted by `\_the\_font`. We must re-create the control sequence `\_the\_font` because its original meaning is set to \"inaccessible" by \TeX/ when `\font` primitive is started. \nl \`\resizethefont` is implemented by `\newcurrfontsize` using data from the \^`\_sizespec` macro. \_cod ----------------------------- \_def \_newcurrfontsize #1{% \newcurrfontsize{at25pt} \_edef\_tmp{\_ea\_csstring \_the\_font}% \_ea \_fontlet \_csname \_tmp\_ea\_endcsname \_the\_font \_space #1\_relax \_csname \_tmp\_endcsname } \_protected\_def \_resizethefont{\_newcurrfontsize\_sizespec} \_public \newcurrfontsize \resizethefont ; \_doc ----------------------------- The variant selector is defined by `\protected\def\XX{\_tryloadXX \_tenXX}` The `\_tryloadXX` can be in `\_relax` state if no font modifiers were declared. But normally it does \^`\_resizefont``{XX}\tenXX`. This meaning is activated by the \`\_reloading` macro. \_cod ----------------------------- \_def\_reloading{\_loadf{rm}\_tenrm \_loadf{bf}\_tenbf \_loadf{it}\_tenit \_loadf{bi}\_tenbi } \_def\_loadf#1#2{\_sdef{_tryload#1}{\_ifmmode \_else \_resizefont{#1}#2\_fi}} \_def\_tryloadtt{\_resizefont{tt}\_tentt} \_let\_tryloadrm=\_relax \_let\_tryloadbf=\_relax \_let\_tryloadit=\_relax \_let\_tryloadbi=\_relax \_doc ---------------------------- The font selection system allows to use \`\currvar` instead explicitly specified variant selector. The current variant is extracted from `\the\font` output which could be `\_tenXX` control sequence. Then `\currvar` expands to `\_rm` or `\_it` etc. \_cod ---------------------------- \_protected \_def \_currvar{\_cs{_currvar:\_ea \_csstring \_the\_font}} \_sdef{_currvar:_tenrm}{\_rm} \_sdef{_currvar:_tenbf}{\_bf} \_sdef{_currvar:_tenit}{\_it} \_sdef{_currvar:_tenbi}{\_bi} \_sdef{_currvar:_tentt}{\_tt} \_public \currvar ; \_doc ----------------------------- The \`\_regtfm` ` ` saves the concerned to ``. The `` is in the form as shown below in the code where `\_regtfm` is used. \nl The \`\_wichtfm` `` expands to the `` or to the corrected `` read from the ``. It is used in the \^`\_rfontskipat` macro and it is used in \^`\fontlet` macro. It means that each `` generated by the `\fontname` primitive in the `\fontlet` macro is processed by the `\_whichtfm`. The real `` or corrected `` (depending on the optical data does not exist or exist) is the output of the expansion before `\font` primitive takes this output as its parameter. The implementation detail: The `\_:reg` is defined as the `` and all control sequences `\_:reg` from this data line have the same meaning because of the \`\_reversetfm` macro. The `\_whichtfm` expands this data line and apply \`\_dowhichtfm`. This macro selects the right result from the data line by testing with the current `\_optsize` value. \_cod ----------------------------- \_def\_regtfm #1 0 #2 *{\_ea\_def \_csname _#1:reg\_endcsname{#2 16380 \_relax}% \_def\_tmpa{#1}\_reversetfm #2 * % } \_def\_reversetfm #1 #2 {% we need this data for \_setmathfamily \_ea\_let\_csname _#1:reg\_ea\_endcsname \_csname _\_tmpa:reg\_endcsname \_if*#2\_else \_ea\_reversetfm \_fi } \_def\_whichtfm #1{% \_ifcsname _#1:reg\_endcsname \_ea\_ea\_ea \_dowhichtfm \_csname _#1:reg\_ea\_endcsname \_else #1% \_fi } \_def\_dowhichtfm #1 #2 {% \_ifdim\_optsize<#2pt #1\_ea\_ignoretfm\_else \_ea\_dowhichtfm \_fi } \_def\_ignoretfm #1\_relax{} \_doc ----------------------------- Optical sizes data for preloaded 8bit Latin Modern fonts: \_cod ----------------------------- \_regtfm lmr 0 ec-lmr5 5.5 ec-lmr6 6.5 ec-lmr7 7.5 ec-lmr8 8.5 ec-lmr9 9.5 ec-lmr10 11.1 ec-lmr12 15 ec-lmr17 * \_regtfm lmbx 0 ec-lmbx5 5.5 ec-lmbx6 6.5 ec-lmbx7 7.5 ec-lmbx8 8.5 ec-lmbx9 9.5 ec-lmbx10 11.1 ec-lmbx12 * \_regtfm lmri 0 ec-lmri7 7.5 ec-lmri8 8.5 ec-lmri9 9.5 ec-lmri10 11.1 ec-lmri12 * \_regtfm lmtt 0 ec-lmtt8 8.5 ec-lmtt9 9.5 ec-lmtt10 11.1 ec-lmtt12 * \_setfontsize {at10pt} % default font size \_endcode %--------------------------------------------------- \sec[setfontsize] Scaling fonts in text mode (low-level macros) %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \secc The `\setfontsize` macro The \^`\setfontsize` `{}` saves the information about ``. This information is taken into account when a variant selector (for example `\rm`, `\bf`, `\it`, `\bi`) or `\resizethefont` is used. The `` can be: \begitems * `at`, for example `\setfontsize{at12pt}`. It gives the desired font size directly. * `scaled`, for example `\setfontsize{scaled1200}`. The font is scaled in respect to its native size (which is typically 10\,pt). It behaves like `\font\... scaled`. * `mag`, for example `\setfontsize{mag1.2}`. The font is scaled in respect to the current size of the fonts given by the previous \^`\setfontsize` command. \enditems The initialization value in \OpTeX/ is given by `\setfontsize{at10pt}`. The \^`\resizethefont` resizes the currently selected font to the size given by previous \^`\setfontsize`. For example \begtt The 10 pt text is here, \setfontsize{at12pt} the 10 pt text is here unchanged... \resizethefont and the 12 pt text is here. \endtt % The \^`\setfontsize` command acts like {\em font modifier}. It means that it saves information about fonts but does not change the font actually until variant selector or \^`\resizethefont` is used. The following example demonstrates the `mag` format of \^`\setfontsize` parameter. It is only a curious example probably not used in practical typography. \begtt \def\smaller{\setfontsize{mag.9}\resizethefont} Text \smaller text \smaller text \smaller text. \endtt \secc[fontprimitive] The `\font` primitive If you load a font directly by `\font` primitive and you want to create a size-dependent selector for such font then you can use \~`\resizethefont`: \begtt \font\tencomfortaa=Comfortaa-Regular-T1 at10pt \def\comfortaa{\tencomfortaa\resizethefont} \comfortaa The 10 pt text is here \setfontsize{at12pt} \comfortaa The 12 pt text is here \endtt % The example above uses the 8\,bit `tfm` font. You can use Unicode font too, of course. The \^`\fontfam` macro initializes the extended `\font` primitive features for \LuaTeX/ (see section \ref[exfont]). If you didn't use this command, you must initialize these features by the \^`\initunifonts` command explicitly, for example: \begtt \initunifonts \font\tencyklop=[cyklop-regular] at10pt % the font cyklop-regular.otf is loaded \def\cyklop{\tencyklop\resizethefont} \cyklop The 10 pt text is here \setfontsize{at12pt} \cyklop The 12 pt text is here \endtt \secc[fontdef] The \code{\\fontdef} declarator You can declare `\` by the \~`\fontdef` command. \begtt \catcode`\<=13 \fontdef \ { \} example: \fontdef \bigfont {\setfontsize{at15pt}\bf} \endtt % This command runs ` \` in an internal group and sets the resulting selected font as `\`. The resulting `\` declared by \~`\fontdef` is \"fixed font switch" independent of \^`\setfontsize` and other font modifiers. More exactly, it is a fixed font switch when it is used but it can depend on the current font modifiers and font family and given font modifiers when it is declared. The parameter of the \~`\fontdef` macro must be exactly finished by the variant selector. More information about font modifiers and variant selectors are in the section~\ref[fontsystem]. \secc[fontlet] The \code{\\fontlet} declarator We have another command for scaling: \^`\fontlet` which can resize arbitrary font given by its font switch. This font switch was declared by the `\font` primitive or the \~`\fontdef` macro. \begtt \catcode`\<=13 \fontlet \ = \ example: \fontlet \bigfont = \_tenbf at15pt \endtt The resulted `\bigfont` is the same as in the previous example where \~`\fontdef` was used. The advantage of \~`\fontdef` macro will be more clear when you load font families by `\fontfam` and you are using more font modifiers declared in such families. Summary: you can declare font switches: \begitems * by the `\font` primitive if you know the font file, * by the \^`\fontlet` command if you know the font switch and the size, or * by the \~`\fontdef` command if you know the variant and modifiers. \enditems \secc Optical sizes There are font families with more font files where almost the same font is implemented in various design sizes: `cmr5`, `cmr6`, `cmr7`, `cmr8`, `cmr9`, `cmr10`, `cmr12`, `cmr17` for example. This feature is called \"optical sizes". \OpTeX/ chooses a font with an optical size closest to desired size specified by the \^`\setfontsize`, when `at` or `mag` is used. When `scaled` is used then optical size is chosen using the value of the `\defaultoptsize` register and such font is scaled by the specified ``. There is `\defaultoptsize=10pt` by default. Font collections with optical sizes must be registered by the \^`\_regtfm` for `tfm` files or \^`\_regoptsizes` for Unicode fonts. \OpTeX/ registers 8bit Latin Moder fonts in the format (`fonts-resize.opm` file) and OTF Latin Modern fonts in the `f-lmfonts.opm` file. \secc Implementation notes \_endinput 2020-04-17 \resizethefont introduced 2020-03-17 released