summaryrefslogtreecommitdiff
path: root/macros/optex/base/f-heros.opm
blob: a7aebdb4b827cbb0141ee4bfa3d990da2b3874b6 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
%% This is part of the OpTeX project, see http://petr.olsak.net/optex

\_famdecl [Heros] \Heros {TeX Gyre Heros fonts based on Helvetica}
     {\caps \cond} {\rm \bf \it \bi} {FiraMath}
     {[texgyreheros-regular]}
     {\_def\_fontnamegen{[texgyreheros\_condV-\_currV]:\_capsV\_fontfeatures}}

\_wlog{\_detokenize{%
Modifiers:^^J
 \caps ...... caps & small caps^^J
 \cond ...... condensed variants^^J
}}

\_moddef \resetmod {\_fsetV caps={},cond={} \_fvars regular bold italic bolditalic }
\_moddef \caps     {\_fsetV caps=+smcp;\_ffonum; }
\_moddef \nocaps   {\_fsetV caps={} }
\_moddef \cond     {\_fsetV cond=cn }
\_moddef \nocond   {\_fsetV cond={} }

\_initfontfamily % new font family must be initialized

\_ifmathloading
   \_loadmath {[FiraMath-Regular]}
   \_addUmathfont \_xits {[XITSMath-Regular]}{} {[XITSMath-Bold]}{} {}
   \_addto\_frak{\_fam\_xits}\_addto\_cal{\_fam\_xits} \_public \frak \cal ;
   % \bf, \bi from FiraMath:
   \_let\_bsansvariables=\_bfvariables
   \_let\_bsansGreek=\_bfGreek
   \_let\_bsansgreek=\_bfgreek
   \_let\_bsansdigits=\_bfdigits
   \_let\_bisansvariables=\_bivariables
   \_let\_bisansgreek=\_bigreek
   % \_resetmathchars <fam-number> <list of \Umathchardef csnames> ;
   \_mathchars \_xits {\bigtriangleup \bigblacktriangleup \blacktriangle
       \vartriangle \smallblacktriangleright
       \unicodevdots \unicodeadots \unicodeddots} % ... etc. you can add more
\_fi

\_endcode

The font family file declares the font family for selecting fonts from this
family at the arbitrary size and with various shapes. Unicode fonts (OTF)
are preferred. The following example declares the Heros family:

\printdoc f-heros.opm

If you want to write such a font family file, you need to keep the following rules.

