summaryrefslogtreecommitdiff
path: root/macros/luatex/optex/base/fonts-select.opm
blob: 83ded2f35b8e50fa52739eb980e552fc4abe95b4 (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
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
%% This is part of OpTeX project, see http://petr.olsak.net/optex

\_codedecl \fontfam {Fonts selection system <2020-03-18>} % preloaded in format

   \_doc -----------------------------
   The \`\initunifonts` initializes extended `\font` primitive 
   (to be able to load Unicode fonts). Unfortunately, this part of
   \OpTeX/ depends on \LaTeX/ lua codes `ltluatex.lua` and
   `luaotfload-main.lua`. And this code need to be declared a
   control sequence `\e@alloc@attribute@count` by `\countdef` primitive.
   Moreover, the `\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, the `\initunifnt` sets itself to relax because we need not to do
   this work twice.
   \_cod -----------------------------

\_def\_initunifonts {%
   \_ea\_newcount \_csname e@alloc@attribute@count\_endcsname
   \_global \_csname e@alloc@attribute@count\_endcsname=-1   
   \_directlua{%
      require("ltluatex")
      require('luaotfload-main') local _void = luaotfload.main ()
   }%
   \_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` `[<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 \`\_mainfamcommand` 
   macro because the \`\_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 faily context. The font family context is given by the current
   `\_currfamily` value and by the actual meaning of the \^`\_fontnamegen` macro. 
   \_cod -----------------------------

\_def\_famdecl [#1]#2#3#4#5#6#7#8{%
   \_initunifonts \_uniaccents
   \_ifx #2\_undefined 
      \_isfont{#7}\_iffalse
         \_opwarning{Family [#1] skipped, font "#7" not found}\_ea\_ea\_ea\_endinput \_else
         \_edef\_currfamily {\_csstring #2}%
         \_def\_mainfamcommand{#2}\_def\_mathfaminfo{#6}%
         \_protected\_edef#2{\_def\_noexpand\_currfamily{\_csstring #2}\_unexpanded{#8\_resetmod}}%
         \_wterm {FONT: [#1] -- \_string#2 \_detokenize{(#3)^^J mods:{#4} vars:{#5} math:{#6}}}%
      \_fi 
   \_else \_ea #2\_ea\_endinput \_fi
}
\_def\_initfontfamily{%
   \_mainfamcommand \_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
   \`\_fset` `<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>`.
   \_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{,#2,}{,\_cs{_#1V},}}\_act
    \_iftrue #3\_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
   warning. When the `\_currfamily` value is
   changed then we can declare the same `\<modifier>` with different meaning.

   When user declare a prefixed variant of the `\<modifier>` then unprefixed
   modifier name is used in internal macros, this is 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 `_`.
   \_cod -----------------------------

\_def \_moddef #1#2{\_edef\_tmp{\_csstring#1}\_remfirstunderscore\_tmp
   \_sdef{_f:\_currfamily:\_tmp}{#2\_reloading}%
   \_protected \_edef #1{\noexpand\_famdepend\noexpand#1{_f:\noexpand\_currfamily:\_tmp}}%
   \_ea \_ifx \_csname\_tmp\_endcsname #1\_else
      \_ea \_public \_csname\_tmp\_endcsname ;\_fi
}
\_def\_remfirstunderscore#1{\_ea\_remfirstunderscoreA#1\_relax#1}
\_def\_remfirstunderscoreA#1#2\_relax#3{\_if _#1\_def#3{#2}\_fi}

\_protected \_def\_resetmod {\_cs{_f:\_currfamily:resetmod}} % private variant of \resetmod
\_def\_currfamily{} % default current family is empty

\_def\_famdepend#1#2{\_ifcsname#2\_endcsname \_csname#2\_ea\_endcsname \_else
   \_opwarning{\_string#1 is undeclared in current family "\_currfamily", ignored}\_fi
}
\_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
   * `\protected\def \<XX> {\_famdepend \<XX> {_f:\_currfamily:<XX>}}`,
   * `\def \_f:<current family>:<XX> {\_tryload<XX>\_ten<XX>}` keeps family dependent definition,
   * `\def \_tryload<XX> {`\^`\fontdef`` \_ten<XX> {<data>}}` loads actually the font `\_ten<XX>`,
   * `\def \_currvar:_ten<XX> {\<XX>}` in ordef to the \^`\currvar` macro
   work correctly.
   \enditems
   \_cod -----------------------------

\_def\_famvardef#1{\_edef\_tmp{\_csstring#1}\_remfirstunderscore\_tmp
   \_ea\_famvardefA \_ea#1\_csname _ten\_tmp\_ea\_endcsname
      \_csname _tryload:\_tmp\_endcsname
}
\_def\_famvardefA #1#2#3#4{% #1=\_XX #2=\_tenXX #3=\_tryloadXX #4=data
   \_isinlist{.\_rm\_bf\_it\_bi\currvar\_currvar}#1\_iftrue
      \_opwarning{\_string\famvardef: 
          You cannot re-declare private standard variant selector \_string#1}%
   \_else
      \_protected\_edef #1{\_noexpand\_famdepend\_noexpand#1{_f:\_noexpand\_currfamily:\_tmp}}%
      \_sdef{_f:\_currfamily:\_tmp}{#3#2}%
      \_def#3{\_fontdef#2{#4}}%
      \_ifx#1\tt \_addto#1{\_fam\_ttfam}\_fi
      \_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 to 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}
   \_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-loca.opm` files are read then we need
   to save ony 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 infrormation 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. 
   \_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\_famname{\_ea\_removespaces #1 {} }}%
   \_sdef{_famf:\_famname\_ea}\_ea{\_famfile}%
}   
\_input fams-ini.opm
\_let\_famfile=\_undefined

   \_doc -----------------------------
   When the \^`\fontfam``[catalog]` is used then the file
   `fonts-tatalog.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,
* {\em variant selectors}, there are four basic variant selectors
  `\rm`, `\bf`, `\it`, `\bi`, there is a special selector `\currvar`
  and more variant selectors can be declared by the \^`\famvardef` macro.
* {\em font modifiers} (for example `\cond`, `\caps`, \^`\setfontsize``{<size spec>}`), 
  they are in two types: bulid in (like \^`\setfontsize`) or
  declared modifiers (by by the \^`\moddef` macro).
* {\em family selectors} (for example `\Termes`, `\LMfonts`), 
  they are declared typically in the {\em font family files}. 
\enditems

These selectors / switchers sets its values locally. When the \TeX/ group is
leaved then selected font and the {\em font context} are returned back to the values
used when the group was opened. They have the following features:

\begitems
* The {\em font switchers} select fonts independent on the font context.
* The {\em variant selectors} select the font depending on the font context and on
  the specified variant.
* The {\em font modifiers} create a change in the font context but they 
  don't select the font itself.
* The {\em family selectors} set a family in the font context and resets all
  font modifiers. They dont't select the font itself.
\enditems

The variant selectors and declared font modifiers are 
defined in the family context.  They can behave differently 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 user 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. Their definitions depends on given family.
The family is set as active in the font context and `\rm` variant selector is run.

The available declared font modifiers and declared variant selectors are
listed in the log file when 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 arbitrary combined (in arbitrary order) and if the font family disposes
with all such sub-variants then the desired font is selected (after variant
selector is used). On the other hand there are font modifiers which 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 variant selector. 
It keeps the current variant and the font of such variant is 
reloaded with respect to the current font context by previously given family
selector and font modifiers. 

You can use the \^`\setfontsize` `{<sizespec>}` command in the same sense as
other font modifiers. It saves only 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

Much more comfortable way to resize fonts is using OPmac-like command
`\typosize`, `\typoscale`. 
These commands prepare the right sizes for math
fonts too and re-calculates 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 Declaring font commands
%----------------------------

The font switches can be declared by `\font` primitive or by \^`\fontdef` or
\^`\fontlet` macros. See the sections~\ref[fontdef] and~\ref[fontlet] 
for more details. The general format for \^`\fontdef` is
\begtt \catcode`\<=13
\fontdef\<font switch> {\<family selector> <font modifiers> \<variant selector>}
\endtt

Such font switches should be used in `\output` routine (headers, footers) for
example. We need fixed sizes here. But they are less usable in common
text. For example the document includes notices in smaller font. 
When the notice is started then we want
to do all variants smaller: `\rm`, `\it`, `\bf`, etc.
It means that the smaller font for notices should be initialized by
`\setfontsize{at9pt}\rm` for example. If you want a \"notices font selector"
then you can do `\def\noticefont{\setfontsize{at9pt}\rm}`. This font
selector does not change the `\baselineskip`. If you want to do this then
put different `\baselineskip` setting to your definition. But you must not
forget that the end of group before `\par` is a typical mistake of \TeX/
users: the last paragraph is in smaller font but in normal baselineskip,
because `\baselineskip` setting is taken into account when `\par` 
command is processed.

Somewhat more complicated task is the \"title font selector", because titles are
not only bigger but they are typically in bold variant. When the user puts 
`{\it...}` into the title 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 here we have bold 14pt font and {\it here} was bold 14pt italics}
\endtt

You can declare a new variant slector by the \^`\famvardef` macro. This
macro has similar syntax as \^`\fontdef`:
\begtt \catcode`\<=13
\famvardef\<new variant selector> {<font modifiers> \<variant selector>}
\endtt
%
The `\<new variant selector>` should be used in the same sense as `\rm`,
`\bf` etc. It can be used as the final command in the 
`\fontdef` or `\famvardef` declarators
too. When the `\<new variant selector>` is used in normal text then it does
following steps: pushes current font context to a stack, modifies font
context by declared `<font modifiers>`, runs following `\<variant selector>`.
It selects a font. Then pops the stack. The font context have its original
values but new font is selected.

The \^`\famvardef` creates the `\<new variant selector>` family dependent.
When the selector is used in another family than it is defined then warning is
printed on the terminal \"<var selector> 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
will be 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 but supports only basic variant selectors `\rm`, `\bf`, `\it`,
and `\bi`. Then you can declare:
\begtt
\famvardef \mr {\medium\rm}
\famvardef \mi {\medium\it}
\endtt
Now, you can use six independent variant selectors `\rm`, `\bf`, `\it`,
`\bi`, `\mr` 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 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

There exists analogical declarator `\moddef` for declaration family dependent 
font modifiers. It is described in detail the section~\ref[fontfamfiles].


\secc 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 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 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 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 backslash) 
instead of the hexadecimal specification. 
The empty parameter `<color>` 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` `{<number>}` specifies letter spacing of the font. The
`<number>` 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 `<number>` means no letter spacing which is default.

\^`\setwordspace` `{<scaling>}` scales the default inter word space (defined in the
font) and its stretching and shrinking parameters by given `<scaling>`
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

\endinput

2020-04-18  \_tryloadfamslocal introduced
            \_fontdecl -> \_famdecl with different concept
2020-03-18  released