1
2
3\usemodule[presentboring,abbreviationslogos]
4
5
6\definehighlight[nb][style=bold,color=middlegray,define=no]
7
8\definecolor[maincolor][g=.3]
9
10\startdocument
11 [title={COMPACT FONTS},
12 banner={a different approach to scaling},
13 location={context\enspace {\bf 2021}\enspace meeting}]
14
15\starttitle[title=How \TEX\ uses fonts]
16
17\startitemize
18 \startitem
19 In a \TEX\ engine there is a 1to1 mapping from characters in the input
20 to a slot in a font.
21 \stopitem
22 \startitem
23 Combinations of characters can be mapped onto one shape: ligatures.
24 \stopitem
25 \startitem
26 Hyphenation is (also) controlled by the input encoding of a font which
27 imposes some limitations.
28 \stopitem
29 \startitem
30 In the typeset result characters (glyphs) can be (re)positioned relatively: kerns.
31 \stopitem
32 \startitem
33 This all happens in a very interwoven way (e.g. inside the par builder).
34 \stopitem
35\stopitemize
36
37\stoptitle
38
39\starttitle[title=How traditional \TEX\ sees fonts]
40
41\startitemize
42 \startitem
43 A font is just a (binary) blob of data with information where characters
44 have a width, height, depth and italic correction.
45 \stopitem
46 \startitem
47 The engine only needs the dimensions and when the same font is used with a
48 different scale a copy with scaled dimensions is used.
49 \stopitem
50 \startitem
51 There can be recipes for ligatures and (more complex) so called math extensible
52 shapes (like arrows, wide accents, fences and radicals)
53 \stopitem
54 \startitem
55 There are pairwise specification for kerning.
56 \stopitem
57 \startitem
58 A handful of font parameters is provided in order to control for instance spacing.
59 \stopitem
60 \startitem
61 Virtual fonts are just normal fonts but they have recipes for the backend to
62 construct shapes: \TEX\ uses the normal metric file, the backend also the virtual
63 specification file.
64 \stopitem
65\stopitemize
66
67\blank[2*big]
68
69An example of a definition and usage:
70
71\starttyping
72\font\cs somename [somescale] test {\cs test} test
73\stoptyping
74
75\stoptitle
76
77\starttitle[title=\UNICODE\ engines]
78
79\startitemize
80 \startitem
81 There are no fundamental differences between a traditional engine and an
82 \UNICODE\ aware one with respect to what \TEX\ needs from fonts:
83 dimensions.
84 \stopitem
85 \startitem
86 There can be more than 256 characters in a font.
87 \stopitem
88 \startitem
89 Some mechanisms have to be present for applying font features (like ligaturing and
90 kerning).
91 \stopitem
92 \startitem
93 In \LUATEX\ hyphenation, ligaturing and kerning are clearly separate steps.
94 \stopitem
95 \startitem
96 In \LUATEX\ callbacks can do lots of things with fonts and characters.
97 \stopitem
98 \startitem
99 Math fonts are handled differently and there is more info that comes from the font.
100 \stopitem
101 \startitem
102 In \LUATEX\ features like expansion are implemented differently, i.e.\ no
103 copies of fonts are made and applied expansion travels with the glyphs.
104 \stopitem
105\stopitemize
106
107\stoptitle
108
109\starttitle[title=Overhead]
110
111\startitemize
112 \startitem
113 In all engines scales copies are used. For traditional \TEX\ a copy is cheap, but a
114 font that supports more of \UNICODE\ cna be quite large.
115 \stopitem
116 \startitem
117 Different feature sets in principle make for a different font (this can be different
118 per macro package).
119 \stopitem
120 \startitem
121 Every math scale needs three font instances: text, script and scriptscript.
122 \stopitem
123 \startitem
124 In \CONTEXT\ lots of sharing takes place and a lot of low level
125 optimizations happens (memory, performance). We always made sure (already
126 in \MKII) that the font system was not the bottleneck.
127 \stopitem
128 \startitem
129 In most cases font definitions are dynamic, and we delay initialization
130 as much as possible.
131 \stopitem
132 \startitem
133 In \MKIV\ font features can be dynamic which saves a lot of memory at the
134 cost of some extra processing overhead.
135 \stopitem
136\stopitemize
137
138\stoptitle
139
140\starttitle[title=Design sizes]
141
142\startitemize
143 \startitem
144 A macro packages font handling is complicated by design sizes. The low level
145 code can look complex too.
146 \stopitem
147 \startitem
148 There are hardly any fonts that come in design sizes (basically only Computer
149 Modern) so we need to support that.
150 \stopitem
151 \startitem
152 Design sizes make sense for math fonts where very small characters and
153 symbols are used in scripts.
154 \stopitem
155 \startitem
156 In \OPENTYPE\ fonts smaller math design sizes are part of the font (that
157 then gets loaded three times with different \type {ssty} settings).
158 \stopitem
159\stopitemize
160
161\startlinecorrection
162\dontleavehmode\scale[frame=on,height=5ex]{$\textstyle 2$}\quad
163\dontleavehmode\scale[frame=on,height=5ex]{$\scriptstyle 2$}\quad
164\dontleavehmode\scale[frame=on,height=5ex]{$\scriptscriptstyle 2$}\quad\quad
165\dontleavehmode\scale[frame=on,height=2ex]{$\textstyle 2$}\quad
166\dontleavehmode\scale[frame=on,height=2ex]{$\scriptstyle 2$}\quad
167\dontleavehmode\scale[frame=on,height=2ex]{$\scriptscriptstyle 2$}\quad\quad
168\dontleavehmode\scale[frame=on,width=4em]{\colored[r=.6,a=1,t=.5]{$\textstyle 2$}}\hskip4em
169\dontleavehmode\scale[frame=on,width=4em]{\colored[g=.6,a=1,t=.5]{$\scriptstyle 2$}}\hskip4em
170\dontleavehmode\scale[frame=on,width=4em]{\colored[b=.6,a=1,t=.5]{$\scriptscriptstyle 2$}}\quad\quad
171\dontleavehmode{$\textstyle 2$}\quad
172\dontleavehmode{$\scriptstyle 2$}\quad
173\dontleavehmode{$\scriptscriptstyle 2$}\quad
174\stoplinecorrection
175
176\stoptitle
177
178\starttitle[title=The system]
179
180\startitemize
181 \startitem
182 Each bodyfont size (often a few are defined) has regular, bold, italic,
183 bold italic, slanted, bold slanted, etc. There can be unscaled instances
184 (design size) or scaled ones.
185 \stopitem
186 \startitem
187 Within a bodyfont size we have size variants: smaller {\tx x} and {\tx xx},
188 larger {\tfa a}, {\tfb b}, {\tfc c} and {\tfd d}.
189 \stopitem
190 \startitem
191 In \MKII\ we inherit smallcap and oldstyle setups but in \MKIV\ one can either
192 do that dynamic or define an additional bodyfont instance.
193 \stopitem
194 \startitem
195 A document can use a mix of fonts mixed setup, so there is a namespace
196 used per family.
197 \stopitem
198 \startitem
199 In \OPENTYPE\ symbols are more naturally part of a font, as are emoji and
200 colored shapes.
201 \stopitem
202 \startitem
203 Lack of variants can result in artificially slanted of boldened fonts (more
204 advanced in \MKIV). Variable fonts are not special, but demand some work
205 when loading and embedding.
206 \stopitem
207 \startitem
208 Runtime virtual fonts are part of \MKIV\ as are fallback shapes.
209 \stopitem
210 \startitem
211 Languages and scripts can introduce an extra dimension to operate on.
212 \stopitem
213 \startitem
214 Math is greatly simplified by the fact that families are part of a font.
215 \stopitem
216 \startitem
217 Bold math fonts are provided by the boldening feature.
218 \stopitem
219\stopitemize
220
221\stoptitle
222
223\starttitle[title={Practice}]
224
225\startitemize
226 \startitem
227 Due to optimizations the actual number of loaded instances is normally
228 small but there are exceptions.
229 \stopitem
230 \startitem
231 The \LUAMETATEX\ manual has 158 instances most of which are math (six per
232 used bodyfont for math plus a regular: Lucida, Pagella, Latin Modern,
233 Dejavu, Cambria).
234 \stopitem
235 \startitem
236 The final \PDF\ file has 21 embedded fonts (subsets).
237 \stopitem
238 \startitem
239 The fact that different sizes each have an instance and that for math
240 we need three per size plus one for r2l, while the only difference
241 is scale, makes one think of other solutions.
242 \stopitem
243 \startitem
244 Using duplicates of huge \CJK\ fonts makes it even more noticeable.
245 \stopitem
246\stopitemize
247
248But there is a way out!
249
250\stoptitle
251
252\starttitle[title=Glyph scaling]
253
254We can scale glyphs in three ways:
255
256\startbuffer
257\definedfont[lmroman10regular*default]
258test {\glyphxscale 2500 test} test
259test {\glyphyscale 2500 test} test
260test {\glyphscale 2500 test} test
261\stopbuffer
262
263\typebuffer {\getbuffer}
264
265We do need to honor grouping:
266
267\startbuffer
268\definedfont[lmroman10regular*default]
269e{\glyphxscale 2500 ff}icient
270ef{\glyphxscale 2500 f}icient
271ef{\glyphxscale 2500 fi}cient
272e{\glyphxscale 2500 ffi}cient
273\stopbuffer
274
275\typebuffer {\getbuffer}
276
277These scales can also be part of a font definition so we can do with less
278instances.
279
280\stoptitle
281
282\starttitle[title=Implications]
283
284\startitemize
285 \startitem
286 The text processing part of the engine has to scale on the fly (e.g.\
287 when dimensions are needed in paragraph building and (box) packing.
288 \stopitem
289 \startitem
290 Font processing (features) already distinguishes per instance but now also
291 has to differentiate by (upto three) scales (we use the same font id
292 for scaled instances).
293 \stopitem
294 \startitem
295 The math machinery has to check for smaller sizes and also scale
296 dimensions on the fly.
297 \stopitem
298 \startitem
299 For math that means two times scaling: the main scale (like glyph scale) plus
300 the relative scaling of script and scriptscript.
301 \stopitem
302 \startitem
303 When they are used font dimensions and math parameters are to be scaled as are
304 rules in some math extensibles.
305 \stopitem
306 \startitem
307 This all has to be done efficiently so that there is no significant drop in
308 performance.
309 \stopitem
310 \startitem
311 But quite a bit less memory is used and loading time has become less too.
312 \stopitem
313\stopitemize
314
315Some day this will become default (which means a sentimental process of dropping
316ancient code):
317
318\starttyping
319\enableexperiments[fonts.compact]
320\stoptyping
321
322\stoptitle
323
324\starttitle[title=Details]
325
326The tricks shown on this page and following pages have been in place and tested
327for a while now. Because \TEX\ uses integers a scale value of 1000 means 1.000,
328as in other mechanisms:
329
330\startbuffer
331\definedfont[lmroman10regular*default]
332test {\glyphscale 2500 test} test
333\stopbuffer
334
335\typebuffer {\getbuffer}
336
337
338
339
340
341\page
342
343The font definition mechanism supports horizontal and vertical scaling:
344
345\startbuffer
346\definefont[FooA][Serif*default @ 12pt 1800 500]
347\definefont[FooB][Serif*default @ 12pt 0.85 0.4]
348\definefont[FooC][Serif*default @ 12pt]
349
350There is also a new command:
351
352\definetweakedfont[runwider] [xscale=1.5]
353\definetweakedfont[runtaller][yscale=2.5,xscale=.8,yoffset=.2ex]
354
355{\FooA test test \runwider test test \runtaller test test}\par
356{\FooB test test \runwider test test \runtaller test test}\par
357{\FooC test test \runwider test test \runtaller test test}\par
358\stopbuffer
359
360\typebuffer
361
362\getbuffer
363
364\page
365
366Tweaking also works in math:
367
368\startbuffer
369\definetweakedfont[squeezed][xscale=0.9]
370\definetweakedfont[squoozed][xscale=0.7]
371
372\startlines
373$a = b2 \sqrt{c}$
374{\squeezed $a = b2 \sqrt{c}$}
375{\squoozed $a = b2 \sqrt{c}$}
376{$\squoozed a = b2 \sqrt{c}$}
377{$\scriptstyle a = b2 \sqrt{c}$}
378\stoplines
379\stopbuffer
380
381\typebuffer
382
383\getbuffer
384
385\page
386
387\startbuffer
388\startcombination[3*1]
389 {\bTABLE
390 \bTR \bTD foo \eTD \bTD[style=\squeezed] $x = 1$ \eTD \eTR
391 \bTR \bTD oof \eTD \bTD[style=\squeezed] $x = 2$ \eTD \eTR
392 \eTABLE} {local}
393 {\bTABLE[style=\squeezed]
394 \bTR \bTD $x = 1$ \eTD \bTD $x = 3$ \eTD \eTR
395 \bTR \bTD $x = 2$ \eTD \bTD $x = 4$ \eTD \eTR
396 \eTABLE} {global}
397 {\bTABLE[style=\squeezed\squeezed\squeezed\squeezed]
398 \bTR \bTD $x = 1$ \eTD \bTD $x = 3$ \eTD \eTR
399 \bTR \bTD $x = 2$ \eTD \bTD $x = 4$ \eTD \eTR
400 \eTABLE} {multiple}
401\stopcombination
402\stopbuffer
403
404\typebuffer
405
406\startlinecorrection
407\getbuffer
408\stoplinecorrection
409
410\page
411
412Tweaking can be combined with styles:
413
414\startbuffer
415\definetweakedfont[MyLargerFontA][scale=2000,style=bold]
416test {\MyLargerFontA test} test
417\stopbuffer
418
419\typebuffer
420
421\getbuffer
422
423\page
424
425We can use negative scale values:
426
427\startbuffer
428\bTABLE[align=middle]
429 \bTR
430 \bTD a{\glyphxscale 1000 \glyphyscale 1000 bc}d \eTD
431 \bTD a{\glyphxscale 1000 \glyphyscale 1000 bc}d \eTD
432 \bTD a{\glyphxscale 1000 \glyphyscale 1000 bc}d \eTD
433 \bTD a{\glyphxscale 1000 \glyphyscale 1000 bc}d \eTD
434 \eTR
435 \bTR
436 \bTD \tttf 1000 1000 \eTD
437 \bTD \tttf 1000 1000 \eTD
438 \bTD \tttf 1000 1000 \eTD
439 \bTD \tttf 1000 1000 \eTD
440 \eTR
441\eTABLE
442\stopbuffer
443
444\typebuffer
445
446\startlinecorrection
447\getbuffer
448\stoplinecorrection
449
450\page
451
452There are more glyph properties:
453
454\startbuffer
455\ruledhbox{
456 \ruledhbox{\glyph yoffset 1ex options 0 123}
457 \ruledhbox{\glyph xoffset .5em yoffset 1ex options "C0 123}
458 \ruledhbox{oeps{\glyphyoffset 1ex \glyphxscale 800
459 \glyphyscale\glyphxscale oeps}oeps}
460}
461\stopbuffer
462
463\typebuffer \scale[width=\textwidth]{\getbuffer}
464
465\page
466
467Glyph scales are internal counter values, like any other:
468
469\startbuffer
470\samplefile{jojomayer}
471{\glyphyoffset .8ex
472 \glyphxscale 700 \glyphyscale\glyphxscale
473 \samplefile{jojomayer}}
474{\glyphyscale\numexpr3*\glyphxscale2\relax
475 \samplefile{jojomayer}}
476{\glyphyoffset .2ex
477 \glyphxscale 500 \glyphyscale\glyphxscale
478 \samplefile{jojomayer}}
479\samplefile{jojomayer}
480\stopbuffer
481
482\typebuffer
483
484\getbuffer
485
486\page
487
488There is a helper for real (float) scales:
489
490\startbuffer
4911200 : \the\numericscale1200
4921.20 : \the\numericscale1.200
493\stopbuffer
494
495\typebuffer
496
497These lines produce the same integer:
498
499\startlines\tttf
500\getbuffer
501\stoplines
502
503\page
504
505You can do this but its not always predictable (depends on outer scales too):
506
507\startbuffer[definition]
508\def\UnKernedTeX
509 {T
510 {\glyph xoffset .2ex yoffset .4ex E}
511 {\glyph xoffset .4ex options "60 X}}
512\stopbuffer
513
514\startbuffer[example]
515We use \UnKernedTeX\ and {\bf \UnKernedTeX} and {\bs \UnKernedTeX}:
516the slanted version could use some more left shifting of the E.
517\stopbuffer
518
519\typebuffer[definition,example]
520
521\startnarrower
522 \getbuffer[definition,example]
523\stopnarrower
524
525Marks and cursive features can interfere, so this is an alternative:
526
527\startbuffer[definition]
528\def\UnKernedTeX
529 {T\glyph left .2ex raise .4ex E\glyph left .2ex X\relax}
530\stopbuffer
531
532\typebuffer[definition]
533
534\startnarrower
535 \getbuffer[definition,example]
536\stopnarrower
537
538\page
539
540Yet another glyph option:
541
542\starttyping
543\multiply\glyphscale by 2 <{\darkgray \glyph M}>
544\multiply\glyphscale by 2 <{\darkgray \glyph raise 3pt M}>
545\multiply\glyphscale by 2 <{\darkgray \glyph raise 3pt M}>
546\multiply\glyphscale by 2 <{\darkgray \glyph left 3pt M}>
547\multiply\glyphscale by 2 <{\darkgray \glyph right 2pt M}>
548\multiply\glyphscale by 2 <{\darkgray \glyph left 3pt right 2pt M}>
549\multiply\glyphscale by 2 <{\darkgray \glyph left 3pt M}>
550\multiply\glyphscale by 2 <{\darkgray \glyph right 2pt M}>
551\multiply\glyphscale by 2 <{\darkgray \glyph left 3pt right 2pt M}>
552\stoptyping
553
554\startlinecorrection
555\bTABLE[align=middle,width=.33\textwidth]
556 \bTR
557 \bTD \showglyphs \multiply\glyphscale by 2 <{\darkgray \glyph M}>\eTD
558 \bTD \showglyphs \multiply\glyphscale by 2 <{\darkgray \glyph raise 3pt M}>\eTD
559 \bTD \showglyphs \multiply\glyphscale by 2 <{\darkgray \glyph raise 3pt M}>\eTD
560 \eTR
561 \bTR[frame=off]
562 \bTD \tttf \eTD
563 \bTD \tttf raise 3pt \eTD
564 \bTD \tttf raise 3pt \eTD
565 \eTR
566 \bTR
567 \bTD \showglyphs \multiply\glyphscale by 2 <{\darkgray \glyph left 3pt M}>\eTD
568 \bTD \showglyphs \multiply\glyphscale by 2 <{\darkgray \glyph right 2pt M}>\eTD
569 \bTD \showglyphs \multiply\glyphscale by 2 <{\darkgray \glyph left 3pt right 2pt M}>\eTD
570 \eTR
571 \bTR[frame=off]
572 \bTD \tttf left 3pt \eTD
573 \bTD \tttf right 2pt\eTD
574 \bTD \tttf left 3pt right 2pt\eTD
575 \eTR
576 \bTR
577 \bTD \showglyphs \multiply\glyphscale by 2 <{\darkgray \glyph left 3pt M}>\eTD
578 \bTD \showglyphs \multiply\glyphscale by 2 <{\darkgray \glyph right 2pt M}>\eTD
579 \bTD \showglyphs \multiply\glyphscale by 2 <{\darkgray \glyph left 3pt right 2pt M}>\eTD
580 \eTR
581 \bTR[frame=off]
582 \bTD \tttf left 3pt \eTD
583 \bTD \tttf right 2pt \eTD
584 \bTD \tttf left 3pt right 2pt \eTD
585 \eTR
586\eTABLE
587\stoplinecorrection
588
589\page
590
591A larger example:
592
593\startbuffer
594\glyphscale 4000
595\vl\glyph M\vl\quad
596\vl\glyph raise .2em M\vl\quad
597\vl\glyph left .3em M\vl\quad
598\vl\glyph right .2emM\vl\quad
599\vl\glyph left .2em right .2emM\vl\quad
600\vl\glyph raise .2em right .4emM\vl
601\stopbuffer
602
603\typebuffer
604
605{\getbuffer}
606
607\stoptitle
608
609\stopdocument
610 |