summaryrefslogtreecommitdiff
path: root/macros/optex/base/fonts-resize.opm
blob: 68ebf763db46f8db585deb4deafedde1e34d6b06 (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
%% This is part of the OpTeX project, see http://petr.olsak.net/optex

\_codedecl \setfontsize {Font resizing macros <2021-05-02>} % preloaded in format

   \_doc -----------------------------
   The \`\setfontsize` `{<sizespec>}` saves the `<sizespec>` to the \`\_sizespec` macro.
   The \`\_optsize` value is calculated from the `<sizespec>`.
   If the `<sizepec>` is in the `mag<number>` format then the contents of
   the `\_sizespec` macro is re-calculated to the `at<dimen>` format using
   previous `\_optsize` value.
   \par \goodbreak
   \_cod -----------------------------

\_newdimen \_optsize         \_optsize=10pt
\_newdimen \_defaultoptsize  \_defaultoptsize=10pt
\_newdimen\_lastmagsize

\_def\_setfontsize #1{%
   \_edef\_sizespec{#1}%
   \_ea \_setoptsize \_sizespec\_relax
   \_reloading
}
\_def\_setoptsize {\_isnextchar a{\_setoptsizeA}
                                 {\_isnextchar m{\_setoptsizeC}{\_setoptsizeB}}}
\_def\_setoptsizeA at#1\_relax{\_optsize=#1\_relax\_lastmagsize=\_optsize}   % at<dimen>
\_def\_setoptsizeB scaled#1\_relax{\_optsize=\_defaultoptsize\_relax} % scaled<scalenum>
\_def\_setoptsizeC mag#1\_relax{%
   \_ifdim\_lastmagsize>\_zo \_optsize=\_lastmagsize \_else \_optsize=\_pdffontsize\_font \_fi
   \_optsize=#1\_optsize
   \_lastmagsize=\_optsize
   \_edef\_sizespec{at\_the\_optsize}%
}
\_public \setfontsize \defaultoptsize ;

   \_doc -----------------------------
   \`\fontlet` `<font switch A> <font switch B> <size spec>` does
   \begtt \catcode`\<=13
   \font <font switch A> = <fontname> <sizespec>
   \endtt
   The `<fontname>` is extracted using the primitive command `\_fontname <font switch B>`.
   \_cod -----------------------------

\_def\_fontlet#1#2{\_ifx #2=\_ea\_fontlet \_ea#1\_else
   \_ea\_font\_ea#1\_ea\_rfontskipat\_fontname#2 \_relax\_space \_fi
}
\_public \fontlet ;

   \_doc -----------------------------
   \`\newcurrfontsize` `<size spec>` sets current font size to the `<size spec>`
   It is implemented by \^`\fontlet`.
   The font switch of the current font is extracted by `\_the\_font`.
   We must re-create the control sequence `\_the\_font` because
   its original meaning is set to \"inaccessible" by \TeX/ when `\font`
   primitive is started.
   \nl
   \`\resizethefont` is implemented by `\newcurrfontsize` using data from
   the \^`\_sizespec` macro.
   \_cod -----------------------------

