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