From a04a6e9b9b68a836f27d971115fd1049c04e6c19 Mon Sep 17 00:00:00 2001
From: Hans Hagen <pragma@wxs.nl>
Date: Wed, 30 Dec 2020 17:22:53 +0100
Subject: 2020-12-30 16:45:00

---
 tex/context/base/mkii/cont-new.mkii                |   2 +-
 tex/context/base/mkii/context.mkii                 |   2 +-
 tex/context/base/mkiv/cont-new.mkiv                |   2 +-
 tex/context/base/mkiv/context.mkiv                 |   2 +-
 tex/context/base/mkiv/font-ots.lua                 |   6 +-
 tex/context/base/mkiv/status-files.pdf             | Bin 26387 -> 26481 bytes
 tex/context/base/mkiv/status-lua.pdf               | Bin 253447 -> 253845 bytes
 tex/context/base/mkxl/cont-new.mkxl                |   2 +-
 tex/context/base/mkxl/context.mkxl                 |   2 +-
 tex/context/base/mkxl/font-con.lmt                 |  10 ++
 tex/context/base/mkxl/font-glf.mklx                |  24 +--
 tex/context/base/mkxl/font-imp-math.lmt            | 153 ++++++++++++++++++
 tex/context/base/mkxl/font-lib.mklx                |   2 +-
 tex/context/base/mkxl/font-mat.mklx                |  48 +++++-
 tex/context/base/mkxl/font-otj.lmt                 | 171 +++++++++------------
 tex/context/base/mkxl/font-ots.lmt                 |   6 +-
 tex/context/base/mkxl/font-pre.mkxl                |  36 +++++
 tex/context/base/mkxl/lpdf-lmt.lmt                 |   6 +-
 tex/context/base/mkxl/node-nut.lmt                 |   1 +
 tex/context/base/mkxl/strc-des.mklx                |   3 +-
 tex/context/base/mkxl/trac-vis.lmt                 |   6 +-
 tex/generic/context/luatex/luatex-fonts-merged.lua |   8 +-
 22 files changed, 351 insertions(+), 141 deletions(-)
 create mode 100644 tex/context/base/mkxl/font-imp-math.lmt

(limited to 'tex')

diff --git a/tex/context/base/mkii/cont-new.mkii b/tex/context/base/mkii/cont-new.mkii
index d7324dd0e..9343bef06 100644
--- a/tex/context/base/mkii/cont-new.mkii
+++ b/tex/context/base/mkii/cont-new.mkii
@@ -11,7 +11,7 @@
 %C therefore copyrighted by \PRAGMA. See mreadme.pdf for
 %C details.
 
-\newcontextversion{2020.12.28 01:37}
+\newcontextversion{2020.12.30 16:42}
 
 %D This file is loaded at runtime, thereby providing an
 %D excellent place for hacks, patches, extensions and new
diff --git a/tex/context/base/mkii/context.mkii b/tex/context/base/mkii/context.mkii
index 706d4230b..630e02b76 100644
--- a/tex/context/base/mkii/context.mkii
+++ b/tex/context/base/mkii/context.mkii
@@ -20,7 +20,7 @@
 %D your styles an modules.
 
 \edef\contextformat {\jobname}
-\edef\contextversion{2020.12.28 01:37}
+\edef\contextversion{2020.12.30 16:42}
 
 %D For those who want to use this:
 
diff --git a/tex/context/base/mkiv/cont-new.mkiv b/tex/context/base/mkiv/cont-new.mkiv
index f1ef91312..c234af299 100644
--- a/tex/context/base/mkiv/cont-new.mkiv
+++ b/tex/context/base/mkiv/cont-new.mkiv
@@ -13,7 +13,7 @@
 
 % \normalend % uncomment this to get the real base runtime
 
-\newcontextversion{2020.12.28 01:37}
+\newcontextversion{2020.12.30 16:42}
 
 %D This file is loaded at runtime, thereby providing an excellent place for hacks,
 %D patches, extensions and new features. There can be local overloads in cont-loc
diff --git a/tex/context/base/mkiv/context.mkiv b/tex/context/base/mkiv/context.mkiv
index 3288402bb..b7a0b6f8d 100644
--- a/tex/context/base/mkiv/context.mkiv
+++ b/tex/context/base/mkiv/context.mkiv
@@ -45,7 +45,7 @@
 %D {YYYY.MM.DD HH:MM} format.
 
 \edef\contextformat {\jobname}
-\edef\contextversion{2020.12.28 01:37}
+\edef\contextversion{2020.12.30 16:42}
 
 %D Kind of special:
 