\_def \_newcurrfontsize #1{% \newcurrfontsize{at25pt}
   \_edef\_tmp{\_ea\_csstring \_the\_font}%
   \_ea \_fontlet \_csname \_tmp\_ea\_endcsname \_the\_font \_space #1\_relax
   \_ea\_fontloaded \_csname \_tmp \_ea\_endcsname \_csname \_tmp\_endcsname
}
\_protected\_def \_resizethefont{\_newcurrfontsize\_sizespec}

 \_public \newcurrfontsize \resizethefont ;

   \_doc -----------------------------
   The \`\_regtfm` `<font id> <optical size data>`
   saves the <optical size data> concerned to `<font id>`.
   The `<optical size data>` is in the form as shown below in the code where
   `\_regtfm` is used.
   \nl
   The \`\_wichtfm` `<fontname>` expands to the `<fontname>` or to the corrected
   `<fontname>` read from the `<optical size data>`. It is used in the
   \^`\_rfontskipat` macro and it is used in \^`\fontlet` macro.
   It means that each `<fontname>` generated by the `\fontname` primitive in the
   `\fontlet` macro is processed by the `\_whichtfm`. The real `<fontname>` or
   corrected `<fontname>` (depending on the optical data does not exist or exist)
   is the output of the expansion before `\font` primitive takes this output
   as its parameter.

   The implementation detail: The `\_<font id>:reg` is defined as the
   `<optical size data>` and all control sequences `\_<fontname>:reg`
   from this data line have the same meaning because of the
   \`\_reversetfm` macro. The `\_whichtfm` expands this data line and apply
   \`\_dowhichtfm`. This macro selects the right result from the data line
   by testing with the current `\_optsize` value.
   \_cod -----------------------------

\_def\_regtfm #1 0 #2 *{\_ea\_def \_csname _#1:reg\_endcsname{#2 16380 \_relax}%
  \_def\_tmpa{#1}\_reversetfm #2 * %
}
\_def\_reversetfm #1 #2 {% we need this data for \_setmathfamily
   \_ea\_let\_csname _#1:reg\_ea\_endcsname
   \_csname _\_tmpa:reg\_endcsname
   \_if*#2\_else \_ea\_reversetfm \_fi
}
\_def\_whichtfm #1{%
   \_ifcsname _#1:reg\_endcsname
      \_ea\_ea\_ea \_dowhichtfm
      \_csname _#1:reg\_ea\_endcsname
   \_else
      #1%
   \_fi
}
\_def\_dowhichtfm #1 #2 {%
   \_ifdim\_optsize<#2pt #1\_ea\_ignoretfm\_else \_ea\_dowhichtfm
\_fi
}
\_def\_ignoretfm #1\_relax{}

   \_doc -----------------------------
   Optical sizes data for preloaded 8bit Latin Modern fonts:
   \_cod -----------------------------

\_regtfm lmr  0 ec-lmr5 5.5 ec-lmr6 6.5 ec-lmr7 7.5 ec-lmr8 8.5 ec-lmr9 9.5
                ec-lmr10 11.1 ec-lmr12 15 ec-lmr17 *
\_regtfm lmbx 0 ec-lmbx5 5.5 ec-lmbx6 6.5 ec-lmbx7 7.5 ec-lmbx8 8.5 ec-lmbx9 9.5
                ec-lmbx10 11.1 ec-lmbx12 *
\_regtfm lmri 0 ec-lmri7 7.5 ec-lmri8 8.5 ec-lmri9 9.5 ec-lmri10 11.1 ec-lmri12 *
\_regtfm lmtt 0 ec-lmtt8 8.5 ec-lmtt9 9.5 ec-lmtt10 11.1 ec-lmtt12 *

\_endcode %---------------------------------------------------


\sec[setfontsize] Scaling fonts in text mode (low-level macros)
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

This section describes single part of Font Selection System: resizing fonts
to various sizes. This feature is available in both modes: TFM mode
(initialized when format starts) and OTF mode (after \~`\fontfam` or
\~`\initunifonts` is used).

\secc The `\setfontsize` macro

The \^`\setfontsize` `{<size spec>}`
saves the information about `<size spec>`. This information is taken into
account when a variant selector (for example `\rm`, `\bf`, `\it`, `\bi`)
or `\resizethefont` is used. The `<size spec>` can be:
\begitems
* `at<dimen>`, for example `\setfontsize{at12pt}`. It gives the desired font size directly.
* `scaled<scale factor>`, for example `\setfontsize{scaled1200}`. The font is
  scaled in respect to its native size (which is typically 10\,pt). It
  behaves like `\font\... scaled<number>`.
* `mag<decimal number>`, for example `\setfontsize{mag1.2}`. The font is
  scaled in respect to the current size of the fonts given by the previous
  \^`\setfontsize` command.
