followingup-fonts.tex /size: 27 Kb    last modification: 2021-10-28 13:50
1% language=us runpath=texruns:manuals/followingup
2
3\startcomponent followingup-fonts
4
5\environment followingup-style
6
7\startchapter[title={Scaled fonts}]
8
9\startsection[title={History}]
10
11The infrastructure for fonts makes up a large part of the code of any \TEX\ macro
12package. We have to go back in time to understand why. When \TEX\ showed up,
13fonts were collections of bitmaps and measures. There were at most 256 glyphs in
14a font and in order to do its job, \TEX\ needed to know (and still needs to know)
15the width, height and depth of glyphs. If you want ligatures it also needs to
16know how to construct them from the input and when you want kerning there has to
17be additional information about what neighboring glyphs need a kern in between.
18Math is yet another subtask that demands extra information, like chains of glyphs
19that grow in size and if needed even recipes of how to construct large shapes
20from smaller ones.
21
22Fonts come in sizes. Latin Modern and the original Computer Modern, for instance,
23have quite a few variants where the shapes are adapted to the size. This means
24that when you need a 9pt regular shape alongside a 12pt one, two fonts have to be
25loaded. This is quite visible in math where we have three related sizes: text,
26script and scriptscript, grouped in so called families. When we scale the digit~2
27to the same height you will notice that the text, script and scriptscript sizes
28look different (the last three are unscaled):
29
30\startlinecorrection
31\dontleavehmode\scale[frame=on,height=5ex]{$\textstyle         2$}\quad
32\dontleavehmode\scale[frame=on,height=5ex]{$\scriptstyle       2$}\quad
33\dontleavehmode\scale[frame=on,height=5ex]{$\scriptscriptstyle 2$}\quad\quad
34\dontleavehmode\scale[frame=on,height=2ex]{$\textstyle         2$}\quad
35\dontleavehmode\scale[frame=on,height=2ex]{$\scriptstyle       2$}\quad
36\dontleavehmode\scale[frame=on,height=2ex]{$\scriptscriptstyle 2$}\quad\quad
37\dontleavehmode\scale[frame=on,width=4em]{\colored[r=.6,a=1,t=.5]{$\textstyle         2$}}\hskip-4em
38\dontleavehmode\scale[frame=on,width=4em]{\colored[g=.6,a=1,t=.5]{$\scriptstyle       2$}}\hskip-4em
39\dontleavehmode\scale[frame=on,width=4em]{\colored[b=.6,a=1,t=.5]{$\scriptscriptstyle 2$}}\quad\quad
40\dontleavehmode{$\textstyle         2$}\quad
41\dontleavehmode{$\scriptstyle       2$}\quad
42\dontleavehmode{$\scriptscriptstyle 2$}\quad
43\stoplinecorrection
44
45Plenty has been written (in various documents that come with \CONTEXT) about how
46this all works together and how it impacts the design of the system, so here I
47just give a short summary of what a font system has to deal with.
48
49\startitemize
50\startitem
51    In a bodyfont setup different sizes (9pt, 10pt, 12pt) can have their own
52    specific set of fonts. This can result in quite a number of definitions that
53    relate to the style, like regular, bold, italic, bold italic, slanted, bold
54    slanted, etc. When possible loading the fonts is delayed. In \CONTEXT\ often
55    the number of fonts that are actually loaded is not that large.
56\stopitem
57\startitem
58    Some font designs have different shapes per bodyfont size. A minor
59    complication is that when one is missing some heuristic best|-|match choice
60    might be needed. Okay, in practice only Latin Modern falls into this category
61    for \CONTEXT. Maybe \OPENTYPE\ variable fonts can be seen this way, but,
62    although we supported that right from the start, I haven't noticed much
63    interest in the \TEX\ community.
64\stopitem
65\startitem
66    Within a bodyfont size we distinguish size variants. We can go smaller (x and
67    xx), for instance when we use sub- and superscripts in text, or we can go
68    larger, for instance in titles (a, b, c, d, \unknown). Fortunately most of
69    the loading of these can be delayed too.
70\stopitem
71\startitem
72    When instances are not available, scaling can be used, as happens for
73    instance with 11pt in Computer Modern. Actually, this is why in \CONTEXT\ we
74    default to 12pt, because the scaled versions didn't look as nice as the
75    others (keep in mind that we started in the age of bitmaps).
76\stopitem
77\startitem
78    Special features, such as smallcaps or oldstyle numerals, can demand their own
79    definitions. More loading and automatic definitions can be triggered by sizes
80    needed in, e.g., scripts and titles.
81\stopitem
82\startitem
83    A document can have a mixed setup, that is: using different font
84    designs within one
85    document, so some kind of namespace subsystem is needed.
86\stopitem
87\startitem
88    In an eight|-|bit font world, we not only have text fonts but also collections
89    of symbols, and even in math there are additional symbol collections. In
90    \OPENTYPE\ symbols end up in text fonts, but there we have tons of emojis
91    and color fonts. All has to be dealt with in an integrated way. And we're
92    not even talking of virtual fonts, (runtime) \METAPOST\ generated fonts, and
93    so on.
94\stopitem
95\startitem
96    In traditional eight|-|bit engines, hyphenation depends on a font's encoding,
97    which can require loading a font multiple times in different encodings. This
98    depends on the language mix used. A side point is that defining a European
99    encoding covering most Latin languages was not that hard, especially when one
100    keeps in mind that many eight|-|bit encodings waste slots on seldom used
101    symbols, but by that time \OPENTYPE\ and \UNICODE\ input started to dominate.
102\stopitem
103\startitem
104    In the more modern \OPENTYPE\ fonts combinations of features can demand
105    additional instances: one can think of language|/|script combinations,
106    substitutions in base mode, special effects like emboldening, color fonts,
107    etc.
108\stopitem
109\startitem
110    Math is complicated by the fact that in traditional \TEX, alphabets come from
111    different fonts, which is why we have many so|-|called families; a font can
112    have several alphabets which means that some mapping can be needed. Operating
113    on the size, shape, encoding and style axes puts some demands on the font
114    system. Add to this the (often) partial (due to lack of fonts) bold support
115    and it gets even more complicated. In \OPENTYPE\ all the alphabets come from
116    one font.
117\stopitem
118\startitem
119    There is additional math auto|-|definition and loading code for the sizes
120    used in text scripts and titles.
121\stopitem
122\stopitemize
123
124All this has resulted in a pretty complex subsystem. Although going \OPENTYPE\
125(and emulated \OPENTYPE\ with \TYPEONE\ fonts as we do in \MKIV) removes some
126complications, like encodings, it also adds complexity because of the many
127possible font features, either dependent or not on script and language. Text as
128well as math got simpler in the \TEX\ code, though that was traded for quite a
129bit of \LUA\ code to deal with new features.
130
131So, in order to let the font subsystem not impact performance too much, let alone
132extensive memory usage, the \CONTEXT\ font subsystem is rather optimized. The
133biggest burden comes from fonts that have a dynamic (adaptive) definition because
134then we need to do quite a bit of testing per font switch, but even that has
135always been rather fast.
136
137\stopsection
138
139\startsection[title={Reality}]
140
141In \MKIV\ and therefore also in \LUAMETATEX\ (\LMTX) more font magic happens. The
142initial node lists that make up a box or paragraph can get manipulated in several
143ways and often fonts are involved. The font features (smallcaps, oldstyle,
144alternates, etc.)\ can be defined as static (part of the definition) or as
145dynamic (resolved on the spot at the cost of some overhead). Characters can be
146remapped, fonts can be replaced. The math subsystem in \MKIV\ was different right
147from the start: we use a limited number of families (regular, bold, l2r and r2l),
148and stay abstract till the moment we need to deal with the specific alphabets.
149But still, in \MKIV, we have the families with three fonts.
150
151In the \LUAMETATEX\ manual we show some math magic for different fonts. As a side
152effect, we set up half a dozen bodyfont collections: Lucida, Pagella, Latin
153Modern, Dejavu, the math standard Cambria, etc. Even with delayed and shared font
154loading, we end up with 158 instances but quite a few of them are math fonts, at
155least six per bodyfont size: regular and bold (emboldened) text, script and
156scriptscript. Of course most are just copies with different scaling that reuse
157already loaded resources. In the final \PDF\ we have 21 subsetted fonts.
158
159If we look at the math fonts that we use today, there is however quite some
160overlap. It starts with a text font. From that, script and scriptscript variants
161are derived, but often these variants use many text size related shapes too. Some
162shapes get alternatives (from the \type {ssty} feature), and the whole clone gets
163scaled. But, much of the logic of, for instance, extensibles is the same.
164
165A similar situation happens with large \CJK\ fonts: there are hardly any advanced
166features involved there, so any size is basically a copy with scaled dimensions,
167and these fonts can be truly huge!
168
169When we talk about features, in many cases in \CONTEXT\ you don't define them as
170part of the font. For instance small caps can best be triggered by using a
171dynamic feature: applied to a specific stretch of text. In fact, often features
172like superiors of fractions only work well on characters that fit the bill and
173produce weird side effects otherwise (a matter of design completeness). When the
174font handler does its work there are actually four cases: no features get applied
175(something that happens with, for instance, most monospaced fonts); base mode is
176used (which means that the \TEX\ machinery takes care of constructing ligatures
177and injecting kerns); and node mode (where \LUA\ handles the features). The
178fourth case is a special case of node mode where a different feature set is
179applied. \footnote {We also have so|-|called plug mode where an external renderer
180can do the work but that one is only around due to some experiments during Idris
181Hamid's font development.} At the cost of some extra overhead (for each node mode
182run) dynamic features are quite powerful and save quite a lot of memory and
183definitions. \footnote {The generic font handler that is derived from the
184\CONTEXT\ one doesn't implement this, so it runs a little faster.} The overhead
185comes from much more testing regarding the font we deal with because suddenly the
186same font can demand different treatments, depending on what dynamic features are
187active. \footnote {Originally this model was introduced for a dynamic paragraph
188optimization subsystem for Arabic but in practice no one uses it because there
189are no suitable fonts.}
190
191Although the font handling is responsible for much of the time spent in \LUA, it
192is still reasonable given what has to be done. Because we have an extensible
193system, it's often the extensions that takes additional runtime. Flexibility
194comes at a price.
195
196\stopsection
197
198\startsection[title={Progress}]
199
200At some point I started playing with realtime glyph scaling. Here realtime means
201that it doesn't depend on the font definition. To get an idea, here is an example
202(all examples are additionally scaled for \TUGBOAT):
203
204\startbuffer
205test {\glyphxscale 2500 test} test
206\stopbuffer
207
208\typebuffer
209
210\getbuffer
211
212The glyphs in the current font get scaled horizontally without the need for an
213extra font instance. Now, this kind of trickery puts some constraints on the font
214handling, as is demonstrated in the next example. We use Latin Modern because
215that font has all these ligatures:
216
217\startbuffer
218\definedfont[lmroman10-regular*default]%
219e{\glyphxscale 2500 ff}icient
220ef{\glyphxscale 2500 f}icient
221ef{\glyphxscale 2500 fi}cient
222e{\glyphxscale 2500 ffi}cient
223\stopbuffer
224
225\typebuffer
226
227{\getbuffer}
228
229In order to deal with this kind of scaling, we now operate not only on the font
230(id) and dynamic feature axes, but also on the scales, of which we have three
231variants: glyph scale, glyph xscale and glyph yscale. There is actually also a
232state dimension but we omit that for now (think of flagging glyphs as initial or
233final). This brings the number of axes to six. It is important to stress that in
234these examples the same font instance is used!
235
236Just for the record: several approaches to switching fonts are possible but for
237now we stick to a simple font id switch plus glyph scale settings at the \TEX\
238end. A variant would be to introduce a new mechanism where id's and scales go
239together but for now I see no real gain in that.
240
241\stopsection
242
243\startsection[title={Math}]
244
245Given what has been discussed in the previous sections, a logical question would
246be \quotation {Can we apply scaling to math?} and the answer is \quotation {Yes,
247we can!}. We can even go a bit further and that is partly due to some other
248properties of the engine.
249
250From \PDFTEX\ the \LUATEX\ engines inherited character protrusion and glyph
251expansions, aka hz. However, where in \PDFTEX\ copies of the font are made that
252carry the expanded dimensions, in \LUATEX\ at some point this was replaced by an
253expansion field in the glyph and kern nodes. So, instead of changing the font id
254of expanded glyphs, the same id is used but with the applied expansion factor set
255in the glyph. A side effect was that in places where dimensions are needed, we
256call functions that calculate the expanded widths on request (as these can change
257during linebreak calculations) in combination with accessing font dimensions
258directly. This level of abstraction is even more present in \LUAMETATEX. This
259means that we have an uniform interface to fonts and as a side effect scaling
260need be dealt with in only a few places in the code.
261
262Now, in math we have a few more complications. First of all, we have three sizes
263to consider and we also have lots of parameters that depend on the size. But, as
264I wanted to be able to apply scaling to math, the whole machinery was also
265abstracted in a way that, at the cost of some extra overhead, made it easier to
266work with scaled glyph properties. This means that we can stick to loading only
267one bodyfont size of math (note that each math family has three sizes, where the
268script and script sizes can have different, fine tuned, shapes) and just scale
269that on demand.
270
271Once all that was in place it was a logical next step to see if we could stick to
272just a single instance. Because in \LUAMETATEX\ we try to load fonts efficiently
273we store only the minimally needed information at the \TEX\ end. A font with no
274math therefore has less data per glyph. Again, this brings some abstraction that
275helped to implement the one instance mechanism. A math glyph has optional lists
276of increasing sizes and vertical or horizontal extensibles. So what got added was
277an optional chain of smaller sizes. If a character has three different glyphs for
278the three sizes, the text glyph has a pointer to the script glyph which in turn
279has a pointer to the scriptscript glyph. This means that when the math engine
280needs a specific character at a given size (text, script, scriptscript) we just
281follow that chain.
282
283In an \OPENTYPE\ math font the script and scriptscript sizes are specified as
284percentages of the text size. When the dimensions of a glyph are needed, we just
285scale on the fly. Again this adds some overhead but I'm pretty sure that no user
286will notice.
287
288So, to summarize: if we need a character at scriptscript size, we access the text
289size glyph, check for a pointer to a script size, go there, and again check for a
290smaller size. We use only what fits the bill. And, when we need dimensions we
291just scale. In order to scale we need the relative size, so we need to set that
292up when we load the font. Because in \CONTEXT\ we also can assemble a virtual
293\OPENTYPE\ font from \TYPEONE\ fonts, it was actually that (old) compatibility
294feature, the one that implements \TYPEONE\ based on \OPENTYPE\ math, that took
295the most time to adapt, not so much because it is complicated but because in
296\LMTX\ we have to bypass some advanced loading mechanisms. Because we can scale
297in two dimensions the many (font|-|related) math parameters also need to be dealt
298with accordingly.
299
300The end result is that for math we now only need to define two fonts per bodyfont
301setup: regular and bold at the natural scale (normally 10pt) and we share these
302for all sizes. As a result of this and what we describe in the next section, the
303158 instances for the \LUAMETATEX\ manual can be reduced to~30.
304
305
306\stopsection
307
308\startsection[title={Text}]
309
310Sharing instances in text mode is relatively simple, although we do have to keep
311in mind that scaling is an extra axis when dealing with font features: two
312neighboring glyphs with the same font id and dynamics but with different scales
313are effectively from different fonts.
314
315Another complication is that when we use font fallbacks (read:\ take missing
316glyphs from another font) we no longer have a dedicated instance but use a shared
317one. This in itself is not a problem but we do need to handle specified relative
318scales. This was not that hard to patch in \CONTEXT\ \LMTX.
319
320We can enforce aggressive font sharing with:
321
322\starttyping
323\enableexperiments[fonts.compact]
324\stoptyping
325
326After that we often use fewer instances. Just to give an idea, on the \LUAMETATEX\
327manual we get these stats:
328
329\starttyping
330290 pages, 10.8 sec, 292M lua, 99M tex, 158 instances
331290 pages,  9.5 sec, 149M lua, 35M tex,  30 instances
332\stoptyping
333
334So, we win on all fronts when we use this glyph scaling mechanism. The magic
335primitive that deals with this is named \type {\glyphscale}; it accepts a number,
336where \type {1200} means scaling to 20\percent\ more than normal. But it's best
337not to use this primitive directly.
338
339A specific scaled font can be defined using the \type {\definefont} command. In
340\LMTX\ a regular scaler can be followed by two scale factors. The next example
341demonstrates this (as can be seen, the \type {yoffset} affects the baseline):
342
343\startbuffer
344\definefont[FooA][Serif*default @ 12pt 1800 500]
345\definefont[FooB][Serif*default @ 12pt 0.85 0.4]
346\definefont[FooC][Serif*default @ 12pt]
347
348\definetweakedfont[runwider] [xscale=1.5]
349\definetweakedfont[runtaller][yscale=2.5,xscale=.8,yoffset=-.2ex]
350
351{\FooA test test \runwider test test \runtaller test test}\par
352{\FooB test test \runwider test test \runtaller test test}\par
353{\FooC test test \runwider test test \runtaller test test}\par
354\stopbuffer
355
356\typebuffer
357
358We also use the new \type {\definetweakedfont} command here. This example not
359only shows the two scales but also introduces the offset.
360
361\getbuffer
362
363In compact mode this is one font. Here is another example:
364
365\startbuffer
366\definetweakedfont[squeezed][xscale=0.9]
367
368\startlines
369$a = b^2 + \sqrt{c}$
370{\squeezed $a = b^2 + \sqrt{c}$}
371\stoplines
372\stopbuffer
373
374\typebuffer
375
376\getbuffer
377
378Watch this:
379
380\startbuffer
381\startcombination[3*1]
382    {\bTABLE
383        \bTR \bTD foo \eTD \bTD[style=\squeezed] $x = 1$ \eTD \eTR
384        \bTR \bTD oof \eTD \bTD[style=\squeezed] $x = 2$ \eTD \eTR
385     \eTABLE}
386    {local}
387    {\bTABLE[style=\squeezed]
388        \bTR \bTD $x = 1$ \eTD \bTD  $x = 3$ \eTD \eTR
389        \bTR \bTD $x = 2$ \eTD \bTD  $x = 4$ \eTD \eTR
390     \eTABLE}
391    {global}
392    {\bTABLE[style=\squeezed\squeezed]
393        \bTR \bTD $x = 1$ \eTD \bTD  $x = 3$ \eTD \eTR
394        \bTR \bTD $x = 2$ \eTD \bTD  $x = 4$ \eTD \eTR
395     \eTABLE}
396    {multiple}
397\stopcombination
398\stopbuffer
399
400\typebuffer
401
402\startlinecorrection
403\getbuffer
404\stoplinecorrection
405
406An additional style parameter is also honored:
407
408\startbuffer
409\definetweakedfont[MyLargerFontA][scale=2000,style=bold]
410test {\MyLargerFontA test} test
411\stopbuffer
412
413\typebuffer
414
415This gives:
416
417\getbuffer
418
419Just for the record: the Latin Modern fonts, when set up to use design sizes,
420will still use the specific size|-|related files.
421
422\stopsection
423
424\startsection[title={Hackery}]
425
426You can use negative scale values, as is demonstrated in the following
427code:
428
429\startbuffer
430\bTABLE[align=middle]
431  \bTR
432    \bTD a{\glyphxscale  1000 \glyphyscale  1000 bc}d \eTD
433    \bTD a{\glyphxscale  1000 \glyphyscale -1000 bc}d \eTD
434    \bTD a{\glyphxscale -1000 \glyphyscale -1000 bc}d \eTD
435    \bTD a{\glyphxscale -1000 \glyphyscale  1000 bc}d \eTD
436  \eTR
437  \bTR
438    \bTD \tttf +1000 +1000 \eTD
439    \bTD \tttf +1000 -1000 \eTD
440    \bTD \tttf -1000 -1000 \eTD
441    \bTD \tttf -1000 +1000 \eTD
442  \eTR
443\eTABLE
444\stopbuffer
445
446\typebuffer
447
448gives:
449
450\startlinecorrection
451\getbuffer
452\stoplinecorrection
453
454Glyphs can have offsets and these are used for implementing \OPENTYPE\ features.
455However, they are also available on the \TEX\ side. Take this example where we
456use the new \type {\glyph} primitive (a variant of \type {\char} that takes
457keywords):
458
459\startbuffer
460\ruledhbox{
461    \ruledhbox{\glyph yoffset 1ex options 0 123} % left curly brace
462    \ruledhbox{\glyph xoffset .5em yoffset 1ex options "C0 123}
463    \ruledhbox{oeps{\glyphyoffset 1ex \glyphxscale 800
464                    \glyphyscale\glyphxscale oeps}oeps}
465}
466\stopbuffer
467
468\typebuffer \getbuffer
469
470This example demonstrates that the \type {\glyph} primitive takes quite a few
471keywords: \type {xoffset}, \type {yoffset}, \type {xscale}, \type {yscale}, \type
472{left}, \type {right}, \type {raise}, \type {options}, \type {font} and \type
473{id} where the last two take a font identifier or font id (a positive number).
474For this article it's enough to know that the option indicates that glyph
475dimension should include the offset. In a moment we will see an alternative that
476doesn't need that.
477
478\startbuffer
479\samplefile{jojomayer}
480{\glyphyoffset .8ex
481 \glyphxscale 700 \glyphyscale\glyphxscale
482 \samplefile{jojomayer}}
483{\glyphyscale\numexpr3*\glyphxscale/2\relax
484 \samplefile{jojomayer}}
485{\glyphyoffset -.2ex
486 \glyphxscale 500 \glyphyscale\glyphxscale
487 \samplefile{jojomayer}}
488\samplefile{jojomayer}
489\stopbuffer
490
491\typebuffer
492
493To quote Jojo Mayer:
494
495\startnarrower
496\darkred \getbuffer
497\stopnarrower
498
499Keep in mind that this can interfere badly with font feature processing which also
500used offsets. It might often work out okay vertically, but less well horizontally.
501
502The scales, as mentioned, works with pseudo|-|scales but that is sometimes a bit
503cumbersome. This is why a special \type {\numericscale} primitive has been
504introduced.
505
506\startbuffer
5071200 : \the\numericscale1200
5081.20 : \the\numericscale1.200
509\stopbuffer
510
511\typebuffer
512
513Both these lines produce the same integer:
514
515\startlines\tttf
516\getbuffer
517\stoplines
518
519You can do strange things with these primitives but keep in mind that you can
520also waste the defaults.
521
522\startbuffer[definition]
523\def\UnKernedTeX
524  {T%
525   {\glyph xoffset -.2ex yoffset -.4ex `E}%
526   {\glyph xoffset -.4ex options "60 `X}}
527\stopbuffer
528
529\startbuffer[example]
530We use \UnKernedTeX\ and {\bf \UnKernedTeX} and {\bs \UnKernedTeX}:
531the slanted version could use some more left shifting of the E.
532\stopbuffer
533
534\typebuffer[definition,example]
535
536This gives the \TEX\ logos but of course we normally use the more official
537definitions instead.
538
539\startnarrower
540    \darkred \getbuffer[definition,example]
541\stopnarrower
542
543Because offsets are (also) used for handling font features like mark and cursive
544placement as well as special inter|-|character positioning, the above is
545suboptimal. Here is a better alternative:
546
547\startbuffer[definition]
548\def\UnKernedTeX
549  {T\glyph left .2ex raise -.4ex `E\glyph left .2ex `X\relax}
550\stopbuffer
551
552\typebuffer[definition]
553
554The result is the same:
555
556\startnarrower
557    \darkgreen \getbuffer[definition,example]
558\stopnarrower
559
560But anyway: don't overdo it. We have dealt with such cases for decades without
561these fancy new features. The next example shows margins in action:
562
563\startlinecorrection
564\bTABLE[align=middle,width=.33\textwidth]
565    \bTR
566        \bTD \showglyphs \multiply\glyphscale by 2 <{\darkgray \glyph                      `M}>\eTD
567        \bTD \showglyphs \multiply\glyphscale by 2 <{\darkgray \glyph raise 3pt            `M}>\eTD
568        \bTD \showglyphs \multiply\glyphscale by 2 <{\darkgray \glyph raise -3pt           `M}>\eTD
569    \eTR
570    \bTR[frame=off]
571        \bTD \tttf            \eTD
572        \bTD \tttf raise  3pt \eTD
573        \bTD \tttf raise -3pt \eTD
574    \eTR
575    \bTR
576        \bTD \showglyphs \multiply\glyphscale by 2 <{\darkgray \glyph left  3pt            `M}>\eTD
577        \bTD \showglyphs \multiply\glyphscale by 2 <{\darkgray \glyph           right  2pt `M}>\eTD
578        \bTD \showglyphs \multiply\glyphscale by 2 <{\darkgray \glyph left  3pt right  2pt `M}>\eTD
579    \eTR
580    \bTR[frame=off]
581        \bTD \tttf left  3pt           \eTD
582        \bTD \tttf           right  2pt\eTD
583        \bTD \tttf left  3pt right  2pt\eTD
584    \eTR
585    \bTR
586        \bTD \showglyphs \multiply\glyphscale by 2 <{\darkgray \glyph left -3pt            `M}>\eTD
587        \bTD \showglyphs \multiply\glyphscale by 2 <{\darkgray \glyph           right -2pt `M}>\eTD
588        \bTD \showglyphs \multiply\glyphscale by 2 <{\darkgray \glyph left -3pt right -2pt `M}>\eTD
589    \eTR
590    \bTR[frame=off]
591        \bTD \tttf left -3pt            \eTD
592        \bTD \tttf           right -2pt \eTD
593        \bTD \tttf left -3pt right -2pt \eTD
594    \eTR
595\eTABLE
596\stoplinecorrection
597
598Here is another way of looking at it:
599
600\startbuffer
601\glyphscale 4000
602\vl\glyph                        `M\vl\quad
603\vl\glyph raise  .2em            `M\vl\quad
604\vl\glyph left   .3em            `M\vl\quad
605\vl\glyph             right  .2em`M\vl\quad
606\vl\glyph left  -.2em right -.2em`M\vl\quad
607\vl\glyph raise -.2em right  .4em`M\vl
608\stopbuffer
609
610\typebuffer
611
612The raise as well as left and right margins are taken into account when calculating the
613dimensions of a glyph.
614
615{\getbuffer}
616
617\stopsection
618
619\startsection[title={Implementation}]
620
621Discussing the implementation in the engine makes no sense here, also because
622details might change. However, it is good to know that many properties travel
623with the glyph nodes, for instance the scales, margins, offsets, language, script
624and state properties, control over kerning, ligaturing, expansion and protrusion,
625etc. The dimensions (width, height and depth) are not stored in the glyph node
626but calculated from the font, scales and optionally the offsets and expansion
627factor. One problem is that the more clever (and nice) solutions we cook up, the
628more it might impact performance. So, I will delay some experiments till I have a
629more powerful machine.
630
631One reason for {\em not} storing the dimensions in a glyph node is that we often
632copy those nodes or change character fields in the font handler and we definitely
633don't want the wrong dimensions there. At that moment, offsets and margin fields
634don't reflect features yet, so copying them is no big deal because at that moment
635these are still zero. However, dimensions are rather character bound so every
636time a character is set, we also would have to set the dimensions. Even worse,
637when we can set them, the question arises if they were already set explicitly.
638So, this is a can of worms we're not going to open: the basic width, height and
639depth of the glyph as specified in the font is used and combined with actual
640dimensions (likely already scaled according the glyph scales) in offset and
641margin fields.
642
643Now, I have to admit that especially playing with using margins to glyphs instead
644of font kerns is more of an experiment to see what the consequences are than a
645necessity, but what would be the joy of \TEX\ without such experiments? And as
646usual, in \CONTEXT\ these will become options in the font handler that one can
647enable, or not.
648
649\stopsection
650
651\stopchapter
652
653\stopcomponent
654
655% As often there is a musical timestamp to this text: discovering Julia Hofer
656% (bass, came there via checking out (of course) Leland Sklar, and now i have to
657% watch a bunch of Victor Wooten videos too) and Neon Vine's (play and combine
658% anything) on YT. Both examples of where (imo extensive) practicing real
659% instruments can bring you with todays diverse equipment. These are interesting
660% times (it's now last days of 2020).
661%
662% The initial \definescaledfont was replaced by \definetweakedfont in the first
663% week of Januari 2021, when I watched the joyful covers of Peter Gabriels
664% "Steam" by Yoyoka which shows that the future belongs to the real young kids
665% (so much explosive creativity!) and not to the old folks.
666