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.lmt681
1 files changed, 474 insertions, 207 deletions
diff --git a/tex/context/base/mkxl/math-act.lmt b/tex/context/base/mkxl/math-act.lmt
index 713635583..c18dcda29 100644
--- a/tex/context/base/mkxl/math-act.lmt
+++ b/tex/context/base/mkxl/math-act.lmt
@@ -10,7 +10,7 @@ if not modules then modules = { } end modules ['math-act'] = {
-- have been removed (no longer viable) but can be found in the .lua variant.
local type, next, tonumber = type, next, tonumber
-local fastcopy, copytable, insert, remove = table.fastcopy, table.copy, table.insert, table.remove
+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 setmetatableindex, sortedkeys, sortedhash = table.setmetatableindex, table.sortedkeys, table.sortedhash
@@ -24,6 +24,7 @@ local report_math = logs.reporter("mathematics","initializing")
local report_mathtweak = logs.reporter("mathematics","tweak")
local getfontoffamily = tex.getfontoffamily
+local texget = tex.get
local fontcharacters = fonts.hashes.characters
local chardata = characters.data
local extensibles = mathematics.extensibles
@@ -245,8 +246,22 @@ end
-- a couple of predefined tweaks:
-local mathtweaks = { }
-mathematics.tweaks = mathtweaks
+local datasets = { }
+local mathtweaks = { datasets = datasets }
+mathematics.tweaks = mathtweaks
+
+-- can be a common helper:
+
+local f_u = formatters["%U"]
+
+local function unicodecharlist(t)
+ local r = { }
+ local n = 0
+ for u in sortedhash(t) do
+ n = n + 1 ; r[n] = f_u(u)
+ end
+ return concat(r," ")
+end
local function report_tweak(fmt,target,original,...)
if fmt then
@@ -269,6 +284,16 @@ local function report_tweak(fmt,target,original,...)
end
end
+local function feedback_tweak(tweak,target,original,done)
+ if not done or (type(done) == "table" and not next(done)) then
+if trace_tweaking then -- for now
+ report_tweak("no need for %a",target,original,tweak)
+end
+ elseif trace_tweaking then
+ report_tweak("tweak %a applied to: %s",target,original,tweak,unicodecharlist(done))
+ end
+end
+
mathtweaks.subsets = {
acenorsuvxz = { 0x1D44E, 0x1D450, 0x1D452, 0x1D45B, 0x1D45C, 0x1D45F, 0x1D460, 0x1D462, 0x1D463, 0x1D465, 0x1D467 },
bhklt = { 0x1D44F, 0x1D455, 0x1D458, 0x1D459, 0x1D461 },
@@ -341,7 +366,7 @@ local detail do
c = characters[nxt]
nxt = c.next
end
- c = c.hparts or c.vparts
+ c = c.parts
if c then
local index = t[3]
if index == "*" then
@@ -414,6 +439,12 @@ do
t = type(v)
end
if t == "table" and next(v) then
+
+ local axis = tonumber(v.axis)
+ if axis then
+ axis = target.mathparameters.AxisHeight * axis
+ end
+
local factor = v.factor
if factor then
local m = v
@@ -490,6 +521,13 @@ do
if yoffsetfactor then
character.yoffset = yoffsetfactor * total
end
+
+ if axis then
+ character.height = (character.height or 0) - axis
+ character.depth = (character.depth or 0) + axis
+ character.yoffset = (character.yoffset or 0) + axis
+ end
+
if italicfactor then
if italic then
character.italic = italicfactor * italic
@@ -533,7 +571,7 @@ do
if nxt then
adapt(list,target,original,targetcharacters,originalcharacters,nxt,v,compact,n)
else
- local parts = character.hparts
+ local parts = character.parts
if parts then
for i=1,#parts do
adapt(list,target,original,targetcharacters,originalcharacters,parts[i],v,compact,n)
@@ -621,25 +659,24 @@ do
-- local originalcharacters = original.characters
local count = 0
-- local also = getalso(target,original)
- -- local done = { }
+ local done = false
for k, v in sortedhash(list) do
local ori = targetcharacters[k]
local nxt = ori.next
local cnt = v
if nxt then
- local hpt, vpt
+ local prt = nil
local lst = { }
while nxt do
local chr = targetcharacters[nxt]
lst[#lst+1] = chr
nxt = chr.next
if not nxt then
- hpt = chr.hparts
- vpt = chr.vparts
+ prt = chr.parts
break
end
end
- if hpt or vpt then
+ if prt then
count = count + 1
if cnt ~= "*" then
if #lst < cnt then
@@ -647,15 +684,18 @@ do
end
ori = lst[cnt]
end
- ori.hparts = hpt
- ori.vparts = vpt
- -- ori.next = nil -- so we keep the chain
+ ori.parts = prt
+ end
+ if not trace_tweaking then
+ done = true
+ elseif done then
+ done[k] = true
+ else
+ done = { [k] = true }
end
end
end
- if trace_tweaking and count > 0 then
- report_tweak("%i variants wiped",target,original,count)
- end
+ feedback_tweak("wipevariants",target,original,done)
end
end
@@ -663,7 +703,7 @@ end
do
- function mathtweaks.replacements(target,original,parameters)
+ function mathtweaks.replace(target,original,parameters)
local list = parameters.list
if list then
local targetcharacters = target.characters
@@ -687,7 +727,7 @@ do
end
end
- function mathtweaks.substitutes(target,original,parameters)
+ function mathtweaks.substitute(target,original,parameters)
local list = parameters.list
if list then
local targetcharacters = target.characters
@@ -707,9 +747,6 @@ do
end
end
- mathtweaks.replace = mathtweaks.replacements
- mathtweaks.substitute = mathtweaks.substitutes
-
end
do
@@ -721,7 +758,7 @@ do
if list then
local targetcharacters = target.characters
local originalcharacters = original.characters
- local count = 0
+ local done = false
local function add(v,n)
local chardata = targetcharacters[mathgaps[n] or n]
@@ -735,7 +772,13 @@ do
local t = mathgaps[nn] or nn
if t then
kerns[t] = vv * width
- count = count + 1
+ if not trace_tweaking then
+ done = true
+ elseif done then
+ done[t] = true
+ else
+ done = { [t] = true }
+ end
end
end)
end
@@ -768,9 +811,7 @@ do
-- end
-- end
- if trace_tweaking and count > 0 then
- report_tweak("%i kern pairs",target,original,count)
- end
+ feedback_tweak("kernpairs",target,original,done)
end
end
@@ -1038,65 +1079,67 @@ do
end
-do
-
- function mathtweaks.fixanchors(target,original,parameters)
- local targetcharacters= target.characters
- local factor = tonumber(parameters.factor) or 0
- if factor ~= 0 then
- local count = 0
- for k, v in next, targetcharacters do
- local a = v.topanchor
- if a and a > 0 then
- v.topanchor = a * factor
- count = count + 1
- end
- end
- if trace_tweaking and count > 0 then
- report_tweak("%i top anchors fixed",target,original,count)
- end
- end
- end
-
- mathtweaks.fixaccents = mathtweaks.fixanchors
-
-end
-
-do
-
- -- actually this should be a an engine feature driven by category because we don't
- -- want this in display mode .. only a test for MS and HH
+-- do
+--
+-- function mathtweaks.fixanchors(target,original,parameters)
+-- local targetcharacters= target.characters
+-- local factor = tonumber(parameters.factor) or 0
+-- if factor ~= 0 then
+-- local done = false
+-- for k, v in next, targetcharacters do
+-- local a = v.topanchor
+-- if a and a > 0 then
+-- v.topanchor = a * factor
+-- count = count + 1
+-- if not trace_tweaking then
+-- done = true
+-- elseif done then
+-- done[u] = true
+-- else
+-- done = { [u] = true }
+-- end
+-- end
+-- end
+-- end
+-- feedback_tweak("fixanchors",target,original,done)
+-- end
+--
+-- end
+-- do
+--
+-- -- actually this should be a an engine feature driven by category because we don't
+-- -- want this in display mode .. only a test for MS and HH
+--
-- local issymbol = characters.is_symbol
--
-- function mathtweaks.oldstylemath(target,original,parameters)
--- local chardata = characters.data
+-- local chardata = characters.data
-- local characters = target.characters
-- local axis = target.mathparameters.AxisHeight
-- local delta = (parameters.factor or .1) * axis
-- target.mathparameters.AxisHeight = (axis - delta)
-- for k, v in sortedhash(characters) do
-- if issymbol[k] then -- quick hack, engine knows
--- print("old style math",k,chardata[k].description)
-- v.yoffset = -delta
-- v.height = (v.height or 0) - delta
-- v.depth = (v.depth or 0) - delta
-- end
-- end
-- end
-
- function mathtweaks.oldstylemath(target,original,parameters)
- -- not relevant
- end
-
-end
+--
+-- function mathtweaks.oldstylemath(target,original,parameters)
+-- -- not relevant
+-- end
+--
+-- end
do
function mathtweaks.simplifykerns(target,original,parameters)
local characters = target.characters
- local simplified = 0
- for k, v in sortedhash(characters) do
+ local done = false
+ for u, v in sortedhash(characters) do
local mathkerns = v.mathkerns
if mathkerns then
local k = mathkerns.topleft
@@ -1128,25 +1171,28 @@ do
end
end
v.mathkerns = nil
- simplified = simplified + 1
+ if not trace_tweaking then
+ done = true
+ elseif done then
+ done[u] = true
+ else
+ done = { [u] = true }
+ end
end
end
- if simplified == 0 then
- report_tweak("no need to simplify mathkerns",target,original)
- elseif trace_tweaking then
- report_tweak("%i mathkerns simplified",target,original,simplified)
- end
+ feedback_tweak("simplifykerns",target,original,done)
end
end
do
- local function wipe(target,original,parameters,field,move,integrals)
+ local function wipe(whatever,target,original,parameters,field,move,integrals)
local targetcharacters = target.characters
local targetdescriptions = target.descriptions
local factor = target.parameters.factor
local correct = parameters.correct
+ local done = false
local function getllx(u)
local d = targetdescriptions[u]
if d then
@@ -1172,7 +1218,7 @@ do
goto smaller
end
else
- local done = false
+ local okay = false
local italic = c.italic
if move and not c.advance then -- advance check prevents double move
local width = c.width or 0
@@ -1187,39 +1233,41 @@ do
if topanchor then
c.topanchor = topanchor + llx
end
- c.bottomleft = (c.bottomleft or 0) - llx
- c.topleft = (c.topleft or 0) - llx
- done = true
+ -- too bad (schola e^x):
+ -- c.bottomleft = (c.bottomleft or 0) - llx
+ -- c.topleft = (c.topleft or 0) - llx
+ okay = true
end
end
if italic and italic ~= 0 then
c.width = width + italic
c.bottomright = - italic
- done = true
+ okay = true
else
c.width = width
end
end
if italic then
c.italic = nil
- done = true
+ okay = true
end
- if not done then
- goto smaller
- end
- end
- if trace_tweaking then
- if l then
- report_tweak("%s %a in range %a from %C","removing",target,original,field,l,s)
+ if okay then
+ if not trace_tweaking then
+ done = true
+ elseif done then
+ done[u] = true
+ else
+ done = { [u] = true }
+ end
else
- report_tweak("%s %a from %C","removing",target,original,field,s)
+ goto smaller
end
end
goto smaller
::smaller::
s = c.smaller
::variants::
- -- no italics here anyway butr we could check them some day
+ -- no italics here anyway but we could check them some day
else
break
end
@@ -1262,22 +1310,21 @@ do
end
end
end
+ feedback_tweak(whatever,target,original,done)
end
function mathtweaks.wipeanchors(target,original,parameters)
- wipe(target,original,parameters,"topanchor")
+ wipe("wipeanchors",target,original,parameters,"topanchor")
end
- mathtweaks.wipeaccents = mathtweaks.wipeanchors
-
function mathtweaks.wipeitalics(target,original,parameters)
if not checkitalics then
- wipe(target,original,parameters,"italic")
+ wipe("wipeitalics",target,original,parameters,"italic")
end
end
function mathtweaks.moveitalics(target,original,parameters)
- wipe(target,original,parameters,"italic",true)
+ wipe("moveitalics",target,original,parameters,"italic",true)
end
-- function mathtweaks.fixdigits(target,original,parameters)
@@ -1292,7 +1339,8 @@ do
local characters = target.characters
local list = parameters.list
if list then
- for k, v in sortedhash(list) do
+ local done = false
+ for u, v in sortedhash(list) do
local c = characters[k]
if c then
local w = c.width
@@ -1301,15 +1349,20 @@ do
if trace_tweaking then
-- todo
end
+ if not trace_tweaking then
+ done = true
+ elseif done then
+ done[u] = true
+ else
+ done = { [u] = true }
+ end
end
end
end
- -- todo: small
+ feedback_tweak("topanchors",target,original,done)
end
end
- mathtweaks.topaccents = mathtweaks.topanchors
-
function mathtweaks.movelimits(target,original,parameters)
local characters = target.characters
local list = parameters.list
@@ -1346,6 +1399,27 @@ do
if n then
relocate(n,factor)
end
+ -- Kind of tricky: we configure the engine to use the vitalic
+ -- so when we tweak we need to set that to zero.
+ local parts = c.parts
+ local italic = c.partsitalic
+ if parts and italic then
+ if italic ~= 0 then
+ local tchar = characters[parts[#parts].glyph]
+ local bchar = characters[parts[1].glyph]
+ local width = tchar.width or 0
+ local half = (italic/2) * factor
+ tchar.topanchor = width + half
+ bchar.bottomanchor = width - half
+ bchar.bottomright = - italic
+ if trace_tweaking then
+ -- todo
+ end
+ tchar.italic = nil
+ bchar.italic = nil
+ end
+ c.vitalic = nil
+ end
if also then
local a = also[u]
if a then
@@ -1365,9 +1439,7 @@ do
relocate(k,tonumber(v) or factor)
end
end
- if not next(done) then
- report_tweak("no need to move limits",target,original)
- end
+ feedback_tweak("movelimits",target,original,done)
end
end
@@ -1544,6 +1616,8 @@ do
},
}
+ datasets.accentdimensions = candidates
+
local function adapt(c,factor,baseheight,basedepth)
-- if not c.tweaked then
local height = c.height or 0
@@ -1593,7 +1667,7 @@ do
nv = nv + 1
nc = c.next
if not nc then
- local hv = c.hparts
+ local hv = c.parts
if hv then
for i=1,#hv do
local c = characters[hv[i].glyph]
@@ -1656,7 +1730,7 @@ do
-- depth = 0,
-- unicode = 0x203E,
-- commands = { { "rule", height, width } },
- -- hparts = {
+ -- parts = {
-- { advance = width, ["end"] = step, glyph = 0x203E, start = 0 },
-- { advance = width, ["end"] = 0, glyph = 0x203E, start = step, extender = 1 },
-- }
@@ -1668,7 +1742,7 @@ do
-- yoffset = -depth,
-- unicode = 0x0332,
-- commands = { { "rule", height, width } },
- -- hparts = {
+ -- parts = {
-- { advance = width, ["end"] = step, glyph = 0x0332, start = 0 },
-- { advance = width, ["end"] = 0, glyph = 0x0332, start = step, extender = 1 },
-- }
@@ -1687,7 +1761,7 @@ do
yoffset = - thickness / 2,
unicode = 0x203E,
commands = { { "rule", thickness, width } },
- hparts = {
+ parts = {
{ advance = width, ["end"] = step, glyph = 0x203E, start = 0 },
{ advance = width, ["end"] = 0, glyph = 0x203E, start = step, extender = 1 },
}
@@ -1714,7 +1788,7 @@ do
depth = double,
unicode = 0x23B4,
commands = { { "rule", thickness, width } },
- hparts = {
+ parts = {
{ advance = thickness, glyph = tpiece, ["end"] = 0, start = half },
{ advance = width, glyph = 0x203E, ["end"] = step, start = step, extender = 1 },
{ advance = thickness, glyph = tpiece, ["end"] = half, start = 0 },
@@ -1735,7 +1809,7 @@ do
depth = half,
unicode = 0x23B5,
commands = { { "rule", thickness, width } },
- hparts = {
+ parts = {
{ advance = thickness, glyph = bpiece, ["end"] = 0, start = half },
{ advance = width, glyph = 0x203E, ["end"] = step, start = step, extender = 1 },
{ advance = thickness, glyph = bpiece, ["end"] = half, start = 0 },
@@ -1776,13 +1850,12 @@ do
while chardata.next do
chardata = characters[chardata.next]
end
--- if chardata and (force or not chardata.hparts) then
- if chardata and (force or overloads[unicode] == false or not chardata.hparts) then
+ if chardata and (force or overloads[unicode] == false or not chardata.parts) then
if not list then
- chardata.hparts = nil -- when we test
+ chardata.parts = nil -- when we test
else
local overload = overloads[unicode]
- local hparts = { }
+ local parts = { }
for i=1,#list do
local part = list[i]
local glyph = part.glyph or unicode
@@ -1797,7 +1870,7 @@ do
local width = characters[glyph].width
local step = width/2
if part.extensible then
- hparts[#hparts+1] = {
+ parts[#parts+1] = {
advance = width,
glyph = glyph,
["end"] = step,
@@ -1805,7 +1878,7 @@ do
extender = 1,
}
else
- hparts[#hparts+1] = {
+ parts[#parts+1] = {
advance = width,
glyph = glyph,
["end"] = 0,
@@ -1813,8 +1886,8 @@ do
}
end
end
- if #hparts == #list then
- chardata.hparts = hparts
+ if #parts == #list then
+ chardata.parts = parts
end
end
end
@@ -1886,6 +1959,8 @@ do
}
end
+ datasets.addarrows = { }
+
function mathtweaks.addarrows(target,original,parameters)
local overloads = parameters.list or { } -- { [unicode] = { left = .1, right = .1 } }
local left = parameters.left or 0.05
@@ -1896,6 +1971,10 @@ do
for unicode, list in sortedhash(arrows) do
create(target,unicode,list,overloads)
end
+ datasets.addarrows = sortedkeys(arrows)
+ if trace_tweaking then
+ report_tweak("arrows added",target,original)
+ end
end
end
@@ -1915,7 +1994,7 @@ do -- this could be combined with the previous
local sequence = data.sequence
local horizontal = data.horizontal
if sequence then
- local parts = horizontal and source.hparts or source.vparts
+ local parts = source.parts
if parts then
local p = { }
for i=1,#sequence do
@@ -1943,7 +2022,7 @@ do -- this could be combined with the previous
end
end
if #p > 0 then
- target[horizontal and "hparts" or "vparts"] = p
+ target.parts = p
end
end
end
@@ -1982,6 +2061,8 @@ do
{ 0x205F, "s", 1/2 }, -- math thinspace
}
+ datasets.checkspacing = list
+
function mathtweaks.checkspacing(target,original,parameters)
local characters = target.characters
local parameters = target.parameters
@@ -2073,6 +2154,32 @@ do
end
end
+ 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.innerxoffset = (l.hfactor or 1) * (data.width or 0)
+ data.inneryoffset = (l.vfactor or 1) * ((data.height or 0) + (data.depth or 0))
+ end
+ end
+
+ function mathtweaks.radicaldegreeanchors(target,original,parameters)
+ local list = parameters.list
+ if list then
+ local characters = target.characters
+ for unicode, l in sortedhash(list) do -- resolve variants
+ local u = detail(characters,unicode) or unicode
+ if type(u) == "table" then
+ for i=1,#u do
+ fix(target,original,characters,u[i],l)
+ end
+ else
+ fix(target,original,characters,u,l)
+ end
+ end
+ end
+ end
+
end
do
@@ -2137,15 +2244,48 @@ do
done = nil
end
+ -- After the next one I rewarded myself by (again) watching Joe Parrish interpretation
+ -- of Shostakovich 10 Mvmt. II - Metal several times (video on yt, track on bandcamp)
+ -- ... timestamp: awaiting the new Albion (Official) single; their work comes in parts.
+
+ function mathtweaks.fixintegrals(target,original,parameters)
+ local characters = target.characters
+ local integral = characters[0x222B]
+ if integral and not integral.parts then
+ local top = characters[0x2320]
+ local mid = characters[0x23AE]
+ local bot = characters[0x2321]
+ if top and mid and bot then
+ top = top.height
+ mid = mid.height
+ bot = bot.height
+ integral.partsitalic = integral.italic
+ integral.parts = {
+ { advance = bot, ["end"] = bot/3, glyph = 0x2321, start = bot/3 },
+ { advance = mid, ["end"] = mid/2, glyph = 0x23AE, start = mid/2, extender = 1 },
+ { advance = top, ["end"] = top/3, glyph = 0x2320, start = top/3 },
+ }
+ if trace_tweaking then
+ report_tweak("fixing the integral extensible",target,original)
+ end
+ end
+ else
+ report_tweak("no need to fix the integral extensible",target,original)
+ end
+ end
+
end
do
local list = { 0x2061, 0x2062, 0x2063, 0x2064 }
+ datasets.wipecues = list
+
function mathtweaks.wipecues(target,original,parameters)
local characters = target.characters
local tobewiped = parameters.list or list
+ local done = false
for i=1,#tobewiped do
local unicode = tobewiped[i]
characters[unicode] = {
@@ -2154,10 +2294,15 @@ do
depth = 0,
unicode = unicode,
}
- if trace_tweaking then
- report_tweak("character %U has been wiped",target,original,unicode)
+ if not trace_tweaking then
+ done = true
+ elseif done then
+ done[unicode] = true
+ else
+ done = { [unicode] = true }
end
end
+ feedback_tweak("wipecues",target,original,done)
end
end
@@ -2168,48 +2313,62 @@ do
[0x002F] = 0x2044,
}
+ datasets.fixslashes = mapping
+
function mathtweaks.fixslashes(target,original,parameters)
local characters = target.characters
+ -- local done = false
for normal, weird in sortedhash(mapping) do
local normalone = characters[normal]
local weirdone = characters[weird]
if normalone and weirdone and not normalone.next then
normalone.next = weirdone.next
- if trace_tweaking then
- report_tweak("extensibles from %U used for %U",target,original,weird,normal)
- end
+ -- if not trace_tweaking then
+ -- done = true
+ -- elseif done then
+ -- done[normal] = true
+ -- else
+ -- done = { [normal] = true }
+ -- end
end
weirdone = copytable(normalone)
characters[weird] = weirdone
weirdone.unicode = weird
end
- end
+ -- feedback_tweak("fixslashes",target,original,done)
+ if trace_tweaking then
+ report_tweak("slashes fixed",target,original)
+ end
+ end
end
do -- see pagella for an extensive example
+ local nps = fonts.helpers.newprivateslot
+
local mapping = {
- [0x0300] = { 0x0060, false }, -- aliases can be a table
- [0x0308] = { 0x00A8, false },
- [0x0304] = { 0x00AF, false },
- [0x0301] = { 0x00B4, false },
- [0x0302] = { 0x02C6, true },
- [0x030C] = { 0x02C7, true },
- [0x0306] = { 0x02D8, false },
- [0x0307] = { 0x02D9, false },
- [0x030A] = { 0x02DA, false },
- [0x0303] = { 0x02DC, true },
- [0x20DB] = { 0x20DB, false },
+ [0x0300] = { 0x0060, false, nps("flat 0x0060 1") },
+ [0x0308] = { 0x00A8, false, nps("flat 0x00A8 1") },
+ [0x0304] = { 0x00AF, false, nps("flat 0x00AF 1") },
+ [0x0301] = { 0x00B4, false, nps("flat 0x00B4 1") },
+ [0x0302] = { 0x02C6, true, nps("flat 0x02C6 1") },
+ [0x030C] = { 0x02C7, true, nps("flat 0x02C7 1") },
+ [0x0306] = { 0x02D8, false, nps("flat 0x02D8 1") },
+ [0x0307] = { 0x02D9, false, nps("flat 0x02D9 1") },
+ [0x030A] = { 0x02DA, false, nps("flat 0x02DA 1") },
+ [0x0303] = { 0x02DC, true, nps("flat 0x02DC 1") },
+ [0x20DB] = { 0x20DB, false, nps("flat 0x20DB 1") },
}
-local hat = fonts.helpers.newprivateslot("hat 0x0302") -- todo other sizes
+ datasets.fixaccents = mapping
+ datasets.extendaccents = mapping
+ datasets.flattenaccents = mapping
+ datasets.copyaccents = mapping
function mathtweaks.fixaccents(target,original,parameters)
local characters = target.characters
-
-characters[hat] = copytable(characters[0x0302]) -- TODO
-
+ local done = false
for stretching, entry in sortedhash(mapping) do
local alias = entry[1]
local stretchingdata = characters[stretching]
@@ -2218,23 +2377,43 @@ characters[hat] = copytable(characters[0x0302]) -- TODO
local width = -topanchor
topanchor = width/2
stretchingdata.width = width
+ stretchingdata.advance = 0
stretchingdata.topanchor = topanchor
stretchingdata.commands = { rightcommand[width + topanchor], charcommand[stretching] }
- if trace_tweaking then
- report_tweak("width of initial extensible accent %U set",target,original,stretching)
+ if not trace_tweaking then
+ done = true
+ elseif done then
+ done[stretching] = true
+ else
+ done = { [stretching] = true }
end
end
end
+ feedback_tweak("fixaccents",target,original,done)
end
+ -- all true|number false
+
function mathtweaks.extendaccents(target,original,parameters)
local characters = target.characters
+ local all = parameters.all
+ local count = tonumber(all)
+ local done = false
for stretching, entry in sortedhash(mapping) do
local extend = entry[2]
- local stretchingdata = characters[stretching]
if extend then
- local last = stretchingdata
+ local last = characters[stretching]
+ local cnt = 1
+ local okay = false
while last do
+ if all or (count and cnt > count) then
+ last.extensible = true
+ local flataccent = last.flataccent
+ if flataccent then
+ characters[flataccent].extensible = true
+ okay = true
+ end
+ end
local n = last.next
if n then
last = characters[n]
@@ -2243,16 +2422,72 @@ characters[hat] = copytable(characters[0x0302]) -- TODO
local flataccent = last.flataccent
if flataccent then
characters[flataccent].extensible = true
+ okay = true
end
break
end
+ cnt = cnt + 1
+ end
+ if okay then
+ if not trace_tweaking then
+ done = true
+ elseif done then
+ done[stretching] = true
+ else
+ done = { [stretching] = true }
+ end
+ end
+ end
+ end
+ feedback_tweak("extendaccents",target,original,done)
+ end
+
+ -- force true false
+ -- height factor 0.8
+ -- offset factor 0.9|calculated
+ -- squeeze factor 0.1|calculated
+
+ function mathtweaks.flattenaccents(target,original,parameters)
+ local characters = target.characters
+ local force = parameters.force
+ local squeeze = parameters.squeeze or 0.8
+ local ofactor = parameters.offset or (squeeze/2)
+ local hfactor = parameters.height or (1 - ofactor)
+ local done = false
+ for stretching, entry in sortedhash(mapping) do
+ local last = characters[stretching]
+ while last do
+ if force or not last.flataccent then
+ local slot = entry[3]
+ local data = copytable(last)
+ local height = data.height or 0
+ data.effect = { squeeze = squeeze }
+ data.height = hfactor * height
+ data.yoffset = ofactor * height
+ characters[slot] = data
+ last.flataccent = slot
+ if not trace_tweaking then
+ done = true
+ elseif done then
+ done[stretching] = true
+ else
+ done = { [stretching] = true }
+ end
+ end
+ local n = last.next
+ if n then
+ last = characters[n]
+ else
+ break
end
end
end
+ feedback_tweak("flattenaccents",target,original,done)
end
function mathtweaks.copyaccents(target,original,parameters)
local characters = target.characters
+ local done = false
for stretching, entry in sortedhash(mapping) do
local alias = entry[1]
if alias ~= stretching then
@@ -2266,15 +2501,20 @@ characters[hat] = copytable(characters[0x0302]) -- TODO
next = stretchingdata.next,
commands = { charcommand[stretching] },
topanchor = stretchingdata.topanchor,
- -- unicode = stretching, -- when we aliasize to combiners
+ -- unicode = stretching, -- when we alias to combiners
unicode = alias, -- when we keep the original
}
- if trace_tweaking then
- report_tweak("extensibles accent %U copied to %U",target,original,stretching,alias)
+ if not trace_tweaking then
+ done = true
+ elseif done then
+ done[stretching] = true
+ else
+ done = { [stretching] = true }
end
end
end
end
+ feedback_tweak("copyaccents",target,original,done)
end
end
@@ -2335,8 +2575,8 @@ do
local parameters = target.parameters
local linewidth = target.MathConstants.RadicalRuleThickness -- make option
local basechar = characters[radical]
- local baseheight = basechar.height/2
- local basedepth = basechar.depth/2
+ local baseheight = (basechar.height or 0)/2
+ local basedepth = (basechar.depth or 0)/2
local basetotal = baseheight + basedepth
local used = baseheight
--
@@ -2364,7 +2604,7 @@ do
downcommand[basedepth],
{ "rule", basetotal, linewidth },
},
- vparts = {
+ parts = {
{
advance = basetotal,
["end"] = used,
@@ -2408,7 +2648,7 @@ do
upcommand[baseheight-4*linewidth],
{ "rule", 4*linewidth, linewidth },
},
- vparts = {
+ parts = {
{
advance = basetotal,
["end"] = used,
@@ -2489,7 +2729,7 @@ do
commands = {
scale == 1 and charcommand[basecode] or { "slot", 0, basecode, scale, scale },
},
- vparts = {
+ parts = {
{
advance = used,
["end"] = used,
@@ -2553,13 +2793,13 @@ do
-- local used = 0.8*height
local used = 1.2*height -- large overlap because no smaller pieces
local total = height + depth
- characters[single].vparts = extensible(single,total,used)
+ characters[single].parts = extensible(single,total,used)
characters[double] = {
unicode = double,
width = 2*width - 1*advance,
height = height,
depth = depth,
- vparts = extensible(double,total,used),
+ parts = extensible(double,total,used),
callback = "devirtualize",
commands = {
charcommand[single],
@@ -2787,16 +3027,10 @@ do
elseif trace_tweaking then
report_tweak("skipping mirror %U (%s)",target,original,unicode,what)
end
- local hparts = data.hparts
- if hparts then
- for i=1,#hparts do
- add(target,original,characters,hparts[i],"hpart")
- end
- end
- local vparts = data.vparts
- if vparts then
- for i=1,#vparts do
- add(target,original,characters,vparts[i],"vpart")
+ local parts = data.parts
+ if parts then
+ for i=1,#parts do
+ add(target,original,characters,parts[i],"hpart")
end
end
local smaller = data.smaller
@@ -2907,7 +3141,7 @@ do
if setlist or resetlist then
local properties = target.properties
local codes = tex.mathcontrolcodes
- local oldcontrol = tex.get("mathfontcontrol")
+ local oldcontrol = texget("mathfontcontrol")
local newcontrol = oldcontrol
-- todo: reset
if resetlist then
@@ -2989,15 +3223,13 @@ do
local features = target.specification.features.normal
local definedfont = fonts.definers.internal
local copiedglyph = fonts.handlers.vf.math.copy_glyph
--- does a deep copy, including parts and so
+ -- does a deep copy, including parts and so
local getsubstitution = fonts.handlers.otf.getsubstitution
local fontdata = fonts.hashes.identifiers
--
local fonts = target.fonts
local size = target.size
local characters = target.characters
--- local descriptions = target.descriptions
- -- compact: size = 655360
if not fonts then
fonts = { }
target.fonts = fonts
@@ -3019,8 +3251,7 @@ do
local firstsource = sourcerange.first
local lastsource = sourcerange.last or firstsource
if firstsource and firsttarget then
- local offset = firsttarget - firstsource
- local topovershoot = entry.topovershoot
+ local offset = firsttarget - firstsource
if filename then
local rscale = entry.rscale or 1 -- todo
size = size * rscale -- maybe use scale in vf command
@@ -3047,11 +3278,10 @@ do
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
+-- 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)
--- description
end
end
elseif feature then
@@ -3062,11 +3292,10 @@ do
local variant = getsubstitution(original,sourceunicode,feature,true,"math","dflt")
local data = characters[variant]
if data then
- if trace_tweaking then
- report_tweak("copying %s %U from feature %a to %s %U",target,original,thesource,sourceunicode,feature,thetarget,targetunicode)
- end
+-- if trace_tweaking then
+-- report_tweak("copying %s %U from feature %a to %s %U",target,original,thesource,sourceunicode,feature,thetarget,targetunicode)
+-- end
characters[targetunicode] = copytable(data)
--- description
end
end
else
@@ -3075,13 +3304,12 @@ do
local sourceunicode = mathgaps[s] or s
local targetunicode = mathgaps[t] or t
if sourceunicode ~= targetunicode then
- local data = characters[sourceunicode]
+ local data = characters[sourceunicode]
if data then
- if trace_tweaking then
- report_tweak("copying %s %U to %s %U",target,original,thesource,sourceunicode,thetarget,targetunicode)
- end
+-- if trace_tweaking then
+-- report_tweak("copying %s %U to %s %U",target,original,thesource,sourceunicode,thetarget,targetunicode)
+-- end
characters[targetunicode] = copytable(data)
--- description
end
end
end
@@ -3184,21 +3412,23 @@ local function applytweaks(when,target,original)
end
end
+local function tweakable(target)
+ local mathparameters = target.mathparameters
+-- local features = target.specification.features
+-- local mathscript = features and features.normal and features.normal.script == "math"
+-- return mathparameters and mathscript -- and target,properties.hasmath
+ return mathparameters
+end
+
function mathematics.tweakbeforecopyingfont(target,original)
- if use_math_goodies then
- local mathparameters = target.mathparameters -- why not hasmath
- if mathparameters then
- applytweaks("beforecopying",target,original)
- end
+ if use_math_goodies and tweakable(target) then
+ applytweaks("beforecopying",target,original)
end
end
function mathematics.tweakaftercopyingfont(target,original)
- if use_math_goodies then
- local mathparameters = target.mathparameters -- why not hasmath
- if mathparameters then
- applytweaks("aftercopying",target,original)
- end
+ if use_math_goodies and tweakable(target) then
+ applytweaks("aftercopying",target,original)
end
end
@@ -3232,8 +3462,7 @@ do
local reported = table.setmetatableindex("table")
function mathematics.checkaftercopyingfont(target,original)
- local mathparameters = target.mathparameters -- why not hasmath
- if mathparameters then
+ if tweakable(target) then
local chardata = characters.data
local characters = target.characters
--
@@ -3300,11 +3529,8 @@ do
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
+ if tweakable(target) then
+ applytweaks("beforepassing",target,target)
end
end
@@ -3352,15 +3578,7 @@ local function extensiblecode(font,unicode)
if not char then
return unknown
end
- if character.hparts then
- if character.vparts then
- return { e_mixed, code, character }
- else
- local m = char.mathextensible
- local e = m and extensibles[m]
- return e and { e, code, character } or unknown
- end
- elseif character.vparts then
+ if character.parts then
local m = char.mathextensible
local e = m and extensibles[m]
return e and { e, code, character } or unknown
@@ -3402,19 +3620,19 @@ local function horizontalcode(family,unicode)
local loffset = 0
local roffset = 0
if kind == e_left then
- local charlist = data[3].hparts
+ local charlist = data[3].parts
if charlist then
local left = charlist[1]
loffset = abs((left["start"] or 0) - (left["end"] or 0))
end
elseif kind == e_right then
- local charlist = data[3].hparts
+ local charlist = data[3].parts
if charlist then
local right = charlist[#charlist]
roffset = abs((right["start"] or 0) - (right["end"] or 0))
end
elseif kind == e_horizontal then
- local charlist = data[3].hparts
+ local charlist = data[3].parts
if charlist then
local left = charlist[1]
local right = charlist[#charlist]
@@ -3444,3 +3662,52 @@ interfaces.implement { -- can be public with two times "integerargument"
context(kind)
end
}
+
+function mathematics.variantcode(unicode,variant)
+ local data = fontcharacters[getfontoffamily(texget("fam"))]
+ local char = data and data[unicode]
+ if char then
+ for i=1,variant do
+ local next = char.next
+ if next then
+ unicode = next
+ char = data[next]
+ else
+ break
+ end
+ end
+ end
+ return unicode
+end
+
+function mathematics.variantcount(unicode)
+ local data = fontcharacters[getfontoffamily(texget("fam"))]
+ local char = data and data[unicode]
+ local count = 0
+ if char then
+ while true do
+ local next = char.next
+ if next then
+ count = count + 1
+ char = data[next]
+ else
+ break
+ end
+ end
+ end
+ return count
+end
+
+interfaces.implement {
+ name = "mathvariantcode",
+ public = true,
+ arguments = { "integer", "integer" },
+ actions = { mathematics.variantcode, context },
+}
+
+interfaces.implement {
+ name = "mathvariantcount",
+ public = true,
+ arguments = "integer",
+ actions = { mathematics.variantcount, context },
+}