\enditems
The initialization value in \OpTeX/ is given by `\setfontsize{at10pt}`.

The \^`\resizethefont` resizes the currently selected font to the size given by previous
\^`\setfontsize`. For example

\begtt
                     The 10 pt text is here,
\setfontsize{at12pt} the 10 pt text is here unchanged...
\resizethefont       and the 12 pt text is here.
\endtt
%
The \^`\setfontsize` command acts like {\em font modifier}. It means that it
saves information about fonts but does not change the font actually until
variant selector or \^`\resizethefont` is used.

The following example demonstrates the `mag` format of \^`\setfontsize`
parameter. It is only a curious example probably not used in practical
typography.

\begtt
\def\smaller{\setfontsize{mag.9}\resizethefont}
Text \smaller text \smaller text \smaller text.
\endtt

\secc[fontprimitive] The `\font` primitive

If you load a font directly by `\font` primitive and you want to
create a size-dependent selector for such font then you can use
\~`\resizethefont`:

\begtt
\font\tencomfortaa=Comfortaa-Regular-T1 at10pt
\def\comfortaa{\tencomfortaa\resizethefont}

\comfortaa The 10 pt text is here
\setfontsize{at12pt}
\comfortaa The 12 pt text is here
\endtt
%
The example above uses the 8\,bit `tfm` font. You can use Unicode font too, of
course. The \^`\fontfam` macro initializes the extended `\font` primitive
features for \LuaTeX/ (see section \ref[exfont]).
If you didn't use this command, you must initialize
these features by the \^`\initunifonts` command explicitly, for example:

\begtt
\initunifonts
\font\tencyklop=[cyklop-regular] at10pt % the font cyklop-regular.otf is loaded
\def\cyklop{\tencyklop\resizethefont}

\cyklop The 10 pt text is here
\setfontsize{at12pt}
\cyklop The 12 pt text is here
\endtt

\secc[fontlet] The \code{\\fontlet} declarator

We have another command for scaling: \^`\fontlet` which can resize
arbitrary font given by its font switch.
This font switch was declared by the
`\font` primitive or the \~`\fontdef` macro.

\begtt \catcode`\<=13
  \fontlet \<newfont> = \<fontswitch> <sizespec>
  example:
  \fontlet \bigfont = \_tenbf at15pt
\endtt

The resulted `\bigfont` is the same as in the previous example where \~`\fontdef`
was used. The advantage of \~`\fontdef` macro will be more clear when you load
font families by `\fontfam` and you are using more font modifiers declared
in such families.

Summary: you can declare font switches:
\begitems
* by the `\font` primitive if you know the font file,
* by the \^`\fontlet` command if you know the font switch and the size, or
* by the \~`\fontdef` command if you know the variant and modifiers.
\enditems

\secc Optical sizes

There are font families with more font files where almost the same font is
implemented in various design sizes: `cmr5`, `cmr6`, `cmr7`, `cmr8`, `cmr9`,
`cmr10`, `cmr12`, `cmr17` for example. This feature is called \"optical
sizes". \OpTeX/ chooses a font with an optical size closest to desired size
specified by the \^`\setfontsize`, when `at<dimen>` or `mag<coefficient>` is used.
When `scaled<scale factor>` is used then optical size is chosen using the value
of the `\defaultoptsize` register and such font is scaled by the specified
`<scale factor>`. There is `\defaultoptsize=10pt` by default.

Font collections with optical sizes must be registered by the
\^`\_regtfm` for `tfm` files or \^`\_regoptsizes` for Unicode fonts.
\OpTeX/ registers 8bit Latin Modern fonts in the format
and OTF Latin Modern fonts in the `f-lmfonts.opm` file.
See also section~\ref[optsizes].

\_endinput

2021-05-02 better concept of doc, moving parts to fonts-select
2021-04-17 \_fontloaded, \_newfontloaded introduced
2020-04-17 \resizethefont introduced
2020-03-17 released