diff options
Diffstat (limited to 'Master/texmf-dist/tex/optex/base/fonts-select.opm')
-rw-r--r-- | Master/texmf-dist/tex/optex/base/fonts-select.opm | 846 |
1 files changed, 846 insertions, 0 deletions
diff --git a/Master/texmf-dist/tex/optex/base/fonts-select.opm b/Master/texmf-dist/tex/optex/base/fonts-select.opm new file mode 100644 index 00000000000..740b311a677 --- /dev/null +++ b/Master/texmf-dist/tex/optex/base/fonts-select.opm @@ -0,0 +1,846 @@ +%% This is part of the OpTeX project, see http://petr.olsak.net/optex + +\_codedecl \fontfam {Fonts selection system <2021-02-25>} % 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.\nl + \`\_ttunifont` is default font for `\tt` variant if + `f-lmfonts.opm` (or another font file where `\tt` is declared) is not loaded. + \_cod ----------------------------- + +\_def\_initunifonts {% + \directlua{% + require('luaotfload-main') + luaotfload.main() + }% + \_gdef\_rfskipatX ##1" ##2\_relax{"##1"}% + \_global\_let \_doresizefont=\_doresizeunifont + \_gdef\_tryloadtt {\_fontdef\_tentt{\_let\_fontnamegen=\_ttunifont\_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 +} +\_def\_ttunifont{[lmmono10-regular]:\_fontfeatures-tlig;} + +\_public \initunifonts ; + + \_doc ----------------------------- + The \`\_famdecl` `[<Family Name>] \<Famselector> {<comment>} {<modifiers>} {<variants>} {<math>}`\nl + `{<font for testing>} {\def`\^`\_fontnamegen``{<data>}}` runs \^`\initunifonts`, then + checks if `\<Famselector>` is defined. If it is true, then closes the file by + `\endinput`. Else it defines `\<Famselector>` and saves it to the + internal `\_f:<currfamily>:main.fam` command. + The macro \`\_initfontfamily` needs it. The \`\_currfamily` is set + to the `<Famselector>` because the following \^`\moddef` commands need to + be in the right font family context. The `\_currfamily` is set to the + `<Famselector>` by the `\<Famselector>` too, because `\<Famselector>` + 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 catalog. + \_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` `<internal-template> <left-output>?<right-output> <resizing-data>` + prepares data for using by the \`\_optname` `<internal-template>` macro. + The data are saved to the `\_oz:<internal-template>` macro. + When the `\_optname` is expanded then the data are scanned by the macro + \`\_optnameA` `<left-output>?<right-output> <mid-output> `\code{<}`<size>` + in the loop.\nl + \`\_optfontalias` `{<template A>}{<template B>}` is defined as + `\let\_oz:<templateA>=\_oz:<templateB>`. + \_cod ----------------------------- + +\_def\_regoptsizes #1 #2?#3 #4*{\_sdef{_oz:#1}{#2?#3 #4* }} +\_def\_optname #1{\_ifcsname _oz:#1\_endcsname + \_ea\_ea\_ea \_optnameA \_csname _oz:#1\_ea\_endcsname + \_else \_failedoptname{#1}\_fi +} +\_def\_failedoptname #1{optname-fails:(#1)} +\_def\_optnameA #1?#2 #3 <#4 {\_ifx*#4#1#3#2\_else + \_ifdim\_optsize<#4pt #1#3#2\_optnameC + \_else \_afterfifi \_optnameA #1?#2 \_fi\_fi +} +\_def\_optnameC #1* {\_fi\_fi} +\_def\_afterfifi #1\_fi\_fi{\_fi\_fi #1} +\_def\_optfontalias #1#2{\_slet{_oz:#1}{_oz:#2}} + + \_doc ----------------------------- + \`\_fvars` `<rm-template> <bf-template> <it-template> <bi-template>` + saves data for usage by the `\_currV` macro. If a template is only dot + then previous template is used (it can be used if the font family doesn't + dispose with all standard variants). + \nl + \`\_currV` expands to a template declared by `\_fvars` depending on the + `<variant name>`. Usable only of standard four variants. Next variants + can be declared by the \^`\famvardef` macro. + \nl + \`\_fsetV` `<key>=<value>,...,<key>=<value>` expands to + `\def\_<key>V{<value>}` in the loop. + \nl + \`\_onlyif` `<key>=<value-a>,<value-b>...,<value-z>: {<what>}` + runs <what> only if the `\_<key>V` is defined as `<value-a>` or + `<value-b>` or ... or `<value-z>`. + \nl + \`\_prepcommalist` `ab,{},cd,\_end,` expands to `ab,,cd,` (auxiliary macro + used in `\_onlyif`). + \_cod ----------------------------- + +\_def\_fvars #1 #2 #3 #4 {% + \_sdef{_fvar:rm}{#1}% + \_sdef{_fvar:bf}{#2}% + \_ifx.#2\_slet{_fvar:bf}{_fvar:rm}\_fi + \_sdef{_fvar:it}{#3}% + \_ifx.#3\_slet{_fvar:it}{_fvar:rm}\_fi + \_sdef{_fvar:bi}{#4}% + \_ifx.#4\_slet{_fvar:bi}{_fvar:it}\_fi +} +\_def\_currV{\_cs{_fvar:\_whatresize}} +\_def\_V{ } +\_def \_fsetV #1 {\_fsetVa #1,=,} +\_def \_fsetVa #1=#2,{\_isempty{#1}\_iffalse + \_ifx,#1\_else\_sdef{_#1V}{#2}\_ea\_ea\_ea\_fsetVa\_fi\_fi +} +\_def \_onlyif #1=#2:#3{% + \_edef\_act{\_noexpand\_isinlist{,\_prepcommalist #2,\_end,}{,\_cs{_#1V},}}\_act + \_iftrue #3\_fi +} +\_def\_prepcommalist#1,{\_ifx\_end#1\_empty\_else #1,\_ea\_prepcommalist\_fi} + + \_doc ----------------------------- + The \`\moddef` `\<modifier> {<data>}` simply speaking does + `\def\<modifier>{<data>}`, but we need to respect + the family context. In fact, `\protected\def\_f:<current family>:<modifier>{<data>}` is + performed and the `\<modifier>` is defined as + \`\_famdepend``\<modifier>{_f:\_currfamily:<modifier>}`. It expands to + `\_f:\_currfamily:<modifier>` value if it is defined or it prints + the warning. When the `\_currfamily` value is + changed then we can declare the same `\<modifier>` with a different meaning. + + When a user declares a prefixed variant of the `\<modifier>` then unprefixed + modifier name is used in internal macros, this is the reason why we are using + the \`\_remifirstunderscore``\_tmp` (where `\_tmp` expands to + `_<something>` or to `<something>`. The `\_remifirstunderscore` + redefines `\_tmp` in the way that it + expands only to `<something>` without the first `_`. + + \`\_setnewmeaning` `<cs-name>=\_tmpa <by-what>` does exactly `\_let <csname>=\_tmpa` + but warning is printed if <cs-name> is defined already and it is not a variant + selector or font modifier. + + \`\_addtomodlist` `<font modifier>` adds given modifier to \`\_modlist` + macro. This list is used after `\resetmod` when a new family is selected by + a family selector, see \`\_resetfam` macro. + This allows reinitializing the same current modifiers in the font context + after the family is changed. + \_cod ----------------------------- + +\_def \_moddef #1#2{\_edef\_tmp{\_csstring#1}% + \_sdef{_f:\_currfamily:\_tmp}{\_addtomodlist#1#2\_reloading}% + \_protected \_edef \_tmpa{\_noexpand\_famdepend\_noexpand#1{_f:\_noexpand\_currfamily:\_tmp}}% + \_setnewmeaning #1=\_tmpa \moddef +} +\_protected \_def\_resetmod {\_cs{_f:\_currfamily:resetmod}} % private variant of \resetmod +\_def \_resetfam{\_def\_addtomodlist##1{}\_resetmod + \_edef \_modlist{\_ea}\_modlist + \_let\_addtomodlist=\_addtomodlistb +} +\_def \_currfamily{} % default current family is empty +\_def \_modlist{} % list of currently used modifiers + +\_def \_addtomodlist#1{\_addto\_modlist#1} +\_let \_addtomodlistb=\_addtomodlist + +\_def\_famdepend#1#2{\_ifcsname#2\_endcsname \_csname#2\_ea\_endcsname \_else + \_ifx\_addtomodlist\_addtomodlistb + \_opwarning{\_string#1 is undeclared in family "\_currfamily", ignored}\_fi\_fi +} +\_def\_setnewmeaning #1=\_tmpa#2{% + \_ifx #1\_undefined \_else \_ifx #1\_tmpa \_else + \_opwarning{\_string#1 is redefined by \_string#2}% + \_fi\_fi + \_let#1=\_tmpa +} +\_public \moddef ; + + \_doc ----------------------------- + The \`\famvardef` `\<XX> {<data>}` + uses analogical trick like \^`\moddef` with + the \^`\_famdepend` macro. The auxiliary + \`\_famvardefA` `\<XX> \_ten<XX> \_tryload<XX> {<data>}` is used. + It does: + \begitems + * `\def \_tryload:<currfam>:<XX> {`\^`\fontdef`` \_ten<XX> {<data>}}` loads font `\_ten<XX>`, + * `\protected\def \<XX> {\_famdepend \<XX> {_f:<currfam>:<XX>}}`, + * `\def \_f:<currfam>:<XX> {\_tryload:<currfam>:<XX>\_ten<XX>}` keeps family dependent definition, + * `\def \_currvar:_ten<XX> {\<XX>}` in order to the \^`\currvar` macro work correctly. + \enditems + `\famvardef\tt` behaves somewhat differently: it doesn't re-define the + `\tt` macro which is defined as `\_tryloadtt \_tentt` in sections~\ref[math-preload] + and~\ref[unimath-codes]. It only re-defines the internal `\_tryloadtt` macro. + \_cod ----------------------------- + +\_def\_famvardef#1{\_edef\_tmp{\_csstring#1}% + \_ea\_famvardefA \_ea#1\_csname _ten\_tmp\_ea\_endcsname + \_csname _tryload:\_currfamily:\_tmp\_endcsname +} +\_def\_famvardefA #1#2#3#4{% #1=\XX #2=\_tenXX #3=\_tryload:currfam:XX #4=data + \_isinlist{.\_rm\_bf\_it\_bi\currvar\_currvar}#1\_iftrue + \_opwarning{\_string\famvardef: + You cannot re-declare standard variant selector \_string#1}% + \_else + \_def#3{\_fontdef#2{#4}}% + \_protected\_edef\_tmpa{\_noexpand\_famdepend\_noexpand#1{_f:\_noexpand\_currfamily:\_tmp}}% + \_ifx #1\_tt \_let\_tryloadtt=#3\_else \_setnewmeaning #1=\_tmpa \famvardef \_fi + \_sdef{_f:\_currfamily:\_tmp}{#3#2}% + \_sdef{_currvar:\_csstring#2}{#1}% + \_fi +} +\_public \famvardef ; + + \_doc ----------------------------- + The \`\fontfam` `[<Font Family>]` does: + \begitems + * Convert its parameter to lower case and without spaces, e.g.\ `<fontfamily>`. + * If the file `f-<fontfamily>.opm` exists read it and finish. + * Try to load user defined `fams-local.opm`. + * If the `<fontfamily>` is declared in `fams-local.opm` or `fams-ini.opm` + read relevant file and finish. + * Print the list of declared families. + \enditems + The `fams-local.opm` is read by the \`\_tryloadfamslocal` macro. It sets + itself to `\_relax` because we need not load this file twice. + The \`\_listfamnames` macro prints registered font families to the + terminal and to the log file. + \_cod ----------------------------- + +\_def\_fontfam[#1]{% + \_lowercase{\_edef\_famname{\_ea\_removespaces #1 {} }}% + \_isfile {f-\_famname.opm}\_iftrue \_opinput {f-\_famname.opm}% + \_else + \_tryloadfamslocal + \_edef\_famfile{\_trycs{_famf:\_famname}{}}% + \_ifx\_famfile\_empty \_listfamnames + \_else \_opinput {\_famfile.opm}% + \_fi\_fi +} +\_def\_tryloadfamslocal{% + \_isfile {fams-local.opm}\_iftrue + \_opinput {fams-local.opm}\_famfrom={}% + \_fi + \_let \_tryloadfamslocal=\_relax % need not to load fams-local.opm twice +} +\_def\_listfamnames {% + \_wterm{===== List of font families ======} + \_begingroup + \_let\_famtext=\_wterm + \_def\_faminfo [##1]##2##3##4{% + \_wterm{ \_space\_noexpand\fontfam [##1] -- ##2}% + \_let\_famalias=\_famaliasA}% + \_opinput {fams-ini.opm}% + \_isfile {fams-local.opm}\_iftrue \_opinput {fams-local.opm}\_fi + \_message{^^J}% + \_endgroup +} +\_def\_famaliasA{\_message{ \_space\_space\_space\_space -- alias:} + \_def\_famalias[##1]{\_message{[##1]}}\_famalias +} +\_public \fontfam ; + + \_doc ----------------------------- + When the `fams-ini.opm` or `fams-local.opm` files are read then we need + to save only a mapping from family names or alias names to the font family file + names. All other information is ignored in this case. But if these files + are read by the `\_listfamnames` macro or when printing a catalog then more + information is used and printed.\nl + \`\_famtext` does nothing or prints the text on the terminal. + \nl + \`\_faminfo` `[<Family Name>] {<comments>} {<file-name>} {<mod-plus-vars>}` + does\nl `\_def \_famf:<familyname> {<file-name>}` or prints information on + the terminal. + \nl + \`\_famalias` `[<Family Alias>]` does `\def \_famf:<familyalias> {<file-name>}` + where `<file-name>` is stored from the previous `\_faminfo` command. Or + prints information on the terminal. + \nl + \`\_famfrom` declares type foundry or owner or designer of the font family. + It can be used in `fams-ini.opm` or `fams-local.opm` and it is printed + in the font catalog. + \_cod ----------------------------- + +\_def\_famtext #1{} +\_def\_faminfo [#1]#2#3#4{% + \_lowercase{\_edef\_tmp{\_ea\_removespaces #1 {} }}% + \_sdef{_famf:\_tmp}{#3}% + \_def\_famfile{#3}% +} +\_def\_famalias [#1]{% + \_lowercase{\_edef\_tmpa{\_ea\_removespaces #1 {} }}% + \_sdef{_famf:\_tmpa\_ea}\_ea{\_famfile}% +} +\_newtoks\_famfrom +\_input fams-ini.opm +\_let\_famfile=\_undefined +\_famfrom={} + + \_doc ----------------------------- + When the \^`\fontfam``[catalog]` is used then the file + `fonts-catalog.opm` is read. The macro \^`\_faminfo` is redefined here + in order to print catalog samples of all declared modifiers/variant + pairs. The user can declare different samples and different behavior of + the catalog, see the end of catalog listing for more information. + The default parameters + \`\catalogsample`, \`\catalogmathsample`, \`\catalogonly` and + \`\catalogexclude` of the catalog are declared here. + \_cod ----------------------------- + +\_newtoks \_catalogsample +\_newtoks \_catalogmathsample +\_newtoks \_catalogonly +\_newtoks \_catalogexclude +\_catalogsample={ABCDabcd Qsty fi fl áéíóúüů řžč ÁÉÍÓÚ ŘŽČ 0123456789} + +\_public \catalogonly \catalogexclude \catalogsample \catalogmathsample ; + + \_doc ----------------------------- + The font features are managed in the \`\_fontfeatures` macro. + They have their implicit values saved in the \`\_defaultfontfeatures` + and the \`\setff` `{<features>}` + can add next font features. If there is the same font feature as the newly + added one then the old value is removed from the `\_fontfeatures` list. + \_cod ----------------------------- + +\_def \_defaultfontfeatures {+tlig;} +\_def \_setff #1{% + \_ifx^#1^\_let \_fontfeatures=\_defaultfontfeatures + \_else \_edef\_fontfeatures{\_fontfeatures #1;}\_fi + \_reloading +} +\_setff {} % default font features: +tlig; +\_def\_removefeature #1{% + \_isinlist\_fontfeatures{#1}\_iftrue + \_def\_tmp ##1#1##2;##3\_relax{\_def\_fontfeatures{##1##3}}% + \_ea \_tmp \_fontfeatures \_relax + \_fi +} +\_public \setff ; + + \_doc ----------------------------- + The \`\setfontcolor` and \`\setletterspace` are macros based on the + special font features provided by \LuaTeX/ (and by \XeTeX/ too but it is not + our business). The \`\setwordspace` recalulates the `\fontdimen2,3,4` + of the font using the \`\setwsp` macro which is used by the + \^`\_doresizeunifont` macro. It activates a dummy font feature `+Ws` too in + order the font is reloded by the `\font` primitive (with independent + `\fontdimen` registers). + \_cod ----------------------------- + +\_def\_savedfontcolor{} +\_def\_savedletterspace{} +\_def\_savedwsp{} + +\_def \_setfontcolor #1{\_removefeature{color=}% + \_edef\_tmp{\_calculatefontcolor{#1}}% + \_ifx\_tmp\_empty \_else \_edef\_fontfeatures{\_fontfeatures color=\_tmp;}\_fi + \_reloading +} +\_def \_setletterspace #1{\_removefeature{letterspace=}% + \_if^#1^\_else \_edef\_fontfeatures{\_fontfeatures letterspace=#1;}\_fi + \_reloading +} +\_def \_setwordspace #1{% + \_if^#1^\_def\_setwsp##1{}\_removefeature{+Ws}% + \_else \_def\_setwsp{\_setwspA{#1}}\_setff{+Ws}\_fi + \_reloading +} +\_def\_setwsp #1{} +\_def\_setwspA #1#2{\_fontdimen2#2=#1\_fontdimen2#2% + \_fontdimen3#2=#1\_fontdimen3#2\_fontdimen4#2=#1\_fontdimen4#2} + +\_def\_calculatefontcolor#1{\_trycs{_fc:#1}{#1}} % you can define more smart macro ... +\_sdef{_fc:red}{FF0000FF} \_sdef{_fc:green}{00FF00FF} \_sdef{_fc:blue}{0000FFFF} +\_sdef{_fc:yellow}{FFFF00FF} \_sdef{_fc:cyan}{00FFFFFF} \_sdef{_fc:magenta}{FF00FFFF} +\_sdef{_fc:white}{FFFFFFFF} \_sdef{_fc:grey}{00000080} \_sdef{_fc:lgrey}{00000025} +\_sdef{_fc:black}{} % ... you can declare more colors... + +\_public \setfontcolor \setletterspace \setwordspace ; + +\_endcode %--------------------------------------------------- + + +\sec[fontsystem] The Font Selection System +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +The basic principles of the Font Selection System used in \OpTeX/ +was documented in the section~\ref[fontfam]. + +\secc Terminology + +We distinguish between +\begitems +* {\em font switchers}, they are declared by the `\font` primitive or by + \^`\fontlet` or \~`\fontdef` macros, they select given font. +* {\em variant selectors}, there are four basic variant selectors + \^`\rm`, \^`\bf`, \^`\it`, \^`\bi`, there is a special selector \^`\currvar`. + More variant selectors can be declared by the \~`\famvardef` macro. + They select the font depending on the given variant and on the {\em font context} + (i.e.\ on current family and on more features given by font modifiers). + In addition, \OpTeX/ defines \~`\tt` as variant selector + independent of chosen font family. It selects typewriter-like font. +* {\em font modifiers} are declared in a family (`\cond`, `\caps`) or are + \"build in" (\^`\setfontsize``{<size spec>}`, \~`\setff{<features>}`). + They do appropriate change in the {\em font context} but do not select + the font. +* {\em family selectors} (for example `\Termes`, `\LMfonts`), + they are declared typically in the {\em font family files}. + They enable to switch between font families, they do appropriate + change in the {\em font context} but do not select + the font. +\enditems + +These commands set their values locally. When the \TeX/ group is +left then the selected font and the {\em font context} are returned back to the values +used when the group was opened. They have the following features: + +The {\em font context} is a set of macro values that will affect the +selection of real font when the variant selector is processed. It includes the +value of {\em current family}, current font size, and +more values stored by font modifiers. + +The {\em family context} is the current family value stored in the font +context. The variant selectors declared by \~`\famvardef` and +font modifiers declared by \~`\moddef` are dependent on the {\em family context}. +They can have the same names but different behavior in different families. + +The fonts registered in \OpTeX/ have their macros in the {\em font family files}, +each family is declared in one font family file with the name `f-famname.opm`. +All families are collected in `fams-ini.opm` and users can give more +declarations in the file `fams-local.opm`. + +\secc Font families, selecting fonts + +The \^`\fontfam` `[<Font Family>]` opens the relevant font family file where +the `<Font Family>` is declared. The family selector is defined here by rules +described in the section~\ref[fontfamfiles]. Font modifiers and variant +selectors may be declared here. +The loaded family is set as current and `\rm` variant selector is processed. + +The available declared font modifiers and declared variant selectors are +listed in the log file when the font family is load. Or you can print +`\fontfam[catalog]` to show available font modifiers and variant selectors. + +The font modifiers can be independent, like `\cond` and `\light`. They can +be arbitrarily combined (in arbitrary order) and if the font family disposes +of all such sub-variants then the desired font is selected (after variant +selector is used). On the other hand, there are font modifiers that negates +the previous font modifier, for example: `\cond`, `\extend`. You can reset +all modifiers to their initial value by the \^`\resetmod` command. + +You can open more font families by more \^`\fontfam` commands. Then the +general method to selecting the individual font is: + +\begtt \catcode`\<=13 +<family selector> <font modifiers> <variant selector> +\endtt +For example: +\begtt +\fontfam [Heros] % Heros family is active here, default \rm variant. +\fontfam [Termes] % Termes family is active here, default \rm variant. +{\Heros \caps \cond \it The caps+condensed italics in Heros family is here.} +The Termes roman is here. +\endtt + +There is one special command \^`\currvar` which acts as a variant selector. +It keeps the current variant and the font of such variant is +reloaded with respect to the current font context by the previously given family +selector and font modifiers. + +You can use the \^`\setfontsize` `{<sizespec>}` command in the same sense as +other font modifiers. It saves information about font size to the font +context. See section~\ref[setfontsize]. Example: + +\begtt +\rm default size \setfontsize{at14pt}\rm here is 14pt size \it italic is +in 14pt size too \bf bold too. +\endtt + +A much more comfortable way to resize fonts is using OPmac-like commands +\~`\typosize` and \~`\typoscale`. +These commands prepare the right sizes for math +fonts too and they re-calculate many internal parameters like `\baselineskip`. +See section~\ref[opmac-fonts] for more information. + + +\secc Math Fonts +%--------------- + +Most font families are connected with a preferred Unicode-math font. This +Unicode-math is activated when the font family is loaded. If you don't prefer +this and you are satisfied with 8bit math CM+AMS fonts preloaded in the +\OpTeX/ format then you can use command \^`\noloadmath` before you load a first +font family. + +If you want to use your specially selected Unicode-math font then use +\^`\loadmath` `{[<font_file>]}` or \^`\loadmath` `{<font_name>}` before first +`\fontfam` is used. + + +\secc[fontcommands] Declaring font commands +%---------------------------- + +Font commands can be font switches, variant selectors, font modifiers, +family selectors and defined font macros doing something with fonts. + +\begitems +* Font switches can be decared by `\font` primitive (see + section~\ref[fontprimitive]) or by \^`\fontlet` command (see + section~\ref[fontlet]) or by \~`\fontdef` command (see + sections~\ref[fontdef2] and~\ref[fontdef]). + When the font switches are used then they select the given font independently + of the current font context. They can be used + in `\output` routine (for example) because we need to set fixed fonts + in headers and footers. +* Variant selectors are \^`\rm`, \^`\bf`, \^`\it`, \^`\bi`, \~`\tt` and \^`\currvar`. More + variant selectors can be declared by \~`\famvardef` command. They select a + font dependent on the current font context, see section~\ref[famvardef]. + The `\tt` selector is documented in section~\ref[tt]. +* Font modifiers are \"build in" or declared by \~`\moddef` command. + They do modifications in the font context but don't select any font. + \begitems + * \"build-in" font modifiers are \^`\setfontsize` (see + section~\ref[setfontsize]), \~`\setff` (see section~\ref[setff]), + \~`\setfontcolor`, \~`\setletterspace` and \~`\setwordspace` + (see section~\ref[specff]). They are independent of font family. + * Font modifiers declared by \~`\moddef` depend on the font family and they + are typically declared in font family files, see + section~\ref[fontfamfiles]. + \enditems +* Family selectors set the given + font family as current and re-set data used by the family-dependent font + modifiers to initial values and to the currently used modifiers. + They are declared in font family files + by \~`\_famdecl` macro, see section~\ref[fontfamfiles]. +* Font macros can be defined arbitrarily by `\def` primitive by users. + See an example in section~\ref[fontmacros]. +\enditems + +All declaration commands mentioned here: `\font`, `\fontlet`, `\fontdef`, `\famvardef`, +`\moddef`, `\_famdecl` and `\def` make local assignment. + +\secc[fontdef2] The `\fontdef` declarator in detail + +The general format for \^`\fontdef` usage is +\begtt \catcode`\<=13 +\fontdef\<font switch> {\<family selector> <font modifiers> \<variant selector>} +\endtt +% +where `\<family selector>` and `<font modifiers>` are optional and +`\<variant selector>` is mandatory. + +The \^`\fontdef` does the following steps. +It pushes the current font context to a stack, it does modifications of the font +context by given `\<family selector>` and/or `<font modifiers>` and it +finds the real font by `\<variant selector>`. This font is not selected but +it is assigned to the declared `\<font switch>` (like `\font` primitive does +it). Finally, `\fontdef` pops the font context stack, so the current +font context is the same as it was before `\fontdef` is used. + +More about `\fontdef` command including examples is written in +section~\ref[fontdef]. + + +\secc[famvardef] The `\famvardef` declarator + +You can declare a new variant selector by the \^`\famvardef` macro. This +macro has similar syntax as \^`\fontdef`: +\begtt \catcode`\<=13 +\famvardef\<new variant selector> {\<family selector> <font modifiers> \<variant selector>} +\endtt +% +where `\<family selector>` and `<font modifiers>` are optional and +`\<variant selector>` is mandatory. +The `\<new variant selector>` should be used in the same sense as `\rm`, +`\bf` etc. It can be used as the final command in next +\^`\fontdef` or \^`\famvardef` declarators +too. When the `\<new variant selector>` is used in the normal text then it does +the following steps: pushes current font context to a stack, modifies font +context by declared `\<family selector>` and/or `<font modifiers>`, +runs following `\<variant selector>`. +This last one selects a real font. Then pops the font context stack. +The new font is selected but the font context has its original values. +This is main difference between `\famvardef\foo{...}` and `\def\foo{...}`. + +Moreover, the \^`\famvardef` creates the `\<new variant selector>` family dependent. +When the selector is used in another family context than it is defined then a warning is +printed on the terminal \"<var selector> is undeclared in the current family" +and nothing happens. But you can declare the same variant selector by +\^`\famvardef` macro in the context of a 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 `\<family selector>` can be written before `<font modifiers>` in the +`\famvardef` parameter. Then the `\<new variant selector>` is declared in +the current family but it can use fonts from another family represented by +the `\<family selector>`. + +When you are mixing fonts from more families then you probably run +into a 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 namespace can be here. For example: if `\mf` is defined by a 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 an additional special variant selector which is defined as \"select typewriter +font independently of the 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 a special feature only +for `\tt` selector. New definition is used in \^`\_ttfont` and \^`\_urlfont` too. +It is recommended to use `\setff{-liga;-tlig}` to suppress the +ligatures 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, +citations, etc. Users can define them. + +The following example shows how to define a \"title-font selector". +Titles are not only bigger but they are typically in the bold variant. When a 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` `{<feature>}` acts like family independent font modifier and +prepares a new <feature>. 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 support the given font feature then the font is reloaded +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 +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{<sizespec>} % sets the font size +\setff{<font feature>} % adds the font feature +\setfontcolor{<color>} % sets font color +\setletterspace{<number>} % sets letter spacing +\setwordspace{<scaling>} % modifies word spacing +\endtt + +The \^`\setfontsize` command is described in the section \ref[setfontsize]. +The \^`\setff` command was described in previous subsection. + +\^`\setfontcolor` `{<color>}` specifies the color and the opacity of the text. +The <color> parameter should be in the hexadecimal format of four bytes +`<red><green><blue><opacity>`, 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 the backslash) +instead of the hexadecimal specification. +The empty parameter `<color>` means default black color. + +These colors of fonts are implemented using \LuaTeX/ internal font feature. This +is different approach than using colors in section \ref[colors]. + +\^`\setletterspace` `{<number>}` specifies the letter spacing of the font. The +`<number>` is a 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 `<number>` means no letter spacing which is the default. + +\^`\setwordspace` `{<scaling>}` scales the default interword space (defined in the +font) and its stretching and shrinking parameters by given `<scaling>` +factor. For example `\setwordspace{2.5}` multiplies interword 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 +\setff{upper}\rm % to uppercase (lower=lowecase) conversion at font level +\endtt + +Use font transformations mentioned above and \^`\setletterspace`, +\^`\setwordspace` with care. The best setting of these values is the default +setting in every font, of course. If you really need to set a different +letter spacing then it is strongly recommended to add `\setff{-liga}` +to disable ligatures. And setting a positive letter spacing probably +needs to scale interword spacing too. + +All mentioned font modifiers (except for `\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 loaded by extended `\font` primitive. This extension is +not activated in \OpTeX/ by default, \^`\initunifonts` macro activates it. +You need not use \^`\initunifonts` explicitly if \^`\fontfam` macro is +used because \^`\fontfam` runs it internally. + +The \^`\initunifonts` loads the Lua code from the Luaotfload package which +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 to 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 the 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 the `luahbtex` engine is not used then `mode=harf` is ignored. See +Luaotfload documentation for more information. + +\endinput + +2021-02-25 \_ttunifont introduced +2021-01-27 lua hack (print function) removed because luaotfload 3.17 removes bug. +2020-12-12 \_modlist added, doc improved +2020-04-18 \_tryloadfamslocal introduced + \_fontdecl -> \_famdecl with different concept +2020-03-18 released |