summaryrefslogtreecommitdiff
path: root/Master/texmf-dist/doc/context/sources/general/manuals/followingup/followingup-fonts.tex
diff options
context:
space:
mode:
Diffstat (limited to 'Master/texmf-dist/doc/context/sources/general/manuals/followingup/followingup-fonts.tex')
-rw-r--r--Master/texmf-dist/doc/context/sources/general/manuals/followingup/followingup-fonts.tex711
1 files changed, 711 insertions, 0 deletions
diff --git a/Master/texmf-dist/doc/context/sources/general/manuals/followingup/followingup-fonts.tex b/Master/texmf-dist/doc/context/sources/general/manuals/followingup/followingup-fonts.tex
new file mode 100644
index 00000000000..502370d7db1
--- /dev/null
+++ b/Master/texmf-dist/doc/context/sources/general/manuals/followingup/followingup-fonts.tex
@@ -0,0 +1,711 @@
+% language=us
+
+\startcomponent followingup-fonts
+
+\environment followingup-style
+
+\startchapter[title={Scaled fonts}]
+
+\startsection[title={History}]
+
+The infrastructure for fonts makes up a large part of the code of any \TEX\ macro
+package. We have to go back in time to understand why. When \TEX\ showed up,
+fonts were collections of bitmaps and measures. There were at most 256 glyphs in
+a font and in order to do its job, \TEX\ needed to know (and still needs to know)
+the width, height and depth of glyphs. If you want ligatures it also needs to
+know how to construct them from the input and when you want kerning there has to
+be additional information about what neighboring glyphs need a kern in between.
+Math is yet another subtask that demands extra information, like chains of glyphs
+that grow in size and if needed even recipes of how to construct large shapes
+from smaller ones.
+
+Fonts come in sizes. Latin Modern and the original Computer Modern, for instance,
+have quite a few variants where the shapes are adapted to the size. This means
+that when you need a 9pt regular shape alongside a 12pt one, two fonts have to be
+loaded. This is quite visible in math where we have three related sizes: text,
+script and scriptscript, grouped in so called families. When we scale the digit~2
+to the same height you will notice that the text, script and scriptscript sizes
+look different (the last three are unscaled):
+
+\startlinecorrection
+\dontleavehmode\scale[frame=on,height=5ex]{$\textstyle 2$}\quad
+\dontleavehmode\scale[frame=on,height=5ex]{$\scriptstyle 2$}\quad
+\dontleavehmode\scale[frame=on,height=5ex]{$\scriptscriptstyle 2$}\quad\quad
+\dontleavehmode\scale[frame=on,height=2ex]{$\textstyle 2$}\quad
+\dontleavehmode\scale[frame=on,height=2ex]{$\scriptstyle 2$}\quad
+\dontleavehmode\scale[frame=on,height=2ex]{$\scriptscriptstyle 2$}\quad\quad
+\dontleavehmode\scale[frame=on,width=4em]{\colored[r=.6,a=1,t=.5]{$\textstyle 2$}}\hskip-4em
+\dontleavehmode\scale[frame=on,width=4em]{\colored[g=.6,a=1,t=.5]{$\scriptstyle 2$}}\hskip-4em
+\dontleavehmode\scale[frame=on,width=4em]{\colored[b=.6,a=1,t=.5]{$\scriptscriptstyle 2$}}\quad\quad
+\dontleavehmode{$\textstyle 2$}\quad
+\dontleavehmode{$\scriptstyle 2$}\quad
+\dontleavehmode{$\scriptscriptstyle 2$}\quad
+\stoplinecorrection
+
+Plenty has been written (in various documents that come with \CONTEXT) about how
+this all works together and how it impacts the design of the system, so here I
+just give a short summary of what a font system has to deal with.
+
+\startitemize
+\startitem
+ In a bodyfont setup different sizes (9pt, 10pt, 12pt) can have their own
+ specific set of fonts. This can result in quite a number of definitions that
+ relate to the style, like regular, bold, italic, bold italic, slanted, bold
+ slanted, etc. When possible loading the fonts is delayed. In \CONTEXT\ often
+ the number of fonts that are actually loaded is not that large.
+\stopitem
+\startitem
+ Some font designs have different shapes per bodyfont size. A minor
+ complication is that when one is missing some heuristic best|-|match choice
+ might be needed. Okay, in practice only Latin Modern falls into this category
+ for \CONTEXT. Maybe \OPENTYPE\ variable fonts can be seen this way, but,
+ although we supported that right from the start, I haven't noticed much
+ interest in the \TEX\ community.
+\stopitem
+\startitem
+ Within a bodyfont size we distinguish size variants. We can go smaller (x and
+ xx), for instance when we use sub- and superscripts in text, or we can go
+ larger, for instance in titles (a, b, c, d, \unknown). Fortunately most of
+ the loading of these can be delayed too.
+\stopitem
+\startitem
+ When instances are not available, scaling can be used, as happens for
+ instance with 11pt in Computer Modern. Actually, this is why in \CONTEXT\ we
+ default to 12pt, because the scaled versions didn't look as nice as the
+ others (keep in mind that we started in the age of bitmaps).
+\stopitem
+\startitem
+ Special features, such as smallcaps or oldstyle numerals, can demand their own
+ definitions. More loading and automatic definitions can be triggered by sizes
+ needed in, e.g., scripts and titles.
+\stopitem
+\startitem
+ A document can have a mixed setup, that is: using different font
+ designs within one
+ document, so some kind of namespace subsystem is needed.
+\stopitem
+\startitem
+ In an eight|-|bit font world, we not only have text fonts but also collections
+ of symbols, and even in math there are additional symbol collections. In
+ \OPENTYPE\ symbols end up in text fonts, but there we have tons of emojis
+ and color fonts. All has to be dealt with in an integrated way. And we're
+ not even talking of virtual fonts, (runtime) \METAPOST\ generated fonts, and
+ so on.
+\stopitem
+\startitem
+ In traditional eight|-|bit engines, hyphenation depends on a font's encoding,
+ which can require loading a font multiple times in different encodings. This
+ depends on the language mix used. A side point is that defining a European
+ encoding covering most Latin languages was not that hard, especially when one
+ keeps in mind that many eight|-|bit encodings waste slots on seldom used
+ symbols, but by that time \OPENTYPE\ and \UNICODE\ input started to dominate.
+\stopitem
+\startitem
+ In the more modern \OPENTYPE\ fonts combinations of features can demand
+ additional instances: one can think of language|/|script combinations,
+ substitutions in base mode, special effects like emboldening, color fonts,
+ etc.
+\stopitem
+\startitem
+ Math is complicated by the fact that in traditional \TEX, alphabets come from
+ different fonts, which is why we have many so|-|called families; a font can
+ have several alphabets which means that some mapping can be needed. Operating
+ on the size, shape, encoding and style axes puts some demands on the font
+ system. Add to this the (often) partial (due to lack of fonts) bold support
+ and it gets even more complicated. In \OPENTYPE\ all the alphabets come from
+ one font.
+\stopitem
+\startitem
+ There is additional math auto|-|definition and loading code for the sizes
+ used in text scripts and titles.
+\stopitem
+\stopitemize
+
+All this has resulted in a pretty complex subsystem. Although going \OPENTYPE\
+(and emulated \OPENTYPE\ with \TYPEONE\ fonts as we do in \MKIV) removes some
+complications, like encodings, it also adds complexity because of the many
+possible font features, either dependent or not on script and language. Text as
+well as math got simpler in the \TEX\ code, though that was traded for quite a
+bit of \LUA\ code to deal with new features.
+
+So, in order to let the font subsystem not impact performance too much, let alone
+extensive memory usage, the \CONTEXT\ font subsystem is rather optimized. The
+biggest burden comes from fonts that have a dynamic (adaptive) definition because
+then we need to do quite a bit of testing per font switch, but even that has
+always been rather fast.
+
+\stopsection
+
+\startsection[title={Reality}]
+
+In \MKIV\ and therefore also in \LUAMETATEX\ (\LMTX) more font magic happens. The
+initial node lists that make up a box or paragraph can get manipulated in several
+ways and often fonts are involved. The font features (smallcaps, oldstyle,
+alternates, etc.)\ can be defined as static (part of the definition) or as
+dynamic (resolved on the spot at the cost of some overhead). Characters can be
+remapped, fonts can be replaced. The math subsystem in \MKIV\ was different right
+from the start: we use a limited number of families (regular, bold, l2r and r2l),
+and stay abstract till the moment we need to deal with the specific alphabets.
+But still, in \MKIV, we have the families with three fonts.
+
+In the \LUAMETATEX\ manual we show some math magic for different fonts. As a side
+effect, we set up half a dozen bodyfont collections: Lucida, Pagella, Latin
+Modern, Dejavu, the math standard Cambria, etc. Even with delayed and shared font
+loading, we end up with 158 instances but quite a few of them are math fonts, at
+least six per bodyfont size: regular and bold (emboldened) text, script and
+scriptscript. Of course most are just copies with different scaling that reuse
+already loaded resources. In the final \PDF\ we have 21 subsetted fonts.
+
+If we look at the math fonts that we use today, there is however quite some
+overlap. It starts with a text font. From that, script and scriptscript variants
+are derived, but often these variants use many text size related shapes too. Some
+shapes get alternatives (from the \type {ssty} feature), and the whole clone gets
+scaled. But, much of the logic of, for instance, extensibles is the same.
+
+A similar situation happens with large \CJK\ fonts: there are hardly any advanced
+features involved there, so any size is basically a copy with scaled dimensions,
+and these fonts can be truly huge!
+
+When we talk about features, in many cases in \CONTEXT\ you don't define them as
+part of the font. For instance small caps can best be triggered by using a
+dynamic feature: applied to a specific stretch of text. In fact, often features
+like superiors of fractions only work well on characters that fit the bill and
+produce weird side effects otherwise (a matter of design completeness). When the
+font handler does its work there are actually four cases: no features get applied
+(something that happens with, for instance, most monospaced fonts); base mode is
+used (which means that the \TEX\ machinery takes care of constructing ligatures
+and injecting kerns); and node mode (where \LUA\ handles the features). The
+fourth case is a special case of node mode where a different feature set is
+applied. \footnote {We also have so|-|called plug mode where an external renderer
+can do the work but that one is only around due to some experiments during Idris
+Hamid's font development.} At the cost of some extra overhead (for each node mode
+run) dynamic features are quite powerful and save quite a lot of memory and
+definitions. \footnote {The generic font handler that is derived from the
+\CONTEXT\ one doesn't implement this, so it runs a little faster.} The overhead
+comes from much more testing regarding the font we deal with because suddenly the
+same font can demand different treatments, depending on what dynamic features are
+active. \footnote {Originally this model was introduced for a dynamic paragraph
+optimization subsystem for Arabic but in practice no one uses it because there
+are no suitable fonts.}
+
+Although the font handling is responsible for much of the time spent in \LUA, it
+is still reasonable given what has to be done. Because we have an extensible
+system, it's often the extensions that takes additional runtime. Flexibility
+comes at a price.
+
+\stopsection
+
+\startsection[title={Progress}]
+
+At some point I started playing with realtime glyph scaling. Here realtime means
+that it doesn't depend on the font definition. To get an idea, here is an example
+(all examples are additionally scaled for \TUGBOAT):
+
+\startbuffer
+test {\glyphxscale 2500 test} test
+\stopbuffer
+
+\typebuffer
+
+\getbuffer
+
+The glyphs in the current font get scaled horizontally without the need for an
+extra font instance. Now, this kind of trickery puts some constraints on the font
+handling, as is demonstrated in the next example. We use Latin Modern because
+that font has all these ligatures:
+
+\startbuffer
+\definedfont[lmroman10-regular*default]%
+e{\glyphxscale 2500 ff}icient
+ef{\glyphxscale 2500 f}icient
+ef{\glyphxscale 2500 fi}cient
+e{\glyphxscale 2500 ffi}cient
+\stopbuffer
+
+\typebuffer
+
+{\getbuffer}
+
+In order to deal with this kind of scaling, we now operate not only on the font
+(id) and dynamic feature axes, but also on the scales, of which we have three
+variants: glyph scale, glyph xscale and glyph yscale. There is actually also a
+state dimension but we omit that for now (think of flagging glyphs as initial or
+final). This brings the number of axis to six. It is important to stress that in
+these examples the same font instance is used!
+
+Just for the record: several approaches to switching fonts are possible but for
+now we stick to a simple font id switch plus glyph scale settings at the \TEX\
+end. A variant would be to introduce a new mechanism where id's and scales go
+together but for now I see no real gain in that.
+
+\stopsection
+
+\startsection[title={Math}]
+
+Given what has been discussed in the previous sections, a logical question would
+be \quotation {Can we apply scaling to math?} and the answer is \quotation {Yes,
+we can!}. We can even go a bit further and that is partly due to some other
+properties of the engine.
+
+From \PDFTEX\ the \LUATEX\ engines inherited character protrusion and glyph
+expansions, aka hz. However, where in \PDFTEX\ copies of the font are made that
+carry the expanded dimensions, in \LUATEX\ at some point this was replaced by an
+expansion field in the glyph and kern nodes. So, instead of changing the font id
+of expanded glyphs, the same id is used but with the applied expansion factor set
+in the glyph. A side effect was that in places where dimensions are needed, we
+call functions that calculate the expanded widths on request (as these can change
+during linebreak calculations) in combination with accessing font dimensions
+directly. This level of abstraction is even more present in \LUAMETATEX. This
+means that we have an uniform interface to fonts and as a side effect scaling
+need be dealt with in only a few places in the code.
+
+Now, in math we have a few more complications. First of all, we have three sizes
+to consider and we also have lots of parameters that depend on the size. But, as
+I wanted to be able to apply scaling to math, the whole machinery was also
+abstracted in a way that, at the cost of some extra overhead, made it easier to
+work with scaled glyph properties. This means that we can stick to loading only
+one bodyfont size of math (note that each math family has three sizes, where the
+script and script sizes can have different, fine tuned, shapes) and just scale
+that on demand.
+
+Once all that was in place it was a logical next step to see if we could stick to
+just a single instance. Because in \LUAMETATEX\ we try to load fonts efficiently
+we store only the minimally needed information at the \TEX\ end. A font with no
+math therefore has less data per glyph. Again, this brings some abstraction that
+helped to implement the one instance mechanism. A math glyph has optional lists
+of increasing sizes and vertical or horizontal extensibles. So what got added was
+an optional chain of smaller sizes. If a character has three different glyphs for
+the three sizes, the text glyph has a pointer to the script glyph which in turn
+has a pointer to the scriptscript glyph. This means that when the math engine
+needs a specific character at a given size (text, script, scriptscript) we just
+follow that chain.
+
+In an \OPENTYPE\ math font the script and scriptscript sizes are specified as
+percentages of the text size. When the dimensions of a glyph are needed, we just
+scale on the fly. Again this adds some overhead but I'm pretty sure that no user
+will notice.
+
+So, to summarize: if we need a character at scriptscript size, we access the text
+size glyph, check for a pointer to a script size, go there, and again check for a
+smaller size. We use only what fits the bill. And, when we need dimensions we
+just scale. In order to scale we need the relative size, so we need to set that
+up when we load the font. Because in \CONTEXT\ we also can assemble a virtual
+\OPENTYPE\ font from \TYPEONE\ fonts, it was actually that (old) compatibility
+feature, the one that implements \TYPEONE\ based on \OPENTYPE\ math, that took
+the most time to adapt, not so much because it is complicated but because in
+\LMTX\ we have to bypass some advanced loading mechanisms. Because we can scale
+in two dimensions the many (font|-|related) math parameters also need to be dealt
+with accordingly.
+
+The end result is that for math we now only need to define two fonts per bodyfont
+setup: regular and bold at the natural scale (normally 10pt) and we share these
+for all sizes. As a result of this and what we describe in the next section, the
+158 instances for the \LUAMETATEX\ manual can be reduced to~30.
+
+
+\stopsection
+
+\startsection[title={Text}]
+
+Sharing instances in text mode is relatively simple, although we do have to keep
+in mind that scaling is an extra axis when dealing with font features: two
+neighboring glyphs with the same font id and dynamics but with different scales
+are effectively from different fonts.
+
+Another complication is that when we use font fallbacks (read:\ take missing
+glyphs from another font) we no longer have a dedicated instance but use a shared
+one. This in itself is not a problem but we do need to handle specified relative
+scales. This was not that hard to patch in \CONTEXT\ \LMTX.
+
+We can enforce aggressive font sharing with:
+
+\starttyping
+\enableexperiments[fonts.compact]
+\stoptyping
+
+After that we often use fewer instances. Just to give an idea, on the \LUAMETATEX\
+manual we get these stats:
+
+\starttyping
+290 pages, 10.8 sec, 292M lua, 99M tex, 158 instances
+290 pages, 9.5 sec, 149M lua, 35M tex, 30 instances
+\stoptyping
+
+So, we win on all fronts when we use this glyph scaling mechanism. The magic
+primitive that deals with this is named \type {\glyphscale}; it accepts a
+number, where \type {1200} and \type {1.2} both mean scaling to 20\percent\ more
+than normal. But it's best not to use this primitive directly.
+
+A specific scaled font can be defined using the \type {\definefont} command. In
+\LMTX\ a regular scaler can be followed by two scale factors. The next example
+demonstrates this (as can be seen, the \type {yoffset} affects the baseline):
+
+\startbuffer
+\definefont[FooA][Serif*default @ 12pt 1800 500]
+\definefont[FooB][Serif*default @ 12pt 0.85 0.4]
+\definefont[FooC][Serif*default @ 12pt]
+
+\definetweakedfont[runwider] [xscale=1.5]
+\definetweakedfont[runtaller][yscale=2.5,xscale=.8,yoffset=-.2ex]
+
+{\FooA test test \runwider test test \runtaller test test}\par
+{\FooB test test \runwider test test \runtaller test test}\par
+{\FooC test test \runwider test test \runtaller test test}\par
+\stopbuffer
+
+\typebuffer
+
+We also use the new \type {\definetweakedfont} command here. This example not
+only shows the two scales but also introduces the offset.
+
+\getbuffer
+
+In compact mode this is one font. Here is another example:
+
+\startbuffer
+\definetweakedfont[squeezed][xscale=0.9]
+
+\startlines
+$a = b^2 + \sqrt{c}$
+{\squeezed $a = b^2 + \sqrt{c}$}
+\stoplines
+\stopbuffer
+
+\typebuffer
+
+\getbuffer
+
+Watch this:
+
+\startbuffer
+\startcombination[3*1]
+ {\bTABLE
+ \bTR \bTD foo \eTD \bTD[style=\squeezed] $x = 1$ \eTD \eTR
+ \bTR \bTD oof \eTD \bTD[style=\squeezed] $x = 2$ \eTD \eTR
+ \eTABLE}
+ {local}
+ {\bTABLE[style=\squeezed]
+ \bTR \bTD $x = 1$ \eTD \bTD $x = 3$ \eTD \eTR
+ \bTR \bTD $x = 2$ \eTD \bTD $x = 4$ \eTD \eTR
+ \eTABLE}
+ {global}
+ {\bTABLE[style=\squeezed\squeezed]
+ \bTR \bTD $x = 1$ \eTD \bTD $x = 3$ \eTD \eTR
+ \bTR \bTD $x = 2$ \eTD \bTD $x = 4$ \eTD \eTR
+ \eTABLE}
+ {multiple}
+\stopcombination
+\stopbuffer
+
+\typebuffer
+
+\startlinecorrection
+\getbuffer
+\stoplinecorrection
+
+An additional style parameter is also honored:
+
+\startbuffer
+\definetweakedfont[MyLargerFontA][scale=2000,style=bold]
+test {\MyLargerFontA test} test
+\stopbuffer
+
+\typebuffer
+
+This gives:
+
+\getbuffer
+
+Just for the record: the Latin Modern fonts, when set up to use design sizes,
+will still use the specific size|-|related files.
+
+\stopsection
+
+\startsection[title={Hackery}]
+
+You can use negative scale values, as is demonstrated in the following
+code:
+
+\startbuffer
+\bTABLE[align=middle]
+ \bTR
+ \bTD a{\glyphxscale 1000 \glyphyscale 1000 bc}d \eTD
+ \bTD a{\glyphxscale 1000 \glyphyscale -1000 bc}d \eTD
+ \bTD a{\glyphxscale -1000 \glyphyscale -1000 bc}d \eTD
+ \bTD a{\glyphxscale -1000 \glyphyscale 1000 bc}d \eTD
+ \eTR
+ \bTR
+ \bTD \tttf +1000 +1000 \eTD
+ \bTD \tttf +1000 -1000 \eTD
+ \bTD \tttf -1000 -1000 \eTD
+ \bTD \tttf -1000 +1000 \eTD
+ \eTR
+\eTABLE
+\stopbuffer
+
+\typebuffer
+
+gives:
+
+\startlinecorrection
+\getbuffer
+\stoplinecorrection
+
+Glyphs can have offsets and these are used for implementing \OPENTYPE\ features.
+However, they are also available on the \TEX\ side. Take this example where we
+use the new \type {\glyph} primitive (a variant of \type {\char} that takes
+keywords):
+
+\startbuffer
+\ruledhbox{
+ \ruledhbox{\glyph yoffset 1ex options 0 123} % left curly brace
+ \ruledhbox{\glyph xoffset .5em yoffset 1ex options "C0 123}
+ \ruledhbox{oeps{\glyphyoffset 1ex \glyphxscale 800
+ \glyphyscale\glyphxscale oeps}oeps}
+}
+\stopbuffer
+
+\typebuffer \getbuffer
+
+This example demonstrates that the \type {\glyph} primitive takes quite a few
+keywords: \type {xoffset}, \type {yoffset}, \type {xscale}, \type {yscale}, \type
+{left}, \type {right}, \type {raise}, \type {options}, \type {font} and \type
+{id} where the last two take a font identifier or font id (a positive number).
+For this article it's enough to know that the option indicates that glyph
+dimension should include the offset. In a moment we will see an alternative that
+doesn't need that.
+
+\startbuffer
+\samplefile{jojomayer}
+{\glyphyoffset .8ex
+ \glyphxscale 700 \glyphyscale\glyphxscale
+ \samplefile{jojomayer}}
+{\glyphyscale\numexpr3*\glyphxscale/2\relax
+ \samplefile{jojomayer}}
+{\glyphyoffset -.2ex
+ \glyphxscale 500 \glyphyscale\glyphxscale
+ \samplefile{jojomayer}}
+\samplefile{jojomayer}
+\stopbuffer
+
+\typebuffer
+
+To quote Jojo Mayer:
+
+\startnarrower
+\darkred \getbuffer
+\stopnarrower
+
+Keep in mind that this can interfere badly with font feature processing which also
+used offsets. It might often work out okay vertically, but less well horizontally.
+
+The scales, as mentioned, works with pseudo|-|scales but that is sometimes a bit
+cumbersome. This is why a special \type {\numericscale} primitive has been
+introduced.
+
+\startbuffer
+1200 : \the\numericscale1200
+1.20 : \the\numericscale1.200
+\stopbuffer
+
+\typebuffer
+
+Both these lines produce the same integer:
+
+\startlines\tttf
+\getbuffer
+\stoplines
+
+You can do strange things with these primitives but keep in mind that you can
+also waste the defaults.
+
+\startbuffer[definition]
+\def\UnKernedTeX
+ {T%
+ {\glyph xoffset -.2ex yoffset -.4ex `E}%
+ {\glyph xoffset -.4ex options "60 `X}}
+\stopbuffer
+
+\startbuffer[example]
+We use \UnKernedTeX\ and {\bf \UnKernedTeX} and {\bs \UnKernedTeX}:
+the slanted version could use some more left shifting of the E.
+\stopbuffer
+
+\typebuffer[definition,example]
+
+This gives the \TEX\ logos but of course we normally use the more official
+definitions instead.
+
+\startnarrower
+ \darkred \getbuffer[definition,example]
+\stopnarrower
+
+Because offsets are (also) used for handling font features like mark and cursive
+placement as well as special inter|-|character positioning, the above is
+suboptimal. Here is a better alternative:
+
+\startbuffer[definition]
+\def\UnKernedTeX
+ {T\glyph left .2ex raise -.4ex `E\glyph left .2ex `X\relax}
+\stopbuffer
+
+\typebuffer[definition]
+
+The result is the same:
+
+\startnarrower
+ \darkgreen \getbuffer[definition,example]
+\stopnarrower
+
+But anyway: don't overdo it. We have dealt with such cases for decades without
+these fancy new features. The next example shows margins in action:
+
+\startlinecorrection
+\bTABLE[align=middle,width=.33\textwidth]
+ \bTR
+ \bTD \showglyphs \multiply\glyphscale by 2 <{\darkgray \glyph `M}>\eTD
+ \bTD \showglyphs \multiply\glyphscale by 2 <{\darkgray \glyph raise 3pt `M}>\eTD
+ \bTD \showglyphs \multiply\glyphscale by 2 <{\darkgray \glyph raise -3pt `M}>\eTD
+ \eTR
+ \bTR[frame=off]
+ \bTD \tttf \eTD
+ \bTD \tttf raise 3pt \eTD
+ \bTD \tttf raise -3pt \eTD
+ \eTR
+ \bTR
+ \bTD \showglyphs \multiply\glyphscale by 2 <{\darkgray \glyph left 3pt `M}>\eTD
+ \bTD \showglyphs \multiply\glyphscale by 2 <{\darkgray \glyph right 2pt `M}>\eTD
+ \bTD \showglyphs \multiply\glyphscale by 2 <{\darkgray \glyph left 3pt right 2pt `M}>\eTD
+ \eTR
+ \bTR[frame=off]
+ \bTD \tttf left 3pt \eTD
+ \bTD \tttf right 2pt\eTD
+ \bTD \tttf left 3pt right 2pt\eTD
+ \eTR
+ \bTR
+ \bTD \showglyphs \multiply\glyphscale by 2 <{\darkgray \glyph left -3pt `M}>\eTD
+ \bTD \showglyphs \multiply\glyphscale by 2 <{\darkgray \glyph right -2pt `M}>\eTD
+ \bTD \showglyphs \multiply\glyphscale by 2 <{\darkgray \glyph left -3pt right -2pt `M}>\eTD
+ \eTR
+ \bTR[frame=off]
+ \bTD \tttf left -3pt \eTD
+ \bTD \tttf right -2pt \eTD
+ \bTD \tttf left -3pt right -2pt \eTD
+ \eTR
+\eTABLE
+\stoplinecorrection
+
+Here is another way of looking at it:
+
+\startbuffer
+\glyphscale 4000
+\vl\glyph `M\vl\quad
+\vl\glyph raise .2em `M\vl\quad
+\vl\glyph left .3em `M\vl\quad
+\vl\glyph right .2em`M\vl\quad
+\vl\glyph left -.2em right -.2em`M\vl\quad
+\vl\glyph raise -.2em right .4em`M\vl
+\stopbuffer
+
+\typebuffer
+
+The raise as well as left and right margins are taken into account when calculating the
+dimensions of a glyph.
+
+{\getbuffer}
+
+
+\stopsection
+
+\startsection[title={Implementation}]
+
+Discussing the implementation in the engine makes no sense here, also because
+details might change. However, it is good to know that many properties travel
+with the glyph nodes, for instance the scales, margins, offsets, language, script
+and state properties, control over kerning, ligaturing, expansion and protrusion,
+etc. The dimensions (width, height and depth) are not stored in the glyph node
+but calculated from the font, scales and optionally the offsets and expansion
+factor. One problem is that the more clever (and nice) solutions we cook up, the
+more it might impact performance. So, I will delay some experiments till I have a
+more powerful machine.
+
+One reason for {\em not} storing the dimensions in a glyph node is that we often
+copy those nodes or change character fields in the font handler and we definitely
+don't want the wrong dimensions there. At that moment, offsets and margin fields
+don't reflect features yet, so copying them is no big deal because at that moment
+these are still zero. However, dimensions are rather character bound so every
+time a character is set, we also would have to set the dimensions. Even worse,
+when we can set them, the question arises if they were already set explicitly.
+So, this is a can of worms we're not going to open: the basic width, height and
+depth of the glyph as specified in the font is used and combined with actual
+dimensions (likely already scaled according the glyph scales) in offset and
+margin fields.
+
+Now, I have to admit that especially playing with using margins to glyphs instead
+of font kerns is more of an experiment to see what the consequences are than a
+necessity, but what would be the joy of \TEX\ without such experiments? And as
+usual, in \CONTEXT\ these will become options in the font handler that one can
+enable, or not.
+
+\stopsection
+
+\stopchapter
+
+\stopcomponent
+
+% sample file
+
+\setuplayout[topspace=1cm,header=1cm] \setuplayout[middle]
+
+\setupbodyfont[pagella,10pt]
+
+\setupalign[verytolerant,stretch]
+
+\setupwhitespace[big]
+
+\starttext
+
+\startbuffer
+\definetweakedfont[bfe][xscale=2000,yscale=6000,style=bf]
+
+\setuphead[chapter][style=\bfe]
+
+\dostepwiserecurse {10} {2020} {10} {
+ \title{Here we go #1!}
+ \start
+ \glyphxscale#1\relax
+ \glyphyscale#1\relax
+ \setupinterlinespace
+ \samplefile{ward}%
+ \start
+ \bf
+ \samplefile{ward}%
+ \glyphxscale\numexpr(#1*2)/3\relax
+ \glyphyscale#1\relax
+ \samplefile{ward}%
+ \par
+ \stop
+ \def\TEST{y = \sqrt{x^2 + 1}^3}%
+ \dontleavehmode
+ \ruledhbox{\glyphxscale #1 \glyphyscale #1 $\left{\TEST\right}$}
+ \ruledhbox{\glyphxscale #1 \glyphyscale \numexpr#1*3\relax $\left{\TEST\right}$}
+ \ruledhbox{\glyphxscale \numexpr#1/2\relax \glyphyscale \numexpr#1*2\relax $\left{\TEST\right}$}
+ \par
+ \stop
+ \page
+}
+\stopbuffer
+
+\getbuffer
+
+% As often there is a musical timestamp to this text: discovering Julia Hofer
+% (bass, came there via checking out (of course) Leland Sklar, and now i have to
+% watch a bunch of Victor Wooten videos too) and Neon Vine's (play and combine
+% anything) on YT. Both examples of where (imo extensive) practicing real
+% instruments can bring you with todays diverse equipment. These are interesting
+% times (it's now last days of 2020).
+%
+% The initial \definescaledfont was replaced by \definetweakedfont in the first
+% week of Januari 2021, when I watched the joyful covers of Peter Gabriels
+% "Steam" by Yoyoka which shows that the future belongs to the real young kids
+% (so much explosive creativity!) and not to the old folks.