diff --git a/tex/context/base/mkiv/font-ots.lua b/tex/context/base/mkiv/font-ots.lua
index 617c249b3..1f4806ee2 100644
--- a/tex/context/base/mkiv/font-ots.lua
+++ b/tex/context/base/mkiv/font-ots.lua
@@ -1532,7 +1532,8 @@ function chainprocs.gsub_ligature(head,start,stop,dataset,sequence,currentlookup
 end
 
 function chainprocs.gpos_single(head,start,stop,dataset,sequence,currentlookup,rlmode,skiphash,chainindex)
-    if has_glyph_option(start,no_right_kern_code) then
+    -- we actually should check no_left_kern_code with next
+    if not has_glyph_option(start,no_right_kern_code) then
         local mapping = currentlookup.mapping
         if mapping == nil then
             mapping = getmapping(dataset,sequence,currentlookup)
@@ -1561,7 +1562,8 @@ function chainprocs.gpos_single(head,start,stop,dataset,sequence,currentlookup,r
 end
 
 function chainprocs.gpos_pair(head,start,stop,dataset,sequence,currentlookup,rlmode,skiphash,chainindex) -- todo: injections ?
-    if has_glyph_option(start,no_right_kern_code) then
+    -- we actually should check no_left_kern_code with next
+    if not has_glyph_option(start,no_right_kern_code) then
         local mapping = currentlookup.mapping
         if mapping == nil then
             mapping = getmapping(dataset,sequence,currentlookup)
diff --git a/tex/context/base/mkiv/status-files.pdf b/tex/context/base/mkiv/status-files.pdf
index fcdf903a0..a258dd735 100644
Binary files a/tex/context/base/mkiv/status-files.pdf and b/tex/context/base/mkiv/status-files.pdf differ
diff --git a/tex/context/base/mkiv/status-lua.pdf b/tex/context/base/mkiv/status-lua.pdf
index 126f254c3..ef505e334 100644
Binary files a/tex/context/base/mkiv/status-lua.pdf and b/tex/context/base/mkiv/status-lua.pdf differ
diff --git a/tex/context/base/mkxl/cont-new.mkxl b/tex/context/base/mkxl/cont-new.mkxl
index c972c07a0..d18fc6867 100644
--- a/tex/context/base/mkxl/cont-new.mkxl
+++ b/tex/context/base/mkxl/cont-new.mkxl
@@ -13,7 +13,7 @@
 
 % \normalend % uncomment this to get the real base runtime
 
-\newcontextversion{2020.12.28 01:37}
+\newcontextversion{2020.12.30 16:42}
 
 %D This file is loaded at runtime, thereby providing an excellent place for hacks,
 %D patches, extensions and new features. There can be local overloads in cont-loc
diff --git a/tex/context/base/mkxl/context.mkxl b/tex/context/base/mkxl/context.mkxl
index 80bbe9777..9b69a436c 100644
--- a/tex/context/base/mkxl/context.mkxl
+++ b/tex/context/base/mkxl/context.mkxl
@@ -29,7 +29,7 @@
 %D {YYYY.MM.DD HH:MM} format.
 
 \immutable\edef\contextformat {\jobname}
-\immutable\edef\contextversion{2020.12.28 01:37}
+\immutable\edef\contextversion{2020.12.30 16:42}
 
 %overloadmode 1 % check frozen / warning
 %overloadmode 2 % check frozen / error
diff --git a/tex/context/base/mkxl/font-con.lmt b/tex/context/base/mkxl/font-con.lmt
index f7a725160..248bf9ec0 100644
--- a/tex/context/base/mkxl/font-con.lmt
+++ b/tex/context/base/mkxl/font-con.lmt
@@ -480,6 +480,16 @@ function constructors.scale(tfmdata,specification)
         properties.hasmath      = true
         target.nomath           = false
         target.MathConstants    = target.mathparameters
+
+        target.compactmath                 = true
+        target.textscale                   = parameters.textscale
+        target.scriptscale                 = parameters.scriptscale
+        target.scriptscriptscale           = parameters.scriptscriptscale
+
+        targetparameters.textscale         = parameters.textscale
+        targetparameters.scriptscale       = parameters.scriptscale
+        targetparameters.scriptscriptscale = parameters.scriptscriptscale
+
     else
         properties.hasmath      = false
         target.nomath           = true
diff --git a/tex/context/base/mkxl/font-glf.mklx b/tex/context/base/mkxl/font-glf.mklx
index c1fbfcdaa..125acb29b 100644
--- a/tex/context/base/mkxl/font-glf.mklx
+++ b/tex/context/base/mkxl/font-glf.mklx
@@ -56,11 +56,6 @@
       \glyphyscale\bodyglyphscale
       \the\everybodyfont}}
 
-\newtoks\everyenableautoglyphscaling
-
-\permanent\protected\def\enableautoglyphscaling
-  {\the\everyenableautoglyphscaling}
-
 \def\font_helpers_set_glyph_scale_by_size#fontsize%  gets character (x xx a etc)
   {\glyphxscale\numexpr\numericscale
           \ifcsname\??fontenvironments\fontclass\fontbody#fontsize\endcsname
@@ -162,12 +157,17 @@
      \fi
    \fi}
 
-\appendtoks
-    \let\font_helpers_set_current_font_alternative_size      \font_helpers_set_current_font_alternative_size_g
-    \let\font_helpers_set_current_font_size                  \font_helpers_set_current_font_size_g
-    \let\font_helpers_set_current_font_style_size            \font_helpers_set_current_font_style_size_g
-    \let\font_helpers_set_current_font_style_alternative_size\font_helpers_set_current_font_style_alternative_size_g
-    \let\font_helpers_set_current_font_xxx_alternative       \font_helpers_set_current_font_xxx_alternative_g
-\to \everyenableautoglyphscaling
+% \newtoks\everyenableautoglyphscaling
+%
+% \permanent\protected\def\enableautoglyphscaling
+%   {\the\everyenableautoglyphscaling}
+%
+% \appendtoks
+%     \let\font_helpers_set_current_font_alternative_size      \font_helpers_set_current_font_alternative_size_g
+%     \let\font_helpers_set_current_font_size                  \font_helpers_set_current_font_size_g
+%     \let\font_helpers_set_current_font_style_size            \font_helpers_set_current_font_style_size_g
+%     \let\font_helpers_set_current_font_style_alternative_size\font_helpers_set_current_font_style_alternative_size_g
+%     \let\font_helpers_set_current_font_xxx_alternative       \font_helpers_set_current_font_xxx_alternative_g
+% \to \everyenableautoglyphscaling
 
 \protect \endinput
