summaryrefslogtreecommitdiff
path: root/tex/context/base/mkxl/math-act.lmt
diff options
context:
space:
mode:
Diffstat (limited to 'tex/context/base/mkxl/math-act.lmt')
-rw-r--r--tex/context/base/mkxl/math-act.lmt312
1 files changed, 273 insertions, 39 deletions
diff --git a/tex/context/base/mkxl/math-act.lmt b/tex/context/base/mkxl/math-act.lmt
index d1a6b80e1..4cfad32fe 100644
--- a/tex/context/base/mkxl/math-act.lmt
+++ b/tex/context/base/mkxl/math-act.lmt
@@ -64,35 +64,41 @@ function fonts.constructors.assignmathparameters(original,target) -- wrong way a
end
end
+local undefined <const> = 0x3FFFFFFF -- maxdimen or undefined_math_parameter
+
function mathematics.initializeparameters(target,original)
local mathparameters = original.mathparameters
if mathparameters and next(mathparameters) then
mathparameters = mathematics.dimensions(mathparameters)
- if not mathparameters.PrimeRaisePercent then mathparameters.PrimeRaisePercent = 25 end
- if not mathparameters.PrimeShiftUp then mathparameters.PrimeShiftUp = mathparameters.SuperscriptShiftUp end
- if not mathparameters.PrimeBaselineDropMax then mathparameters.PrimeBaselineDropMax = mathparameters.SuperscriptBaselineDropMax end
- if not mathparameters.PrimeShiftUpCramped then mathparameters.PrimeShiftUpCramped = mathparameters.SuperscriptShiftUpCramped end
- if not mathparameters.PrimeSpaceAfter then mathparameters.PrimeSpaceAfter = 0 end
- if not mathparameters.PrimeWidthPercent then mathparameters.PrimeWidthPercent = 50 end
- if not mathparameters.SpaceBeforeScript then mathparameters.SpaceBeforeScript = mathparameters.SpaceAfterScript end
- if not mathparameters.NoLimitSupFactor then mathparameters.NoLimitSupFactor = 0 end
- if not mathparameters.NoLimitSubFactor then mathparameters.NoLimitSubFactor = 0 end
- if not mathparameters.AccentTopShiftUp then mathparameters.AccentTopShiftUp = 0 end
- if not mathparameters.AccentBottomShiftDown then mathparameters.AccentBottomShiftDown = 0 end
- if not mathparameters.FlattenedAccentTopShiftUp then mathparameters.AccentTopShiftUp = 0 end
- if not mathparameters.FlattenedAccentBottomShiftDown then mathparameters.AccentBottomShiftDown = 0 end
- if not mathparameters.AccentBaseDepth then mathparameters.AccentBaseDepth = 0 end
- if not mathparameters.AccentFlattenedBaseDepth then mathparameters.AccentFlattenedBaseDepth = 0 end
- if not mathparameters.AccentTopOvershoot then mathparameters.AccentTopOvershoot = 0 end
- if not mathparameters.AccentBottomOvershoot then mathparameters.AccentBottomOvershoot = 0 end
- if not mathparameters.AccentSuperscriptDrop then mathparameters.AccentSuperscriptDrop = 0 end
- if not mathparameters.AccentSuperscriptPercent then mathparameters.AccentSuperscriptPercent = 0 end
- if not mathparameters.DelimiterPercent then mathparameters.DelimiterPercent = 100 end
- if not mathparameters.DelimiterShortfall then mathparameters.DelimiterShortfall = 0 end
- --
- -- we don't want to reset that each time .. but then we also can't show what the value was
--
- -- mathparameters.RadicalDegreeBefore = 0
+ if not mathparameters.MinConnectorOverlap then mathparameters.MinConnectorOverlap = undefined end
+ if not mathparameters.SubscriptShiftDownWithSuperscript then mathparameters.SubscriptShiftDownWithSuperscript = undefined end -- a tex one
+ if not mathparameters.FractionDelimiterSize then mathparameters.FractionDelimiterSize = undefined end
+ if not mathparameters.FractionDelimiterDisplayStyleSize then mathparameters.FractionDelimiterDisplayStyleSize = undefined end
+ if not mathparameters.SkewedDelimiterTolerance then mathparameters.SkewedDelimiterTolerance = undefined end
+ -- some more can be undefined:
+ if not mathparameters.PrimeRaisePercent then mathparameters.PrimeRaisePercent = 50 end
+ if not mathparameters.PrimeRaiseComposedPercent then mathparameters.PrimeRaiseComposedPercent = 25 end
+ if not mathparameters.PrimeShiftUp then mathparameters.PrimeShiftUp = mathparameters.SuperscriptShiftUp end
+ if not mathparameters.PrimeBaselineDropMax then mathparameters.PrimeBaselineDropMax = mathparameters.SuperscriptBaselineDropMax end
+ if not mathparameters.PrimeShiftUpCramped then mathparameters.PrimeShiftUpCramped = mathparameters.SuperscriptShiftUpCramped end
+ if not mathparameters.PrimeSpaceAfter then mathparameters.PrimeSpaceAfter = 0 end
+ if not mathparameters.PrimeWidthPercent then mathparameters.PrimeWidthPercent = 50 end
+ if not mathparameters.SpaceBeforeScript then mathparameters.SpaceBeforeScript = mathparameters.SpaceAfterScript end
+ if not mathparameters.NoLimitSupFactor then mathparameters.NoLimitSupFactor = 0 end
+ if not mathparameters.NoLimitSubFactor then mathparameters.NoLimitSubFactor = 0 end
+ if not mathparameters.AccentTopShiftUp then mathparameters.AccentTopShiftUp = 0 end
+ if not mathparameters.AccentBottomShiftDown then mathparameters.AccentBottomShiftDown = 0 end
+ if not mathparameters.FlattenedAccentTopShiftUp then mathparameters.AccentTopShiftUp = 0 end
+ if not mathparameters.FlattenedAccentBottomShiftDown then mathparameters.AccentBottomShiftDown = 0 end
+ if not mathparameters.AccentBaseDepth then mathparameters.AccentBaseDepth = 0 end
+ if not mathparameters.AccentFlattenedBaseDepth then mathparameters.AccentFlattenedBaseDepth = 0 end
+ if not mathparameters.AccentTopOvershoot then mathparameters.AccentTopOvershoot = 0 end
+ if not mathparameters.AccentBottomOvershoot then mathparameters.AccentBottomOvershoot = 0 end
+ if not mathparameters.AccentSuperscriptDrop then mathparameters.AccentSuperscriptDrop = 0 end
+ if not mathparameters.AccentSuperscriptPercent then mathparameters.AccentSuperscriptPercent = 0 end
+ if not mathparameters.DelimiterPercent then mathparameters.DelimiterPercent = 100 end
+ if not mathparameters.DelimiterShortfall then mathparameters.DelimiterShortfall = 0 end
--
target.mathparameters = mathparameters
end
@@ -109,6 +115,7 @@ local how = {
NoLimitSupFactor = "unscaled",
NoLimitSubFactor = "unscaled",
PrimeRaisePercent = "unscaled",
+ PrimeRaiseComposedPercent = "unscaled",
PrimeWidthPercent = "unscaled",
AccentTopOvershoot = "unscaled",
AccentBottomOvershoot = "unscaled",
@@ -246,7 +253,8 @@ mathematics.tweaks = mathtweaks
local function report_tweak(fmt,target,original,...)
if fmt then
- local metadata = original.shared.rawdata.metadata
+ local metadata = (original and original.shared.rawdata.metadata) or
+ (target and target .shared.rawdata.metadata)
local parameters = target.parameters
report_mathtweak(
"%a, size %p, math size %i, %s",
@@ -278,16 +286,17 @@ end
do
- local stepper = utilities.parsers.stepper
- local count = 0
- local splitter = lpeg.tsplitat(".")
- local toeffect = fonts.toeffect
+ local stepper = utilities.parsers.stepper
+ local count = 0
+ local splitter = lpeg.tsplitat(".")
+ local toeffect = fonts.toeffect
+ local privateslot = fonts.helpers.privateslot
local function adapt(list,target,original,targetcharacters,originalcharacters,k,v,compact,n)
k = mathgaps[k] or k
local character = targetcharacters[k]
if character then
- if not character.tweaked then
+ if not character.tweaked then -- todo: add a force
local t = type(v)
if t == "number" then
v = list[v]
@@ -337,6 +346,8 @@ do
if width and width ~= 0 then
if advancefactor then
character.advance = advancefactor * width
+ else
+ character.advance = width -- so advance is oldwidth
end
if widthfactor then
character.width = widthfactor * width
@@ -366,12 +377,23 @@ do
if anchorfactor then
character.topaccent = anchorfactor * (topaccent or width)
end
- -- todo: check once per tweak
- character.effect = toeffect(v)
+ -- begin experiment
+ local line = v.wline
+ if line then
+ local parameters = target.parameters
+ v.line = parameters.hfactor * line / parameters.units
+ end
+ -- end experiment
+ character.effect = toeffect(v) -- todo: move wline test inside here
+ -- begin experiment
+ v.line = line
+ -- end experiment
if trace_tweaking then
report_tweak("adapting dimensions of %U ",target,original,k)
end
- local smaller = originalcharacters[k].smaller
+ -- missing when private
+ local originaldata = originalcharacters[k] -- or targetcharacters[k]
+ local smaller = originaldata and originaldata.smaller
if compact and smaller and smaller ~= k then
adapt(list,target,original,targetcharacters,originalcharacters,smaller,v,compact,n+1)
end
@@ -474,7 +496,7 @@ do
if t == "number" then
adapt(list,target,original,targetcharacters,originalcharacters,k,v,compact,1)
elseif t == "string" then
- local d = detail(targetcharacters,k)
+ local d = privateslot(k) or detail(targetcharacters,k) -- watch the private here
local t = type(d)
if t == "table" then
for i=1,#d do
@@ -513,6 +535,14 @@ end
do
+ function mathtweaks.message(target,original,parameters)
+ report_mathtweak(parameters.text or "no message")
+ end
+
+end
+
+do
+
function mathtweaks.wipevariants(target,original,parameters)
local list = parameters.list
if list then
@@ -591,7 +621,7 @@ do
local originalcharacters = original.characters
local getsubstitution = fonts.handlers.otf.getsubstitution
local count = 0
- for k, v in sortedhash(list) do
+ for k, v in next, list do -- no need for sortedhash(list) unless we report
local sub = getsubstitution(original,k,v,true)
if sub then
targetcharacters[mathgaps[k] or k] = targetcharacters[mathgaps[sub] or sub]
@@ -611,6 +641,82 @@ end
do
+ -- maybe we'll have a different name
+
+ mathtweaks.subsets = {
+ acenorsuvxz = { 0x1D44E, 0x1D450, 0x1D452, 0x1D45B, 0x1D45C, 0x1D45F, 0x1D460, 0x1D462, 0x1D463, 0x1D465, 0x1D467 },
+ bhklt = { 0x1D44F, 0x1D455, 0x1D458, 0x1D459, 0x1D461 },
+ d = { 0x1D451 },
+ f = { 0x1D453 },
+ gjqy = { 0x1D454, 0x1D457, 0x1D45E, 0x1D466 },
+ i = { 0x1D456 },
+ mw = { 0x1D45A, 0x1D464},
+ p = { 0x1D45D },
+ }
+
+ function mathtweaks.kernpairs(target,original,parameters)
+ local list = parameters.list
+ if list then
+ local targetcharacters = target.characters
+ local originalcharacters = original.characters
+ local count = 0
+
+ local function add(v,n)
+ local chardata = targetcharacters[mathgaps[n] or n]
+ if chardata then
+ local width = chardata.width
+ if width then
+ local kerns = chardata.kerns or { }
+ for kk, vv in next, v do
+-- for kk, vv in sortedhash(v) do
+ stepper(kk,function(nn) -- todo: also make stepper accept a table
+ local t = mathgaps[nn] or nn
+ if t then
+ kerns[t] = vv * width
+ count = count + 1
+ end
+ end)
+ end
+ chardata.kerns = kerns
+ end
+ end
+ end
+
+ for k, v in next, list do -- no need for sortedhash(list) unless we report
+-- for k, v in sortedhash(list) do -- no need for sortedhash(list) unless we report
+ stepper(k,function(n) -- todo: also make stepper accept a table
+ add(v,n)
+ end)
+ end
+
+-- for k, v in next, list do -- no need for sortedhash(list) unless we report
+-- local chardata = targetcharacters[mathgaps[k] or k]
+-- if chardata then
+-- local width = chardata.width
+-- if width then
+-- local kerns = chardata.kerns or { }
+-- for kk, vv in next, v do
+-- local t = mathgaps[kk] or kk
+-- if t then
+-- kerns[t] = vv * width
+-- count = count + 1
+-- end
+-- end
+-- chardata.kerns = kerns
+-- end
+-- end
+-- end
+
+ if trace_tweaking and count > 0 then
+ report_mathtweak("%i kern pairs",count)
+ end
+ end
+ end
+
+end
+
+do
+
-- What a mess ... should be a different alphabet.
local function expand(target,original,list,selector,feature)
@@ -800,6 +906,118 @@ end
do
+ local copytable = table.copy
+ local nps = fonts.helpers.newprivateslot
+
+ local privates = {
+ [0x2212] = nps("unary minus"),
+ [0x002B] = nps("unary plus"),
+ [0x00B1] = nps("unary plus minus"),
+ [0x2213] = nps("unary minus plus"),
+ }
+
+ -- these are the values tested with texgyre-bonum
+
+ local predefined = {
+ ["unary minus"] = {
+ original = 0x2212,
+ extend = .5,
+ width = .5,
+ unicode = 0x002D, -- hyphen minus
+ },
+ ["unary plus"] = {
+ original = 0x002B,
+ extend = .5,
+ squeeze = .5,
+ width = .5,
+ height = .5,
+ yoffset = .2,
+ mode = 2,
+ wline = .5,
+ unicode = 0x002B,
+ },
+ ["unary plus minus"] = {
+ original = 0x00B1,
+ extend = .5,
+ squeeze = .5,
+ width = .5,
+ height = .5,
+ yoffset = .2,
+ mode = 2,
+ wline = .5,
+ },
+ ["unary minus plus"] = {
+ original = 0x2213,
+ extend = .5,
+ squeeze = .5,
+ width = .5,
+ height = .5,
+ yoffset = .2,
+ mode = 2,
+ wline = .5,
+ },
+ }
+
+ -- {
+ -- tweak = "addprivates",
+ -- list = {
+ -- -- for specific parameters see act file
+ -- ["unary minus"] = { preset = "unary minus" },
+ -- ["unary plus"] = { preset = "unary plus" },
+ -- ["unary plus minus"] = { preset = "unary plus minus" },
+ -- ["unary minus plus"] = { preset = "unary minus plus" },
+ -- },
+ -- },
+
+ function mathtweaks.addprivates(target,original,parameters)
+ local list = parameters.list or predefined
+ if list then
+ local targetcharacters = target.characters
+ local targetparameters = target.parameters
+ local originalcharacters = original.characters
+ local processedprivates = { }
+ for name, v in sortedhash(list) do
+ if type(v) == "table" then
+ local preset = v.preset
+ if preset then
+ local p = predefined[preset]
+ if p then
+ -- p = table.copy(p)
+ v = table.combine(p,v)
+ p.preset = nil
+ else
+ goto NEXT
+ end
+ end
+ local charslot = v.original
+ if charslot then
+ local chardata = targetcharacters[charslot]
+ if chardata then
+ local clonedata = copytable(chardata)
+ local cloneslot = nps(name)
+ local unicode = v.unicode or clonedata.unicode
+ clonedata.uncode = unicode
+ targetcharacters[cloneslot] = clonedata
+ if trace_tweaking then
+ report_tweak("cloning %a from %C into %U with tounicode %U",target,original,name,charslot,cloneslot,unicode)
+ end
+ end
+ processedprivates[name] = v
+ end
+ ::NEXT::
+ end
+ end
+ mathtweaks.dimensions(target,original,{
+ tweak = parameters.tweak,
+ list = processedprivates,
+ })
+ end
+ end
+
+end
+
+do
+
function mathtweaks.fixanchors(target,original,parameters)
local targetcharacters= target.characters
local factor = tonumber(parameters.factor) or 0
@@ -807,7 +1025,7 @@ do
for k, v in next, targetcharacters do
local a = v.topaccent
if a and a > 0 then
- v.topaccent = a * factor
+ v.topaccent = a * factor
end
end
end
@@ -1471,7 +1689,11 @@ local function applytweaks(when,target,original)
if type(tweak) == "table" then
local action = mathtweaks[tweak.tweak or ""]
if action then
- action(target,original,tweak)
+ if original then
+ action(target,original,tweak)
+ else
+ action(target,tweak)
+ end
end
end
end
@@ -1502,6 +1724,15 @@ function mathematics.tweakaftercopyingfont(target,original)
end
end
+function mathematics.beforepassingfonttotex(target)
+ if use_math_goodies then
+ local mathparameters = target.mathparameters -- why not hasmath
+ if mathparameters then
+ applytweaks("beforepassing",target,target)
+ end
+ end
+end
+
sequencers.appendaction("mathparameters","system","mathematics.overloadparameters")
sequencers.appendaction("mathparameters","system","mathematics.scaleparameters")
sequencers.appendaction("mathparameters","system","mathematics.checkaccentbaseheight") -- should go in lfg instead
@@ -1509,6 +1740,7 @@ sequencers.appendaction("mathparameters","system","mathematics.checkaccentbasehe
sequencers.appendaction("beforecopyingcharacters","system","mathematics.tweakbeforecopyingfont")
sequencers.appendaction("aftercopyingcharacters", "system","mathematics.tweakaftercopyingfont")
+sequencers.appendaction("beforepassingfonttotex", "system","mathematics.beforepassingfonttotex")
-- no, it's a feature now (see good-mth):
--
@@ -1661,6 +1893,8 @@ interfaces.implement { -- will be shared with text
actions = mathematics.registerfallbackid,
}
+-- todo: run this directly .. can be done in luametatex
+
function mathematics.resolvefallbacks(target,specification,fallbacks)
local definitions = fonts.collections.definitions[fallbacks]
if definitions then
@@ -1673,7 +1907,7 @@ function mathematics.resolvefallbacks(target,specification,fallbacks)
local name = definition.font
local features = definition.features or ""
local size = size * (definition.rscale or 1)
--- compact: size = 655360
+ -- compact: size = 655360
context.font_fallbacks_register_math(i,name,features,size)
if trace_collecting then
report_math("registering fallback font %i, name %a, size %a, features %a",i,name,size,features)
@@ -1696,7 +1930,7 @@ function mathematics.finishfallbacks(target,specification,fallbacks)
local fonts = target.fonts
local size = specification.size -- target.size
local characters = target.characters
--- compact: size = 655360
+ -- compact: size = 655360
if not fonts then
fonts = { }
target.fonts = fonts