diff options
Diffstat (limited to 'tex/context/base/mkxl/math-act.lmt')
-rw-r--r-- | tex/context/base/mkxl/math-act.lmt | 437 |
1 files changed, 334 insertions, 103 deletions
diff --git a/tex/context/base/mkxl/math-act.lmt b/tex/context/base/mkxl/math-act.lmt index a6614aaa5..0c75147f6 100644 --- a/tex/context/base/mkxl/math-act.lmt +++ b/tex/context/base/mkxl/math-act.lmt @@ -18,6 +18,7 @@ local type, next, tonumber = type, next, tonumber local fastcopy, copytable, insert, remove, concat = table.fastcopy, table.copy, table.insert, table.remove, table.concat local formatters = string.formatters local byte = string.byte +local max = math.max local setmetatableindex, sortedkeys, sortedhash = table.setmetatableindex, table.sortedkeys, table.sortedhash local lpegmatch = lpeg.match @@ -45,13 +46,18 @@ local blocks = characters.blocks local stepper = utilities.parsers.stepper local helpers = fonts.helpers -local upcommand = helpers.commands.up -local downcommand = helpers.commands.down -local rightcommand = helpers.commands.right -local leftcommand = helpers.commands.left -local charcommand = helpers.commands.char local prependcommands = helpers.prependcommands +local vfcommands = helpers.commands +local upcommand = vfcommands.up +local downcommand = vfcommands.down +local rightcommand = vfcommands.right +local leftcommand = vfcommands.left +local slotcommand = vfcommands.slot +local charcommand = vfcommands.char +local push = vfcommands.push +local pop = vfcommands.pop + local sequencers = utilities.sequencers local appendgroup = sequencers.appendgroup local appendaction = sequencers.appendaction @@ -1710,7 +1716,7 @@ do datasets.accentdimensions = candidates local function adapt(c,factor,baseheight,basedepth) --- if not c.tweaked then + if not c.tweaked then local height = c.height or 0 local depth = c.depth or 0 local yoffset = 0 @@ -1736,8 +1742,8 @@ do c.yoffset = yoffset ~= 0 and yoffset or nil c.height = height > 0 and height or nil c.depth = depth > 0 and depth or nil --- c.tweaked = true --- end + c.tweaked = true + end end local function process(target,original,characters,list,baseheight,basedepth) @@ -1806,46 +1812,18 @@ end do - local addprivate = fonts.helpers.addprivate - local privateslot = fonts.helpers.privateslot - - -- function mathtweaks.addrules(target,original,parameters) - -- local characters = target.characters - -- local height = target.mathparameters.OverbarRuleThickness - -- local depth = target.mathparameters.UnderbarRuleThickness - -- local width = target.parameters.emwidth/2 - -- local step = 0.8 * width - -- characters[0x203E] = { -- over - -- width = width, - -- height = height, - -- depth = 0, - -- unicode = 0x203E, - -- commands = { { "rule", height, width } }, - -- parts = { - -- { advance = width, ["end"] = step, glyph = 0x203E, start = 0 }, - -- { advance = width, ["end"] = 0, glyph = 0x203E, start = step, extender = 1 }, - -- } - -- } - -- characters[0x0332] = { -- under - -- width = width, - -- height = 0, - -- depth = depth, - -- yoffset = -depth, - -- unicode = 0x0332, - -- commands = { { "rule", height, width } }, - -- parts = { - -- { advance = width, ["end"] = step, glyph = 0x0332, start = 0 }, - -- { advance = width, ["end"] = 0, glyph = 0x0332, start = step, extender = 1 }, - -- } - -- } - -- end + local addprivate = fonts.helpers.addprivate + local privateslot = fonts.helpers.privateslot + local newprivateslot = fonts.helpers.newprivateslot function mathtweaks.addrules(target,original,parameters) local characters = target.characters local thickness = target.mathparameters.OverbarRuleThickness local width = target.parameters.emwidth / 2 - local step = 0.8 * width - characters[0x203E] = { -- over + local width = target.parameters.emwidth / 3 +-- local step = 0.8 * width + local step = 0.5 * width + characters[0x203E] = { -- middle used for all kind width = width, height = thickness / 2, depth = thickness / 2, @@ -1858,8 +1836,43 @@ do }, partsorientation = "horizontal", } - -- - characters[0x0332] = characters[0x203E] + local function build(target,leftarrow,rightarrow) + if leftarrow and rightarrow then + -- actually the same sort of code as we have for antykwa + local left = leftarrow.parts + local right = rightarrow.parts + if left and right then + local leftline = right[1].glyph + local rightline = left [#left].glyph + local leftdata = characters[leftline] + local rightdata = characters[rightline] + local leftwidth = leftdata.width + local rightwidth = rightdata.width + local result = characters[target] -- copytable(leftdata) + if not result or result.width == 0 then + result = { + height = leftdata.height, + depth = leftdata.depth, + width = 0.9*leftwidth + rightwidth, + unicode = target, + commands = { + slotcommand[0][leftline], + leftcommand[0.1*leftwidth], + slotcommand[0][rightline], + }, + } + characters[target] = result + end + result.parts = { + { advance = leftwidth, glyph = leftline, ["end"] = .9*leftwidth, start = 0 }, + { advance = rightwidth, glyph = rightline, ["end"] = .1*leftwidth, start = .9*rightwidth, extender = 1 }, + } + result.partsorientation = "horizontal" + end + end + end + build(0x305,characters[0x20D6],characters[0x20D7]) -- overbar accent + build(0x332,characters[0x20EE],characters[0x20EF]) -- underbar accent -- -- lucida lacks them ... -- @@ -1875,11 +1888,16 @@ do commands = { { "rule", thickness * 2.5, thickness } }, }) characters[0x23B4] = { -- over - width = width, +-- width = width, + width = 2*thickness+width, height = half, depth = double, unicode = 0x23B4, - commands = { { "rule", thickness, width } }, + commands = { + slotcommand[0][tpiece], + slotcommand[0][0x203E], + slotcommand[0][tpiece], + }, parts = { { advance = thickness, glyph = tpiece, ["end"] = 0, start = half }, { advance = width, glyph = 0x203E, ["end"] = step, start = step, extender = 1 }, @@ -1896,12 +1914,16 @@ do yoffset = - half, commands = { { "rule", thickness * 2.5, thickness } }, }) - characters[0x23B5] = { -- over - width = width, + characters[0x23B5] = { -- under + width = 2*thickness+width, height = double, depth = half, unicode = 0x23B5, - commands = { { "rule", thickness, width } }, + commands = { + slotcommand[0][bpiece], + slotcommand[0][0x203E], + slotcommand[0][bpiece], + }, parts = { { advance = thickness, glyph = bpiece, ["end"] = 0, start = half }, { advance = width, glyph = 0x203E, ["end"] = step, start = step, extender = 1 }, @@ -1913,6 +1935,69 @@ do -- end + -- vfmath.builders.extension(target) + + local rbe = newprivateslot("radical bar extender") + + local function useminus(unicode,characters,parameters) + local minus = characters[0x2212] + local xoffset = parameters.xoffset or .075 + local yoffset = parameters.yoffset or .9 + local xscale = parameters.xscale or 1 + local yscale = parameters.yscale or 1 + local xwidth = parameters.width or (1 - 2*xoffset) + local xheight = parameters.height or (1 - yoffset) + local mheight = minus.height + local mwidth = minus.width + local height = xheight*mheight + local xshift = xoffset * mwidth + local yshift = yoffset * mheight + local advance = xwidth * mwidth + local step = mwidth / 2 + characters[unicode] = { + height = height, + depth = height, + width = advance, + commands = { + push, + leftcommand[xshift], + downcommand[yshift], + -- slotcommand[0][0x2212], + { "slot", 0, 0x2212, xscale, yscale }, + pop, + }, + unicode = unicode, + -- parts = { + -- { extender = 0, glyph = first, ["end"] = fw/2, start = 0, advance = fw }, + -- { extender = 1, glyph = middle, ["end"] = mw/2, start = mw/2, advance = mw }, + -- { extender = 0, glyph = last, ["end"] = 0, start = lw/2, advance = lw }, + -- }, + parts = { + { extender = 0, glyph = unicode, ["end"] = step, start = 0, advance = advance }, + { extender = 1, glyph = unicode, ["end"] = step, start = step, advance = advance }, + }, + partsorientation = "horizontal", + } + end + + function mathtweaks.replacerules(target,original,parameters) + local characters = target.characters + local fraction = parameters.fraction + local radical = parameters.radical + if fraction then + local template = fraction.template + if template == 0x2212 or template == "minus" then + useminus(0x203E,characters,fraction) + end + end + if radical then + local template = radical.template + if template == 0x2212 or template == "minus" then + useminus(rbe,characters,radical) + end + end + end + local force = false experiments.register("math.arrows", function(v) force = v end) local function tighten(target,unicode,left,right,squeeze,yoffset) @@ -1947,7 +2032,7 @@ do if chardata and (force or overloads[unicode] == false or not chardata.parts) then if not list then -- chardata.parts = nil -- when we test - chardata.parts = { { glyph = unicode } } +-- chardata.parts = { { glyph = unicode } } else local overload = overloads[unicode] local parts = { } @@ -1982,7 +2067,8 @@ do end end if #parts == #list then - chardata.parts = parts + chardata.parts = parts + chardata.partsorientation = "horizontal" end end end @@ -2259,7 +2345,8 @@ do local function fix(target,original,characters,u,l) local data = characters[u] if data then - data.innerlocation = l.location == "right" and 2 or 1 + -- data.innerlocation = l.location == "right" and 2 or 1 + data.innerlocation = l.location == "right" and "right" or "left" data.innerxoffset = (l.hfactor or 1) * (data.width or 0) data.inneryoffset = (l.vfactor or 1) * ((data.height or 0) + (data.depth or 0)) end @@ -2636,40 +2723,119 @@ do end +-- do +-- +-- local single <const> = 0x003D +-- local double <const> = 0x2A75 +-- local triple <const> = 0x2A76 +-- +-- function mathtweaks.addequals(target,original,parameters) +-- local characters = target.characters +-- local basechar = characters[single] +-- local width = basechar.width +-- local height = basechar.height +-- local depth = basechar.depth +-- local advance = (parameters.advance or 1/20) * width +-- local char = charcommand[single] +-- local left = leftcommand[advance] +-- characters[double] = { +-- unicode = double, +-- width = 2*width - 1*advance, +-- height = height, +-- depth = depth, +-- commands = { char, left, char }, +-- } +-- characters[triple] = { +-- unicode = triple, +-- width = 3*width - 2*advance, +-- height = height, +-- depth = depth, +-- commands = { char, left, char, left, char }, +-- } +-- if trace_tweaking then +-- report_tweak("double %U and triple %U equals added",target,original,double,triple) +-- end +-- end +-- +-- end + do - local single <const> = 0x003D - local double <const> = 0x2A75 - local triple <const> = 0x2A76 + local function jointwo(characters,force,unicode,ds,u1,d12,u2) + if force or not characters[unicode] then + local c1 = characters[u1] + local c2 = characters[u2] + if c1 and c2 then + local w1 = c1.width + local w2 = c2.width + local width + if d12 == false then + d12 = 0 + width = w2 + elseif d12 < 0 then + d12 = d12 * w2 + width = w2 + else + d12 = d12 * ds + width = w1 + w2 - d12 + end + characters[unicode] = { + unicode = unicode, + width = width, + height = max(c1.height or 0, c2.height or 0), + depth = max(c1.depth or 0, c2.depth or 0), +keepvirtual = true, + commands = { + -- { "inspect" }, + -- { "trace" }, + slotcommand[0][u1], + -- { "trace" }, + d12 ~= 0 and leftcommand[d12] or false, + slotcommand[0][u2], + -- { "trace" }, + }, + } + end + end + end + + local function jointhree(characters,force,unicode,ds,u1,d12,u2,d23,u3) + if force or not characters[unicode] then + local c1 = characters[u1] + local c2 = characters[u2] + local c3 = characters[u3] + if c1 and c2 and c3 then + local w1 = c1.width + local w2 = c2.width + local w3 = c3.width + d12 = d12 * ds + d23 = d23 * ds + characters[unicode] = { + unicode = unicode, + width = w1 + w2 + w3 - d12 - d23, + height = max(c1.height or 0, c2.height or 0, c3.height or 0), + depth = max(c1.depth or 0, c2.depth or 0, c3.depth or 0), + commands = { + slotcommand[0][u1], + d12 ~= 0 and leftcommand[d12] or false, + slotcommand[0][u2], + d23 ~= 0 and leftcommand[d23] or false, + slotcommand[0][u3], + } + } + end + end + end function mathtweaks.addequals(target,original,parameters) local characters = target.characters - local basechar = characters[single] - local width = basechar.width - local height = basechar.height - local depth = basechar.depth - local advance = (parameters.advance or 1/20) * width - local char = charcommand[single] - local left = leftcommand[advance] - characters[double] = { - unicode = double, - width = 2*width - 1*advance, - height = height, - depth = depth, --- callback = "devirtualize", - commands = { char, left, char }, - } - characters[triple] = { - unicode = triple, - width = 3*width - 2*advance, - height = height, - depth = depth, --- callback = "devirtualize", - commands = { char, left, char, left, char }, - } - if trace_tweaking then - report_tweak("double %U and triple %U equals added",target,original,double,triple) - end + local step = target.parameters.size/18 + local force = parameters.force +force = true + jointwo (characters,force,0x2254,step,0x03A,0,0x03D) -- := + jointhree(characters,force,0x2A74,step,0x03A,0,0x03A,0,0x03D) -- ::= + jointwo (characters,force,0x2A75,step,0x03D,0,0x03D) -- == + jointhree(characters,force,0x2A76,step,0x03D,0,0x03D,0,0x03D) -- === end end @@ -2807,28 +2973,45 @@ do { 0x030A, nps("delimited right ring"), nps("delimited ghost ring") }, { 0x0303, nps("delimited right tilde"), nps("delimited ghost tilde") }, { 0x20DB, nps("delimited right dddot"), nps("delimited ghost dddot") }, + + { 0x231C, nps("delimited left upper corner"), nps("delimited ghost upper corner") }, + { 0x231D, nps("delimited right upper corner"), nps("delimited ghost upper corner") }, + { 0x231E, nps("delimited left lower corner"), nps("delimited ghost lower corner"), true }, + { 0x231F, nps("delimited right lower corner"), nps("delimited ghost lower corner"), true }, + + -- If needed we can have an installer: + { 0x2020, nps("delimited right dagger"), nps("delimited ghost dagger") }, { 0x2021, nps("delimited right ddagger"), nps("delimited ghost ddagger") }, { 0x2217, nps("delimited right ast"), nps("delimited ghost ast") }, { 0x22C6, nps("delimited right star"), nps("delimited ghost star") }, - { 0x231C, nps("delimited left upper corner"), nps("delimited ghost upper corner") }, - { 0x231D, nps("delimited right upper corner"), nps("delimited ghost upper corner") }, - { 0x231E, nps("delimited left lower corner"), nps("delimited ghost lower corner"), true }, - { 0x231F, nps("delimited right lower corner"), nps("delimited ghost lower corner"), true }, + { 0x2020, nps("delimited right dagger 1"), nps("delimited ghost dagger 1"), false, 1 }, + { 0x2021, nps("delimited right ddagger 1"), nps("delimited ghost ddagger 1"), false, 1 }, + { 0x2217, nps("delimited right ast 1"), nps("delimited ghost ast 1"), false, 1 }, + { 0x22C6, nps("delimited right star 1"), nps("delimited ghost star 1"), false, 1 }, } function mathtweaks.addfourier(target,original,parameters) local characters = target.characters for i=1,#list do - local entry = list[i] - local basecode = entry[1] - local fouriercode = entry[2] - local movecode = entry[3] - local reverse = entry[4] - local basechar = characters[basecode] + local entry = list[i] + local basecode = entry[1] + local fouriercode = entry[2] + local movecode = entry[3] + local reverse = entry[4] + local size = entry[5] or 0 + local basechar = characters[basecode] + local compactscale = 1 + if basechar and target.properties.compactmath and size > 0 then + compactscale = target.parameters[size > 1 and "scriptscriptscale" or "scriptscale"] / 1000 + for i=1,size do + basecode = basechar.smaller or basecode + basechar = characters[basecode] + end + end if basechar then - local scale = parameters.scale or 1 + local scale = (parameters.scale or 1) * compactscale local variant = parameters.variant if variant then for i=1,variant do @@ -2846,9 +3029,9 @@ do local basewidth = scale * (basechar.width or 0) local used = baseheight/2 local total = baseheight + basedepth -if reverse then - used = total / 2 -- basedepth / 2 -end + if reverse then + used = total / 2 -- basedepth / 2 + end characters[movecode] = { width = basewidth, height = used, @@ -3126,6 +3309,45 @@ end do + function mathtweaks.sortvariants(target,original,parameters) + local list = parameters.list + if list then + local characters = target.characters + local horizontal = parameters.orientation == "horizontal" + for i=1,#list do + local u = list[i] + local c = characters[u] + if c then + local t = { } + while true do + local n = c.next + if n then + c = characters[n] + end + if c and not c.parts then + if horizontal then + t[c.width or 0] = n + else + t[(c.height or 0) + (c.depth or 0)] = n + end + else + break + end + end + local c = characters[u] + for k, v in sortedhash(t) do + c.next = v + c = characters[v] + end + end + end + end + end + +end + +do + -- We started with the list that xits has in rtlm but most of them can be derived from -- the database, and others need to be added. @@ -3251,7 +3473,11 @@ do end local next = data.next if next then - add(target,original,characters,next,"next") + if next == unicode then + report_tweak("skipping cyclic %U (%s)",target,original,unicode,"next") + else + add(target,original,characters,next,"next") + end end end end @@ -3462,6 +3688,7 @@ do local feature = entry.feature local thesource = entry.source local thetarget = entry.target or thesource + local keep = (entry.keep == true) or (parameters.keep == true) if thesource and thetarget then local sourcerange = type(thesource) == "table" and thesource or blocks[thesource] -- .gaps local targetrange = type(thetarget) == "table" and thetarget or blocks[thetarget] -- .gaps @@ -3504,13 +3731,17 @@ do local sourceunicode = mathgaps[s] or s if chars[sourceunicode] then local targetunicode = mathgaps[t] or t - if feature then - sourceunicode = getsubstitution(dropin,sourceunicode,feature,true,"math","dflt") or sourceunicode + if keep and characters[targetunicode] then + -- okay + else + if feature then + sourceunicode = getsubstitution(dropin,sourceunicode,feature,true,"math","dflt") or sourceunicode + end +-- if trace_tweaking then +-- report_tweak("copying %s %U from file %a to %s %U",target,original,thesource,sourceunicode,filename,thetarget,targetunicode) +-- end + characters[targetunicode] = copiedglyph(target,characters,chars,sourceunicode,index) end --- if trace_tweaking then --- report_tweak("copying %s %U from file %a to %s %U",target,original,thesource,sourceunicode,filename,thetarget,targetunicode) --- end - characters[targetunicode] = copiedglyph(target,characters,chars,sourceunicode,index) end end -- |