\begitems
* Use the \^`\_famdecl` command first. It has the following syntax:
\begtt \catcode`\<=13
\_famdecl [<Name of family>] \<Familyselector> {<comments>}
     {<modifiers>} {<variant selectors>} {<comments about math fonts>}
     {<font-for-testing>}
     {\_def\_fontnamegen{<font name or font file name generated>}}
\endtt
  This writes information about font family at the
  terminal and prevents loading such file twice. Moreover, it probes
  existence of `<font-for-testing>` in your system. If it doesn't exist, the
  file loading is skipped with a warning on the terminal.
  The \^`\_ifexistfam` macro returns false in this case.
  The \^`\_fontnamegen` macro must be defined in the last parameter of the
  \^`\_famdecl`. More about it is documented below.
* You can use `\_wlog{\_detokenize{...` to write additional information into a log file.
* You can declare optical sizes using \~`\_regoptsizes` if there are more font files
  with different optical sizes (like in Latin Modern). See `f-lmfonts.opm`
  file for more information about this special feature.
* Declare font modifiers using \~`\moddef` if they are present. The \`\resetmod`
  must be declared in each font family.
* Check if all your declared modifiers do not produce any space in
  horizontal mode. For example check: `X\caps Y`, the letters `XY` must
  be printed without any space.
* Optionally, declare new variants by the \^`\famvardef` macro.
* Run `\_initfontfamily` to start the family (it is mandatory).
* If math font should be loaded, use `\_loadmath{<math font>}`.
\enditems

{\noindent \bf The \`\_fontnamegen` macro}
(declared in the last parameter of the \^`\_famdecl`)
must expand (at the expand processor level only) to a file name of the loaded font (or to its font
name) and to optional font features appended. The Font Selection
System uses this macro at the primitive level in the following sense:

\begtt \catcode`\<=13
\font \<font-switch> {\_fontnamegen} \_sizespec
\endtt
%
Note that the extended `\font` syntax
`\font\<font-switch> {<font name>:<font features>} <size spec.>` or
`\font\<font-switch> {[<font file name>]:<font features>} <size spec.>`
is expected here.

\seccc Example 1

Assume an abstract font family with fonts `xx-Regular.otf`,
`xx-Bold.otf`, `xx-Italic.otf` and `xx-BoldItalic.otf`. Then you can declare
the \^`\resetmod` (for initializing the family) by:
\begtt
\_moddef\resetmod{\_fvars Regular Bold Italic BoldItalic }
\endtt
and define the \^`\_fontnamegen` in the last parameter of the \^`\_famdecl` by:
\begtt
\_famdecl ...
    {\def\_fontnamegen{[xx-\_currV]}}
\endtt
The following auxiliary macros are used here:
\begitems
* \^`\moddef` declares the family dependent modifier. The \^`\resetmod` saves
  initial values for the family.
* \^`\_fvars` saves four names to the memory, they are used by the \^`\_currV` macro.
* \^`\_currV` expands to one of the four names dependent on `\rm` or `\bf` or
  `\it` or `\bi` variant is required.
\enditems
Assume that the user needs `\it` variant in this family. Then the
`\_fontnamegen` macro expands to `[xx-\_currV]` and it expands to
`[xx-Italic]`. The Font Selection System uses `\font {[xx-Italic]}`.
This command loads the `xx-Italic.otf` font file.

See more advanced examples are in `f-<family>.opm` files.

\seccc Example 2

The `f-heros.opm` is listed here. Look at it.
When Heros family is selected and `\bf` is asked then
`\font {[texgyreheros-bold]:+tlig;} at10pt`
is processed.

You can use any expandable macros or expandable primitives in the `\_fontnamegen`
macro. The simple macros in our example with names `\_<word>V` are preferred. They
expand typically to their content. The macro \^`\_fsetV` `<word>=<content>`
(terminated by a space) is equivalent to `\def\_<word>V{<content>}` and you
can use it in font modifiers. You can use the \^`\_fsetV` macro in more
general form:

\begtt \catcode`\<=13
   \_fsetV <word-a>=<value-a>,<word-b>=<value-b>  ...etc. terminated by a space
\endtt
%
with obvious result `\def\_<word-a>V {<value-a>}\def\_<word-b>V {<value-b>}` etc.

\seccc Example 3

If both font modifiers `\caps`, `\cond` were applied in Heros
family, then `\def\_capsV{+smcp;\_ffonum;}` and `\def\_condV{cn}` were processed
by these font modifiers. If a user needs the `\bf` variant at 11\,pt now then
the

\begtt
  \font {[texgyreheroscn-bold]:+smcp;+onum;+pnum;+tlig;} at11pt
\endtt
%
is processed. We assume that a font file `texgyreheroscn-bold.otf` is present
in your \TeX/ system.

\seccc The \code{\\_onlyif} macro

has the syntax \^`\_onlyif` `<word>=<value-a>,<value-b>,...<value-n>: {<what>}`. It can
be used inside `\moddef` as simple IF statement: the `<what>` is processed only
if `<word>` has `<value-a>` or `<value-b>` \dots or `<value-n>`. See
`f-roboto.opm` for examples of usage of many `\_onlyif`'s.

Recommendation: use the \^`\_fontfeatures` macro at the end of the `\_fontnamegen`
macro in order to the \^`\setff`, \^`\setfontcolor`, \^`\setletterspace`
macros can work.

\seccc The \code{\\moddef} macro

has the syntax \^`\moddef\<modifier>{<what to do>}`. It does more things than simple `\_def`:

\begitems
* The modifier macros are defined as `\_protected`.
* The modifier macros are defined as family-dependent.
* If the declared control sequence is defined already (and it is not a font
  modifier) then it is re-defined with a warning.
\enditems
\noindent
The \^`\famvardef` macro has the same features.

\bigskip
{\noindent\bf The `\<Familyselector>`}
is defined by the \^`\_famdecl` macro as:
\begtt \catcode`<=13
\protected\def\<Familyselector> {%
   \_def\_currfamily {<Familyselector>}%
   \_def\_fontnamegen {...}% this is copied from 7-th parameter of \_famdecl
   \resetmod
   <run all family-dependent font modifiers used before Familyselector without warnings>
\endtt

{\noindent\bf The \^`\_initfontfamily`}\nl
must be run after modifier's decaration.
It runs the `\<Familyselector>` and it runs `\_rm`,
so the first font from the new family is loaded and it is ready to use it.

\seccc Name conventions

Create font modifiers, new variants, and the `\<Familyselector>` only in
public namespace without `_` prefix. We assume that if a user re-defines them then he/she needs
not them, so we have no problems. If the user's definition was done before loading
the font family file then it is re-defined and \OpTeX/ warns about it. See the end of
section~\ref[fontcommands].

If you need to use an internal control sequence declared in your fontfile,
use the reserved name space with names starting with two `_` followed by family
indentifier or by `vf` if it relates to variable fonts.

The name of `\<Familyselector>` should begin with an uppercase letter.

Please, look at
\ulink[http://petr.olsak.net/ftp/olsak/optex/op-catalog.pdf]{\OpTeX/ font catalogue}
before you will create your font family file and use the same names for
analogical font modifiers (like `\cond`, `\caps`, `\sans`, `\mono` etc.)\
and for extra variant selectors (like `\lf`, `\li`, `\kf`, `\ki` etc.\ used in
Roboto font family).

If you are using the same font modifier names to analogical font shapes then
such modifiers are kept when the family is changed. For example:

\begtt
\fontfam [Termes] \fontfam[Heros]
\caps\cond\it Caps+Cond italic in Heros \Termes\currvar Caps italic in Termes.
\endtt
%
The family selector first resets all modifiers data by
\^`\resetmod` and then it tries to run all currently used family-dependent modifiers
before the family switching (without warnings if such modifier is
unavailable in the new family).
In this example, `\Termes` does `\resetmod` followed by `\caps\cond`.
The `\caps` is applied and `\cond` is silently ignored in Termes family.

If you need to declare your private modifier (because it is used in other
modifiers or macros, for example), use the name `\_wordM`. You can be
sure that such a name does not influence the private namespace used by \OpTeX/.

\seccc Additional notes

See the font family file `f-libertine-s.opm` which is another example where no
font files but font names are used.

See the font family file `f-lmfonts.opm` or `f-poltawski.opm` where you can find the
the example of the optical sizes declaration including documentation about
it.

Several fonts don't switch to the font features if the features are
specified directly as documented above. You must add the `script=latn;`
specification to the features string when using these fonts, see
`f-baskerville.opm` for example. The reason: these fonts don't follow the
OpenType specification and they don't set the `DFLT` script but only scripts
with given names like `latn`. And the tables implementing all font features
are included here. You can check the internals of the font by FontForge:
View / Show~ATT / OpenType Tables / GSUB. Do you see the `DFLT` script here?

If you need to create a font family file with a non-Unicode font, you can do it.
The `\_fontnamegen` must expand to the name of TFM file in this case. But we
don't prefer such font family files, because they are usable only with
languages with alphabet subset to ISO-8859-1 (Unicodes are equal to letter's
codes of such alphabets), but middle or east Europe use languages where
such a condition is not true.