ontarget-mathfonts.tex /size: 52 Kb    last modification: 2024-01-16 10:21
1% language=us runpath=texruns:manuals/ontarget
2
3% musical timestamp: 2022/07/01 while listening to Hania Rani @ https://www.youtube.com/watch?v=sp3B97N67Cw
4
5% todo apply withprescripts -> to all components
6
7\usemodule[math-tweaks]
8
9\startcomponent ontarget-mathfonts
10
11\environment ontarget-style
12
13\startchapter[title={Dealing with math fonts}]
14
15\startsubject[title=Introduction]
16
17Here we will explain some of the tricks that we apply to math fonts so that they
18not only work better with the \LUAMETATEX\ math engine but also look better, at
19least in our opinion. We will not show specific fonts because after all, who can
20complain about something that comes for free, but you can see whatever we do to
21make it work in action in \CONTEXT\ where we setup these fonts. This is also a
22summary of what Mikael Sundqvist and I have been doing for a while now: improve
23the rendering of math, a rather enjoyable experience, also because we ran into
24humorous effects with and properties of fonts. Because we consider ourselves free
25from any conventions we could happily explore solution.
26
27\stopsubject
28
29\startsubject[title=Fences]
30
31\startMPdefinitions
32path My_left_fence    ; My_left_fence    := (1,1) -- (0,1) -- (0,-1) -- (1,-1) ;
33path My_right_fence   ; My_right_fence   := (0,1) -- (1,1) -- (1,-1) -- (0,-1) ;
34path My_middle_fence  ; My_middle_fence  := (0,1)                    -- (0,-1) ;
35
36path My_right_fence_x ; My_right_fence_x   := (0,1) -- (1, 1/2) -- (1,-1/2) -- (0,-1) ;
37
38path My_left_top      ; My_left_top      := (1, 1  ) -- (0, 1  ) -- (0, 1/2) ;
39path My_left_middle   ; My_left_middle   := (0, 1/2) -- (0,-1/2) ;
40path My_left_bottom   ; My_left_bottom   := (0,-1/2) -- (0,-1  ) -- (1,-1  ) ;
41
42path My_right_top     ; My_right_top     := (0, 1  ) -- (1, 1  ) -- (1, 1/2) ;
43path My_right_middle  ; My_right_middle  := (1, 1/2) -- (1,-1/2) ;
44path My_right_bottom  ; My_right_bottom  := (1,-1/2) -- (1,-1  ) -- (0,-1  ) ;
45
46path My_right_top_x    ; My_right_top_x     := (0, 1  ) -- (1, 1/2) ;
47path My_right_middle_x ; My_right_middle_x  := (1, 1/2) -- (1,-1/2) ;
48path My_right_bottom_x ; My_right_bottom_x  := (1,-1/2) -- (0,-1  ) ;
49
50path My_middle_top    ; My_middle_top    := (0, 1  ) -- (0, 1/2) ;
51path My_middle_middle ; My_middle_middle := (0, 1/2) -- (0,-1/2) ;
52path My_middle_bottom ; My_middle_bottom := (0,-1/2) -- (0,-1  ) ;
53
54path My_content       ; My_content       := fullcircle ;
55
56vardef My_Fenced (expr left, middle, right, size) =
57    image (
58        draw My_left_fence   xyscaled (1,left  ) shifted (0,0) withcolor darkgray ;
59        draw My_content      xyscaled (2,size  ) shifted (3,0) withcolor darkblue ;
60        draw My_middle_fence xyscaled (1,middle) shifted (5,0) withcolor darkgray ;
61        draw My_content      xyscaled (2,size  ) shifted (7,0) withcolor darkblue ;
62        if left <> right :
63            draw My_right_fence_x xyscaled (1,right ) shifted (9,0) withcolor darkgray ;
64        else :
65            draw My_right_fence   xyscaled (1,right ) shifted (9,0) withcolor darkgray ;
66        fi ;
67    )
68enddef ;
69
70vardef My_Extensibled (expr left, middle, right, size) =
71    image (
72        draw        My_left_top      xyscaled (1,left  ) shifted (0,0) withcolor darkgray ;
73        draw        My_left_middle   xyscaled (1,left  ) shifted (0,0) withcolor darkgreen ;
74        draw        My_left_bottom   xyscaled (1,left  ) shifted (0,0) withcolor darkgray ;
75        drawpoints  My_left_middle   xyscaled (1,left  ) shifted (0,0) withpen pencircle scaled .4 withcolor white ;
76        drawpoints  My_left_top      xyscaled (1,left  ) shifted (0,0) withpen pencircle scaled .2 withcolor red ;
77        drawpoints  My_left_bottom   xyscaled (1,left  ) shifted (0,0) withpen pencircle scaled .2 withcolor red ;
78        draw        My_content       xyscaled (2,size  ) shifted (3,0) withcolor darkblue ;
79        draw        My_middle_top    xyscaled (1,middle) shifted (5,0) withcolor darkgray ;
80        draw        My_middle_middle xyscaled (1,middle) shifted (5,0) withcolor darkgreen ;
81        draw        My_middle_bottom xyscaled (1,middle) shifted (5,0) withcolor darkgray ;
82        drawpoints  My_middle_middle xyscaled (1,middle) shifted (5,0) withpen pencircle scaled .4 withcolor white ;
83        drawpoints  My_middle_top    xyscaled (1,middle) shifted (5,0) withpen pencircle scaled .2 withcolor red ;
84        drawpoints  My_middle_bottom xyscaled (1,middle) shifted (5,0) withpen pencircle scaled .2 withcolor red ;
85        draw        My_content       xyscaled (2,size  ) shifted (7,0) withcolor darkblue ;
86        if left <> right :
87            draw        My_right_top     xyscaled (1,right ) shifted (9,0) withcolor darkgray ;
88            draw        My_right_middle  xyscaled (1,right ) shifted (9,0) withcolor darkgreen ;
89            draw        My_right_bottom  xyscaled (1,right ) shifted (9,0) withcolor darkgray ;
90            drawpoints  My_right_middle  xyscaled (1,right ) shifted (9,0) withpen pencircle scaled .4 withcolor white ;
91            drawpoints  My_right_top     xyscaled (1,right ) shifted (9,0) withpen pencircle scaled .2 withcolor red ;
92            drawpoints  My_right_bottom  xyscaled (1,right ) shifted (9,0) withpen pencircle scaled .2 withcolor red ;
93        else :
94            draw        My_right_top_x     xyscaled (1,right ) shifted (9,0) withcolor darkgray ;
95            draw        My_right_middle_x  xyscaled (1,right ) shifted (9,0) withcolor darkgreen ;
96            draw        My_right_bottom_x  xyscaled (1,right ) shifted (9,0) withcolor darkgray ;
97            drawpoints  My_right_middle_x  xyscaled (1,right ) shifted (9,0) withpen pencircle scaled .4 withcolor white ;
98            drawpoints  My_right_top_x     xyscaled (1,right ) shifted (9,0) withpen pencircle scaled .2 withcolor red ;
99            drawpoints  My_right_bottom_x  xyscaled (1,right ) shifted (9,0) withpen pencircle scaled .2 withcolor red ;
100        fi ;
101    )
102enddef ;
103\stopMPdefinitions
104
105Fences come in two variants: fixed sizes and so called extensibles that are
106constructed from recipes that combine snippets that can partially overlap. Fenced
107material has an optional symbol at the start, an optional one at the end and zero
108or more symbols in the middle. Here we have all three:
109
110\startlinecorrection
111\startMPcode
112    draw My_Fenced (2,2,2,2) scaled 5mm ;
113\stopMPcode
114\stoplinecorrection
115
116Ideally these symbols scale in the same way, depending on the other context. This
117means that \TEX\ first has to measure what sits in between but we will not dive
118into that. The left and right symbols are normally pairs like parentheses or
119braces, but any mix is possible. Ideally a font is designed with this in mind but
120unfortunately we see this:
121
122\startlinecorrection
123\startMPcode
124    draw My_Fenced (2,3,2,2) scaled 5mm ;
125\stopMPcode
126\stoplinecorrection
127
128And even this:
129
130\startlinecorrection
131\startMPcode
132    draw My_Fenced (2,3,2.5,2) scaled 5mm ;
133\stopMPcode
134\stoplinecorrection
135
136It might be a side effect of the limited amount fo available slots in traditional
137math fonts that also resulted in non consistent sets in \OPENTYPE\ follow|-|ups
138and when one fonts does that more follow that approach.
139
140You can find rendering like this:
141
142\startlinecorrection
143\startMPcode
144    draw My_Fenced (3,2,3,2) scaled 5mm ;
145\stopMPcode
146\stoplinecorrection
147
148and this
149
150\startlinecorrection
151\startMPcode
152    draw My_Fenced (2,2,2,6) scaled 5mm ;
153\stopMPcode
154\stoplinecorrection
155
156because a programmable language like \TEX\ can use some tricks to force sizes: we
157just create some local fence which dimension is determined by some invisible
158rule. In \LUAMETATEX\ we can actually enforce dimensions and in \CONTEXT\ we can
159filter specific sizes.
160
161So how does this sizing work? A fence character starts out with the normal size
162but then a larger one is needed, the math engine will check if there is a larger
163variant. An \OPENTYPE\ font can provide these and in the engine that works out as
164following a linked list to a next size. When we run out of sizes there can be an
165extension recipe present where a fence is made from snippets pasted together.
166Normally that goes unnoticed because there is a little overlap between these
167snippets.
168
169\startlinecorrection
170\startMPcode
171    draw My_Extensibled (2,2,2,4) scaled 5mm ;
172\stopMPcode
173\stoplinecorrection
174
175A larger fence will simply add more middle pieces, and it will not do as below:
176
177\startlinecorrection
178\startMPcode
179    draw My_Extensibled (3,3,3,6) scaled 5mm ;
180\stopMPcode
181\stoplinecorrection
182
183Because we're talking of a deliberate design you cannot simply scale snippets and
184expect them to work out well visually. However, in a pure vertical case one
185actually could and in practice all these extensibles have (of course) vertical
186bars. Anyway, in the above example the larger middle piece actually is just
187several middle pieces overlapping.
188
189However, as we mentioned, fonts are not always consistent. First of all, when we
190run over the (increasing in size) variants we have discrete steps and you're
191lucky if a font has more than half a dozen. As soon as we end up with the
192extensible the size can be matched well.
193
194So how do we compensate for misbehavior? There are two parameters in \TEX\ then
195determine the matching: \typ {\delimiterfactor} and \typ {\delimitershortfall}.
196Plain \TEX\ set them to 901 and 5pt which works okay in most cases. In \CONTEXT\
197we set them to 1000 and 0pt and instead use the parameters \typ
198{\UmathDelimiterPercent} and \typ {\UmathDelimiterShortfall} that are bound fo
199fonts. In addition to that we use the \typ {nooverflow} keyword with \type
200{\Umiddle} which makes sure that we always stay within the size of the outer
201fences. That just looks better.
202
203In addition we can tweak the dimensions of glyphs and apply effects such as
204expanding so that we get a bit more consistent visual appearance. We can also
205signal that we should ignore sizes larger than a given index.
206
207The next sequence show what happens in practice when we tell \type {\Umiddle} to
208never exceed the requested size. Because we start with stepwise sizes the first
209part of this sequence has no matching sizes. At some point we end up at the
210extensibles.
211
212\showmathmiddletweaks
213
214Its is worth noticing that we tried several alternative approaches. For instance
215what happens when we only use extensibles? In that case there will be no fit for
216the smaller ones because the at least two parts of an extensible can seldom
217completely overlap that much.
218
219Actually, when we tested that we noticed that even in valid situations there can
220be strange overlap. At that time for instance the Lucida fonts had overlapping
221artifact in some curly braces which we found out when we tried to nil some of the
222larger, odd looking, step variants. Latin modern and some of the gyre fonts had
223unexpected jumps to larger sizes which made us decide to make the delimiter
224parameters font specific so that we could more easily adapt them: they basically
225became part of the math parameters of a font.
226
227There are also inconsistencies in the perceived widths of glyphs used: often the
228bars are too thin. That can be solved by applying effects like scaling
229horizontally or vertically and cheating a bit with the dimensions. Another
230solution is that we ignore the variants after a certain size and force
231extensibles sooner but that of course needs to be tested for unwanted overlaps
232too. All these tricks combined make it possible to use math fonts with imperfect
233fences more or less reliable.
234
235\startitemize[packed]
236\startitem
237    Provide an equal amount of fixed size larger variants for all fences: assume
238    arbitrary pairing.
239\stopitem
240\startitem
241    Because fonts have plenty room, provide some ten variants before going
242    extensible.
243\stopitem
244\startitem
245    Try to make the variants and the extensibles similar in look.
246\stopitem
247\startitem
248    Ensure that the width of the vertical bar matches the design.
249\stopitem
250\startitem
251    Make sure that the odd entries in a extensible recipe don't overlap badly.
252\stopitem
253\stopitemize
254
255\stopsubject
256
257\startsubject[title=Accents]
258
259When traditional \TEX\ showed up it was not that common to have pre|-|composed
260characters so when you needed something with an accept on top the way to go was
261to typeset the base character and position the accent on top using either the
262\type {\accent} primitive or some macro. It always was a compromise but
263eventually fonts with more assembled characters showed up. In \OPENTYPE\ fonts
264that operate in the \UNICODE\ domain we have even more characters but even there
265characters can be composed. However, anchors that help achieving this are part of
266the format. For text we use the mark features and for math we use the top anchor.
267Given that, why do we need to tweak it?
268
269\startMPdefinitions
270path My_top_accent ; My_top_accent    := (-1/2,0) -- (0,1/4) -- (1/2,0) ;
271
272path My_content    ; My_content       := fulldiamond ;
273
274vardef My_Accent (expr shift, accent, size, slant) =
275    image (
276        path p ; p := My_content
277            xyscaled (2,size)
278            slanted slant
279        ;
280        draw My_top_accent
281            xyscaled (1,accent)
282            shifted (0,2)
283            withcolor darkgray ;
284        draw p
285            withcolor darkblue ;
286    )
287enddef ;
288
289vardef My_Accent_X (expr shift, accent, size, slant, rotation) =
290    image (
291        path p ; p := My_content rotated rotation
292            xyscaled (2,size)
293            slanted slant
294        ;
295        draw My_top_accent
296            xyscaled (1,accent)
297            shifted point 2 of p
298            shifted - (0,-1)
299            withcolor darkgray ;
300        draw p
301            withcolor darkblue ;
302    )
303enddef ;
304
305vardef My_Accent_Y (expr shift, accent, size, scale) =
306    image (
307        path p ; p := My_content
308            xyscaled (2,size)
309        ;
310        draw My_top_accent xscaled scale
311            xyscaled (1,accent)
312            shifted (0,2)
313            withcolor darkgray ;
314        draw p
315            withcolor darkblue ;
316    )
317enddef ;
318
319vardef My_Accent_Z (expr shift, accent, size, scale) =
320    image (
321        path p ; p := My_content
322            xyscaled (2,size)
323        ;
324        path q ; q := My_top_accent
325            xscaled scale
326            xyscaled (1,accent)
327            shifted (0,2)
328        ;
329        draw q
330            withcolor darkgray ;
331        draw p
332            withcolor darkblue ;
333        draw outerboundingbox q
334            withpen pencircle scaled 1/20
335            withcolor darkred ;
336        draw outerboundingbox p
337            withpen pencircle scaled 1/20
338            withcolor darkred ;
339    )
340enddef ;
341\stopMPdefinitions
342
343Here we have a base character with an accent on top. The character is upright and
344the accent gets positioned in the middle.
345
346\startlinecorrection
347\startMPcode
348    draw My_Accent (2.5,1,2,0) scaled 5mm ;
349\stopMPcode
350\stoplinecorrection
351
352This doesn't work out well if we have a slanted or italic shape:
353
354\startlinecorrection
355\startMPcode
356    draw My_Accent (2.5,1,2,.2) scaled 5mm ;
357    draw My_Accent (2.5,1,2,.4) scaled 5mm shifted (2cm,0) ;
358    draw My_Accent (2.5,1,2,.6) scaled 5mm shifted (4cm,0) ;
359\stopMPcode
360\stoplinecorrection
361
362So we need to compensate, for instance like this:
363
364\startlinecorrection
365\startMPcode
366    draw My_Accent_X (2.5,1,2,.2,0) scaled 5mm ;
367    draw My_Accent_X (2.5,1,2,.4,0) scaled 5mm shifted (2cm,0) ;
368    draw My_Accent_X (2.5,1,2,.6,0) scaled 5mm shifted (4cm,0) ;
369\stopMPcode
370\stoplinecorrection
371
372However, what does determine the right anchor point? From this example you can
373conclude that it is the top of the character. It is probably for that reason why
374the semi automated construction of Latin Modern and the Gyre fonts have quite
375some anchors that are rather bad: getting the anchors right is more a visual job
376than something that can be automated. The topmost point is not really the best
377one to focus on.
378
379\startlinecorrection
380\startMPcode
381    draw My_Accent_X (2.5,1,2,.2,35) scaled 5mm ;
382    draw My_Accent_X (2.5,1,2,.4,35) scaled 5mm shifted (2cm,0) ;
383    draw My_Accent_X (2.5,1,2,.6,35) scaled 5mm shifted (4cm,0) ;
384\stopMPcode
385\stoplinecorrection
386
387Here the topmost position is very off center. In for instance Latin Modern that
388means that on digits like~7 and~4 you get very weird anchoring. And this is why
389we have a tweak that just wipes all the anchors from an alphabet: most alphabets
390don't need them anyway and the engine will use the center when no anchor is
391defined. Just for the record: in traditional \TEX\ engines the horizontal
392position is determined by the kern between a so called skew character and the
393base character. The font format has no anchor field but it has kerns, so this
394trick makes much sense.
395
396We discussed vertical extensible that grow but horizontally we have accents that
397can grow. There are also a few horizontal fences like braces that have
398extensibles but we will cover that later. Accents are such that they only have a
399fixed set of variants and one problem is that there are often not enough of them.
400This means that the engine has to choose one that is reasonable.
401
402\startlinecorrection
403\startMPcode
404    draw My_Accent_Y (2.5,1,2,1)   scaled 5mm ;
405    draw My_Accent_Y (2.5,1,2,2)   scaled 5mm shifted (2cm,0) ;
406    draw My_Accent_Y (2.5,1,2,2.5) scaled 5mm shifted (4cm,0) ;
407    draw My_Accent_Y (2.5,1,2,3)   scaled 5mm shifted (6cm,0) ;
408\stopMPcode
409\stoplinecorrection
410
411In the example above the first two are acceptable but the third and fourth are
412not. Just imagine that there is a superscript or subscript involved. Here we
413apply another cheat: we lie about the dimensions. A glyph can have left and right
414margins that get subtracted when the accent analyzer tries to make a fit which
415means that we can sort of enforce the second solution. The \CONTEXT\ font goodie
416files set the margins for some problematic characters because (of course) these
417are not part of \OPENTYPE\ math fonts. This is an optical issue mostly because the
418engine will not easily put a too wide one on top.
419
420\startlinecorrection
421\startMPcode
422    draw My_Accent_Z (2.5,1.0,2,1) scaled 5mm ;
423    draw My_Accent_Z (2.5,1.5,2,2) scaled 5mm shifted ( 2cm,0) ;
424    draw My_Accent_Z (2.5,2.0,2,3) scaled 5mm shifted ( 4cm,0) ;
425\stopMPcode
426\stoplinecorrection
427
428Watch how the larger accents also have a larger bounding box. That is all right
429but does interfere with a consistent makeup. The solution is simple: we use the
430\CONTEXT\ dimension tweak to reposition accents and cheat with their height and
431depth to make sure that we get consistent rendering. We need to tweak anyway
432because sometimes accents have bad dimensions. The smallest one is actually a
433text accent and therefore can have properties that are inconsistent with its
434wider variants. This is typically a side effect of the fact that math accents and
435text accents are not considered to be different.
436
437\startitemize[packed]
438\startitem
439    Only add anchors to some (forward leaning!) italic shapes.
440\stopitem
441\startitem
442    Make extensibles as much a possible consistent with respect to dimensions.
443\stopitem
444\stopitemize
445
446\stopsubject
447
448\startsubject[title=Kerning]
449
450In a text font there are two mechanisms that influence the spacing between
451individual characters: kerning and italic corrections. In \OPENTYPE\ text fonts
452we have a more generalized relative positioning mechanism which can be seen as
453kerning. The italic correction well known to \TEX\ users can be implemented as a
454positional font feature but very seldom is.
455
456An \OPENTYPE\ math font has both kerning and italic correction. The kerning at
457the left top, left bottom, right top and right bottom of a glyph can be specified
458as a staircase and is used to position scripts. The italic correction is bit more
459curious and is applied is some cases. Keep in mind that in math a sequence of
460alphabetic characters does not make a word but represents a multiplication of
461ordinary symbols and thereby specific inter|-|atom spacing rules apply.
462
463A traditional \TEX\ font has kerns and italic correction and an \OPENTYPE\ font has
464staircase kerns and italic correction. For practical (space and time) reasons the
465widths of italic shapes in traditional math fonts are such that when you add the
466correction they kind of match the bounding box.
467
468So, one way to suit both kind of fonts is to add the italic correction (often
469absent in \OPENTYPE\ glyphs but very present in traditional ones) as well as the
470staircase kerns (present in \OPENTYPE\ fonts and unknown to traditional fonts).
471
472There are however some complications: what if a glyph has both? Which one is to
473be preferred? Should we try our luck? Even worse: in the traditional the italic
474correction is {\em always} added to the box that wraps a glyph but in some cases
475that correction gets removed. \footnote {In \LUAMETATEX\ we never remove but
476compensate so that we can track what happens.} But should we also remove a
477staircase kern? When we started with \LUAMETATEX\ it was a bit of a gamble
478because the specification only showed up later and improved over time. \footnote
479{This is true for much of \OPENTYPE\ which has the danger that bugs and side
480effects become features. Keep that in mind when you criticize solutions that
481early adopters came up with!}
482
483In \LUATEX\ we often have to code paths. That was done after other attempts to
484deal with this weak aspect of fonts worked for one font and not for the other.
485For instance at the time of this writing some fonts have italic corrections for
486upright characters! In \LUAMETATEX\ that model was changed into a detailed
487control model at the font as well as engine level. Later, when Mikael and I went
488over the fonts, usage of characters in math, atoms and spacing, we decided to
489kick out that detailed control and use more general control mechanisms assuming
490that we use \OPENTYPE\ fonts without bad italics. Whenever we had bad ones we
491could correct that in a so called font goodie file. In other words: no heuristics
492in the engine but fixed fonts. For that we always take Cambria as reference.
493
494{\em To be considered: should we finally turn italic correction into top and
495bottom kerns? Basically: model after Cambria? Then we can kick out code! We just
496assume font goodies.}
497
498\startMPdefinitions
499vardef My_Character (expr shape, sx, sy, slant, left, right, side) =
500    image (
501        path p ; p := shape
502            xyscaled (sx, sy)
503            slanted slant
504        ;
505        draw p
506            withcolor darkgray ;
507        draw (outerboundingbox p) leftenlarged side rightenlarged side
508            withpen pencircle scaled 1/20
509            withcolor darkgreen ;
510        draw (outerboundingbox p) leftenlarged left rightenlarged right
511            withpen pencircle scaled 1/20
512            withcolor darkred ;
513    )
514enddef ;
515
516vardef My_Character_K (expr shape, sx, sy, slant, left, right, lt, lb, rt, rb) =
517    image (
518        path p ; p := shape
519            xyscaled (sx, sy)
520            slanted slant
521        ;
522        draw p
523            withcolor darkgray ;
524        draw (outerboundingbox p) leftenlarged left rightenlarged right
525            withpen pencircle scaled 1/20
526            withcolor darkred ;
527        draw (ulcorner outerboundingbox p) shifted (lt,0)
528            withpen pencircle scaled 1/2
529            withcolor darkgreen ;
530        draw (llcorner outerboundingbox p) shifted (lb,0)
531            withpen pencircle scaled 1/2
532            withcolor darkgreen ;
533        draw (urcorner outerboundingbox p) shifted (rt,0)
534            withpen pencircle scaled 1/2
535            withcolor darkgreen ;
536        draw (lrcorner outerboundingbox p) shifted (rb,0)
537            withpen pencircle scaled 1/2
538            withcolor darkgreen ;
539    )
540enddef ;
541\stopMPdefinitions
542
543\startlinecorrection
544\startMPcode
545    draw My_Character (fulldiamond, 2, 4, 0, 1/4, 1/4, 0) scaled 5mm ;
546    draw My_Character (fullcircle,  2, 4, 0, 1/4, 1/4, 0) scaled 5mm shifted (3cm,0) ;
547    draw My_Character (fullsquare,  2, 4, 0, 1/4, 1/4, 0) scaled 5mm shifted (6cm,0) ;
548\stopMPcode
549\stoplinecorrection
550
551Here we have three shapes and as usual they have some space at the left and right.
552A text font like Lucida is designed in such a way that no kerns between glyphs
553are needed but most text fonts have kerns. These compensate for these average
554acceptable side bearings.
555
556\startlinecorrection
557\startMPcode
558    draw My_Character (fulldiamond, 2, 4, 0.3, 1/4, 1/4, 0) scaled 5mm ;
559    draw My_Character (fullcircle,  2, 4, 0.3, 1/4, 1/4, 0) scaled 5mm shifted (3cm,0) ;
560    draw My_Character (fullsquare,  2, 4, 0.3, 1/4, 1/4, 0) scaled 5mm shifted (6cm,0) ;
561\stopMPcode
562\stoplinecorrection
563
564In these slanted versions we get wider shapes but not always. For some shapes the
565amount of perceived spacing at the left top and right bottom increases and this is
566where we start thinking in terms of italic correction:
567
568\startlinecorrection
569\startMPcode
570    draw My_Character (fulldiamond, 2, 4, 0.3,  1/4,  1/4, 0  ) scaled 5mm ;
571    draw My_Character (fullcircle,  2, 4, 0.3,  1/4,  1/4, 0  ) scaled 5mm shifted (3cm,0) ;
572    draw My_Character (fullsquare,  2, 4, 0.3,  1/4, -1/2, 1/4) scaled 5mm shifted (6cm,0) ;
573    draw My_Character (fullsquare,  2, 4, 0.3, -1/2, -1/2, 1/4) scaled 5mm shifted (9cm,0) ;
574\stopMPcode
575\stoplinecorrection
576
577That way, when we put characters next to each other on the average words look
578better. But how about math: a superscript should be outside that bounding box and
579a subscript inside, assuming that we have a shape like this. It is unfortunate
580that the widely used $f$ is the perfect candidate. When using that one as test
581case things can look great but kick in a $g$ and it gets worse. The $v$ and $w$
582are also a fertile playground. It is hard to come up with logic that satisfied
583all which is why glyph specific engine control was implemented (and later
584dropped). In the previous graphic the fourth shape also cheats on the left and
585yes, there are some fonts that do just that, which the of course interferes with
586prescripts.
587
588Now think of using shapes in formulas: some are put in sequence, in which case
589inter atom spacing is added so there is less danger of touching due to too a
590narrow width and \TEX ies somehow accepted that adding thin spaces every now and
591then is fine \footnote {We don't think so which is why we came up with a more
592granular inter atom spacing mode.} But there's more than sequences: shapes end up
593in scripts, as degrees in radicals, above and below fraction rules, as fences and
594accents. Just assume the worst possible scenarios!
595
596In these examples the italic correction at the right is the difference between
597the red and green box. There is no left italic correction and that is why \OPENTYPE\
598math (driven by Cambria) has these four sets of kerns.
599
600\startlinecorrection
601\startMPcode
602    draw My_Character_K (fulldiamond, 2, 4, 0.3, 1/4, 1/4, 1/4, -1/4, 1/2, -1/4) scaled 5mm ;
603    draw My_Character_K (fullcircle,  2, 4, 0.3, 1/4, 1/4, 1/8,  0,   0,   -1/8) scaled 5mm shifted (3cm,0) ;
604    draw My_Character_K (fullsquare,  2, 4, 0.3, 1/4, 1/4, 1/8, -1/2, 1/2, -1/8) scaled 5mm shifted (6cm,0) ;
605\stopMPcode
606\stoplinecorrection
607
608Here we show some possibilities for better anchoring but it will be clear that it
609is a compromise. Staircase kerns as in \OPENTYPE\ therefore have a set of kerns
610going up or down for not only the base character but also the one that ends up in
611a script as that one itself can have a \quote {problematic} shape.
612
613Our solution to this problem is to tweak dimensions and italic correction of
614problematic characters. We also can add four kerns that roughly compensate for
615tricky corrections needed. We therefore have more glyph properties than the
616official \OPENTYPE\ specification provides (cheaper and easier than staircase
617kerns that work on pairs of characters) . But we have more font parameters
618anyway, and with \TEX\ being one of the main math renderers and \TEX ies always
619being to tune and tweak we think this is okay. It is better to have more control
620than to rely on (hard to fight) heuristics.
621
622We're stuck with the fonts we have and (in the case of \TEX\ fonts) the chosen
623traditional approach of dimensions and italic corrections (no staircase kerns) but
624the least we can ask is:
625
626\startitemize[packed]
627    \startitem
628        Be consistent in dimensions and italic corrections. Get rid of limitations
629        imposed by the 8 bit font era: we have plenty slots available and some more
630        glyph properties as well. And if you compromise: make that clear.
631    \stopitem
632    \startitem
633        Don't just take the old properties but assume that \OPENTYPE\ math fonts
634        are used in a modern \OPENTYPE\ \TEX\ engine.
635    \stopitem
636    \startitem
637        Assume that any character is used in any combination: that is what made it
638        hard to satisfy all needs at the engine end. Better play safe.
639    \stopitem
640\stopitemize
641
642\stopsubject
643
644\startsubject[title=Scripts and primes]
645
646We start with showing a few shapes (in \TEX\ speak: nuclei) with a different
647perceived spacing and with some items attached to the corners: scripts.
648
649\startMPdefinitions
650vardef My_Character_P (expr shape, sx, sy, slant, left, right, prime, index) =
651    image (
652        path p ; p := shape
653            xyscaled (sx, sy)
654            slanted slant
655        ;
656        draw p
657            withcolor darkgray ;
658        draw (outerboundingbox p) leftenlarged left rightenlarged right
659            withpen pencircle scaled 1/20
660            withcolor darkred ;
661        draw (fullsquare shifted (ulcorner outerboundingbox p)) shifted (-1,0)
662            withpen pencircle scaled 1/5
663            withcolor darkgreen ;
664        draw (fullsquare shifted (llcorner outerboundingbox p)) shifted (-1,0)
665                withpen pencircle scaled 1/5
666                withcolor darkgreen ;
667        if prime:
668            draw (fullsquare xyscaled(1/2,1) shifted (urcorner outerboundingbox p)) shifted (.75,1/2)
669                withpen pencircle scaled 1/5
670                withcolor darkblue ;
671            draw (fullsquare shifted (urcorner outerboundingbox p)) shifted (1.75,0)
672                withpen pencircle scaled 1/5
673                withcolor darkgreen ;
674        else :
675            draw (fullsquare shifted (urcorner outerboundingbox p)) shifted ( 1,0)
676                withpen pencircle scaled 1/5
677                withcolor darkgreen ;
678        fi
679        if index:
680            draw (fullsquare shifted (lrcorner outerboundingbox p)) shifted (if prime: 3 else : 2 fi,0)
681                withpen pencircle scaled 1/5
682                withcolor darkyellow ;
683        else :
684            draw (fullsquare shifted (lrcorner outerboundingbox p)) shifted ( 1,0)
685                withpen pencircle scaled 1/5
686                withcolor darkgreen ;
687        fi ;
688    )
689enddef ;
690\stopMPdefinitions
691
692\startlinecorrection
693\startMPcode
694    draw My_Character_P (fulldiamond, 2, 4, 0, 1/4, 1/4, false, false) scaled 5mm ;
695    draw My_Character_P (fullcircle,  2, 4, 0, 1/4, 1/4, false, false) scaled 5mm shifted ( 5cm,0) ;
696    draw My_Character_P (fullsquare,  2, 4, 0, 1/4, 1/4, false, false) scaled 5mm shifted (10cm,0) ;
697\stopMPcode
698\stoplinecorrection
699
700The green ones represent the super- and sub-, pre- and postscripts. According to what we
701discussed previously the anchoring depends on the shape
702
703\startlinecorrection
704\startMPcode
705    draw My_Character_P (fulldiamond, 2, 4, .3, 1/4, 1/4, false, false) scaled 5mm ;
706    draw My_Character_P (fullcircle,  2, 4, .3, 1/4, 1/4, false, false) scaled 5mm shifted ( 5cm,0) ;
707    draw My_Character_P (fullsquare,  2, 4, .3, 1/4, 1/4, false, false) scaled 5mm shifted (10cm,0) ;
708\stopMPcode
709\stoplinecorrection
710
711But we will not take that into account here because this time we focus on support
712for primes and indices. A prime normally is a narrow character that is positioned
713after the nuclues and sits in a similar position as a superscript. When it is
714present a subscript doesn't move. Here the blue rectangle represents the prime.
715
716\startlinecorrection
717\startMPcode
718    draw My_Character_P (fulldiamond, 2, 4, 0, 1/4, 1/4, true, false) scaled 5mm ;
719    draw My_Character_P (fullcircle,  2, 4, 0, 1/4, 1/4, true, false) scaled 5mm shifted ( 5cm,0) ;
720    draw My_Character_P (fullsquare,  2, 4, 0, 1/4, 1/4, true, false) scaled 5mm shifted (10cm,0) ;
721\stopMPcode
722\stoplinecorrection
723
724An index, here yellow, is a subscript that applies to the whole so that one does
725move. We cannot have a subscript and an index at the same time. The prescripts
726are not affected by primes and indices other than that the engine has to do more
727work in getting it right.
728
729\startlinecorrection
730\startMPcode
731    draw My_Character_P (fulldiamond, 2, 4, 0, 1/4, 1/4, false, true) scaled 5mm ;
732    draw My_Character_P (fullcircle,  2, 4, 0, 1/4, 1/4, false, true) scaled 5mm shifted ( 5cm,0) ;
733    draw My_Character_P (fullsquare,  2, 4, 0, 1/4, 1/4, false, true) scaled 5mm shifted (10cm,0) ;
734\stopMPcode
735\stoplinecorrection
736
737Of course we can have primes and indices at the same time. A prime actually belongs to the
738nuclues so that combination determines quite a bit of the vertical and horizontal spacing.
739
740\startlinecorrection
741\startMPcode
742    draw My_Character_P (fulldiamond, 2, 4, 0, 1/4, 1/4, true, true) scaled 5mm ;
743    draw My_Character_P (fullcircle,  2, 4, 0, 1/4, 1/4, true, true) scaled 5mm shifted ( 5cm,0) ;
744    draw My_Character_P (fullsquare,  2, 4, 0, 1/4, 1/4, true, true) scaled 5mm shifted (10cm,0) ;
745\stopMPcode
746\stoplinecorrection
747
748The problem with primes is that they were never part of the concept and
749\OPENTYPE\ math inherited that. Thanks to \UNICODE\ (and the math community not
750being convincing enough) we ended up with a prime being equivalent to minutes and
751double primes being minutes. The fact that we have triple and quadruple primes as
752well as reverse primes is a consequence of not having symbols for sub second
753indicators. And even the seconds are overloaded by meaning: time related and
754geographical.
755
756What has this to do with primes? Well, it means that a font has a prime character
757that is already positioned at a certain distance from the baseline. But in most
758math fonts the script and scriptscript sizes aren't. It looks as if the
759assumption is that primes are treated like superscripts. But which one then gets
760superscripted at the text level? The text one or the script one? Unfortunately
761fonts are somewhat inconsistent in the sizing and positioning of primes and the
762math community not being convincing enough. It was a tough decision to make: in
763some fonts using the text prime have nice output and in other fonts the script
764one.
765
766So, because in the traditional approach primes had to be manually positioned, be
767able deal with super and subscripts the old school approach was to make them
768active characters and pick up what follows in order to deal with this situation.
769It probably is the main reason why we have a somewhat special active character
770mechanism in math mode. In \CONTEXT\ \MKIV\ we followed a different approach,
771also because we wanted to deal with collapsing multiple primes to their rightful
772\UNICODE\ slot.
773
774In \LMTX\ and \LUAMETATEX\ we (need to) go a step further because we want proper
775inter|-|atom space as well as more fine tuned positioning. Primes became elements
776bound to a nucleus! We also wanted to solve this issue once and for all (in
777\MKIV\ we has several methods but in \LMTX\ we only have one left). We not only
778added a native prime element to nuclei but also introduced font parameters
779similar to those of superscripts. Just keep in mind that in \LUAMETATEX\ we don't
780need to worry about having a few more fields in a math node. There are not that
781many nodes involved and the amount of extra memory used can be neglected. Of
782course there is plenty of code added to deal with it so the binary definitely is
783larger due to it and the code way more complex. In fact we already introduced
784some missing parameters for the spacing related to prescripts. Furthermore we can
785tune the prime spacing relative to the scripts.
786
787In the goodie files you can add fixes that relate to primes and most of them
788involved quite a bit of experimental. We can safely say that we spent quite some
789prime time on this issue.
790
791\startitemize[packed]
792\startitem
793    It would be nice if fonts at least has prime shapes that are consistent
794    because currently script one can look quite different (tilt and shape).
795\stopitem
796\startitem
797    Because primes are also minutes and seconds we probably have to accept the
798    current situation and deal with it in the goodie files forever.
799\stopitem
800\stopitemize
801
802\stopsubject
803
804% Yet another section, this time I got in the mood after listening to Cindy
805% Blackman Santana’s "Give The Drummer Some" ... here we go:
806
807\startsubject[title=Two choices]
808
809Imagine a situation like this: a sequence of characters with a leading left fence
810but nothing at the right. The fence is not really a fence but something that can
811grow and have its own super and subscripts, either after it or on top and below.
812We leave these scripts (aka limits) out of the discussion.
813
814\startMPdefinitions
815vardef My_Character (expr shape, sx, sy, c) =
816    image (
817        draw
818            shape xyscaled (sx, sy)
819            withcolor c ;
820    )
821enddef ;
822\stopMPdefinitions
823
824\startlinecorrection
825\startMPcode
826    draw My_Character (fulldiamond, 2, 4, darkblue) scaled 5mm ;
827    for i = 1 upto 5 :
828        draw My_Character (fullcircle, 2, 2 randomized 1, darkgray ) scaled 5mm shifted (i * 2cm,0) ;
829    endfor ;
830\stopMPcode
831\stoplinecorrection
832
833There is a visual aspect here, which can be illustrated from a variant:
834
835\startlinecorrection
836\startMPcode
837    draw My_Character (fulldiamond, 2, 4, darkblue)                  scaled 5mm ;
838    for i = 1 upto 3 :
839        draw My_Character (fullcircle, 2, 2 randomized 1, darkgray ) scaled 5mm shifted (i * 2cm,0) ;
840    endfor ;
841    draw My_Character (fulldiamond, 2, 6, darkblue)                  scaled 5mm shifted (9cm,0) ;
842    for i = 1 upto 3 :
843        draw My_Character (fullcircle, 2, 3 randomized 1, darkgray ) scaled 5mm shifted (9cm + i * 2cm,0) ;
844    endfor ;
845\stopMPcode
846\stoplinecorrection
847
848One can argue that the larger characters in the second sequence rightfully trigger a larger
849blue variant. But for consistency one might actually go for:
850
851\startlinecorrection
852\startMPcode
853    draw My_Character (fulldiamond, 2, 6, darkblue)                  scaled 5mm ;
854    for i = 1 upto 3 :
855        draw My_Character (fullcircle, 2, 2 randomized 1, darkgray ) scaled 5mm shifted (i * 2cm,0) ;
856    endfor ;
857    draw My_Character (fulldiamond, 2, 6, darkblue)                  scaled 5mm shifted (9cm,0) ;
858    for i = 1 upto 3 :
859        draw My_Character (fullcircle, 2, 3 randomized 1, darkgray ) scaled 5mm shifted (9cm + i * 2cm,0) ;
860    endfor ;
861\stopMPcode
862\stoplinecorrection
863
864Now imagine that you only have two choices? When do you go for the larger one?
865This situation occurs with so called large operators like integrals and
866summations. The original \TEX\ fonts have two sizes of these characters. The
867smaller one is used in normal (text) math and the larger one in display math.
868
869But what if, as in \OPENTYPE\ fonts there are more? There is a font parameter \typ
870{DisplayOperatorMinHeight} that tells what size to use (as a minimum) in display
871mode. Because the \TEX\ engines never had to make a decision the value of that
872variable in the Latin Modern and Gyre fonts is somewhat arbitrary. It is one of
873the variables that we need to adapt in the goodie files: we roughly bump from
8741300 to 1800 to get what we are accustomed to in display mode.
875
876So what are these large operators anyway? In traditional \TEX\ they are just
877that: larger variants of smaller ones. In \OPENTYPE\ math however, they are
878extensibles. That means that when there are more variants and an extensible
879recipe it can grow on demand. That conflicts with the expectations of two sizes.
880
881In order to support these two conflicting demands \LUAMETATEX\ provides so called
882left operators that either act upon their own, in which case we talk of \quote
883{auto} mode, or they can be told to have a specific size, or they can adapt, in
884which case they have the usual bogus right companion that ends the subformula.
885And, because they are implemented as fences but are not really fences there are
886some provisions for the scripts: they bind to the left fence and not the right
887one.
888
889As side note: when we were experimenting with the usage of these (new) mechanisms
890we again ran into the race condition that is imposed by the algorithm that
891determines the size of fences: the delimiters target height is either a fraction
892of the total height of the sublist or the total height diminished by some
893constant amount. In \LUAMETATEX\ we therefore added the already discussed \typ
894{\UmathDelimiterPercent} and \typ {\UmathDelimiterShortfall} but these only kick
895in when we have a wrapped integral or such.
896
897\startitemize[packed]
898\startitem
899    We can't be too picky but it would be nice if fonts have \typ
900    {DisplayOperatorMinHeight} set to a more reasonable value. We have to tweak
901    most font for this now (and probably forever).
902\stopitem
903\stopitemize
904
905\stopsubject
906
907\startsubject[title=To the point]
908
909A nice feature of math fonts is that they have so called extensible characters. Fences
910can grow vertically and accents horizontally. When we run out of discrete steps in size,
911we end up with a recipe that build large characters from snippets as we discussed before.
912
913The limitations in the size of fonts and the fact that the engine also had to
914impose some limits in the amount of used fonts and complexity of their usage made
915for some exceptions to the rule and, no pun intended, it might be why \TEX\ has a
916concept of rules. Lines over and under something, arrows, fractions and radicals
917all use rules. It is interesting to notice that when \OPENTYPE\ fonts showed up
918the converted \TEX\ fonts didn't make arrows and bars use the extension
919mechanism, thereby forcing the old school construction of them. This doesn't hurt
920\CONTEXT\ much because we can implement proper characters using the virtual
921character mechanism and we did things different anyway (for instance we can kick
922in \METAFUN\ replacements).
923
924Nevertheless there is this curious in|-|between: radical. It comes in a set of
925fixed sized often sloped characters and then switches to an upright one. In all
926cases there is that horizontal rule attached that covers the nucleus. There is no
927mix of horizontal and vertical extensibles so there is no fancy end of rule
928thingie possible (the little hook that we learned to draw at school): it's just a
929stupid rule.
930
931\startlinecorrection
932\startMPcode
933    for i = 1 upto 5 :
934        draw image (
935            draw fullsquare xyscaled(2, 4+i)
936                withcolor darkblue ;
937            fill fullsquare xyscaled(1/2, 1/2+i)
938                shifted (1,2)
939                withcolor darkblue ;
940            draw fullsquare xyscaled(1, 1)
941                shifted (1+i/100,2+i/2+i/100)
942                withcolor darkgray ;
943        ) scaled 5mm shifted (i*2cm, 0) ;
944    endfor ;
945\stopMPcode
946\stoplinecorrection
947
948Instead of a rule, these examples show a simple rectangle attached to another
949one. The idea is that the center of that small one snaps onto the upper right
950corner of the large one. In these examples we show how it looks when that is not
951exact. At small sizes it goes unnoticed but at larger ones it becomes visible.
952Actually, when you start scaling up math you often see artifacts in shapes, which
953makes one wonder if high resolution screens are really used for proofing.
954
955\startlinecorrection
956\startMPcode
957    for i = 1 upto 5 :
958        draw image (
959            draw fullsquare xyscaled(2, 4+i)
960                withcolor darkblue ;
961            draw fullsquare xyscaled(1, 1)
962                shifted (1+i/100,2+i/2+i/100)
963                withcolor darkgray ;
964        ) scaled 5mm shifted (i*2cm, 0) ;
965    endfor ;
966\stopMPcode
967\stoplinecorrection
968
969In the first example the effect is small because we make sure that the right top
970corner is square but in the second one we don't do that. Now it really becomes
971annoying, even if we remove the small errors in positioning.
972
973\startlinecorrection
974\startMPcode
975    for i = 1 upto 5 :
976        draw image (
977            draw fullsquare xyscaled(2, 4+i)
978                withcolor darkblue ;
979            draw fullsquare xyscaled(1, 1)
980                shifted (1,2+i/2)
981                withcolor darkgray ;
982        ) scaled 5mm shifted (i*2cm, 0) ;
983    endfor ;
984\stopMPcode
985\stoplinecorrection
986
987We have seen different effects. The most common was an inaccurate font dimension
988that determines what the height of the rule is. That we can fix in the goodie
989file and we do that. Other artifacts were (in the stepwise sizes) characters that
990were so sloped that there was not possibility for properly attaching the rule (we
991noticed this best when checking the Lucida and Latin Modern fonts): one can cheat
992and move a little to the left but the thickness of the sloped line was not enough
993for that, so it could qualify as a design error but a design cannot simply be
994changed in such case: one has to compromise and assume no scaling (keep in mind
995that we scale on screen while on print one has to take a magnifying glass and
996reading math that way is not much fun).
997
998Some of these extensible radicals have rather thin vertical lines but we can
999assume that their height is never such that this becomes too annoying. One
1000complication in designing these shapes is that when one uses a font creator
1001program it is unlikely to provide a math composer for testing. The same is true
1002for overlapping the end glyphs of e.g.\ curly braces: the middle piece can get
1003into the way when we have the smallest extensible and have that one kick in too
1004soon due to the lack of stepwise sizes. It's hard to check that without an engine
1005applying them to the extreme cases.
1006
1007\startitemize[packed]
1008\startitem
1009    Benefit from your high resolution screen and zoom in on the results. Take no
1010    risk.
1011\stopitem
1012\startitem
1013    Play safe and create an top right corner that has some overlap and already
1014    starts out horizontally.
1015\stopitem
1016\startitem
1017    If the design complicates rule attachments, move to an extensible sooner
1018    because that one can have a horizontal attachment point as part of the
1019    design.
1020\stopitem
1021\stopitemize
1022
1023\startsubject[title=Removing slack]
1024
1025In the process of optimizing the spacing we ran into several cases where a bit of
1026spacing was added that eventually made that the resulting formula had small quite
1027visible whitespace at the edges. Take for instance the little bit of kerning
1028between a nuclues and a superscript.
1029
1030\startlinecorrection
1031\startMPcode
1032    draw image (
1033        draw fullsquare xyscaled(2, 4)
1034            withcolor darkblue ;
1035        draw fullsquare xyscaled(1/2, 1)
1036            shifted (2-1/4,-1.5)
1037            withcolor darkred ;
1038        draw fullsquare xyscaled(1, 1)
1039            shifted (3,2)
1040            withcolor darkgray ;
1041    ) scaled 5mm shifted (2cm, 0) ;
1042\stopMPcode
1043\stoplinecorrection
1044
1045Normally one can predict this situation but when components are glued together
1046that are typeset independently the (in this case red) spacing remains. The engine
1047is capable to remove that kind of slack at the left and right of the formula so
1048that one gets a proper tight bounding box. There is a bit more logic on board now.
1049
1050The fact that all kind of spacing gets added is one of the reasons for the more
1051granular inter atom spacing: that way we could remove for instance the spacing
1052added to the left and right of fractions (which is buried in the constructed
1053box).
1054
1055\startitemize[packed]
1056\startitem
1057    There is not much we can advice here because it doesn't relate to fonts.
1058    However, given that Lucida text fonts have no kerning could make one wonder
1059    to what extend math fonts needs all these compensations.
1060\stopitem
1061\startitem
1062    Some of the inter atom|/|script kerning is probably there as safeguard for
1063    italic shapes where staircase kerns are lacking. The question then is how the
1064    related font parameters themselves relate to staircase kerns. We suppose that
1065    this puts some stress on the font designer.
1066\stopitem
1067\stopitemize
1068
1069\stopsubject
1070
1071\page
1072
1073\startsubject[title=Initializing fonts]
1074
1075\startsubsubject[title=introduction]
1076
1077When a math font is initialized there are (as with any font) features applies.
1078The only official one is the {ssty} feature that defines the substitution sets
1079for script and scripscript size. In traditional \TEX\ one has to set up multiple
1080fonts because one can only have 256 characters and because one might want to map
1081alphabets on the regular \ASCII\ slots. In an \OPENTYPE\ font all these alphabets
1082are on the same font so basically one can do with three instances per size: text,
1083script and scriptscript. What actually is done depends on the philosophy of the
1084macro package but we will not discuss that here. So let's assume three instances
1085in the default case. In \LUAMETATEX\ we can scale on the fly and therefore we can
1086stick to one instance: as long as we know what the slots of the (optionally
1087provided) smaller sizes are. Supporting this had quite some consequences for the
1088engine as scaling happens all over the place (also think of font parameters) and
1089we're talking two independent dimensions here: horizontal and vertical sizing.
1090
1091In addition to this size related font feature \CONTEXT\ provide some additional
1092ones (and always had). Some are set up as regular features and some are driven by
1093the font goodie features which organizes a lot of features under one umbrella.
1094Font goodies always have been part of \MKIV\ and \LMTX.
1095
1096{\em also mention the non tweak related ones}
1097
1098\stopsubsubject
1099
1100\startsubsubject[title=wipeitalics]
1101
1102This tweak wipes the italics from one or more characters, most noticeable upright
1103characters. Because locating the individual characters took too much time, we
1104added the option complete alphabets.
1105
1106\starttyping
1107example
1108\stoptyping
1109
1110\stopsubsubject
1111
1112\startsubsubject[title=wipeanchors]
1113
1114This tweak removes the top anchors from one or more characters, most noticeable
1115upright characters. As with wiping italics, we often wipe complete alphabets.
1116
1117\starttyping
1118example
1119\stoptyping
1120
1121\stopsubsubject
1122
1123\startsubsubject[title=accentdimensions]
1124
1125Configure the position of overbar, underbar, overbrace, underbrace, overparent,
1126underparent, overbracket and underbracket. More? Added 220307.
1127
1128\stopsubsubject
1129
1130\startsubsubject[title=addrules]
1131
1132I think we did not get overbars for some fonts (kpfonts and erewhon come to
1133mind).
1134
1135\stopsubsubject
1136
1137\startsubsubject[title=addscripts]
1138
1139Maybe something done for Ton? (\typ{math-act})
1140
1141\stopsubsubject
1142
1143\startsubsubject[title=checkspacing]
1144
1145I don't know how it works. Seems there is not really any settings. But you once
1146wrote
1147
1148\starttyping
1149$\liminf$ \quad
1150$\limsup$ \quad [\sixperemspace] \quad
1151$x\sixperemspace x$
1152
1153\setbox0\hbox{$x\sixperemspace x$} \showbox0
1154\stoptyping
1155
1156in an email (220118).
1157
1158\stopsubsubject
1159
1160\startsubsubject[title=dimensions]
1161
1162We use this to change anchor points of accents, to raise/lower them, and of
1163course to change bounding boxes and italic correction for many letters/symbols.
1164We use it in bonum to resize the whole lower case fraktur alphabet (and maybe
1165more should be added)
1166
1167\stopsubsubject
1168
1169\startsubsubject[title=fixprimes]
1170
1171Maybe explained elsewhere? But it could belong here.
1172
1173\stopsubsubject
1174
1175\startsubsubject[title=fixradicals]
1176
1177I don't know what it does. Could be: In some fonts the radicals are just
1178positioned wrongly, and this moves them up/down to have something uniform to work
1179with. (\typ{math-act})
1180
1181\stopsubsubject
1182
1183\startsubsubject[title=kerns]
1184
1185A bit like staircase kerning. The \quote{topleft} and \quote{bottomright} come in
1186handy, in particular the last one when it comes to the position of subscripts.
1187
1188\stopsubsubject
1189
1190\startsubsubject[title=margins]
1191
1192We fake the width of some characters. Useful, for example, not to get too
1193large/too small accents when using \tex{widehat} (also to get a uniform size over
1194some alphabets or glyphs that often go togeter).
1195
1196\stopsubsubject
1197
1198\startsubsubject[title=variants]
1199
1200Some fonts (lucida, xits, stixtwo) have calligraphic (chancery) and script
1201(roundhand) alphabets. Of course not the same as default, and of course not the
1202same ss0X.
1203
1204\stopsubsubject
1205
1206\startsubsubject[title=wipecues]
1207
1208Only added to cambria and dejavu. Added 220327. I think it has to do with
1209characters like 2061, 2062 and 2063. From the mails I think it has why does 2061
1210render a shape in some fonts so we need an 'wipe char' tweak (basically making it
1211a zero dimensions symbol)
1212
1213\starttyping
1214\mathspacingmode2
1215\showmakeup[mathglue]
1216$ \sin                 \Uchar"2061  (y) $ \quad
1217$ x                    \Uchar"2062   y  $ \quad
1218$ x                    \Uchar"2063   y  $ \par
1219$ \sin      \mathghost{\Uchar"2061} (y) $ \quad
1220$ x         \mathghost{\Uchar"2062}  y  $ \quad
1221$ x         \mathghost{\Uchar"2063}  y  $ \par
1222\stoptyping
1223
1224\stopsubsubject
1225
1226\startsubsubject[title=bigslots]
1227
1228Fences are chosen automatically to match what they surround. However, in traditional
1229engines a fenced sub formula won't break across lines. In \CONTEXT\ we have sveral st
1230
12311, 3, 5, 7 that could fit here, if we find a font where the linking is not
1232present.
1233
1234\stopsubsubject
1235
1236\startsubsubject[title=parameters]
1237
1238I don't know if all of them are parameters that typically moved from document to
1239font level.
1240
1241\stopsubsubject
1242
1243\stopsubject
1244
1245\stopchapter
1246
1247\stopcomponent
1248