diff --git a/tex/context/base/mkxl/font-imp-math.lmt b/tex/context/base/mkxl/font-imp-math.lmt
new file mode 100644
index 000000000..664a0c147
--- /dev/null
+++ b/tex/context/base/mkxl/font-imp-math.lmt
@@ -0,0 +1,153 @@
+if not modules then modules = { } end modules ['font-imp-math'] = {
+    version   = 1.001,
+    comment   = "companion to font-ini.mkiv and hand-ini.mkiv",
+    author    = "Hans Hagen, PRAGMA-ADE, Hasselt NL",
+    copyright = "PRAGMA ADE / ConTeXt Development Team",
+    license   = "see context related readme files"
+}
+
+
+local next, type, tonumber = next, type, tonumber
+
+local fonts              = fonts
+local helpers            = fonts.helpers
+local registerotffeature = fonts.handlers.otf.features.register
+
+local setmetatableindex  = table.setmetatableindex
+
+-- requested for latex but not supported unless really needed in context:
+--
+-- registerotffeature {
+--     name         = "ignoremathconstants",
+--     description  = "ignore math constants table",
+--     initializers = {
+--         base = function(tfmdata,value)
+--             if value then
+--                 tfmdata.mathparameters = nil
+--             end
+--         end
+--     }
+-- }
+
+-- tfmdata.properties.mathnolimitsmode = tonumber(value) or 0
+
+local splitter  = lpeg.splitat(",",tonumber)
+local lpegmatch = lpeg.match
+
+local function initialize(tfmdata,value)
+    local mathparameters = tfmdata.mathparameters
+    if mathparameters then
+        local sup, sub
+        if type(value) == "string" then
+            sup, sub = lpegmatch(splitter,value)
+            if not sup then
+                sub, sup = 0, 0
+            elseif not sub then
+                sub, sup = sup, 0
+            end
+        elseif type(value) == "number" then
+            sup, sub = 0, value
+        end
+        if sup then
+            mathparameters.NoLimitSupFactor = sup
+        end
+        if sub then
+            mathparameters.NoLimitSubFactor = sub
+        end
+    end
+end
+
+registerotffeature {
+    name         = "mathnolimitsmode",
+    description  = "influence nolimits placement",
+    initializers = {
+        base = initialize,
+        node = initialize,
+    }
+}
+
+local function initialize(tfmdata,value)
+    tfmdata.properties.nostackmath = value and true
+end
+
+registerotffeature {
+    name        = "nostackmath",
+    description = "disable math stacking mechanism",
+    initializers = {
+        base = initialize,
+        node = initialize,
+    }
+}
+
+-- A quick and dirty and low level implementation but okay for testing:
+
+local function manipulate(tfmdata,key,value)
+    if value then
+        local rawdata           = tfmdata.shared.rawdata
+        local rawresources      = rawdata and rawdata.resources
+        local rawfeatures       = rawresources and rawresources.features
+        local basesubstitutions = rawfeatures and rawfeatures.gsub
+        local sequences         = basesubstitutions and tfmdata.resources.sequences
+        if sequences then
+            local characters = tfmdata.characters
+            for s=1,#sequences do
+                local sequence = sequences[s]
+                local sfeatures = sequence.features
+                if sfeatures and sfeatures.ssty then
+                    local steps = sequence.steps
+                    for i=1,#steps do
+                        local coverage = steps[i].coverage
+                        if coverage then
+                            for textcode, v in next, coverage do
+                                local textdata = characters[textcode]
+                                if textdata then
+                                    local scriptcode       = v[1]
+                                    local scriptscriptcode = v[2]
+                                    local scriptdata       = characters[scriptcode]
+                                    local scriptscriptdata = characters[scriptscriptcode]
+                                    if scriptdata then
+                                        textdata.smaller = scriptcode
+                                    end
+                                    if scriptscriptdata then
+                                        scriptdata.smaller = scriptscriptcode
+                                    end
+                                end
+                            end
+                        end
+                    end
+                end
+            end
+        end
+    end
+end
+
+local function initialize(tfmdata,key,value)
+    if value then
+        local rawdata       = tfmdata.shared.rawdata
+        local rawresources  = rawdata and rawdata.resources
+        local mathconstants = rawresources.mathconstants
+        if mathconstants then
+            local parameters = tfmdata.parameters
+            -- will become configurable: 1000 = 100%
+            parameters.textscale         = 1000 -- math_scale_identity
+            parameters.scriptscale       = mathconstants.ScriptPercentScaleDown * 10
+            parameters.scriptscriptscale = mathconstants.ScriptScriptPercentScaleDown * 10
+        end
+    end
+end
+
+
+local specification = {
+    name         = "compactmath",
+    description  = "use one math font",
+    manipulators = {
+        base = manipulate,
+        node = manipulate,
+    },
+    initializers = {
+        base = initialize,
+        node = initialize,
+    }
+}
+
+registerotffeature(specification)
diff --git a/tex/context/base/mkxl/font-lib.mklx b/tex/context/base/mkxl/font-lib.mklx
index 940141fe7..00bddc2c3 100644
--- a/tex/context/base/mkxl/font-lib.mklx
+++ b/tex/context/base/mkxl/font-lib.mklx
@@ -100,7 +100,7 @@
 \registerctxluafile{font-imp-reorder}{}
 \registerctxluafile{font-imp-properties}{}
 \registerctxluafile{font-imp-unicode}{}
