diff options
Diffstat (limited to 'tex/context/base/mkxl/math-act.lmt')
-rw-r--r-- | tex/context/base/mkxl/math-act.lmt | 312 |
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 |