%% This is part of OpTeX project, see http://petr.olsak.net/optex \_codedecl \fontfam {Fonts selection system <2020-12-12>} % preloaded in format \_doc ----------------------------- \`\initunifonts` macro extends \LuaTeX's font capabalities, in order to be able to load Unicode fonts. Unfortunately, this part of \OpTeX/ depends on `luaotfload` package, which adapts Con\TeX/t's generic font loader for plain \TeX/ and \LaTeX. `luaotfload` uses Lua functions from \LaTeX's `luatexbase` namespace, we provide our own replacements. Moreover, `\initunifont` switches with the \^`\_doresizefont` macro to OTF mode which is represented by the macro \`\_doresizeunifont`. This mode includes a fallback to TFM mode if \^`\_fontnamegen` is not defined. Finally, `\initunifonts` sets itself to relax because we don't want to do this work twice. \_cod ----------------------------- \_def\_initunifonts {% \directlua{% require('luaotfload-main') print_bak = print print = function () end luaotfload.main() print = print_bak % "print hack" until luaotfload will be corrected }% \_gdef\_rfskipatX ##1" ##2\_relax{"##1"}% \_global\_let \_doresizefont=\_doresizeunifont \_gdef\_tryloadtt {\_fontdef\_tentt{\_def\_fontnamegen{[lmmono10-regular]}\_rm}}% \_global\_let \_initunifonts=\_relax % we need not to do this work twice \_global\_let \initunifonts=\_relax } \_gdef\_doresizeunifont #1{\_logfont{#1}% \_ifx\_fontnamegen\_undefined \_doresizetfmfont#1\_else \_font#1={\_fontnamegen} \_sizespec \_relax \_setwsp#1\_relax \_fi } \_public \initunifonts ; \_doc ----------------------------- The \`\_famdecl` `[] \ {} {} {} {}`\nl `{} {\def`\^`\_fontnamegen``{}}` runs \^`\initunifonts`, then checks if `\` is defined. If it is true, then closes the file by `\endinput`. Else it defines `\` and saves it to the internal `\_f::main.fam` command. The macro \`\_initfontfamily` needs it. The \`\_currfamily` is set to the `` because the following \^`\moddef` commands need to be in the right font family context. The `\_currfamily` is set to the `` by the `\` too, because `\` must set the right font family context. The font family context is given by the current `\_currfamily` value and by the actual meaning of the \^`\_fontnamegen` macro. The \`\_mathfaminfo` is saved for usage in the catalogue. \_cod ----------------------------- \_def\_famdecl [#1]#2#3#4#5#6#7#8{% \_initunifonts \_uniaccents \_unless\_ifcsname _f:\_csstring#2:main.fam\_endcsname \_isfont{#7}\_iffalse \_opwarning{Family [#1] skipped, font "#7" not found}\_ea\_ea\_ea\_endinput \_else \_edef\_currfamily {\_csstring #2}\_def\_mathfaminfo{#6}% \_wterm {FONT: [#1] -- \_string#2 \_detokenize{(#3)^^J mods:{#4} vars:{#5} math:{#6}}}% \_unless \_ifx #2\_undefined \_opwarning{\_string#2 is redefined by \_string\_famdecl\_space[#1]}\_fi \_protected\_edef#2{\_def\_noexpand\_currfamily{\_csstring #2}\_unexpanded{#8\_resetfam}}% \_ea \_let \_csname _f:\_currfamily:main.fam\_endcsname =#2% \_fi \_else \_csname _f:\_csstring#2:main.fam\_endcsname \_reloading \_rm \_ea \_endinput \_fi } \_def\_initfontfamily{% \_csname _f:\_currfamily:main.fam\_endcsname \_reloading \_rm } \_doc ----------------------------- \`\_regoptsizes` ` ? ` prepares data for using by the \`\_optname` `` macro. The data are saved to the `\_oz:` macro. When the `\_optname` is expanded then the data are scanned by the macro \`\_optnameA` `? `\code{<}`` in the loop.\nl \`\_optfontalias` `{ is undeclared in current family" and nothing happens. But you can declare the same variant selector by \^`\famvardef` macro in the context of new family. Then the same command may do different work depending on the current font family. Suppose that the selected font family provides the font modifier `\medium` for mediate weight of fonts. Then you can declare: \begtt \famvardef \mf {\medium\rm} \famvardef \mi {\medium\it} \endtt Now, you can use six independent variant selectors `\rm`, `\bf`, `\it`, `\bi`, `\mf` and `\mi` in the selected font family. A `\` can be written before `` in the `\famvardef` parameter. Then the `\` is declared in the current family but it can use fonts from another family represented by the `\`. When you are mixing fonts from more families then you probably run into problem with incompatible ex-heights. This problem can be solved using \^`\setfontsize` and \^`\famvardef` macros: \begtt \fontfam[Heros] \fontfam[Termes] \def\exhcorr{\setfontsize{mag.88}} \famvardef\rmsans{\Heros\exhcorr\rm} \famvardef\itsans{\Heros\exhcorr\it} Compare ex-height of Termes \rmsans with Heros \rm and Termes. \endtt The variant selectors (declared by \~`\famvardef`) or font modifiers (declared by \~`\moddef`) are (typically) control sequences in user name space (`\mf`, `\caps`). They are most often declared in font family files and they are loaded by \^`\fontfam`. A conflict with such names in user name space can be here. For example: if `\mf` is defined by user and then `\fontfam[Roboto]` is used then `\famvardef\mf` is performed for Roboto family and the original meaning of `\mf` is lost. But \OpTeX/ prints warning about it. There are two cases: \begtt \def\mf{Metafont} \fontfam[Roboto] % warning: "The \mf is redefined by \famvardef" is printed or \fontfam[Roboto] \def\mf{Metafont} % \mf variant selector redefined by user, we suppose that \mf % is used only in the meaning of "Metafont" in the document. \endtt \secc[tt] The `\tt` variant selector \^`\tt` is additional special variant selector which is defined as \"select typewriter font independently of current font family". By default, the typewriter font-face from LatinModern font family is used. The \^`\tt` variant selector is used in \OpTeX/ internal macros \^`\_ttfont` (verbatim texts) and \^`\_urlfont` (printing URL's). You can redefine the behavior of `\tt` by \^`\famvardef`. For example: \begtt \fontfam[Cursor] \fontfam[Heros] \fontfam[Termes] \famvardef\tt{\Cursor\setff{-liga;-tlig}\rm} Test in Termes: {\tt text}. {\Heros\rm Test in Heros: {\tt text}}. Test in URL \url{http://something.org}. \endtt % You can see that `\tt` stay family independent. This is special feature only for `\tt` selector. New definition is used in \^`\_ttfont` and \^`\_urlfont` too. It is recommended to use `\setff{-liga;-tlig}` in order to supress the liguatures in typewriter fonts. If Unicode math font is loaded then the `\tt` macro selects typewriter font-face in math mode too. This face is selected from used Unicode math font and it is independent of `\famvardef\tt` declaration. \secc[fontmacros] Font commands defined by `\def` Such font commands can be used as fonts selectors for titles, footnotes, ctitations etc. User can define them. The following example shows how to define a \"title-font selector". Titles are not only bigger but they are typically in bold variant. When the user puts `{\it...}` into the title text then he/she expects bold italic here, no normal italic. You can remember the great song by John Lennon \"Let It Be" and define: \begtt \def\titlefont{\setfontsize{at14pt}\bf \let\it\bi} ... {\titlefont Title in bold 14pt font and {\it bold 14pt italics} too} \endtt \OpTeX/ defines similar internal commands \^`\_titfont`, \^`\_chapfont`, \^`\_secfont` and \^`\_seccfont`, see section~\ref[sections]. The commands \^`\typosize` and \^`\boldify` are used in these macros. They set the math fonts to given size too and they are defined in section~\ref[opmac-fonts]. \secc[setff] Modifying font features %---------------------------- Each OTF font provides \"font features". You can list these font features by `otfinfo -f font.otf`. For example LinLibertine fonts provide `frac` font feature. If it is active then fractions like 1/2 are printed in a special form. The font features are part of the font context data. The macro \^`\setff` `{}` acts like family independent font modifier and prepares a new . You must use a variant selector in order to reinitialize the font with the new font feature. For example \^`\setff``{+frac}\rm` or \^`\setff``{+frac}`\^`\currvar`. You can declare a new variant selector too: \begtt \fontfam[LinLibertine] \famvardef \fraclig {\setff{+frac}\currvar} Compare 1/2 or 1/10 \fraclig to 1/2 or 1/10. \endtt If the used font does not supports given font feature then font is realoaded without warning nor error, silently. The font feature is not activated. The `onum` font feature (old style digits) is connected to `\caps` macro for Caps+SmallCaps variant in \OpTeX/ font family files. So you need not to create a new modifier, just use `{\caps`\^`\currvar`` 012345}`. \secc[specff] Special font modifiers %--------------------------- Despite the font modifiers declared in the font family file (and dependent on the font family), we have following font modifiers (independent of font family): \begtt \catcode`\<=13 \setfontsize{} % sets the font size \setff{} % adds the font feature \setfontcolor{} % sets font color \setletterspace{} % sets letter spacing \setwordspace{} % modifies word spacing \endtt The \^`\setfontsize` command is described in the section \ref[setfontsize]. The \^`\setff` command was described in previous subsection. \^`\setfontcolor` `{}` specifies the color and the opacity of the text. The parameter should be in hexadecimal format of four bytes ``, for example `FF0080FF` means full red, zero green, half blue and full opacity. You can use names `red`, `green`, `blue`, `yellow`, `cyan`, `magenta`, `white`, `grey`, `lgrey` (without backslash) instead of the hexadecimal specification. The empty parameter `` means default black color. That colors of fonts are implemented using \LuaTeX/ internal font feature. This is different approach than using colors in section \ref[colors]. \^`\setletterspace` `{}` specifies letter spacing of the font. The `` is decimal number without unit. The unit is supposed as 1/100 of the font size. I.e. `2.5` means 0.25 pt when the font is at 10 pt size. The empty parameter `` means no letter spacing which is default. \^`\setwordspace` `{}` scales the default inter word space (defined in the font) and its stretching and shrinking parameters by given `` factor. For example `\setwordspace{2.5}` multiplies inter word space by 2.5. If you need another font transformations, you can use `\setff` with following font features provided by Lua\TeX/: \begtt \setff{embolden=1.5}\rm % font is bolder because outline has nonzero width \setff{slant=0.2}\rm % font is slanted by a linear transformation \setff{extend=1.2}\rm % font is extended by a linear transformation. \setff{colr=yes}\rm % if the font includes colored characters, use colors \endtt Use font transformations mentioned above and \^`\setletterspace`, \^`\setwordspace` with care. The best setting of these values is default setting in every font, of course. If you really needs to set a different letter spacing then it is strongly recommended to add `\setff{-liga}` in order to disable ligatures. And setting a positive letter spacing probably needs to scale inter word spacing too. All mentioned font modifiers (with the exception of `\setfontsize`) work only with Unicode fonts loaded by \^`\fontfam`. \secc[fontfamfiles] How to create the font family file %------------------------------------------------------ \printdoctail f-heros.opm \printdoctail f-lmfonts.opm \secc How to register the font family in the Font Selection System %--------------------------------------------------------------- \printdoctail fams-ini.opm \secc[exfont] Notices about extension of `\font` primitive %--------------------------------------------------------- Unicode fonts are dealed by extended `\font` primitive. This extension is not activated in \OpTeX/ by default, \^`\initunifonts` macro activates it. You need not to use \^`\initunifonts` explicitly if \^`\fontfam` macro is used because \^`\fontfam` runs it internally. The \^`\initunifonts` loads the lua code from Luaotfload package which actually implements the `\font` primitive extension. See its documentation `luaotfload-latex.pdf` for information about all possibilities of extended `\font` primitive. The \OpTeX/ format is initialized by `luatex` engine by default but you can initialize it by `luahbtex` engine too. Then the harfbuzz library is ready to use for font rendering as an alternative of build-in font renderer from Luaotfload. The harfbuzz library gives more features for rendering indic and arabic scripts. But it is not used as default, you need to specify `mode=harf` in fontfeatures field when `\font` is used. Moreover, when `mode=harf` is used, then you must specify `script` too. For example \begtt \font\devafont=[NotoSansDevanagari-Regular]:mode=harf;script=dev2 \endtt % If `luahbtex` engine is not used then `mode=harf` is ignored. See Luaotfload documentation for more information. \endinput 2020-12-12 \_modlist added, doc improved 2020-04-18 \_tryloadfamslocal introduced \_fontdecl -> \_famdecl with different concept 2020-03-18 released