-\registerctxluafile{font-imp-math}{}
+\registerctxluafile{font-imp-math}{autosuffix}
 \registerctxluafile{font-imp-notused}{}
 \registerctxluafile{font-imp-effects}{}
 \registerctxluafile{font-imp-quality}{}
diff --git a/tex/context/base/mkxl/font-mat.mklx b/tex/context/base/mkxl/font-mat.mklx
index b3008b6be..b364e1520 100644
--- a/tex/context/base/mkxl/font-mat.mklx
+++ b/tex/context/base/mkxl/font-mat.mklx
@@ -122,6 +122,25 @@
    \let\fontbody\savedfontbody
    \setfalse\c_font_auto_size}
 
+\def\font_helpers_set_math_family_bold_indeed#mbfam#familytag#mrfam% \c_font_fam_mb \s!mb \c_font_fam_mr
+  {\let\savedfontclass\defaultfontclass
+   \let\defaultfontclass\fontclass % else truefontname falls back on the wrong one
+   \let\savedfontbody\fontbody
+   \let\fontfamily#familytag%
+   \let\mathsizesuffix\mathscriptscriptsuffix\let\fontface\!!plusthree
+   \font_helpers_set_math_family_bold_a\scriptscriptfont#mbfam#mrfam% defines
+   \font_helpers_set_math_family_bold_a\scriptscriptfont#mbfam#mrfam% enables
+   \let\mathsizesuffix\mathscriptsuffix      \let\fontface\!!plustwo
+   \font_helpers_set_math_family_bold_a\scriptfont      #mbfam#mrfam% defines
+   \font_helpers_set_math_family_bold_a\scriptfont      #mbfam#mrfam% enables
+   \let\mathsizesuffix\mathtextsuffix        \let\fontface\!!plusone
+   \font_helpers_set_math_family_bold_a\textfont        #mbfam#mrfam% defines
+   \font_helpers_set_math_family_bold_a\textfont        #mbfam#mrfam% enables
+   \let\mathsizesuffix\empty                 \let\fontface\!!zerocount
+   \let\fontbody\savedfontbody
+   \let\defaultfontclass\savedfontclass
+   \setfalse\c_font_auto_size}
+
 \def\font_helpers_set_math_family_bold_a#font#mbfam#mrfam%
   {\ifcsname\??fontinstanceready\fontclass-\fontbody-\s!mm-\fontfamily-\fontsize\endcsname \setfalse\c_font_auto_size
      \lastnamedcs #font#mbfam\font \orelse
@@ -130,20 +149,30 @@
      #font#mbfam#font#mrfam%
    \fi}
 
