math-tweaks.tex /size: 79 Kb    last modification: 2024-01-16 10:21
1% language=us runpath=texruns:manuals/math macros=mkvi
2
3% \enabletrackers[math.tweaks]
4
5% \mapfontsize[pagella][script]      [.30] % a test
6% \mapfontsize[pagella][scriptscript][.45] % a test
7
8\hyphenation{ere-whon}
9
10\enableexperiments[fonts.compact] % gives different sized outline !
11
12% \definefontfeature[stixtwo:mathextra][kern=yes,script=dflt,language=dflt]
13
14\startluacode
15local list = {
16     { "cambria",    "cambria-math"    },
17     { "modern",     "modern-math"     },
18     { "pagella",    "pagella-math"    },
19     { "termes",     "termes-math"     },
20     { "schola",     "schola-math"     },
21     { "bonum",      "bonum-math"      },
22     { "dejavu",     "dejavu-math"     },
23     { "erewhon",    "erewhon-math"    },
24     { "concrete",   "concrete-math"   },
25     { "kpfonts",    "kpfonts-math"    },
26     { "lucida",     "lucida-math"     },
27     { "stixtwo",    "stixtwo-math"    },
28     { "ebgaramond", "ebgaramond-math" },
29     { "libertinus", "libertinus-math" },
30     { "xcharter",   "xcharter-math"   },
31}
32
33local loaded = { }
34local used   = table.setmetatableindex("table")
35
36local function identify(fontname,filename)
37    local g = fonts.goodies.load(filename)
38    if g then
39        local tweaks = g.mathematics.tweaks
40        if tweaks then
41            local after = tweaks.aftercopying
42            if after then
43                local sequence = { }
44                local usage    = { }
45                local bigslots = false
46                for i=1,#after do
47                    local tweak = after[i].tweak
48                    if tweak then
49                        sequence[#sequence+1] = tweak
50                        usage[tweak] = true
51                        used[tweak][fontname] = true
52                        if tweak == "bigslots" then
53                            bigslots = bigslots
54                        end
55                    end
56                end
57                local t = {
58                    sequence = sequence,
59                    usage    = usage,
60                    goodies  = g.mathematics,
61                    bigslots = bigslots,
62                }
63                loaded[fontname] = t
64            end
65        else
66            print("no tweaks",filename)
67        end
68    else
69        print("no goodie file",filename)
70    end
71end
72
73for i=1,#list do
74    local l = list[i]
75    identify(l[1],l[2])
76    context.usebodyfont { l[1] }
77    context.usebodyfont { l[1] .. "-nt" }
78end
79
80document.usedfonts   = list -- order
81document.usedgoodies = loaded
82document.usedtweaks  = used
83
84function document.gettweakusage(name)
85    local list = table.sortedkeys(document.usedtweaks[name])
86    if #list > 0 then
87        context("This tweak is used in: %, t.",list)
88    else
89        context("This tweak is used \\emphasized{nowhere}.")
90    end
91end
92
93function document.showsomething(name)
94    for i=1,#document.usedfonts do
95        context[name](document.usedfonts[i][1])
96    end
97end
98
99-- inspect(loaded)
100
101\stopluacode
102
103\def\ShowTweakUsage#1{\ctxlua{document.gettweakusage("#1")}}
104\def\ShowSomething #1{\ctxlua{document.showsomething("#1")}}
105
106\setupbodyfont[bonum]
107
108\usemodule[abbreviations-logos]
109
110\setuplayout
111  [height=middle,
112   width=middle,
113   footer=0pt]
114
115\setupwhitespace
116  [big]
117
118\setuphead
119  [chapter]
120  [header=high]
121
122\starttext
123
124% A riddle. Maybe use the path and the path randomizer.
125
126\startMPpage
127    fill Page enlarged 1mm withcolor darkred ;
128
129    picture p ; p := lmt_outline [ text = "\textdollar" ] ;
130    picture q ; q := lmt_outline [ text = "\texteuro" ] ;
131
132    p := (p shifted - center p) randomized .7 ;
133    q := (q shifted - center q) randomized .7 ;
134
135    draw image ( draw p ; draw q ; )
136        xysized (PaperWidth -4cm, PaperHeight -10cm)
137        shifted center Page
138        shifted (0,4cm)
139        withcolor yellow
140        withpen pencircle scaled 5mm ;
141
142    draw textext ("tweaking")
143        xsized (PaperWidth -4cm)
144        shifted center bottomboundary Page
145        shifted (0,5.5cm)
146        withcolor white ;
147
148    draw textext ("math fonts")
149        xsized (PaperWidth -4cm)
150        shifted center bottomboundary Page
151        shifted (0,2.25cm)
152        withcolor white ;
153
154    setbounds currentpicture to Page ;
155\stopMPpage
156
157\starttitle[title=Contents]
158    \startcolumns
159        \placelist[chapter][before=,after=,alternative=a]
160    \stopcolumns
161\stoptitle
162
163\startchapter[title=What is there to tweak]
164
165We have written about our struggle to \OPENTYPE\ render math fonts well before,
166but here we will do it from the perspective of \LUAMETATEX\ and \CONTEXT\ \LMTX\
167combined with the fonts available in 2022. So what is the state of these fonts?
168The answer to this question is that now the landscape has settled we have a
169curious mix of old and new style fonts that has to be dealt with. Our answer to
170this is an updated math engine combined with (in \CONTEXT) tweaking font
171properties that we can (or will not) deal with in the engine: think of adapting
172dimensions, adding missing shapes, variants and extensibles, normalizing anchors
173and kerns. Before we discuss these in details let us look at what fonts we
174have.
175
176In 2022 we can distinguish several groups of math fonts. The first contains only
177one font: Cambria by \MICROSOFT. This is the reference font that more or less
178defines the standard and indicates how an \OPENTYPE\ math font is to be
179constructed. It has been stable for a long time and we don't see any development
180in it. In the meantime the specification has been improved but there is still
181room for interpretation.
182
183The second group consists if Latin Modern, Pagella, Termes, Bonum, Schola and
184Dejavu. These are the outcome of the \TEX Gyre project funded by user groups and
185conducted by the GUST foundation (Jerzy, Jacko and friends). In this project some
186choices were made that are reflected in todays versions. It is a mix between old
187school \TEX\ fonts (that were the starting point) and interpretation of the
188\quote {standard} that at that time to some extend had to be deduced from
189observing Cambria usage in MSWord.
190
191The third group started with the release of the \TYPEONE\ \STIX\ fonts that had
192been announced several times as the reference \UNICODE\ math coverage font. In
193order to check its promises those fonts were quickly converted into a useable
194\XITS\ \OPENTYPE\ math font by Khaled Hosny. It took a while before an official
195\STIX\ (two) showed up. In principle that font can replace \XITS\ now because
196\XITS\ is no longer maintained (but it remain useful as it is a good benchmark
197for \STIX). We also inherit some bidirectional elements of \XITS\ that we can
198inject into other fonts.
199
200A fourth group contains Erewhon, Kepler, XCharter, Concrete and Euler. These are
201existing fonts repackaged and fine-tuned by Daniel Flippo. At the time of writing
202this they are a bit in flux and getting better by the day.
203
204Then there are the commercial fonts. Most noticeable is Lucida by Biggelow and
205Holmes which is font expanded, maintained and distributed by \TUG\ derived from
206the original \TYPEONE\ fonts. When we were upgrading the math engine we were
207happy to be awarded the opportunity to improve the metrics (and some minor)
208details in order to bring down the quite extensive number of runtime tweaks
209needed. As a commercial font it stands out because there is an update policy, so
210we can trust fixes to be available to users. The complete \OPENTYPE\ Lucida font
211family is also dirt cheap compared to fonts with such a broad coverage. Another
212commercial math font is Minion Math by Johannes Küstler but we have limited
213possibilities to tweak that because one needs the font as well as the text
214minions. It doesn't make sense to spend much time on fonts that one can't use in
215(sample) documents and one cannot expect us to invest in fonts we can't use
216anyway, right? So where Lucida is extensively supported for other commercial
217fonts we just apply default tweaks to those fonts which is probably good enough.
218
219Group six contains the left-overs: Garamond and Libertinus. We also expect a Plex
220Math companion. Originally Asana was in this group but eventually we decided that
221it is unusable in practice, so we dropped support for that weird and visually
222inconsistent mix of fonts. We have to see how Computer Modern Book will fit in
223but as we can use Latin Modern with effects instead there is no hurry with that
224one. The mentioned Garamond (that is meant to be combined with EBGaramond) is a
225bit outlier in the sense that it has excessive amounts of variants and some
226shapes that might look okay in text but not so in math, but thereby it makes a
227good test case for tweaks.
228
229There are some other setups that we take into account, like Euler over Pagella and
230Pagella over Euler but these just use the tweaks that apply to either of them.
231
232\stopchapter
233
234\startchapter[title=Math fonts in \CONTEXT]
235
236In \MKII\ math fonts are set up in the traditional way and because all available
237fonts \TYPEONE\ are modelled after Computer Modern quite some definitions were
238needed to populate the math families: the basic foursome: roman, italic, symbol,
239extensible, as well as additional families that deal with additional alphabets.
240
241In \MKIV\ it became simpler: we went \UNICODE. Traditional fonts can be assembled
242into a virtual \UNICODE\ font at runtime. Loading now came down to just one font,
243or two when bold math is required. Because \XITS\ introduced right-to-left math
244we actually can kick in a a few more instances but it doesn't change the
245principles.
246
247In \LMTX\ we integrated bidirectional math in such a way that we now only need
248one instance and the new \LUAMETATEX\ engine also provides an alternative to the
249triple family model where text, script and scriptscript share the same font
250instance which further limits loading time, which in turn means that we can waste
251some runtime on tweaking.
252
253So indeed in \MKIV\ and \LMTX\ we can tweak fonts runtime: we patch them before
254passing them to the engine. What was still experimental in \MKIV\ has matured in
255\LMTX, also because now considerable time was spent on trying out and configuring
256tweaks. This made sense because by now we can consider the math fonts to be sort
257of frozen: we have to accept that and have to rely on these patches. That we
258divert a bit from the \quote {official} \OPENTYPE\ math approach doesn't bother
259us much because after all, \TEX\ is still sort of setting the quality standard.
260
261We start with showing some usage tables. When defining a typeface one or more
262goodie files can be specified. This is what we set up by default:
263
264\startluacode
265
266context.starttabulate { "|l|l|" }
267    context.NC() context("bodyfont")
268    context.NC() context("goodie file")
269    context.NC() context.NR()
270    for i=1,#document.usedfonts do
271        local name   = document.usedfonts[i][1]
272        local goodie = document.usedfonts[i][2]
273        context.NC() context(name)
274        context.NC() context(goodie)
275        context.NC() context.NR()
276    end
277context.stoptabulate()
278\stopluacode
279
280Tweaks are applied in a specific order and sometimes a tweak is applied several
281times with different character lists and|/|or directives:
282
283\startluacode
284context.starttabulate { "|l|lp|" }
285    context.NC() context("bodyfont")
286    context.NC() context("tweak order")
287    context.NC() context.NR()
288    for i=1,#document.usedfonts do
289        local name   = document.usedfonts[i][1]
290        local goodie = document.usedfonts[i][2]
291        local sequence = document.usedgoodies[name].sequence
292        context.NC() context(name)
293        context.NC() context("% t",sequence)
294        context.NC() context.NR()
295    end
296context.stoptabulate()
297\stopluacode
298
299Keep in mind that some of these steps are driven by optional features or specific
300versions of the font, so there are likely less applied than seen here. We can
301condense this list to usage only:
302
303\startluacode
304context.starttabulate { "|l|lp|" }
305    context.NC() context("bodyfont")
306    context.NC() context("tweak usage")
307    context.NC() context.NR()
308    for i=1,#document.usedfonts do
309        local name   = document.usedfonts[i][1]
310        local goodie = document.usedfonts[i][2]
311        local usage  = table.sortedkeys(document.usedgoodies[name].usage)
312        context.NC() context(name)
313        context.NC() context("% t",usage)
314        context.NC() context.NR()
315    end
316context.stoptabulate()
317\stopluacode
318
319Finally we show what tweaks are actually applied. We have some more but these are
320either experimental, diagnostic or in the meantime sort of obsolete.
321
322\startluacode
323context.starttabulate { "|l|lp|" }
324    context.NC() context("tweak")
325    context.NC() context("usage")
326    context.NC() context.NR()
327    for tweak, detail in table.sortedhash(document.usedtweaks) do
328        context.NC() context(tweak)
329        context.NC() context("% t",table.sortedkeys(detail))
330        context.NC() context.NR()
331    end
332context.stoptabulate()
333-- inspect(table.sortedkeys(mathematics.tweaks))
334\stopluacode
335
336In the next chapters we will discuss the possible tweaks where roughly group them. Tweaks
337that are no longer used will be left out (even if they are still in \LMTX). One reason
338for orphaning tweaks is that we (finally) decided to get rid of all italics.
339
340(This is work in progress: we don't want to waste time on tweaks that became unused.)
341
342\stopchapter
343
344\startchapter[title=Math constants]
345
346A math goodie file looks like this"
347
348\starttyping
349return {
350    name        = "pagella-math",
351    version     = "1.00",
352    comment     = "Goodies that complement pagella.",
353    author      = "Hans Hagen & Mikael Sundqvist",
354    copyright   = "ConTeXt development team",
355    mathematics = {
356        parameters = {
357            AccentTopShiftUp          =   10,
358            FlattenedAccentTopShiftUp =   10,
359            AccentBaseDepth           =   80,
360            DelimiterPercent          =   90,
361            DelimiterShortfall        =  400,
362            DisplayOperatorMinHeight  = 1800, -- 1500 in font
363            PrimeRaisePercent         =   75, --   50 default
364            PrimeRaiseComposedPercent =   10, --   25 default
365        },
366        tweaks = {
367            -- Here we have a list of tweaks. Just have a look at the file!
368        },
369    }
370}
371\stoptyping
372
373In following chapters we discuss the  entries in the tweaks subtable, here we spend some
374words on the parameters. In \OPENTYPE\ speak these are called constants, which is also the
375term we use when passing a font from \LUA\ to the engine.
376
377\definedescription[MathFP][alternative=serried,width=fit,headstyle=\bf\tt,align={flushleft}]
378
379These are the mandate font parameters with their description straight from the specification:
380
381\startMathFP {ScriptPercentScaleDown}                    Percentage of scaling down for level 1 superscripts and subscripts. Suggested value: 80 pct. \stopMathFP
382\startMathFP {ScriptScriptPercentScaleDown}              Percentage of scaling down for level 2 (scriptscript) superscripts and subscripts. Suggested value: 60 pct. \stopMathFP
383\startMathFP {DelimitedSubFormulaMinHeight}              Minimum height required for a delimited expression (contained within parentheses, etc.) to be treated as a sub-formula. Suggested value: normal line height times 1.5. \stopMathFP
384\startMathFP {DisplayOperatorMinHeight}                  Minimum height of n-ary operators (such as integral and summation) for formulas in display mode (that is, appearing as standalone page elements, not embedded inline within text). \stopMathFP
385\startMathFP {MathLeading}                               White space to be left between math formulas to ensure proper line spacing. For example, for applications that treat line gap as a part of line ascender, formulas with ink going above (\typ {os2.sTypoAscender} + \typ {os2.sTypoLineGap} - \typ {MathLeading}) or with ink going below \typ {os2.sTypoDescender} will result in increasing line height. \stopMathFP
386\startMathFP {AxisHeight}                                Axis height of the font. In math typesetting, the term axis refers to a horizontal reference line used for positioning elements in a formula. The math axis is similar to but distinct from the baseline for regular text layout. For example, in a simple equation, a minus symbol or fraction rule would be on the axis, but a string for a variable name would be set on a baseline that is offset from the axis. The axisHeight value determines the amount of that offset. \stopMathFP
387\startMathFP {AccentBaseHeight}                          Maximum (ink) height of accent base that does not require raising the accents. Suggested: x‑height of the font (\typ {os2.sxHeight}) plus any possible overshots. \stopMathFP
388\startMathFP {FlattenedAccentBaseHeight}                 Maximum (ink) height of accent base that does not require flattening the accents. Suggested: cap height of the font (\typ {os2.sCapHeight}). \stopMathFP
389\startMathFP {SubscriptShiftDown}                        The standard shift down applied to subscript elements. Positive for moving in the downward direction. Suggested: \typ {os2.ySubscriptYOffset}. \stopMathFP
390\startMathFP {SubscriptTopMax}                           Maximum allowed height of the (ink) top of subscripts that does not require moving subscripts further down. Suggested: 4/5 \typ {xheigh}t. \stopMathFP
391\startMathFP {SubscriptBaselineDropMin}                  Minimum allowed drop of the baseline of subscripts relative to the (ink) bottom of the base. Checked for bases that are treated as a box or extended shape. Positive for subscript baseline dropped below the base bottom. \stopMathFP
392\startMathFP {SuperscriptShiftUp}                        Standard shift up applied to superscript elements. Suggested: \typ {os2.ySuperscriptYOffset}. \stopMathFP
393\startMathFP {SuperscriptShiftUpCramped}                 Standard shift of superscripts relative to the base, in cramped style. \stopMathFP
394\startMathFP {SuperscriptBottomMin}                      Minimum allowed height of the (ink) bottom of superscripts that does not require moving subscripts further up. Suggested: 1/4 times \typ {xheight}. \stopMathFP
395\startMathFP {SuperscriptBaselineDropMax}                Maximum allowed drop of the baseline of superscripts relative to the (ink) top of the base. Checked for bases that are treated as a box or extended shape. Positive for superscript baseline below the base top. \stopMathFP
396\startMathFP {SubSuperscriptGapMin}                      Minimum gap between the superscript and subscript ink. Suggested: 4 times default rule thickness. \stopMathFP
397\startMathFP {SuperscriptBottomMaxWithSubscript}         The maximum level to which the (ink) bottom of superscript can be pushed to increase the gap between superscript and subscript, before subscript starts being moved down. Suggested: 4/5 times \typ {xheigh}t. \stopMathFP
398\startMathFP {SpaceAfterScript}                          Extra white space to be added after each subscript and superscript. Suggested: 0.5 pt for a 12 pt font. (Note that, in some math layout implementations, a constant value, such as 0.5 pt, may be used for all text sizes. Some implementations may use a constant ratio of text size, such as 1/24 of \typ {emwidth}.) \stopMathFP
399\startMathFP {UpperLimitGapMin}                          Minimum gap between the (ink) bottom of the upper limit, and the (ink) top of the base operator. \stopMathFP
400\startMathFP {UpperLimitBaselineRiseMin}                 Minimum distance between baseline of upper limit and (ink) top of the base operator. \stopMathFP
401\startMathFP {LowerLimitGapMin}                          Minimum gap between (ink) top of the lower limit, and (ink) bottom of the base operator. \stopMathFP
402\startMathFP {LowerLimitBaselineDropMin}                 Minimum distance between baseline of the lower limit and (ink) bottom of the base operator. \stopMathFP
403\startMathFP {StackTopShiftUp}                           Standard shift up applied to the top element of a stack. \stopMathFP
404\startMathFP {StackTopDisplayStyleShiftUp}               Standard shift up applied to the top element of a stack in display style. \stopMathFP
405\startMathFP {StackBottomShiftDown}                      Standard shift down applied to the bottom element of a stack. Positive for moving in the downward direction. \stopMathFP
406\startMathFP {StackBottomDisplayStyleShiftDown}          Standard shift down applied to the bottom element of a stack in display style. Positive for moving in the downward direction. \stopMathFP
407\startMathFP {StackGapMin}                               Minimum gap between (ink) bottom of the top element of a stack, and the (ink) top of the bottom element. Suggested: 3 times default rule thickness. \stopMathFP
408\startMathFP {StackDisplayStyleGapMin}                   Minimum gap between (ink) bottom of the top element of a stack, and the (ink) top of the bottom element in display style. Suggested: 7 times default rule thickness. \stopMathFP
409\startMathFP {StretchStackTopShiftUp}                    Standard shift up applied to the top element of the stretch stack. \stopMathFP
410\startMathFP {StretchStackBottomShiftDown}               Standard shift down applied to the bottom element of the stretch stack. Positive for moving in the downward direction. \stopMathFP
411\startMathFP {StretchStackGapAboveMin}                   Minimum gap between the ink of the stretched element, and the (ink) bottom of the element above. Suggested: same value as \typ {UpperLimitGapMin}. \stopMathFP
412\startMathFP {StretchStackGapBelowMin}                   Minimum gap between the ink of the stretched element, and the (ink) top of the element below. Suggested: same value as \typ {LowerLimitGapMin}. \stopMathFP
413\startMathFP {FractionNumeratorShiftUp}                  Standard shift up applied to the numerator. \stopMathFP
414\startMathFP {FractionNumeratorDisplayStyleShiftUp}      Standard shift up applied to the numerator in display style. Suggested: same value as \typ {StackTopDisplayStyleShiftUp}. \stopMathFP
415\startMathFP {FractionDenominatorShiftDown}              Standard shift down applied to the denominator. Positive for moving in the downward direction. \stopMathFP
416\startMathFP {FractionDenominatorDisplayStyleShiftDown}  Standard shift down applied to the denominator in display style. Positive for moving in the downward direction. Suggested: same value as \typ {StackBottomDisplayStyleShiftDown}. \stopMathFP
417\startMathFP {FractionNumeratorGapMin}                   Minimum tolerated gap between the (ink) bottom of the numerator and the ink of the fraction bar. Suggested: default rule thickness. \stopMathFP
418\startMathFP {FractionNumDisplayStyleGapMin}             Minimum tolerated gap between the (ink) bottom of the numerator and the ink of the fraction bar in display style. Suggested: 3 times default rule thickness. \stopMathFP
419\startMathFP {FractionRuleThickness}                     Thickness of the fraction bar. Suggested: default rule thickness. \stopMathFP
420\startMathFP {FractionDenominatorGapMin}                 Minimum tolerated gap between the (ink) top of the denominator and the ink of the fraction bar. Suggested: default rule thickness. \stopMathFP
421\startMathFP {FractionDenomDisplayStyleGapMin}           Minimum tolerated gap between the (ink) top of the denominator and the ink of the fraction bar in display style. Suggested: 3 times default rule thickness. \stopMathFP
422\startMathFP {SkewedFractionHorizontalGap}               Horizontal distance between the top and bottom elements of a skewed fraction. \stopMathFP
423\startMathFP {SkewedFractionVerticalGap}                 Vertical distance between the ink of the top and bottom elements of a skewed fraction. \stopMathFP
424\startMathFP {OverbarVerticalGap}                        Distance between the overbar and the (ink) top of he base. Suggested: 3 times default rule thickness. \stopMathFP
425\startMathFP {OverbarRuleThickness}                      Thickness of overbar. Suggested: default rule thickness. \stopMathFP
426\startMathFP {OverbarExtraAscender}                      Extra white space reserved above the overbar. Suggested: default rule thickness. \stopMathFP
427\startMathFP {UnderbarVerticalGap}                       Distance between underbar and (ink) bottom of the base. Suggested: 3 times default rule thickness. \stopMathFP
428\startMathFP {UnderbarRuleThickness}                     Thickness of underbar. Suggested: default rule thickness. \stopMathFP
429\startMathFP {UnderbarExtraDescender}                    Extra white space reserved below the underbar. Always positive. Suggested: default rule thickness. \stopMathFP
430\startMathFP {RadicalVerticalGap}                        Space between the (ink) top of the expression and the bar over it. Suggested: 5/4 times default rule thickness. \stopMathFP
431\startMathFP {RadicalDisplayStyleVerticalGap}            Space between the (ink) top of the expression and the bar over it. Suggested: default rule thickness + 1/2 timss \typ {xheight}. \stopMathFP
432\startMathFP {RadicalRuleThickness}                      Thickness of the radical rule. This is the thickness of the rule in designed or constructed radical signs. Suggested: default rule thickness. \stopMathFP
433\startMathFP {RadicalExtraAscender}                      Extra white space reserved above the radical. Suggested: same value as \typ {RadicalRuleThickness}. \stopMathFP
434\startMathFP {RadicalKernBeforeDegree}                   Extra horizontal kern before the degree of a radical, if such is present. Suggested: 5/18 of \typ {emwidth}. \stopMathFP
435\startMathFP {RadicalKernAfterDegree}                    Negative kern after the degree of a radical, if such is present. Suggested: 10/18 of \typ {emwidth}. \stopMathFP
436\startMathFP {RadicalDegreeBottomRaisePercent}           Height of the bottom of the radical degree, if such is present, in proportion to the ascender of the radical sign. Suggested: 60 pct. \stopMathFP
437
438All these parameters can be set in the goodie file and will then overload the
439ones that are set already in the font. During \LUATEX\ and \LUAMETATEX\ development some
440additional parameters have been added:
441
442\startMathFP {MinConnectorOverlap}               to be described \stopMathFP
443\startMathFP {SubscriptShiftDownWithSuperscript} to be described \stopMathFP
444\startMathFP {FractionDelimiterSize}             to be described \stopMathFP
445\startMathFP {FractionDelimiterDisplayStyleSize} to be described \stopMathFP
446\startMathFP {NoLimitSubFactor}                  to be described \stopMathFP
447\startMathFP {NoLimitSupFactor}                  to be described \stopMathFP
448\startMathFP {AccentBaseDepth}                   to be described \stopMathFP
449\startMathFP {FlattenedAccentBaseDepth}          to be described \stopMathFP
450\startMathFP {SpaceBeforeScript}                 to be described \stopMathFP
451\startMathFP {PrimeRaisePercent}                 to be described \stopMathFP
452\startMathFP {PrimeShiftUp}                      to be described \stopMathFP
453\startMathFP {PrimeShiftUpCramped}               to be described \stopMathFP
454\startMathFP {PrimeSpaceAfter}                   to be described \stopMathFP
455\startMathFP {PrimeBaselineDropMax}              to be described \stopMathFP
456\startMathFP {PrimeWidthPercent}                 to be described \stopMathFP
457\startMathFP {SkewedDelimiterTolerance}          to be described \stopMathFP
458\startMathFP {AccentTopShiftUp}                  to be described \stopMathFP
459\startMathFP {AccentBottomShiftDown}             to be described \stopMathFP
460\startMathFP {AccentTopOvershoot}                to be described \stopMathFP
461\startMathFP {AccentBottomOvershoot}             to be described \stopMathFP
462\startMathFP {AccentSuperscriptDrop}             to be described \stopMathFP
463\startMathFP {AccentSuperscriptPercent}          to be described \stopMathFP
464\startMathFP {FlattenedAccentTopShiftUp}         to be described \stopMathFP
465\startMathFP {FlattenedAccentBottomShiftDown}    to be described \stopMathFP
466\startMathFP {DelimiterPercent}                  to be described \stopMathFP
467\startMathFP {DelimiterShortfall}                to be described \stopMathFP
468
469Whenever we thought that we should have some control we added a variable to play
470with. There are more variables that control the engine and some are set in
471\CONTEXT. Often a parameter can be set per style. We don't set them all.
472
473\stopchapter
474
475\startchapter[title=Font sizes]
476
477For quite a while \CONTEXT\ \MKIV\ and \LMTX\ have been set up to use the script
478and scriptscript scales from the \OPENTYPE\ fonts. However, the method used
479didn't always work as expected with the configured sizes in bodyfont environments
480that were based on initial usage of Computer Modern. That in itself is no big
481problem but as we defined the smaller sizes of for instance five point to be that
482value too, a conflict of namespace surfaced. It's a side effect of race
483condition: we want fast loading for which we need a namespace (at every size) but
484when the size in the \OPENTYPE\ file is non standard (read: the 10pt, 7pt, 5pt
485ratio) we get the wrong scales from the hash. We need to know the scale before we
486initialize the font. But as we don't want to consult the font data each time we
487check a scale we have now moved the ratios to the typescripts. This also makes it
488possible to overload them easier.
489
490The following table shows the values as configured and you will notice that there
491are differences. By moving them into the typescript we can also assure that
492updates to the font have no side effects. As with most math parameters in the
493font, these are not then well defined|/|explored anyway.
494
495\def\MappedScriptSize      {\cldcontext{fonts.hashes.mathparameters[\the\fontid\scriptscriptfont0].ScriptPercentScaleDown}}
496\def\MappedScriptScriptSize{\cldcontext{fonts.hashes.mathparameters[\the\fontid\scriptscriptfont0].ScriptScriptPercentScaleDown}}
497
498\starttexdefinition ShowMappedFontSize #1
499    \NC #1
500    \NC \mappedfontsize{#1}{script}
501    \NC \mappedfontsize{#1}{scriptscript}
502    \NC \bgroup\switchtobodyfont[#1]\normalexpanded{\egroup\MappedScriptSize}
503    \NC \bgroup\switchtobodyfont[#1]\normalexpanded{\egroup\MappedScriptScriptSize}
504    \NC \NR
505\stoptexdefinition
506
507\starttabulate[|l|c|c|c|c|]
508    \FL
509    \NC
510    \NS[1][c] user or typescript
511    \NS[1][c] font parameter
512    \NC \NR
513    \NC bodyfont
514    \NC script
515    \NC scriptscript
516    \NC script
517    \NC scriptscript
518    \NC \NR
519    \ML
520    \ShowSomething{ShowMappedFontSize}
521    \LL
522\stoptabulate
523
524A user can do the following:
525
526\starttyping
527\mapfontsize[pagella][script]      [.75]
528\mapfontsize[pagella][scriptscript][.65]
529\stoptyping
530
531before defining a typeface. In that case the definition in the typescript is
532ignored.
533
534Below we show the script and scriptscript shapes as available in the font. We
535just show overlayed shaped, so this is not a formula with proper spacing.
536
537\definecolor[tred]  [r=1,t=.5,a=1]
538\definecolor[tgreen][g=1,t=.5,a=1]
539\definecolor[tblue] [b=1,t=.5,a=1]
540
541\starttexdefinition ShowSizes #1
542    \startoverlay
543        {\tred  \definedfont[MathRoman*math]#1}
544        {\tgreen\definedfont[MathRoman*math-script]#1}
545        {\tblue \definedfont[MathRoman*math-scriptscript]#1}
546    \stopoverlay
547\stoptexdefinition
548
549\starttexdefinition ShowMathSizes #1
550    \NC #1 \NC \scale [s=4] {\inframed[frame=off]
551        {\switchtobodyfont[#1]\showglyphs%
552         \dontleavehmode \strut
553         \ShowSizes{2}\ShowSizes{+}
554         \ShowSizes{𝐴}\ShowSizes{=}
555         \ShowSizes{𝑔}\ShowSizes{}
556         \ShowSizes{𝜋}\ShowSizes{)}}}
557    \NR \NR
558\stoptexdefinition
559
560\starttabulate[|l|l|]
561    \ShowSomething{ShowMathSizes}
562\stoptabulate
563
564\stopchapter
565
566\startchapter[title=Data structure]
567
568A traditional \TEX\ engine only needs metrics, that is: the shape is not
569relevant. The only measure that somewhat reflect the shape is the italic
570correction but it actually is not so much a correction and more the anchor of the
571subscript. This is also true for an engine that can deal with \OPENTYPE\ math.
572However, there the shape is reflected in the staircase kern tables that define
573the kerning at the corners.
574
575In \LUAMETATEX\ each character has the following numeric properties (there cna be
576more at the \LUA\ end: width, height, depth, italic, expansion, leftprotrusion
577and rightprotrusion. An \OPENTYPE\ font only provides the width and boundingbox
578so the later defines the height and depth. We have an status field that tells
579what we're dealing with and some special treatments is needed and a pointer
580(index) to a follow up glyph (the next in size in math.) There are an optional
581kerning table and ligature table (pointers to allocated arrays) as well as an
582optional pointer to a math specific table. At the \LUA\ end we have more fields
583and some play a role in tweaks. For instance, we can redefine dimensions and
584shift the shape around. These are \CONTEXT\ specific.
585
586The optional math (sub)table of a character has many fields. Here we only mention
587them because some will be referred to in later chapters: smaller, mirror, {\em
588flat accent}, top anchor, bottom anchor, {\em four optional corner math kerns
589arrays (with their size)}, {\em optional horizontal and vertical extensible
590recipes}, four simple corner kerns, four edge margins, a top and bottom accent
591overshoot, {\em italics for vertical and horizontal extensibles}, and an inner
592location, x offset and y offset for e.g. degree anchoring. The cursive fields
593come from \OPENTYPE\ MATH.
594
595This means that a math character has more data in the engine and therefore uses
596more memory. However, there are only a few math fonts loaded and not all
597characters need the math information. One reason for splitting the data in
598\LUAMETATEX\ is that we could save a lot of memory when huge e.g. \CJK\ fonts are
599used: there we want to occupy as little memory as possible.
600
601When reading the next chapters keep in mind that quite a bit fo the
602implementation of tweaks is \CONTEXT\ specific. The engine should be able to do a
603proper job without tweaks in which case one just has to live with the limitations
604of and artifacts in fonts.
605
606When making a manual like this a complication is that one has to load many math
607fonts and also find a way to show both the tweaked and non-tweaked version. We
608only demonstrate the core set of tweaked files so here is an example:
609
610\starttexdefinition TweakTest #1
611    \NC #1
612    \NC \switchtobodyfont[#1]    $\showglyphs\showfontitalics f^2_2 + x + 1$
613    \NC \switchtobodyfont[#1-nt] $\showglyphs\showfontitalics f^2_2 + x + 1$
614    \NC \switchtobodyfont[#1]    $\showglyphs\showfontitalics\showmakeup[mathglue] f^2_2 + x + 1$
615    \NC \switchtobodyfont[#1-nt] $\showglyphs\showfontitalics\showmakeup[mathglue] f^2_2 + x + 1$
616    \NC \NR
617\stoptexdefinition
618
619\starttabulate[|l|c|c|c|c|]
620    \NC \NC tweaked \NC original \NC tweaked \NC original \NC \NR
621    \ctxlua {
622        for i=1,#document.usedfonts do
623            if i > 1 then
624                context.TB()
625            end
626            context.TweakTest(document.usedfonts[i][1])
627        end
628    }
629\stoptabulate
630
631You will notice that in the tweaked version we have no kerns that compensate for the
632width. We will come to that later because these examples are more meant as calibrating
633the loading.
634
635\stopchapter
636
637\startchapter[title=Script parameters]
638
639Here we show the parameters that deal with script placement. This chapter was
640added after we found that some values in Latin Modern were off. The tables show a
641factor that relates the value to the x-height which is for some part of the
642recommendation.
643
644\starttabulate[|c|l|c|l|]
645\NC       \NC SubscriptBaselineDropMin          \NC .10 \NC harmless, seldom triggered \NC \NR
646\NC \star \NC SubscriptShiftDown                \NC .40 \NC by inspection in several files \NC \NR
647\NC \star \NC SubscriptShiftDownWithSuperscript \NC .40 \NC as above \NC \NR
648\NC       \NC SubscriptTopMax                   \NC .80 \NC Microsoft recommendation \NC \NR
649\NC       \NC SuperscriptBaselineDropMax        \NC .10 \NC see Subscript..Min variant \NC \NR
650\NC       \NC SuperscriptBottomMaxWithSubscript \NC .80 \NC Microsoft recommendation \NC \NR
651\NC       \NC SuperscriptBottomMin              \NC .25 \NC Microsoft recommendation \NC \NR
652\NC \star \NC SuperscriptShiftUp                \NC .65 \NC by inspection, a gamble \NC \NR
653\NC \star \NC SuperscriptShiftUpCramped         \NC .65 \NC see above, non-\TEX \NC \NR
654\stoptabulate
655
656In the end only the ones marked with a star are really important. The other ones
657are often small and the drop ones between .5 and 1.5 points with (to us) no clear
658logic. We decided to not enable a tweak but explicitly check and set the (four)
659values in the goodie file.
660
661\starttexdefinition ShowScriptsValue #1#2#3
662    \NC \csstring#2
663    \NC \bgroup \switchtobodyfont[#1-nt]\normalexpanded{\egroup\fam0 \cldcontext{"\letterpercent0.3f",\number#2\textstyle/\number\exheight}}
664    \NC \bgroup \switchtobodyfont[#1-nt]\normalexpanded{\egroup\fam0 \the#2\textstyle}
665    \NC \bgroup \switchtobodyfont   [#1]\normalexpanded{\egroup\fam0 \the#2\textstyle}
666    \NC \NR
667\stoptexdefinition
668
669\starttexdefinition ShowScripts #1
670    \testpage[4]
671    \starttabulate[|l|r|r|r|]
672        \FL
673        \NC \bf #1
674        \NC factor
675        \NC original
676        \NC tweaked
677        \NC \NR
678        \ML
679      % \ShowScriptsValue{#1}{\Umathaxis}           {MathAxis}
680        \ShowScriptsValue{#1}{\Umathsubshiftdown}   {SubscriptShiftDown}
681        \ShowScriptsValue{#1}{\Umathsubshiftdrop}   {SubscriptBaselineDropMin}
682        \ShowScriptsValue{#1}{\Umathsubsupshiftdown}{SubscriptShiftDownWithSuperscript}
683      % \ShowScriptsValue{#1}{\Umathsubsupvgap}     {}
684        \ShowScriptsValue{#1}{\Umathsubtopmax}      {SubscriptTopMax}
685        \ShowScriptsValue{#1}{\Umathsupbottommin}   {SuperscriptBottomMin}
686        \ShowScriptsValue{#1}{\Umathsupshiftdrop}   {SuperscriptBaselineDropMax}
687        \ShowScriptsValue{#1}{\Umathsupshiftup}     {SuperscriptShiftUp}
688        \ShowScriptsValue{#1}{\Umathsupsubbottommax}{SuperscriptBaselineDropMax}
689        \LL
690    \stoptabulate
691\stoptexdefinition
692
693\ShowSomething{ShowScripts}
694
695One of the pitfalls is that in \CONTEXT\ we actually set \type
696{\Umathsubsupshiftdown} which the results in a bad parameter being used. This
697also makes that we do need to fix the font. footnote {Other macro packages are
698less likely to suffer from this as long as they don't set that parameter.} These
699are issues that we easily spent days on checking, double checking and exploring
700variants before settling on some approach. In this case we compared traditional
701\PDFTEX\ output using Computer Modern with \OPENTYPE\ rendering using Latin
702Modern which exposed the issue.
703
704\stopchapter
705
706\startchapter[title=primes]
707
708A few words on primes, a pain in the butt symbol. In traditional \TEX\ (fonts) a
709prime is a special symbol. Macro packages are set up in such a way that single
710quotes become primes. In practice that then boils down to putting the symbol in
711the superscript which means that at the \TEX\ level the smaller size is used.
712
713This smaller size is somehow reflected in the \OPENTYPE\ math fonts: the script
714and scriptscript sized (ssty variant 1 and 2) are basically meant to be
715superscripted. The text size however often looks differently and is positioned
716like an accent. Supposedly it is meant to be used without placement, as minute or
717second indicator. This is one of the cases where a text, script and scriptscript
718variant of the same glyphs looks pretty incompatible.
719
720Combined with up to four primes being combined as well as up to three reverse
721primes being provided this a rather messy implementation. In \CONTEXT\ we always
722tweaked the dimensions to consistently suit our purpose.
723
724When we experimented with primes as operator, implemented like we do with fourier
725using right delimited radicals, we realized that hooking this into the text level
726symbol gave inconsistent results so in the end we simplified the \type
727{fixprimes} tweak in a way that suits both usage patterns: we just use the \type
728{ssty}~1 variant (of course scaled to the right relative size) for all three
729sizes: there is no need to be more granular and it safes us some trouble. We
730thereby also sacrifice some detailed tweaking but also got rid of potential
731visual incompatibilities as for instance in \STIX.
732
733\stopchapter
734
735\startchapter[title=Tweak: dimensions] \ShowTweakUsage{dimensions}
736
737Usage of this tweak can best be observed (and experimented) in the goodie files
738because there are many parameters. Most are fractions, for instance of the width.
739It is important to realize than when you mess with the \type {width} and \type
740{xoffset}, you need to set the \type {advance} to (most likely) the old width
741when it hasn't yet be set. This tells the backend what the natural glyph
742progression is.
743
744\stopchapter
745
746\startchapter[title=Tweak: topanchors]   \ShowTweakUsage{topanchors}
747
748\startbuffer
749\im{\hat{f}+\widehat{f}}
750\stopbuffer
751
752\starttabulate[|l|c|c|]
753    \NC \NC tweaked \NC original \NC \NR
754    \NC ebgaramond
755    \NC \switchtobodyfont[ebgaramond]    \getbuffer
756    \NC \switchtobodyfont[ebgaramond-nt] \getbuffer \NR
757\stoptabulate
758
759\stopchapter
760
761\startchapter[title=Tweak: moveitalics]  \ShowTweakUsage{moveitalics}
762
763By now we have written plenty about italic correction in math fonts. To summarize
764it: in traditional \TEX\ fonts the width of characters is such that the subscript
765sits nicely against the shape, and the italic correction determines where the
766superscript ends up or when that is absent where the next item starts. It is also
767used for positioning the limits on n-ary operators. In \OPENTYPE\ fonts kerning
768happens with staircase kerns and italic correction is supposedly only used after
769a run of italic shapes. There positioning the limits is also driven by that
770correction.
771
772The dual purpose is confusing. In traditional fonts the italic correction is
773actually a kern and that is why we decided to just add it to the width and use
774the same value for a negative bottom kern. An exception is the integral where as
775mentioned the correction determines the limits.
776
777With the fonts being some mix for old and new we also have to deal with the left
778end of the shapes, especially in relation to the positioning of top accents which
779can be somewhat erratic.
780
781All this head lead us to a tweak that does several things at once: get rid of
782weird left side bearings (so that for instance a math italic \type {f} doesn't
783stick out in a way that makes it unusable), correct the advance width with the
784italic correction, turn top accent values into top and bottom anchors, add top
785and bottom right and left kerns based on all this. Finally we wipe the old italic
786and top accent values and end up with a clean glyph that we can deal with properly
787in several circumstances.
788
789In the goodie files you can find these lines:
790
791\starttyping
792presets.moveitalics { correct = true },
793presets.moveitalics { correct = true, letters = true },
794\stoptyping
795
796In the file \type {common-math.lfg} you can find how these are defined. The first
797one does the alphabets and the second one all the letters. That second one is
798sort of redundant but one can now comment the line in order to check for
799left-overs. Because we do this for all fonts, we have defined these operations as
800presets. so it makes sense to study this file. These lines are in fact function
801calls that return a regular tweak table entry.
802
803\stopchapter
804
805\startchapter[title=Tweak: movelimits]   \ShowTweakUsage{movelimits}
806
807This tweak turns the italic correction of integrals into anchors and right kerns,
808something that the engine can deal with in a more advanced way than just some
809fuzzy italic correction because kerns permeable through the renderer. Again we
810have a preset:
811
812\starttyping
813presets.moveintegrals { factor = 1.5 }
814\stoptyping
815
816This is defined as:
817
818\starttyping
819moveintegrals = function(parameters)
820    return {
821        tweak  = "movelimits",
822        factor = parameters.factor or 1,
823        list   = mathematics.tweaks.subsets.integrals,
824    }
825end
826\stoptyping
827
828Watch how we pas a factor that does an extra shift on the top and bottom anchors.
829For the list we use a predefined list of integrals (and there are plenty in
830\UNICODE).
831
832\stopchapter
833
834\startchapter[title=Tweak: wipeanchors]  \ShowTweakUsage{wipeanchors}
835
836This tweak wipes the top anchors (top accents) for the given (ranges) of
837characters. There are fonts out there with weird ones and when wiped the centered
838positioning that kicks in when no anchor is defined works better. In practice
839only a few very sloped characters benefit from anchors. Interesting is that the
840math italic f is sensitive for bad dimensions and anchors and as that character
841is used a lot the impression can be that a whole font is bad if that one is.
842
843\stopchapter
844
845\startchapter[title=Tweak: wipeitalics]  \ShowTweakUsage{wipeitalics}
846
847This tweak wipes the \quote {italic correction} fields that are left over after
848applying \type {moveitalics} and \type {movelimits}. For instance some symbols
849can have italic corrections that make no sense but might have resulted from some
850automatic font generation workflow.
851
852\stopchapter
853
854\startchapter[title=Tweak: checkspacing] \ShowTweakUsage{checkspacing}
855
856This is a rather harmless but still useful tweak. There are plenty of spacing characters
857in \UNICODE\ and although in math mode spacing is handled automatically users might be
858tempted to inject their own. Normally that happens with commands but using these direct
859characters can be an option.
860
861\starttexdefinition CheckSpacingA #1
862    \start
863    \switchtobodyfont[#1]
864    \normalexpanded{\stop\ttx\withoutpt\emwidth}%
865\stoptexdefinition
866
867\starttexdefinition CheckSpacingB #1#2
868    \vrule height 1.5\exheight depth 0.5\exheight width 1pt
869    \start
870    \switchtobodyfont[#1]%
871    \char#2\relax
872    \stop
873    \vrule height 1.5\exheight depth 0.5\exheight width 1pt
874\stoptexdefinition
875
876\startluacode
877    local list = mathematics.tweaks.datasets.checkspacing
878    context.starttabulate { "|l|l|" .. string.rep("c|",#list) }
879        context.NC() context.NC()
880        for i=1,#list do
881            context.NC() context.rotate( { rotation = "90" }, string.formatters["\\ttx %U"](list[i][1]) )
882        end
883        context.NC() context.NR()
884        context.NC() context.NC()
885        for i=1,#list do
886            context.NC() context("\\ttx %s",list[i][2]) -- space quad char
887        end
888        context.NC() context.NR()
889        for i=1,#document.usedfonts do
890            local font = document.usedfonts[i][1]
891            context.NC()
892            context(font)
893            context.NC()
894            context.CheckSpacingA(font)
895            for i=1,#list do
896                context.NC()
897                context.CheckSpacingB(font,list[i][1])
898            end
899            context.NC()
900            context.NR()
901        end
902    context.stoptabulate()
903\stopluacode
904
905In this table the \type {s} indicates that the value is a spacer, like a \quote
906{non breakable space}, the \type {q} that the value is derived from a quad, like
907\quote {four per em space}, and the \type {c} means that we have a character
908driven quantity, like a \quote {punctuation space}.
909
910\stopchapter
911
912\startchapter[title=Tweak: setovershoots] \ShowTweakUsage{setovershoots}
913
914This tweak add some tolerance to characters which will make accents on top of
915them look a bit better.
916
917\starttyping
918{
919    tweak = "setovershoots",
920    list  = {
921        {
922            target       = "uppercasescript",
923            topovershoot = 0.05,
924        },
925        {
926            target       = "uppercaseboldscript",
927            topovershoot = 0.05,
928        },
929    },
930}
931\stoptyping
932
933\stopchapter
934
935\startchapter[title=Tweak: simplifykerns] \ShowTweakUsage{simplifykerns}
936
937The native kerning mechanism in \OPENTYPE\ math fonts uses staircase kerns for
938positioning scripts at each corner. When we looked into fonts in more detail we
939noticed that when the first step was normally okay, the second of third was such
940that the shape was actually touched. This made us add this tweak, where the
941extremes of staircase kerns (first top and last bottom) are used instead. This is
942possible because in \LUAMETATEX\ we have additional kerning features.
943
944One can argue that this degrades the quality but one has to keep in mind that
945\TEX\ will move script up and down anyway, so one seldom ends up in the more
946dangerous zones. So it's best to just catch it and throw out the few that we
947could benefit from.
948
949\stopchapter
950
951\startchapter[title=Tweak: kernpairs]     \ShowTweakUsage{kernpairs}
952
953We use this tweak to optimize kerning between successive characters. Here are
954some examples for bonum:
955
956\startlines
957{\showglyphs\switchtobodyfont   [bonum]$aj$\quad $fj$\quad $ij$}
958{\showglyphs\switchtobodyfont[bonum-nt]$aj$\quad $fj$\quad $ij$}
959\stoplines
960
961It might take while before we have set them up; fortunately we can use
962categories to set up a lot at the same time.
963
964Some fonts have kerns, for instance \STIX\ but not for math. Borrowing the
965default latin ones is no real option because it looks too inconsistent for use in
966math. This is why for now we keep it explicit.
967
968% \startlines
969% {\showglyphs\switchtobodyfont   [stixtwo]$aj$\quad $fj$\quad $ij$\quad \char65 \char67}
970% {\showglyphs\switchtobodyfont[stixtwo-nt]$aj$\quad $fj$\quad $ij$\quad \char65 \char67}
971% \stoplines
972
973\stopchapter
974
975\startchapter[title=Tweak: kerns]         \ShowTweakUsage{kerns}
976
977This tweak can be used to set the (simple) corner kerns.
978
979\starttyping
980{
981    tweak = "kerns",
982    list  = {
983        [0x002F] = { topleft = -0.2, bottomright = -0.2 },
984    }
985}
986\stoptyping
987
988The numbers are a fraction of the width and valid fields are \typ {topleft}, \typ
989{topright}, \typ {bottomleft} and \typ {bottomright}. These kerns are used in pre
990and postscripts.
991
992\starttexdefinition KernsTest #1
993    \NC #1
994    \NC \switchtobodyfont[#1]    $\showglyphs x^2/2$
995    \NC \switchtobodyfont[#1-nt] $\showglyphs x^2/2$
996    \NC \NR
997\stoptexdefinition
998
999\starttabulate[|l|c|c|]
1000    \NC \NC tweaked \NC original \NC \NR
1001    \ctxlua {
1002        for i=1,#document.usedfonts do
1003            if i > 1 then
1004                context.TB { "medium" }
1005            end
1006            context.KernsTest(document.usedfonts[i][1])
1007        end
1008    }
1009\stoptabulate
1010
1011\stopchapter
1012
1013\startchapter[title=Tweak: margins]       \ShowTweakUsage{margins}
1014
1015This tweak is similar to the kerns tweak but adds margins instead. it is a trick to
1016enforce larger and|/|or smaller accents (like for instance \type {\widetilde}.
1017
1018\starttyping
1019{
1020    tweak = "margins",
1021    list  = {
1022        [0x1D7DC] = { left = -.1, right = -.1 }, -- doublestruck 4
1023    }
1024}
1025\stoptyping
1026
1027The relevant fields are \type {left} and \type {right}, they specify the margins
1028as fraction of the width, and \type {top} and \type {bottom}, those specify
1029margins as fraction of the combined height and depth.
1030
1031Keep in mind that these are not \OPENTYPE\ math properties but specific (and
1032native) to \LUAMETATEX.
1033
1034\stopchapter
1035
1036\startchapter[title=Tweak: staircase]     \ShowTweakUsage{staircase}
1037
1038{\em This tweak is kind of obsolete and might go away some day.}
1039
1040\stopchapter
1041
1042\startchapter[title=Tweak: fixintegrals] \ShowTweakUsage{fixintegrals}
1043
1044In the Computer Modern font there are only a few sizes for the integral sign
1045\type {U+222B} and they are very sloped. Nowadays fonts also have an extensible
1046in which case the shape is upright. In \UNICODE\ there are quite some characters
1047that can be used to construct extensibles (like braces) and there are also
1048snippets for constructing integrals: \type {0x2320}, \type {0x23AE} and \type
1049{0x2321}. The fact that these are there and that fonts then provide them also
1050makes it easy to provide extensibles: you just stack them:
1051
1052\starttexdefinition TestIntegralSnippets #1
1053    \NC #1
1054    \NC \showglyphs \switchtobodyfont[#1-nt]%
1055        $ \displaystyle \integral { \quad \vcenter\bgroup
1056            \darkred
1057            \offinterlineskip
1058            \hpack{$\char"2320$}
1059            \hpack{$\char"23AE$}
1060            \hpack{$\char"2321$}
1061          \egroup } $
1062    \NC \showglyphs \switchtobodyfont[#1-nt]$\char"2320$
1063    \NC \showglyphs \switchtobodyfont[#1-nt]$\char"23AE$
1064    \NC \showglyphs \switchtobodyfont[#1-nt]$\char"2321$
1065    \NC \NR
1066\stoptexdefinition
1067
1068\starttabulate[|||c|c|c|]
1069    \ShowSomething{TestIntegralSnippets}
1070\stoptabulate
1071
1072This tweak can use these snippets to provide an extensible in case it is not part
1073of the integral glyph definition. In these examples we show the untweaked
1074integral that is choosen when we provide the one made from three snippets. The
1075red one is the constructed variant. Keep in mind that an extensible works best
1076when there is some overlap possible.
1077
1078\stopchapter
1079
1080\startchapter[title=Tweak: accentdimensions] \ShowTweakUsage{accentdimensions}
1081
1082Positioning of accents is driven by \typ {AccentBaseHeight} and \typ
1083{AccentBaseDepth} combined with the height of what goes under an accent as we ll
1084as the height of the accent. Unfortunately the height of the accents is not
1085always consistent across the repertoire and within a variant list starting with
1086the initial character.
1087
1088\starttexdefinition TestAccentDimension #1#2#3
1089    \NC \ifnum#3=1 #1\fi
1090    \NC \tttf U+\ifnum#2<"FFF 0\fi\tohexadecimal#2
1091    \NC \switchtobodyfont   [#1]\showglyphs$\char#2$
1092    \NC \switchtobodyfont   [#1]\showglyphs$\dorecurse{3}{\char\mathvariantcode #2 ##1\quad}\unskip$
1093    \NC \switchtobodyfont[#1-nt]\showglyphs$\char#2$
1094    \NC \switchtobodyfont[#1-nt]\showglyphs$\dorecurse{3}{\char\mathvariantcode #2 ##1\quad}\unskip$
1095    \NC \NR
1096\stoptexdefinition
1097
1098\startluacode
1099    function document.TestAccentDimension(list)
1100        context.starttabulate { "|l|c|c|c|c|c|" }
1101        context.FL()
1102        context.NC() context("bodyfont")
1103        context.NC() context("unicode")
1104        context.NC() context("tweaked")
1105        context.NC()
1106        context.NC() context("original")
1107        context.NC()
1108        context.NC() context.NR()
1109        for i=1,#document.usedfonts do
1110            context.ML()
1111            local n = 0
1112            for k, v in table.sortedhash(mathematics.tweaks.datasets.accentdimensions[list]) do
1113                n = n + 1
1114                context.TestAccentDimension(document.usedfonts[i][1],k,n)
1115            end
1116        end
1117        context.LL()
1118        context.stoptabulate()
1119    end
1120\stopluacode
1121
1122The over and under accents are not always present so other tweaks fill in these gaps.
1123
1124\ctxlua{document.TestAccentDimension("over")}
1125\ctxlua{document.TestAccentDimension("under")}
1126
1127We can specify what accents get processed but here we show the default set. In most cases o
1128treatment is needed.
1129
1130\ctxlua{document.TestAccentDimension("accent")}
1131
1132The specification can be simple, just the tweak name, but you can also specify
1133a detailed list:
1134
1135\starttyping
1136{
1137    tweak = "accentdimensions",
1138    list  = { "over", "under" }, -- "accent"
1139}
1140\stoptyping
1141
1142or even:
1143
1144\starttyping
1145{
1146    tweak = "accentdimensions",
1147    list  = {
1148        [0x203E] = { factor = "over"  }, -- overbar
1149        [0x203E] = { factor = "under" }, -- underbar
1150        [0x23DE] = { factor = "over"  }, -- overbrace
1151        [0x23DF] = { factor = "under" }, -- underbrace
1152        [0x23DC] = { factor = "over"  }, -- overparent
1153        [0x23DD] = { factor = "under" }, -- underparent
1154        [0x23B4] = { factor = "over"  }, -- overbracket
1155        [0x23B5] = { factor = "under" }, -- underbracket
1156    }
1157}
1158\stoptyping
1159
1160Instead of a named factor you can pass a number to be applied to the height or
1161depth. As with all tweaks, they are normally not applied at the user level so if
1162you have to you'd better check the source code to see what really happens in this
1163tweak (this is true for more tweaks).
1164
1165\stopchapter
1166
1167\startchapter[title=Tweak: copyaccents]      \ShowTweakUsage{copyaccents}
1168
1169This tweak deals with a mixup of combining accents and wide accents where
1170recipes can be on the \quote {wrong} code point.
1171
1172\startluacode
1173context.starttabulate { "|T|T|c|c|" }
1174context.FL()
1175context.NC() context("base")
1176context.NC() context("accent")
1177context.NC() context("scale")
1178context.NC() context.NR()
1179context.ML()
1180for k, v in table.sortedhash(mathematics.tweaks.datasets.copyaccents) do
1181    context.NC() context("%U",k)
1182    context.NC() context("%U",v[1])
1183    context.NC() context(v[2] and "yes" or "no")
1184    context.NC() context("$\\char %i$",v[1])
1185    context.NC() context.NR()
1186end
1187context.LL()
1188context.stoptabulate()
1189\stopluacode
1190
1191\stopchapter
1192
1193\startchapter[title=Tweak: fixaccents]       \ShowTweakUsage{fixaccents}
1194
1195When the width of an accent is zero but it has an top (accent) anchor defined we
1196can fix the its width, which is what this somewhat obscure tweak does. It belongs
1197to the repertoire of weird tweaks that we came up with when trying to make
1198suboptimal fonts work well.
1199
1200\stopchapter
1201
1202\startchapter[title=Tweak: extendaccents]    \ShowTweakUsage{extendaccents}
1203
1204When a wide accent is used the engine will try to find a best match from a
1205sequence of variants. When there are no more variants it will use an extensible
1206(recipe) when present. When that is not the case, one can decide to stretch the
1207last variant to fit, but that only works for a few accents: the scale column in
1208the table in the chapter about copying accents shows them. This tweak takes a few
1209optional parameters: \type{all} that is either \type {true} or a number
1210indicating after which variant stretching starts, and \type {force} that forces
1211stretch on all variants.
1212
1213\stopchapter
1214
1215% \startchapter[title=Tweak: fixanchors]       \ShowTweakUsage{fixanchors}
1216%   obsolete
1217% \stopchapter
1218
1219\startchapter[title=Tweak: flattenaccents]   \ShowTweakUsage{flattenaccents}
1220
1221An \OPENTYPE\ math font can have a flat variant of an accent that can kick in when we
1222run out of space. This feature will flatten regular accents. The same list is used as
1223for copying accents. There are optional parameters to control the flattening:
1224
1225\starttabulate[||||]
1226\FL
1227\NC parameter \NC type     \NC default           \NC \NR
1228\ML
1229\NC force     \NC boolean  \NC false             \NC \NR
1230\NC height    \NC factor   \NC 0.8               \NC \NR
1231\NC offset    \NC factor   \NC 0.9 or calculated \NC \NR
1232\NC squeeze   \NC factor   \NC 0.1 or calculated \NC \NR
1233\LL
1234\stoptabulate
1235
1236\stopchapter
1237
1238\startchapter[title=Tweak: bigslots]         \ShowTweakUsage{bigslots}
1239
1240This tweak can be applied as tweak or at a higher level in the mathematics goodie
1241table. When defined as tweak it is under font version control.
1242
1243\starttexdefinition CheckBigSlotA #1#2
1244    \start
1245    \switchtobodyfont[#1]%
1246    \im{\char\mathvariantcode "7B #2}%
1247    \stop
1248    \hss
1249\stoptexdefinition
1250
1251\starttexdefinition CheckBigSlotB #1#2
1252    \start
1253    \switchtobodyfont[#1]%
1254    \setbox\scratchbox\hbox{\im{\char\mathvariantcode "7B #2}}%
1255    \normalexpanded{\stop{\ttxx
1256        \cldcontext{"\letterpercent.3f",\number\htdp\scratchbox/\number\exheight}%
1257    }}\quad
1258\stoptexdefinition
1259
1260\starttexdefinition CheckBigSlotC #1
1261    \start
1262    \switchtobodyfont[#1]%
1263    \normalexpanded{\stop{\ttxx\withoutpt\exheight}}%
1264\stoptexdefinition
1265
1266\startluacode
1267context.starttabulate { "|l|l|l|l|l|" }
1268    context.NC() context("font")
1269 -- context.NC() context("tweak")
1270 -- context.NC() context("global")
1271    context.NC() context("sequence")
1272    context.NC() context("ex-height")
1273    context.NC() context("rendering")
1274    context.NC() context("ratio to ex")
1275    context.NC() context.NR()
1276    for i=1,#document.usedfonts do
1277        local font    = document.usedfonts[i][1]
1278        local goodies = document.usedgoodies[font]
1279        local llist   = goodies.bigslots
1280        local glist   = goodies.goodies.bigslots
1281        local list    = glist or llist
1282        context.NC() context(font)
1283     -- context.NC() context("% t",llist)
1284     -- context.NC() context("% t",glist)
1285        context.NC() if list then context("\\ttxx % t",list) else context("unset") end
1286        context.NC()
1287        if list then
1288            context.CheckBigSlotC(font)
1289        end
1290        context.NC()
1291        if list then
1292         -- context.switchtobodyfont { font }
1293         -- for i=1,#list do
1294         --     context(function()
1295         --         context.im(utf.char(mathematics.variantcode(0x7B,list[i]))) context.quad()
1296         --         context.im(utf.char(mathematics.variantcode(0x5D,list[i]))) context.quad()
1297         --     end)
1298         -- end
1299            context.hss()
1300            for i=1,#list do
1301                context.CheckBigSlotA(font,list[i])
1302            end
1303        end
1304        context.NC()
1305        if list then
1306            for i=1,#list do
1307                context.CheckBigSlotB(font,list[i])
1308            end
1309        end
1310        context.NC() context.NR()
1311    end
1312context.stoptabulate()
1313\stopluacode
1314
1315\stopchapter
1316
1317\startchapter[title=Tweak: wipevariants]     \ShowTweakUsage{wipevariants}
1318
1319When a font has too many variants one can wipe them with this tweak. The entries
1320in the list specify the last variant. When a \type {*} will wipe all variants.
1321
1322\starttyping % [style=\ttx]
1323{
1324    tweak   = "radicaldegreeanchors",
1325    list = {
1326        [0x221A] = 5, -- becomes last variant
1327    }
1328}
1329\stoptyping
1330
1331\stopchapter
1332
1333\startchapter[title=Tweak: radicaldegreeanchors] \ShowTweakUsage{radicaldegreeanchors}
1334
1335The position of the radical degree is determined by some font parameters (todo)
1336but these are shared among the different sizes as well as the extensible. We
1337therefore provide a tweak that sets real anchors. These are not officially in
1338\UNICODE\ math but an engine feature. Here is the experimental setup we made for
1339Lucida. It demonstrates that we can set the base character, variants and the
1340extensible. The factors that default to one, are applied to the width and height
1341plus depth in order to get the coordinates.
1342
1343\starttyping[style=\ttx]
1344{
1345    tweak   = "radicaldegreeanchors",
1346    list = {
1347        -- the base radical:
1348     -- [0x221A]                = { hfactor =  .05, vfactor =  .675 },
1349        -- all variants:
1350     -- ["0x221A.variants.*"]   = { hfactor =  .05, vfactor =  .6   },
1351        -- specific variants:
1352     -- ["0x221A.variants.1"]   = { hfactor =  .05, vfactor =  .65  },
1353     -- ["0x221A.variants.2"]   = { hfactor =  .1,  vfactor =  .65  },
1354        ["0x221A.variants.3"]   = { hfactor = 0,    vfactor =  .55  },
1355        ["0x221A.variants.4"]   = { hfactor = 0,    vfactor =  .50  },
1356     -- ["0x221A.variants.5"]   = { hfactor =  .05, vfactor =  .525 },
1357     -- ["0x221A.variants.5"]   = { hfactor =  .1,  vfactor =  .55  },
1358     -- ["0x221A.variants.6"]   = { hfactor =  .1,  vfactor =  .55  },
1359        -- extensibles where the setting of bottom wins over top:
1360     -- ["0x221A.parts.top"]    = { hfactor =  .1,  vfactor = 5.5   },
1361        ["0x221A.parts.bottom"] = { hfactor = 0,    vfactor =  .85  },
1362    }
1363}
1364\stoptyping
1365
1366The \type {location} is not set here and defaults to \type {left}; it is
1367redundant because currently we only have left sided radical degrees (but we do
1368have right sided radicals).
1369
1370\stopchapter
1371
1372\startchapter[title=Tweak: fixradicals]          \ShowTweakUsage{fixradicals}
1373
1374Because there is are limited number of heights and depths available in original
1375\TFM\ files and variants by their nature differ in height and depth some glyphs
1376like radicals have interesting dimensions. At the time of writing this only Latin
1377Modern has this property.
1378
1379{\em ff image needed here}
1380
1381\starttexdefinition TestFixRadical #1
1382    \dontleavehmode
1383    \NC {\srule height3ex depth 2ex \relax}#1
1384    \NC \showglyphs \switchtobodyfont[#1-nt]$\mathaxisbelow \char"221A + x$
1385    \NC \showglyphs \switchtobodyfont   [#1]$\mathaxisbelow \char"221A + x$
1386    \NC \showglyphs \switchtobodyfont   [#1]$\mathaxisbelow \char\mathvariantcode "221A 1 + x$
1387    \NC \showglyphs \switchtobodyfont   [#1]$\mathaxisbelow \sqrt{x}$
1388    \NC \NR
1389\stoptexdefinition
1390
1391\starttabulate[|l|c|c|c|c|]
1392    \NC bodyfont \NC untweaked \NC tweaked \NC first variant \NC example \NC \NR
1393    \ShowSomething{TestFixRadical}
1394\stoptabulate
1395
1396% after this: \dorecurse{15}{ Nacht Na de Dam 2021 | Wende - Bloed in mijn Bloed }
1397
1398\stopchapter
1399
1400\startchapter[title=Tweak: fallbacks]        \ShowTweakUsage{fallbacks}
1401
1402This tweak is not really a tweak but hooks into the fallbacks that a user
1403defined. However, when fallbacks are set, they need to be injected at the right
1404spot in the sequence of tweaks which is why it is defined in the goodie file.
1405
1406\stopchapter
1407
1408\startchapter[title=Tweak: replacealphabets] \ShowTweakUsage{replacealphabets}
1409
1410This tweak is an important one. It is used to add or swap script and calligraphic
1411alphabets, inject right to left variants and configure replacements based on
1412features. The following fields can be set:
1413
1414\starttabulate[||||]
1415\NC filename \NC string \NC source file \NC \NR
1416\NC feature  \NC string \NC feature \NC \NR
1417\NC source   \NC string \NC alphabet name \NC \NR
1418\NC          \NC table  \NC first source range \NC \NR
1419\NC target   \NC string \NC alphabet name \NC \NR
1420\NC          \NC table  \NC first source range \NC \NR
1421\NC rscale   \NC number \NC relative scale \NC \NR
1422\stoptabulate
1423
1424When an effect (like boldening) is used it is also applied to the injected
1425alphabets. When not given, the target range is the same as the source. An example
1426of a more extensive specification is:
1427
1428\starttyping
1429{
1430    tweak    = "replacealphabets",
1431    feature  = "euleroverpagella",
1432    filename = "euler.otf",
1433    list     = {
1434        { source = { first = 0x02100, last = 0x02BFF } },
1435        { source = { first = 0x1D400, last = 0x1D7FF } },
1436        { source = { first = 0x1D538, last = 0x1D550 } },
1437    },
1438}
1439\stoptyping
1440
1441The feature at the outer level is a selector that can be set as follows:
1442
1443\starttyping
1444\definefontfeature[lucida:mathextra][euleroverpagella=yes]
1445\stoptyping
1446
1447This feature is not to be confused by the file related one that we access in for
1448instance for instance Lucida:
1449
1450\starttyping
1451{
1452    tweak   = "replacealphabets",
1453    list    = {
1454        {
1455            source   = "uppercasescript",
1456            target   = "uppercasecalligraphic",
1457            feature  = "ss04",
1458        },
1459        {
1460            source   = "lowercasescript",
1461            target   = "lowercasecalligraphic",
1462            feature  = "ss04",
1463        },
1464        {
1465            source   = "uppercaseboldscript",
1466            target   = "uppercaseboldcalligraphic",
1467            feature  = "ss04",
1468        },
1469        -- No lowercase bold calligraphic/script in font
1470    },
1471},
1472\stoptyping
1473
1474The calligraphic alphabets are not official \UNICODE\ but internal \CONTEXT\ ones
1475that are used to switch between script and calligraphic styles.
1476
1477\stopchapter
1478
1479\startchapter[title=Tweak: replace]     \ShowTweakUsage{replace}
1480
1481You can replace a character in a font by another one:
1482
1483\starttyping
1484{
1485    tweak   = "replace",
1486    list    = {
1487        [0x123] = 0x125
1488    },
1489},
1490\stoptyping
1491
1492\stopchapter
1493
1494\startchapter[title=Tweak: substitute]       \ShowTweakUsage{substitute}
1495
1496You can substitute a character in a font by one from a substitution feature:
1497
1498\starttyping
1499{
1500    tweak   = "substitute",
1501    list    = {
1502        [0x123] = "ss01"
1503    },
1504},
1505\stoptyping
1506
1507\stopchapter
1508
1509\startchapter[title=Tweak: fixprimes] \ShowTweakUsage{fixprimes}
1510
1511\starttexdefinition PrimeTest #1
1512    \NC #1
1513    \NC \showglyphs \switchtobodyfont[#1]    $f'(x)+e^{g'(x)} - a''+ b''' + c''''$
1514    \NC \showglyphs \switchtobodyfont[#1-nt] $f'(x)+e^{g'(x)} - a''+ b''' + c''''$
1515    \NC \showglyphs \switchtobodyfont[#1]    $\primed{f}$
1516    \NC \NR
1517\stoptexdefinition
1518
1519\starttabulate[|l|c|c|c|]
1520    \NC \NC tweaked \NC original \NC primed \NC \NR
1521    \ctxlua {
1522        for i=1,#document.usedfonts do
1523            if i > 1 then
1524                context.TB()
1525            end
1526            context.PrimeTest(document.usedfonts[i][1])
1527        end
1528    }
1529\stoptabulate
1530
1531\stopchapter
1532
1533\startchapter[title=Tweak: fixslashes] \ShowTweakUsage{fixslashes}
1534
1535This tweak makes sure that the regular slash \type {U+002F} behaves compatible
1536with the math one \type {U+2044}. Not all fonts provide the correct variants
1537chain.
1538
1539% There is currently no need to show datasets.fixslashes as there is
1540% just one entry.
1541
1542\stopchapter
1543
1544\startchapter[title=Tweak: fixellipses] \ShowTweakUsage{fixellipses}
1545
1546\startbuffer
1547\im{1 + 2+ \cdots + n} \im{1, 2, \ldots, n}
1548\stopbuffer
1549
1550\starttabulate[|l|c|c|]
1551    \NC \NC tweaked \NC original \NC \NR
1552    \NC concrete
1553    \NC \switchtobodyfont[concrete]    \getbuffer
1554    \NC \switchtobodyfont[concrete-nt] \getbuffer \NR
1555\stoptabulate
1556
1557\stopchapter
1558
1559\startchapter[title=Tweak: wipecues]    \ShowTweakUsage{wipecues}
1560
1561Cues are hidden directives that should not take space so we set their dimensions
1562to zero:
1563
1564\startluacode
1565    local t = mathematics.tweaks.datasets.wipecues
1566    local c = characters.data
1567    context.starttabulate { "|c|c|l|" }
1568    for i=1,#t do
1569        local u = t[i]
1570        context.NC() context("%U",u)
1571        context.NC() context("$\\char %i$",u)
1572        context.NC() context(c[u].description)
1573        context.NC() context.NR()
1574    end
1575    context.stoptabulate()
1576\stopluacode
1577
1578{\em Maybe some day we add tracers in which case they are visible but stil take
1579no space.}
1580
1581\stopchapter
1582
1583\startchapter[title=Tweak: addactuarian] \ShowTweakUsage{addactuarian}
1584
1585This adds the annuity symbol \type {U+020E7} but as extensible because in itself
1586this symbol, if present in the font at all, is rather unusable. It uses the same
1587mechanism as radicals (roots) but from the other edge.
1588
1589% {\em todo: realistic example by Mikael}
1590% From wiki: https://en.wikipedia.org/wiki/Actuarial_notation
1591
1592{\red MPS: In the \typ{\rannuity{m}} example, I would like it to be without the top bar, but I cannot find that. Also, maybe the bar over $n$ should also be tighter.}
1593
1594
1595\starttexdefinition ActuarianTest #1
1596    \NC #1
1597    \NC \switchtobodyfont[#1]
1598    $\bar{A}^1_{x:\rannuity{n}}^^{2}__{\rannuity{m}}$
1599    \NC \NR
1600\stoptexdefinition
1601
1602\starttabulate[|l|c|]
1603    \NC \NC tweaked \NC \NR
1604    \ctxlua {
1605        for i=1,#document.usedfonts do
1606            if i > 1 then
1607                context.TB()
1608            end
1609            context.ActuarianTest(document.usedfonts[i][1])
1610        end
1611    }
1612\stoptabulate
1613
1614
1615
1616\stopchapter
1617
1618\startchapter[title=Tweak: addarrows]    \ShowTweakUsage{addarrows}
1619
1620Not all fonts have extensible arrows. Traditionally in \TEX\ these were made
1621from arrow heads and rules. This tweak makes proper extensibles.
1622
1623\startluacode
1624    local t = mathematics.tweaks.datasets.addarrows
1625    local c = characters.data
1626    context.starttabulate { "|c|c|c|l|" }
1627    for i=1,#t do
1628        local u = t[i]
1629        context.NC() context("%U",u)
1630        context.NC() context("$\\char %i$",u)
1631        context.NC() context("$\\Umathaccent 0 0 %i{\\hskip3em}$",u)
1632        context.NC() context(c[u].description)
1633        context.NC() context.NR()
1634    end
1635    context.stoptabulate()
1636\stopluacode
1637
1638\stopchapter
1639
1640\startchapter[title=Tweak: addbars]      \ShowTweakUsage{addbars}
1641
1642There is only one parameter to this tweak: \type {advance} which is a fraction
1643of the width.
1644
1645\starttexdefinition BarTest #1
1646    \NC #1
1647    \NC \showglyphs \switchtobodyfont[#1]    $\char"007C\quad\char"2016\quad\char"2980$
1648    \NC \showglyphs \switchtobodyfont[#1-nt] $\char"007C\quad\char"2016\quad\char"2980$
1649    \NC \NR
1650\stoptexdefinition
1651
1652\starttabulate[|l|c|c|]
1653    \NC \NC tweaked \NC original \NC \NR
1654    \ctxlua {
1655        for i=1,#document.usedfonts do
1656            if i > 1 then
1657                context.TB()
1658            end
1659            context.BarTest(document.usedfonts[i][1])
1660        end
1661    }
1662\stoptabulate
1663
1664\stopchapter
1665
1666\startchapter[title=Tweak: addequals]    \ShowTweakUsage{addequals}
1667
1668There is only one parameter to this tweak: \type {advance} which is a fraction
1669of the width.
1670
1671\starttexdefinition EqualTest #1
1672    \NC #1
1673    \NC \showglyphs \switchtobodyfont[#1]    $\char"003D\quad\char"2A75\quad\char"2A76$
1674    \NC \showglyphs \switchtobodyfont[#1-nt] $\char"003D\quad\char"2A75\quad\char"2A76$
1675    \NC \NR
1676\stoptexdefinition
1677
1678\starttabulate[|l|c|c|]
1679    \NC \NC tweaked \NC original \NC \NR
1680    \ctxlua {
1681        for i=1,#document.usedfonts do
1682            if i > 1 then
1683                context.TB()
1684            end
1685            context.EqualTest(document.usedfonts[i][1])
1686        end
1687    }
1688\stoptabulate
1689
1690\stopchapter
1691
1692\startchapter[title=Tweak: addfourier]   \ShowTweakUsage{addfourier}
1693
1694This adds the fourier rendering which uses the radical subsystem but with a right
1695hand symbol.
1696
1697% {\em todo: realistic example by Mikael}
1698% From Folland - Real analysis:
1699
1700\starttexdefinition FourierTest #1
1701    \NC #1
1702    \NC \switchtobodyfont[#1]
1703    $\partial^\alpha \hat{f} = \fourier{[(-2\pi i x )^{\alpha} f]}$
1704    \NC \NR
1705\stoptexdefinition
1706
1707\starttabulate[|l|c|]
1708    \NC \NC tweaked \NC \NR
1709    \ctxlua {
1710        for i=1,#document.usedfonts do
1711            if i > 1 then
1712                context.TB()
1713            end
1714            context.FourierTest(document.usedfonts[i][1])
1715        end
1716    }
1717\stoptabulate
1718
1719\stopchapter
1720
1721\startchapter[title=Tweak: addmirrors]   \ShowTweakUsage{addmirrors}
1722
1723This adds symbols for right|-|to|-|left math by simply mirroring existing ones.
1724Deep down the engine doesn't really care about in what direction typesetting
1725happens (wrt spacing and building structures), and it is the backend that does
1726the real work. However, symbols need to be flipped.
1727
1728\stopchapter
1729
1730\startchapter[title=Tweak: addparts]     \ShowTweakUsage{addparts}
1731
1732Here is an example of a (probably rarely used) low level extensible definition:
1733
1734\starttyping
1735{
1736    tweak = "addparts",
1737    list  = {
1738        [0x21F4] = {
1739            horizontal = true,
1740            template   = 0x2192,
1741            sequence   = {
1742                { glyph = "first", factor = 2 },
1743                { glyph = 0x2218 },
1744                { glyph = "first", factor = 2 },
1745                { glyph = "last" },
1746            }
1747        }
1748    }
1749},
1750\stoptyping
1751
1752In this example \type {first} is equivalent to the first part of the template, and
1753\type {last} to the last one. Like:
1754
1755\blank \start \switchtobodyfont[stixtwo] \im {
1756    \char"21F4 \quad
1757    \Umathtopaccent 0 0 "21F4 {\mathtexttf{\strut one two three}}
1758} \stop \blank
1759
1760\stopchapter
1761
1762\startchapter[title=Tweak: addprivates]  \ShowTweakUsage{addprivates}
1763
1764This tweak adds some characters to the repertoire. Currently we have only a few:
1765
1766\starttexdefinition PrivatesTest #1
1767    \NC #1
1768    \NC \switchtobodyfont[#1] $\um  2$
1769    \NC \switchtobodyfont[#1] $\up  2$
1770    \NC \switchtobodyfont[#1] $\ump 2$
1771    \NC \switchtobodyfont[#1] $\upm 2$
1772    \NC \NR
1773\stoptexdefinition
1774
1775\starttabulate[|l|c|c|c|c|]
1776    \NC \NC \type {\um} \NC \type {\up} \NC \type {\ump} \NC \type {\upm} \NC \NR
1777    \ctxlua {
1778        for i=1,#document.usedfonts do
1779%             if i > 1 then
1780%                 context.TB { "small" }
1781%             end
1782            context.PrivatesTest(document.usedfonts[i][1])
1783        end
1784    }
1785\stoptabulate
1786
1787\stopchapter
1788
1789\startchapter[title=Tweak: addrules]     \ShowTweakUsage{addrules}
1790
1791This adds a few (missing) rule based shapes to a font:
1792
1793\starttexdefinition RulesTest #1
1794    \NC #1
1795    \NC \switchtobodyfont[#1] $\Umathaccent top    0 0 "23B4 {\hskip2cm}$
1796    \NC \switchtobodyfont[#1] $\Umathaccent top    0 0 "203E {\hskip2cm}$
1797    \NC \switchtobodyfont[#1] $\Umathaccent bottom 0 0 "23B5 {\hskip2cm}$
1798    \NC \NR
1799\stoptexdefinition
1800
1801\starttabulate[|l|c|c|c|]
1802    \NC \NC \type {0x23B4} \NC \type {0x203E} \NC \type {0x23B5} \NC \NR
1803    \ctxlua {
1804        for i=1,#document.usedfonts do
1805            if i > 1 then
1806                context.TB { "small" }
1807            end
1808            context.RulesTest(document.usedfonts[i][1])
1809        end
1810    }
1811\stoptabulate
1812
1813\stopchapter
1814
1815\startchapter[title=Tweak: addscripts]   \ShowTweakUsage{addscripts}
1816
1817This tweak adds high plus and minus shapes (we use them for indicating calculator
1818input):
1819
1820\starttexdefinition ScriptsTest #1
1821    \NC #1
1822    \NC \switchtobodyfont[#1] $\char"207A x$
1823    \NC \switchtobodyfont[#1] $\char"207B x$
1824    \NC \switchtobodyfont[#1] $\char"208A x$
1825    \NC \switchtobodyfont[#1] $\char"208B x$
1826    \NC \NR
1827\stoptexdefinition
1828
1829\starttabulate[|l|c|c|c|c|]
1830    \NC \NC \type {0x207A} \NC \type {0x2037B} \NC \type {0x208A} \NC \type {0x208B} \NC \NR
1831    \ctxlua {
1832        for i=1,#document.usedfonts do
1833            if i > 1 then
1834                context.TB { "small" }
1835            end
1836            context.ScriptsTest(document.usedfonts[i][1])
1837        end
1838    }
1839\stoptabulate
1840
1841\stopchapter
1842
1843\startchapter[title=What we ran into]
1844
1845\startsubject[title=Introduction]
1846
1847In this chapter we will show some of the characters that triggered adding a tweak
1848feature. It can be that in the meantime something changed (got fixed) but
1849nevertheless we think that by collecting some example here can help developers of
1850math fonts to play safe so that the engine can do a good job even without tweaks.
1851
1852\stopsubject
1853
1854\startsubject[title=Latin Modern: radical base]
1855
1856In traditional \TEX\ fonts, for practical reasons (like implementation limits)
1857the base radical character sits quite a bit below the baseline. The engine will
1858automatically compensate for this when it is defined as radical but it makes
1859usage as stand alone character hard. It also doesn't play well with corner kerns
1860and degree anchoring.
1861
1862\startlinecorrection
1863\startcombination
1864    {\externalfigure[lm-radical-base.png]    [width=.25\textwidth]} {base}
1865    {\externalfigure[lm-radical-variant1.png][width=.25\textwidth]} {variant 1}
1866\stopcombination
1867\stoplinecorrection
1868
1869\stopsubject
1870
1871\startsubject[title=Latin Modern: weird anchors]
1872
1873The \TEX Gyre fonts have top accent anchors defined but they are (at least when
1874we write this) often positioned on the highest point of the shape, which is
1875probably a side effect of some automated heuristic. However, for some shapes that
1876works out bad. This is why we can wipe these anchors, just use the middle of the
1877width and provide our own when it makes sense.
1878
1879\startlinecorrection
1880    \externalfigure[lm-7-anchor.png][width=.25\textwidth]
1881\stoplinecorrection
1882
1883\stopsubject
1884
1885\startsubject[title=StixTwo]
1886
1887When trying to improve font metrics (aka tweaking) we sometimes take a look at
1888the shapes in FontForge. So for instance when we noticed that the integral mid
1889segment in StixTwo was too narrow we took that look. Then we also noticed that
1890the glyph was positioned at the edge instead of in the middle but that the
1891hinting was such that it ended up in the middle. Intrigued by this we looked into
1892it in more detail and noticed that the \OPENTYPE\ and \TRUETYPE\ files show up
1893quite different. So we fetching the source files from the git repository, and
1894played with the build script.
1895
1896The starting point is a \TRUETYPE\ file that seems to provide all kind of tables,
1897that are then adapted using a dedicated glyph name file (basically many verbose
1898glyph names are replaced by (in the end sort of redundant) uni names as well as
1899plenty small glif files (we didn't check if these are different from what is in
1900the original ttf file). Intermediate files are generated and at some point auto
1901hinting happens, using different tools for the two formats.
1902
1903At some point we figured out that the left side bearing in the head table was
1904somehow interfering and more experiments (we used for instance Lucida Math as
1905comparison) if became clear that the lsb bit in the head flags was the culprit.
1906By (un)setting it we could let \FONTFORGE\ show the \OPENTYPE\ and \TRUETYPE\
1907files in the same way of differently. We could also zero the lsb entries in the
1908hmtx table, which sort of fixed it independent of the bit. For the record we
1909show the effect here (this document is also a bit our archive).
1910
1911\startlinecorrection
1912\startcombination[nx=3,ny=1]
1913    {\externalfigure[StixTwo23AE-original.png][width=.25\textwidth]} {original otf}
1914    {\externalfigure[StixTwo23AE-fixed.png]   [width=.25\textwidth]} {fixed otf}
1915    {\externalfigure[StixTwo23AE-ttf.png]     [width=.25\textwidth]} {ttf}
1916\stopcombination
1917\stoplinecorrection
1918
1919The original variant:
1920
1921\starttyping
1922<CharString name="uni23AE">
1923125 21 -21 hstem
1924301 102 vstem
1925403 hmoveto
1926650 -102 -650 vlineto
1927endchar
1928</CharString>
1929\stoptyping
1930
1931The fixed version:
1932
1933\starttyping
1934<CharString name="uni23AE">
1935125 0 650 -629 -21 hstemhm
1936301 102 hintmask 01100000
1937403 0 rmoveto
1938hintmask 10100000
19390 650 rlineto
1940-102 0 rlineto
19410 -650 rlineto
1942endchar
1943</CharString>
1944\stoptyping
1945
1946It was this character that we looked at because we use it in a demo, but actually
1947many characters had this visual hinting side effect. So, one solution is to wipe
1948the hints and let FontForge add new ones, but easier is to just use the
1949\TRUETYPE\ files instead of the \OPENTYPE\ ones, either fixed or with hints
1950removed,as in:
1951
1952\starttyping
1953<CharString name="uni23AE">
1954  125 403 0 rmoveto
1955  0 650 rlineto
1956  -102 0 rlineto
1957  0 -650 rlineto
1958  endchar
1959</CharString>
1960\stoptyping
1961
1962This is the original \type {uni23A_E_.glif} file:
1963
1964\starttyping
1965<?xml version='1.0' encoding='UTF-8'?>
1966<glyph name="uni23AE" format="2">
1967  <advance width="704"/>
1968  <unicode hex="23AE"/>
1969  <outline>
1970    <contour>
1971      <point x="403" y="0" type="line"/>
1972      <point x="403" y="650" type="line"/>
1973      <point x="301" y="650" type="line"/>
1974      <point x="301" y="0" type="line"/>
1975    </contour>
1976  </outline>
1977</glyph>
1978\stoptyping
1979
1980In case one wonders why all this matters: occasionally we use the shape in
1981\METAPOST\ and there we don't apply hinting, which means that we don't want to
1982end up with the glyph positioned wrongly in the bounding box with hints moving
1983them to the right spot. So that is why we now prefer the \TRUETYPE\ variant
1984because then at least we can compare different programs visually. \footnote {In
1985the FontForge preview rendering in the overview, hinting is also not applied so
1986there glyphs are also positioned somewhat weird. In TypeTool3 the glyph doesn't
1987show up at all when we enable outline fill so it makes an interesting puzzle.}
1988
1989\stopsubject
1990
1991\stopchapter
1992
1993% \startchapter[title=Left-overs]
1994
1995%  "action",
1996%  "subsets",
1997%  "parameters",
1998
1999%  "message",
2000%  "showinfo",
2001%  "setoptions",
2002%  "oldstylemath",
2003%  "fixoldschool",
2004%  "version",
2005
2006% \stopchapter
2007
2008\stoptext
2009