-\def\font_helpers_set_math_family_bold_indeed#mbfam#familytag#mrfam% \c_font_fam_mb \s!mb \c_font_fam_mr
+\def\font_helpers_set_math_family_indeed_compact#mrtag#family% \fontface etc are also used later on
+  {\let\savedfontbody\fontbody
+   \let\fontfamily#family%
+   % the order is important as we depend on known id's when completing fonts
+   % enabling is needed when we have fallbacks which spoils the families
+   \let\mathsizesuffix\mathtextsuffix        \let\fontface\!!plusone
+   \font_helpers_set_math_family_a\textfont        #mrtag\font % defines
+   \font_helpers_set_math_family_a\textfont        #mrtag\font % enables
+                                  \scriptfont      #mrtag\font % reuses
+                                  \scriptscriptfont#mrtag\font % reuses
+   \let\mathsizesuffix\empty                 \let\fontface\!!zerocount
+   \let\fontbody\savedfontbody
+   \setfalse\c_font_auto_size}
+
+\def\font_helpers_set_math_family_bold_indeed_compact#mbfam#familytag#mrfam% \c_font_fam_mb \s!mb \c_font_fam_mr
   {\let\savedfontclass\defaultfontclass
    \let\defaultfontclass\fontclass % else truefontname falls back on the wrong one
    \let\savedfontbody\fontbody
    \let\fontfamily#familytag%
-   \let\mathsizesuffix\mathscriptscriptsuffix\let\fontface\!!plusthree
-   \font_helpers_set_math_family_bold_a\scriptscriptfont#mbfam#mrfam% defines
-   \font_helpers_set_math_family_bold_a\scriptscriptfont#mbfam#mrfam% enables
-   \let\mathsizesuffix\mathscriptsuffix      \let\fontface\!!plustwo
-   \font_helpers_set_math_family_bold_a\scriptfont      #mbfam#mrfam% defines
-   \font_helpers_set_math_family_bold_a\scriptfont      #mbfam#mrfam% enables
    \let\mathsizesuffix\mathtextsuffix        \let\fontface\!!plusone
    \font_helpers_set_math_family_bold_a\textfont        #mbfam#mrfam% defines
    \font_helpers_set_math_family_bold_a\textfont        #mbfam#mrfam% enables
+                                       \scriptfont      #mbfam\scriptfont      #mrfam % reuses
+                                       \scriptscriptfont#mbfam\scriptscriptfont#mrfam % reuses
    \let\mathsizesuffix\empty                 \let\fontface\!!zerocount
    \let\fontbody\savedfontbody
    \let\defaultfontclass\savedfontclass
@@ -212,6 +241,11 @@
    \scriptfont      #fam\csname\??fontinstanceclass\fontclass-\fontbody-\s!mm-#familytag-\fontsize-2\endcsname
    \textfont        #fam\v_font_math_one}
 
+\def\font_helpers_preset_math_family_indeed_changed_compact#fam#familytag%
+  {\scriptscriptfont#fam\v_font_math_one
+   \scriptfont      #fam\v_font_math_one
+   \textfont        #fam\v_font_math_one}
+
 \let\font_helpers_reset_fontclass_math_families\gobbleoneargument
 
 %D It would be nice if characters could be defined in a neutral way (say fam 255)
diff --git a/tex/context/base/mkxl/font-otj.lmt b/tex/context/base/mkxl/font-otj.lmt
index d408babeb..15a78d122 100644
--- a/tex/context/base/mkxl/font-otj.lmt
+++ b/tex/context/base/mkxl/font-otj.lmt
@@ -100,6 +100,7 @@ local setkern            = nuts.setkern
 local setlink            = nuts.setlink
 local setwidth           = nuts.setwidth
 local getwidth           = nuts.getwidth
+local setadvance         = nuts.setadvance
 
 local nextchar           = nuts.traversers.char
 local nextglue           = nuts.traversers.glue
@@ -113,6 +114,7 @@ local fontkern           = nuts.pool and nuts.pool.fontkern
 local italickern         = nuts.pool and nuts.pool.italickern
 
 local useitalickerns     = false -- context only
+local useadvance         = false
 
 directives.register("fonts.injections.useitalics", function(v)
     if v then
@@ -121,6 +123,10 @@ directives.register("fonts.injections.useitalics", function(v)
     useitalickerns = v
 end)
 
+registerdirective("fonts.injections.method", function(v)
+    useadvance = v == "advance"
+end)
+
 function injections.installnewkern() end -- obsolete
 
 local nofregisteredkerns     = 0
@@ -620,7 +626,7 @@ local function inject_kerns_only(head,where)
     local prev        = nil
     local next        = nil
     local prevdisc    = nil
- -- local prevglyph   = nil
+-- local prevglyph   = nil
     local pre         = nil -- saves a lookup
     local post        = nil -- saves a lookup
     local replace     = nil -- saves a lookup
@@ -637,15 +643,19 @@ local function inject_kerns_only(head,where)
                     -- left|glyph|right
                     local leftkern = i.leftkern
                     if leftkern and leftkern ~= 0 then
-leftkern = leftkern * getxscale(current)
-                        if prev and getid(prev) == glue_code then
-                            if useitalickerns then
-                                head = insert_node_before(head,current,italickern(leftkern))
+                        if useadvance then
+                            setadvance(current,leftkern,0)
+                        else
+                            leftkern = leftkern * getxscale(current)
+                            if prev and getid(prev) == glue_code then
+                                if useitalickerns then
+                                    head = insert_node_before(head,current,italickern(leftkern))
+                                else
+                                    setwidth(prev, getwidth(prev) + leftkern)
+                                end
                             else
-                                setwidth(prev, getwidth(prev) + leftkern)
+                                head = insert_node_before(head,current,fontkern(leftkern))
                             end
-                        else
-                            head = insert_node_before(head,current,fontkern(leftkern))
                         end
                     end
                 end
@@ -656,9 +666,13 @@ leftkern = leftkern * getxscale(current)
                         if i then
                             local leftkern = i.leftkern
                             if leftkern and leftkern ~= 0 then
-leftkern = leftkern * getxscale(current)
-                                setlink(posttail,fontkern(leftkern))
-                                done = true
+                                if useadvance then
+                                    setadvance(posttail,0,leftkern)
+                                else
+                                    leftkern = leftkern * getxscale(current)
+                                    setlink(posttail,fontkern(leftkern))
+                                    done = true
+                                end
                             end
                         end
                     end
@@ -667,9 +681,13 @@ leftkern = leftkern * getxscale(current)
                         if i then
                             local leftkern = i.leftkern
                             if leftkern and leftkern ~= 0 then
-leftkern = leftkern * getxscale(current)
-                                setlink(replacetail,fontkern(leftkern))
-                                done = true
+                                if useadvance then
+                                    setadvance(replacetail,0,leftkern)
+                                else
+                                    leftkern = leftkern * getxscale(current)
+                                    setlink(replacetail,fontkern(leftkern))
+                                    done = true
+                                end
                             end
                         end
                     else
@@ -678,9 +696,13 @@ leftkern = leftkern * getxscale(current)
                             -- glyph|disc|glyph (special case)
                             local leftkern = i.leftkern
                             if leftkern and leftkern ~= 0 then
-leftkern = leftkern * getxscale(current)
-                                replace = fontkern(leftkern)
-                                done    = true
+                             -- if useadvance then
+                             --     add zwj with offset
+                             -- else
+                                    leftkern = leftkern * getxscale(current)
+                                    replace = fontkern(leftkern)
+                                    done    = true
+                             -- end
                             end
                         end
                     end
@@ -690,11 +712,11 @@ leftkern = leftkern * getxscale(current)
                 end
             end
             prevdisc  = nil
-         -- prevglyph = current
+        -- prevglyph = current
         elseif char == false then
             -- other font
             prevdisc  = nil
-         -- prevglyph = current
+        -- prevglyph = current
         elseif id == disc_code then
             pre, post, replace, pretail, posttail, replacetail = getdisc(current,true)
             local done = false
@@ -707,9 +729,13 @@ leftkern = leftkern * getxscale(current)
                         if i then
                             local leftkern = i.leftkern
                             if leftkern and leftkern ~= 0 then
-leftkern = leftkern * getxscale(n)
-                                pre  = insert_node_before(pre,n,fontkern(leftkern))
-                                done = true
+                                if useadvance then
+                                    setadvance(n,leftkern,0)
+                                else
+                                    leftkern = leftkern * getxscale(n)
+                                    pre  = insert_node_before(pre,n,fontkern(leftkern))
+                                    done = true
+                                end
                             end
                         end
                     end
@@ -724,9 +750,13 @@ leftkern = leftkern * getxscale(n)
                         if i then
                             local leftkern = i.leftkern
                             if leftkern and leftkern ~= 0 then
-leftkern = leftkern * getxscale(n)
-                                post = insert_node_before(post,n,fontkern(leftkern))
-                                done = true
+                                if useadvance then
+                                    setadvance(n,leftkern,0)
+                                else
+                                    leftkern = leftkern * getxscale(n)
+                                    post = insert_node_before(post,n,fontkern(leftkern))
+                                    done = true
+                                end
                             end
                         end
                     end
@@ -741,9 +771,13 @@ leftkern = leftkern * getxscale(n)
                         if i then
                             local leftkern = i.leftkern
                             if leftkern and leftkern ~= 0 then
-leftkern = leftkern * getxscale(n)
-                                replace = insert_node_before(replace,n,fontkern(leftkern))
-                                done    = true
+                                if useadvance then
+                                    setadvance(n,leftkern,0)
+                                else
+                                    leftkern = leftkern * getxscale(n)
+                                    replace = insert_node_before(replace,n,fontkern(leftkern))
+                                    done    = true
+                                end
                             end
                         end
                     end
@@ -752,10 +786,10 @@ leftkern = leftkern * getxscale(n)
             if done then
                 setdisc(current,pre,post,replace)
             end
-         -- prevglyph = nil
+        -- prevglyph = nil
             prevdisc  = current
         else
-         -- prevglyph = nil
+        -- prevglyph = nil
             prevdisc  = nil
         end
         prev    = current
@@ -904,18 +938,18 @@ leftkern = leftkern * getxscale(current)
                     if p then
                         local i = p.injections or p.preinjections
                         if i then
-                            local yoffset = i.yoffset
+                            local yoffset   = i.yoffset
+                            local leftkern  = i.leftkern
+                            local rightkern = i.rightkern
                             if yoffset and yoffset ~= 0 then
 yoffset = yoffset * getyscale(current)
                                 setoffsets(n,false,yoffset)
                             end
-                            local leftkern = i.leftkern
                             if leftkern and leftkern ~= 0 then
 leftkern = leftkern * getxscale(n)
                                 pre  = insert_node_before(pre,n,fontkern(leftkern))
                                 done = true
                             end
-                            local rightkern = i.rightkern
                             if rightkern and rightkern ~= 0 then
 rightkern = rightkern * getxscale(n)
                                 insert_node_after(pre,n,fontkern(rightkern))
@@ -932,18 +966,18 @@ rightkern = rightkern * getxscale(n)
                     if p then
                         local i = p.injections or p.postinjections
                         if i then
-                            local yoffset = i.yoffset
+                            local yoffset   = i.yoffset
+                            local leftkern  = i.leftkern
+                            local rightkern = i.rightkern
                             if yoffset and yoffset ~= 0 then
 yoffset = yoffset * getyscale(current)
                                 setoffsets(n,false,yoffset)
                             end
-                            local leftkern = i.leftkern
                             if leftkern and leftkern ~= 0 then
 leftkern = leftkern * getxscale(n)
                                 post = insert_node_before(post,n,fontkern(leftkern))
                                 done = true
                             end
-                            local rightkern = i.rightkern
                             if rightkern and rightkern ~= 0 then
 rightkern = rightkern * getxscale(n)
                                 insert_node_after(post,n,fontkern(rightkern))
@@ -960,18 +994,18 @@ rightkern = rightkern * getxscale(n)
                     if p then
                         local i = p.injections or p.replaceinjections
                         if i then
-                            local yoffset = i.yoffset
+                            local yoffset   = i.yoffset
+                            local leftkern  = i.leftkern
+                            local rightkern = i.rightkern
                             if yoffset and yoffset ~= 0 then
 yoffset = yoffset * getyscale(current)
                                 setoffsets(n,false,yoffset)
                             end
-                            local leftkern = i.leftkern
                             if leftkern and leftkern ~= 0 then
 leftkern = leftkern * getxscale(n)
                                 replace = insert_node_before(replace,n,fontkern(leftkern))
                                 done    = true
                             end
-                            local rightkern = i.rightkern
                             if rightkern and rightkern ~= 0 then
 rightkern = rightkern * getxscale(n)
                                 insert_node_after(replace,n,fontkern(rightkern))
@@ -1071,8 +1105,6 @@ local function inject_everything(head,where)
     local marks         = { }
     local nofmarks      = 0
     --
- -- local applyfix      = hascursives and fix_cursive_marks
-    --
     -- move out
     --
     local function processmark(p,n,pn) -- p = basenode
@@ -1159,71 +1191,14 @@ oy = oy * getyscale(p)
             showoffset(n,true)
         end
     end
-    -- begin of temp fix --
- -- local base = nil -- bah, some arabic fonts have no mark anchoring
-    -- end of temp fix --
     while current do
         local next, char, id = isnextchar(current)
         if char then
             local p = rawget(properties,current)
-            -- begin of temp fix --
-         -- if applyfix then
-         --     if not p then
-         --         local m = fontmarks[getfont(current)]
-         --         if m and m[char] then
-         --             if base then
-         --                 p = { injections = { markbasenode = base } }
-         --                 nofmarks = nofmarks + 1
-         --                 marks[nofmarks] = current
-         --                 properties[current] = p
-         --                 hasmarks = true
-         --             end
-         --         else
-         --             base = current
-         --         end
-         --     end
-         -- end
-            -- end of temp fix
             if p then
                 local i = p.injections
-                -- begin of temp fix --
-             -- if applyfix then
-             --     if not i then
-             --         local m = fontmarks[getfont(current)]
-             --         if m and m[char] then
-             --             if base then
-             --                 i = { markbasenode = base }
-             --                 nofmarks = nofmarks + 1
-             --                 marks[nofmarks] = current
-             --                 p.injections = i
-             --                 hasmarks = true
-             --             end
-             --         else
-             --             base = current
-             --         end
-             --     end
-             -- end
-                -- end of temp fix --
                 if i then
                     local pm = i.markbasenode
-                    -- begin of temp fix --
-                 -- if applyfix then
-                 --     if not pm then
-                 --         local m = fontmarks[getfont(current)]
-                 --         if m and m[char] then
-                 --             if base then
-                 --                 pm = base
-                 --                 i.markbasenode = pm
-                 --                 hasmarks = true
-                 --             end
-                 --         else
-                 --             base = current
-                 --         end
-                 --     else
-                 --         base = current
-                 --     end
-                 -- end
-                    -- end of temp fix --
                     if pm then
                         nofmarks = nofmarks + 1
                         marks[nofmarks] = current
diff --git a/tex/context/base/mkxl/font-ots.lmt b/tex/context/base/mkxl/font-ots.lmt
index 478dc700d..06268206f 100644
--- a/tex/context/base/mkxl/font-ots.lmt
+++ b/tex/context/base/mkxl/font-ots.lmt
@@ -1571,7 +1571,8 @@ function chainprocs.gsub_ligature(head,start,stop,dataset,sequence,currentlookup
 end
 
 function chainprocs.gpos_single(head,start,stop,dataset,sequence,currentlookup,rlmode,skiphash,chainindex)
-    if has_glyph_option(start,no_right_kern_code) then
+    -- we actually should check no_left_kern_code with next
+    if not has_glyph_option(start,no_right_kern_code) then
         local mapping = currentlookup.mapping
         if mapping == nil then
             mapping = getmapping(dataset,sequence,currentlookup)
@@ -1600,7 +1601,8 @@ function chainprocs.gpos_single(head,start,stop,dataset,sequence,currentlookup,r
 end
 
 function chainprocs.gpos_pair(head,start,stop,dataset,sequence,currentlookup,rlmode,skiphash,chainindex) -- todo: injections ?
-    if has_glyph_option(start,no_right_kern_code) then
+    -- we actually should check no_left_kern_code with next
+    if not has_glyph_option(start,no_right_kern_code) then
         local mapping = currentlookup.mapping
         if mapping == nil then
             mapping = getmapping(dataset,sequence,currentlookup)
diff --git a/tex/context/base/mkxl/font-pre.mkxl b/tex/context/base/mkxl/font-pre.mkxl
index 8468fbbd7..ee3159b1b 100644
--- a/tex/context/base/mkxl/font-pre.mkxl
+++ b/tex/context/base/mkxl/font-pre.mkxl
@@ -935,6 +935,42 @@
 
 \popoverloadmode
 
+% experiment:
+
+\startsetups experiment:math:fonts:compact
+    \let\font_helpers_set_math_family_indeed           \font_helpers_set_math_family_indeed_compact
+    \let\font_helpers_set_math_family_bold_indeed      \font_helpers_set_math_family_bold_indeed_compact
+    \let\font_helpers_preset_math_family_indeed_changed\font_helpers_preset_math_family_indeed_changed_compact
+
+    \definefontfeature[math-text]            [mathematics]    [compactmath=yes]
+    \definefontfeature[math-script]          [mathematics]    [compactmath=yes]
+    \definefontfeature[math-scriptscript]    [mathematics]    [compactmath=yes]
+    \definefontfeature[math-text-l2r]        [mathematics-l2r][compactmath=yes]
+    \definefontfeature[math-script-l2r]      [mathematics-l2r][compactmath=yes]
+    \definefontfeature[math-scriptscript-l2r][mathematics-l2r][compactmath=yes]
+    \definefontfeature[math-text-r2l]        [mathematics-r2l][compactmath=yes]
+    \definefontfeature[math-script-r2l]      [mathematics-r2l][compactmath=yes]
+    \definefontfeature[math-scriptscript-r2l][mathematics-r2l][compactmath=yes]
+\stopsetups
+
+\installtexexperiment
+  {math.fonts.compact}
+  {\directsetup{experiment:math:fonts:compact}}
+  {}
+
+\startsetups experiment:text:fonts:compact
+    \let\font_helpers_set_current_font_alternative_size      \font_helpers_set_current_font_alternative_size_g
+    \let\font_helpers_set_current_font_size                  \font_helpers_set_current_font_size_g
+    \let\font_helpers_set_current_font_style_size            \font_helpers_set_current_font_style_size_g
+    \let\font_helpers_set_current_font_style_alternative_size\font_helpers_set_current_font_style_alternative_size_g
+    \let\font_helpers_set_current_font_xxx_alternative       \font_helpers_set_current_font_xxx_alternative_g
+\stopsetups
+
+\installtexexperiment
+  {text.fonts.compact}
+  {\directsetup{experiment:text:fonts:compact}}
+  {}
+
 \protect \endinput
 
 % LM math vs CM math (analysis by Taco):
diff --git a/tex/context/base/mkxl/lpdf-lmt.lmt b/tex/context/base/mkxl/lpdf-lmt.lmt
index 76b7a025e..ce2de4f89 100644
--- a/tex/context/base/mkxl/lpdf-lmt.lmt
+++ b/tex/context/base/mkxl/lpdf-lmt.lmt
@@ -640,8 +640,7 @@ local flushcharacter  do
                 move = calc_pdfpos(pos_h,pos_v)
             end
             if move then
-                local d = tj_delta * scalefactor
- / f_x_scale
+                local d = tj_delta * scalefactor / f_x_scale
                 if d <= -0.5 or d >= 0.5 then
                     if mode == "char" then
                         end_charmode()
@@ -656,8 +655,7 @@ local flushcharacter  do
             begin_charmode()
         end
 
-        cw = cw + naturalwidth[char] * tmef
-* f_x_scale
+        cw = cw + naturalwidth[char] * tmef * f_x_scale
 
         local index = data.index or char
 
diff --git a/tex/context/base/mkxl/node-nut.lmt b/tex/context/base/mkxl/node-nut.lmt
index 6f1afe74c..7b36d1752 100644
--- a/tex/context/base/mkxl/node-nut.lmt
+++ b/tex/context/base/mkxl/node-nut.lmt
@@ -157,6 +157,7 @@ local nuts = {
     remove                  = d_remove_node,
     reverse                 = direct.reverse,
     set_attribute           = direct.set_attribute,
+    setadvance              = direct.setadvance,
     setattr                 = direct.set_attribute,
     setattrs                = direct.set_attributes,
     setattributelist        = direct.setattributelist,
diff --git a/tex/context/base/mkxl/strc-des.mklx b/tex/context/base/mkxl/strc-des.mklx
index dce8f0537..d3fa6bb4e 100644
--- a/tex/context/base/mkxl/strc-des.mklx
+++ b/tex/context/base/mkxl/strc-des.mklx
@@ -119,8 +119,7 @@
 %    \resetdescriptionparameter\c!referencetext}
 
 \protected\def\strc_descriptions_start_setups[#1]%
-  {\setfalse\c_strc_constructions_title_state
-   \strc_constructions_register[][\c!label={\descriptionparameter\c!text},\c!reference=,\c!title=,\c!bookmark=,\c!list=,\c!referencetext=,#1]%
+  {\strc_constructions_register[][\c!label={\descriptionparameter\c!text},\c!reference=,\c!title=,\c!bookmark=,\c!list=,\c!referencetext=,#1]%
    \csname\??constructionstarthandler\currentconstructionhandler\endcsname}
 
 \protected\tolerant\def\strc_descriptions_start_title[#1]#*#=%
diff --git a/tex/context/base/mkxl/trac-vis.lmt b/tex/context/base/mkxl/trac-vis.lmt
index 29cdbaeda..2be9529a9 100644
--- a/tex/context/base/mkxl/trac-vis.lmt
+++ b/tex/context/base/mkxl/trac-vis.lmt
@@ -177,9 +177,9 @@ local preset_all    = preset_makeup
                     + modes.dir + modes.whatsit
 
 function visualizers.setfont(id)
-    usedfont  = id or current_font()
-    exheight  = exheights[usedfont]
-    emwidth   = emwidths[usedfont]
+    usedfont = id or current_font()
+    exheight = exheights[usedfont]
+    emwidth  = emwidths[usedfont]
 end
 
 -- we can preset a bunch of bits
diff --git a/tex/generic/context/luatex/luatex-fonts-merged.lua b/tex/generic/context/luatex/luatex-fonts-merged.lua
index 42894efdb..0b220327c 100644
--- a/tex/generic/context/luatex/luatex-fonts-merged.lua
+++ b/tex/generic/context/luatex/luatex-fonts-merged.lua
@@ -1,6 +1,6 @@
 -- merged file : c:/data/develop/context/sources/luatex-fonts-merged.lua
 -- parent file : c:/data/develop/context/sources/luatex-fonts.lua
--- merge date  : 2020-12-28 01:37
+-- merge date  : 2020-12-30 16:42
 
 do -- begin closure to overcome local limits and interference
 
@@ -27713,7 +27713,7 @@ function chainprocs.gsub_ligature(head,start,stop,dataset,sequence,currentlookup
  return head,start,false,0,false
 end
 function chainprocs.gpos_single(head,start,stop,dataset,sequence,currentlookup,rlmode,skiphash,chainindex)
- if has_glyph_option(start,no_right_kern_code) then
+ if not has_glyph_option(start,no_right_kern_code) then
   local mapping=currentlookup.mapping
   if mapping==nil then
    mapping=getmapping(dataset,sequence,currentlookup)
@@ -27740,8 +27740,8 @@ function chainprocs.gpos_single(head,start,stop,dataset,sequence,currentlookup,r
  end
  return head,start,false
 end
-function chainprocs.gpos_pair(head,start,stop,dataset,sequence,currentlookup,rlmode,skiphash,chainindex) 
- if has_glyph_option(start,no_right_kern_code) then
+function chainprocs.gpos_pair(head,start,stop,dataset,sequence,currentlookup,rlmode,skiphash,chainindex)
+ if not has_glyph_option(start,no_right_kern_code) then
   local mapping=currentlookup.mapping
   if mapping==nil then
    mapping=getmapping(dataset,sequence,currentlookup)
-- 
cgit v1.2.3