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.lmt1083
1 files changed, 902 insertions, 181 deletions
diff --git a/tex/context/base/mkxl/math-act.lmt b/tex/context/base/mkxl/math-act.lmt
index f0b132d66..7fb4f9b9f 100644
--- a/tex/context/base/mkxl/math-act.lmt
+++ b/tex/context/base/mkxl/math-act.lmt
@@ -23,6 +23,11 @@ local trace_tweaking = false trackers.register("math.tweaks", function(v)
local report_math = logs.reporter("mathematics","initializing")
local report_mathtweak = logs.reporter("mathematics","tweak")
+local getfontoffamily = tex.getfontoffamily
+local fontcharacters = fonts.hashes.characters
+local chardata = characters.data
+local extensibles = mathematics.extensibles
+
local context = context
local commands = commands
local mathematics = mathematics
@@ -166,28 +171,6 @@ function mathematics.checkaccentbaseheight(target,original)
end
end
--- function mathematics.checkprivateparameters(target,original)
--- local mathparameters = target.mathparameters
--- if mathparameters then
--- local parameters = target.parameters
--- local properties = target.properties
--- if parameters then
--- local size = parameters.size
--- if size then
--- -- gone
--- elseif properties then
--- report_math("invalid parameters in font %a",properties.fullname or "?")
--- else
--- report_math("invalid parameters in font")
--- end
--- elseif properties then
--- report_math("no parameters in font %a",properties.fullname or "?")
--- else
--- report_math("no parameters and properties in font")
--- end
--- end
--- end
-
function mathematics.overloadparameters(target,original)
if use_math_goodies then
local mathparameters = target.mathparameters
@@ -200,6 +183,8 @@ function mathematics.overloadparameters(target,original)
if mathematics then
local parameters = mathematics.parameters
local bigslots = mathematics.bigslots or mathematics.bigs
+-- inspect(parameters)
+-- print("before",mathparameters.AxisHeight)
if parameters then
if trace_defining then
report_math("overloading math parameters in %a @ %p",target.properties.fullname,target.parameters.size)
@@ -222,6 +207,7 @@ function mathematics.overloadparameters(target,original)
end
mathparameters[name] = newvalue
end
+-- print("after ",mathparameters.AxisHeight)
for name, value in next, parameters do
local tvalue = type(value)
if tvalue == "string" then
@@ -265,7 +251,7 @@ local function report_tweak(fmt,target,original,...)
(target and target .shared.rawdata.metadata)
local parameters = target.parameters
report_mathtweak(
- "%a, size %p, math size %i, %s",
+ "%a, size %P, math size %i, %s",
metadata and metadata.fontname or "unknown",
parameters.size or 655360,
parameters.mathsize or 1,
@@ -276,6 +262,39 @@ local function report_tweak(fmt,target,original,...)
end
end
+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 },
+ dotless = { 0x00049, 0x0004A, 0x00131, 0x00237, 0x1D6A4, 0x1D6A5 },
+ integrals = { 0x0222B, 0x0222C, 0x0222D, 0x0222E, 0x0222F, 0x02230, 0x02231, 0x02232, 0x02233, 0x02A0B, 0x02A0C, 0x02A0D, 0x02A0E, 0x02A0F, 0x02A10, 0x02A11, 0x02A12, 0x02A13, 0x02A14, 0x02A15, 0x02A16, 0x02A17, 0x02A18, 0x02A19, 0x02A1A, 0x02A1B, 0x02A1C },
+}
+
+local function getalso(target,original)
+ local also = target.tweakalso -- maybe
+ if not also then
+ also = { }
+ for k, v in sortedhash(target.characters) do
+ local u = v.unicode
+ if u and k ~= u then
+ local a = also[u]
+ if a then
+ a[#a+1] = k
+ else
+ also[u] = { k }
+ end
+ end
+ end
+ target.tweakalso = also
+ end
+ return also
+end
+
-- {
-- tweak = "dimensions",
-- list = {
@@ -398,32 +417,33 @@ do
extend = factor,
}, v)
end
- local original = v.original
- if not original then
+ local originalslot = v.original
+ if not originalslot then
local delta = v.delta
if delta then
- original = k + delta
+ originalslot = k + delta
end
end
- if original then
- original = mathgaps[original] or original
- local data = targetcharacters[original]
+ if originalslot then
+ originalslot = mathgaps[originalslot] or originalslot
+ local data = targetcharacters[originalslot]
if data then
data = copytable(data)
- data.unicode = original
+ data.unicode = originalslot
targetcharacters[k] = data
character = data
else
- report_mathtweak("no slot %U",original)
+ report_mathtweak("no slot %U",originalslot)
return
end
end
--
- local width = character.width
- local height = character.height
- local depth = character.depth
- local italic = character.italic
- local topaccent = character.topaccent
+ local width = character.width
+ local height = character.height
+ local depth = character.depth
+ local italic = character.italic
+ local topanchor = character.topanchor
+ local bottomanchor = character.bottomanchor
--
local widthfactor = v.width
local heightfactor = v.height
@@ -442,7 +462,7 @@ do
if advancefactor then
character.advance = advancefactor * width
else
- character.advance = width -- so advance is oldwidth
+ character.advance = character.advance or width -- so advance is oldwidth
end
if widthfactor then
character.width = widthfactor * width
@@ -470,8 +490,11 @@ do
end
end
if anchorfactor then
- character.topaccent = anchorfactor * (topaccent or width)
+ character.topanchor = anchorfactor * (topanchor or width)
end
+-- if anchorfactor then
+-- character.bottomaccent = anchorfactor * (bottomanchor or width)
+-- end
-- begin experiment
local line = v.wline
if line then
@@ -575,12 +598,26 @@ end
do
+ function mathtweaks.showinfo(target,original,parameters)
+ local mathparameters = target.mathparameters
+ for k, v in sortedhash(mathparameters) do
+ report_mathtweak("%s : %s",k,v)
+ end
+ end
+
+end
+
+
+do
+
function mathtweaks.wipevariants(target,original,parameters)
local list = parameters.list
if list then
local targetcharacters = target.characters
-- local originalcharacters = original.characters
local count = 0
+ -- local also = getalso(target,original)
+ -- local done = { }
for k, v in sortedhash(list) do
local ori = targetcharacters[k]
local nxt = ori.next
@@ -675,17 +712,6 @@ 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
@@ -749,37 +775,11 @@ end
do
- -- What a mess ... should be a different alphabet.
-
- local function expand(target,original,list,selector,feature)
- if feature then
- local getsubstitution = fonts.handlers.otf.getsubstitution
- for _, char in next, list do
- local variant = getsubstitution(original,char,feature,true)
- if variant then
- mathematics.addvariant(target,char,variant,selector)
- end
- end
- else
- for i, char in next, list do
- mathematics.addvariant(target,char,0xFE800+i,selector)
- end
- end
- end
-
function mathtweaks.variants(target,original,parameters)
- local feature = parameters.feature
- local selector = parameters.selector
- local kind = parameters.kind
- if kind == "script" then
- if selector then
- expand(target,original,mathematics.alphabets.sr.tf.lcletters,selector,feature)
- expand(target,original,mathematics.alphabets.sr.tf.ucletters,selector,feature)
- end
- end
+ report_mathtweak("todo: remove 'variants' tweak from goodie file")
end
- mathtweaks.variant = mathtweaks.variants
+ mathtweaks.variant = mathtweaks.variants
end
@@ -1052,80 +1052,219 @@ do
local factor = tonumber(parameters.factor) or 0
if factor ~= 0 then
for k, v in next, targetcharacters do
- local a = v.topaccent
+ local a = v.topanchor
if a and a > 0 then
- v.topaccent = a * factor
+ v.topanchor = a * factor
end
end
end
end
- -- local default = {
- -- "digitsnormal",
- -- "lowercasedoublestruck",
- -- "uppercasedoublestruck",
- -- }
+ 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
+
+ local issymbol = characters.is_symbol
+
+ function mathtweaks.oldstylemath(target,original,parameters)
+ 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
+ v.yoffset = -delta
+ v.height = (v.height or 0) - delta
+ v.depth = (v.depth or 0) - delta
+ end
+ end
+ end
- local function wipe(target,original,parameters,field)
- local targetcharacters = target.characters
+end
+
+do
+
+ function mathtweaks.simplifykerns(target,original,parameters)
+ local characters = target.characters
+ local simplified = 0
+ for k, v in sortedhash(characters) do
+ local mathkerns = v.mathkerns
+ if mathkerns then
+ local k = mathkerns.topleft
+ if k then
+ k = k[#k].kern
+ if k then
+ v.topleft = k
+ end
+ end
+ local k = mathkerns.topright
+ if k then
+ k = k[#k].kern
+ if k then
+ v.topright = k
+ end
+ end
+ local k = mathkerns.bottomleft
+ if k then
+ k = k[1].kern -- todo get value at baseline
+ if k then
+ v.bottomleft = k
+ end
+ end
+ local k = mathkerns.bottomright
+ if k then
+ k = k[1].kern -- todo get value at baseline
+ if k then
+ v.bottomright = k
+ end
+ end
+ v.mathkerns = nil
+ simplified = simplified + 1
+ 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
+ end
+
+end
+
+do
+
+ local function wipe(target,original,parameters,field,move,integrals)
+ local targetcharacters = target.characters
+ local targetdescriptions = target.descriptions
+ local factor = target.parameters.factor
+ local correct = parameters.correct
+ local function getllx(u)
+ local d = targetdescriptions[u]
+ if d then
+ local b = d.boundingbox
+ if b then
+ local llx = b[1]
+ if llx < 0 then
+ return - llx
+ end
+ end
+ end
+ return false
+ end
local function step(s,l)
- local done = false
while s do
- local c = targetcharacters[mathgaps[s] or s]
+ local u = mathgaps[s] or s
+ local c = targetcharacters[u]
if c then
- local v = c[field]
- if v then
- if trace_tweaking then
- if l then
- report_tweak("removing %a in range %a from %C",target,original,field,l,s)
+ if field == "topanchor" then
+ if c.topanchor then
+ c.topanchor = nil
+ else
+ goto smaller
+ end
+ else
+ local done = false
+ local italic = c.italic
+ if move then
+ local width = c.width or 0
+ c.advance = width
+ if correct then
+ local llx = getllx(u)
+ if llx then
+ local topanchor = c.topanchor
+ llx = llx * factor
+ width = width + llx
+ c.xoffset = llx
+ if topanchor then
+ c.topanchor = topanchor + llx
+ end
+-- if c.bottomleft or c.topleft then
+-- print("BEFORE",c.bottomleft,c.topleft,llx)
+-- c.bottomleft = (c.bottomleft or 0) - llx
+-- c.topleft = (c.topleft or 0) - llx
+-- print("AFTER",c.bottomleft,c.topleft,llx)
+-- else
+ c.bottomleft = (c.bottomleft or 0) - llx
+ c.topleft = (c.topleft or 0) - llx
+-- end
+ done = true
+ end
+ end
+ if italic and italic ~= 0 then
+ c.width = width + italic
+-- print(">>>",bottomright)
+ c.bottomright = - italic
+-- c.bottomright = c.bottomright - italic
+ done = true
else
- report_tweak("removing %a from %C",target,original,field,s)
+ c.width = width
end
end
- c[field] = nil
- done = true
+ if italic then
+ c.italic = nil
+ done = 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)
+ else
+ report_tweak("%s %a from %C","removing",target,original,field,s)
+ end
+ end
+ goto smaller
+ ::smaller::
s = c.smaller
else
break
end
end
- return done
end
local list = parameters.list -- todo: ranges
- -- if list == "default" then
- -- list = default
- -- else
if type(list) == "string" then
list = { list }
end
for i=1,#list do
local l = list[i]
- local r = blocks[l]
- if r then
- local done = false
- for i=r.first,r.last do
- if step(i,l) then
- done = true
- end
- end
- if not done and trace_tweaking then
- report_mathtweak("there is no need to remove %a range %a",field,l)
+ if type(l) == "table" then
+ for i=1,#l do
+ step(i,l[i])
end
else
- stepper(l,step)
+ local r = blocks[l]
+ if r then
+ for i=r.first,r.last do
+ step(i,l)
+ end
+ else
+ stepper(l,step)
+ end
end
end
end
function mathtweaks.wipeanchors(target,original,parameters)
- wipe(target,original,parameters,"topaccent")
+ wipe(target,original,parameters,"topanchor")
end
+ mathtweaks.wipeaccents = mathtweaks.wipeanchors
+
function mathtweaks.wipeitalics(target,original,parameters)
wipe(target,original,parameters,"italic")
end
+ function mathtweaks.moveitalics(target,original,parameters)
+ wipe(target,original,parameters,"italic",true)
+ end
+
-- function mathtweaks.fixdigits(target,original,parameters)
-- mathtweaks.fixanchors(target,original,{ list = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 } })
-- end
@@ -1134,6 +1273,88 @@ end
do
+ function mathtweaks.topanchors(target,original,parameters)
+ local characters = target.characters
+ local list = parameters.list
+ if list then
+ for k, v in sortedhash(list) do
+ local c = characters[k]
+ if c then
+ local w = c.width
+ if w and w ~= 0 then
+ c.topanchor = v * w
+ if trace_tweaking then
+ -- todo
+ end
+ end
+ end
+ end
+ -- todo: small
+ end
+ end
+
+ mathtweaks.topaccents = mathtweaks.topanchors
+
+ function mathtweaks.limits(target,original,parameters)
+ local characters = target.characters
+ local list = parameters.list
+ if list then
+ local factor = parameters.factor or 1
+ local also = getalso(target,original)
+ local done = { }
+ local function relocate(u,factor)
+ if done[u] then
+ return
+ end
+ done[u] = true
+ local c = characters[u]
+ if c then
+ local italic = c.italic
+ if italic and italic ~= 0 then
+ local width = c.width or 0
+ local half = (italic/2) * factor
+ c.topanchor = width + half
+ c.bottomanchor = width - half
+ c.bottomright = - italic
+ c.italic = nil
+ if trace_tweaking then
+ -- todo
+ end
+ end
+ local s = c.smaller
+ if s then
+ relocate(s,factor)
+ end
+ local n = c.next
+ if n then
+ relocate(n,factor)
+ end
+ if also then
+ local a = also[u]
+ if a then
+ for i=1,#a do
+ relocate(a[i],factor)
+ end
+ end
+ end
+ end
+ end
+ if #list > 0 then
+ for i=1,#list do
+ relocate(list[i],factor)
+ end
+ else
+ for k, v in sortedhash(list) do
+ relocate(k,tonumber(v) or factor)
+ end
+ end
+ end
+ end
+
+end
+
+do
+
-- musical timestamp: March 2022, Antonio Sanches (Bad Hombre), live performance in NL
function mathtweaks.kerns(target,original,parameters)
@@ -1178,12 +1399,14 @@ do
local characters = target.characters
local function setone(unicode,data)
local chardata = characters[mathgaps[unicode] or unicode]
- local width = chardata.width or 0
- local total = (chardata.height or 0) + (chardata.depth or 0)
- local k = data.left ; if k and k ~= 0 then chardata.leftmargin = k * width end
- local k = data.right ; if k and k ~= 0 then chardata.rightmargin = k * width end
- local k = data.top ; if k and k ~= 0 then chardata.topmargin = k * total end
- local k = data.bottom ; if k and k ~= 0 then chardata.bottommargin = k * total end
+ if chardata then
+ local width = chardata.width or 0
+ local total = (chardata.height or 0) + (chardata.depth or 0)
+ local k = data.left ; if k and k ~= 0 then chardata.leftmargin = k * width end
+ local k = data.right ; if k and k ~= 0 then chardata.rightmargin = k * width end
+ local k = data.top ; if k and k ~= 0 then chardata.topmargin = k * total end
+ local k = data.bottom ; if k and k ~= 0 then chardata.bottommargin = k * total end
+ end
end
for unicode, data in next, margins do
setone(unicode,data) -- withscriptcode(tfmdata,unicode,data,kernone)
@@ -1398,39 +1621,39 @@ 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 } },
- -- hparts = {
- -- { 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 } },
- -- hparts = {
- -- { 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
+
+ -- 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 } },
+ -- hparts = {
+ -- { 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 } },
+ -- hparts = {
+ -- { advance = width, ["end"] = step, glyph = 0x0332, start = 0 },
+ -- { advance = width, ["end"] = 0, glyph = 0x0332, start = step, extender = 1 },
+ -- }
+ -- }
+ -- end
function mathtweaks.addrules(target,original,parameters)
local characters = target.characters
@@ -1787,6 +2010,9 @@ end
do
+ -- mirror
+ -- smaller
+
local list = {
0x221A,
}
@@ -1802,11 +2028,19 @@ do
end
data.height = depth
data.depth = height
+if data.rorrim then
+ -- the original does the magic
+else
data.yoffset = depth - height
+end
+ end
+ local smaller = data.smaller
+ if smaller then
+ fix(target,original,characters,smaller)
end
- local small = data.smaller
- if small then
- fix(target,original,characters,small)
+ local mirror = data.mirror
+ if mirror then
+ fix(target,original,characters,mirror)
end
end
end
@@ -1823,6 +2057,70 @@ end
do
+ local done = nil
+
+ local function fix(target,original,characters,unicode,axis)
+ if done[unicode] then
+ return
+ end
+ done[unicode] = true
+ local data = characters[unicode]
+ if data then
+ local height = data.height or 0
+ local depth = data.depth or 0
+ if trace_tweaking then
+ report_tweak("swapping height and depth of %U",target,original,unicode)
+ end
+ local half = (height + depth)/2
+ if data.rorrim then
+ -- the original does the magic
+ else
+ data.yoffset = depth - (half - axis)
+ end
+ height = half + axis
+ depth = half - axis
+ data.height = height
+ data.depth = depth
+ local smaller = data.smaller
+ if smaller then
+ fix(target,original,characters,smaller,axis)
+ end
+ local mirror = data.mirror
+ if mirror then
+ fix(target,original,characters,mirror,axis)
+ end
+ local next = data.next
+ if next then
+ fix(target,original,characters,next,axis)
+ end
+ end
+ end
+
+ function mathtweaks.fixoldschool(target,original,parameters)
+ local characters = target.characters
+ local list = mathtweaks.subsets.integrals
+ local also = getalso(target,original)
+ local axis = target.mathparameters.AxisHeight
+ done = { }
+ for i=1,#list do
+ local unicode = list[i]
+ fix(target,original,characters,unicode,axis)
+ end
+ if also then
+ local a = also[u]
+ if a then
+ for i=1,#a do
+ fix(target,original,characters,a[i],axis)
+ end
+ end
+ end
+ done = nil
+ end
+
+end
+
+do
+
local list = { 0x2061, 0x2062, 0x2063, 0x2064 }
function mathtweaks.wipecues(target,original,parameters)
@@ -1896,12 +2194,12 @@ characters[hat] = copytable(characters[0x0302]) -- TODO
local alias = entry[1]
local stretchingdata = characters[stretching]
if stretchingdata and stretchingdata.width == 0 then
- local topaccent = stretchingdata.topaccent or 0
- local width = -topaccent
- topaccent = width/2
+ local topanchor = stretchingdata.topanchor or 0
+ local width = -topanchor
+ topanchor = width/2
stretchingdata.width = width
- stretchingdata.topaccent = topaccent
- stretchingdata.commands = { rightcommand[width + topaccent], charcommand[stretching] }
+ 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)
end
@@ -1925,7 +2223,7 @@ characters[hat] = copytable(characters[0x0302]) -- TODO
local flataccent = last.flataccent
if flataccent then
characters[flataccent].extensible = true
- end
+ end
break
end
end
@@ -1947,7 +2245,7 @@ characters[hat] = copytable(characters[0x0302]) -- TODO
depth = stretchingdata.depth,
next = stretchingdata.next,
commands = { charcommand[stretching] },
- topaccent = stretchingdata.topaccent,
+ topanchor = stretchingdata.topanchor,
-- unicode = stretching, -- when we aliasize to combiners
unicode = alias, -- when we keep the original
}
@@ -2018,7 +2316,9 @@ do
local linewidth = target.MathConstants.RadicalRuleThickness -- make option
local basechar = characters[radical]
local baseheight = basechar.height
+/2
local basedepth = basechar.depth
+/2
local basetotal = baseheight + basedepth
local used = baseheight
--
@@ -2188,7 +2488,7 @@ do
}
}
if trace_tweaking then
- report_tweak("fourier %U added using %U",target,original,basecode,fourier)
+ report_tweak("fourier %U added using %U",target,original,basecode,fouriercode)
end
end
end
@@ -2284,17 +2584,17 @@ do
function mathtweaks.fixellipses(target,original,parameters)
local characters = target.characters
local function fix(normal,raised)
- local normalone = characters[normal]
- if normalone then
- local raisedone = copytable(normalone)
- characters[raised] = raisedone
- raisedone.unicode = weird
- local height = raisedone.height
+ local normaldata = characters[normal]
+ if normaldata then
+ local raiseddata = copytable(normaldata)
+ characters[raised] = raiseddata
+ raiseddata.unicode = raised
+ local height = raiseddata.height
local yoffset = (parameters.yoffset or 2) * height
- raisedone.yoffset = yoffset
- raisedone.height = height + yoffset
+ raiseddata.yoffset = yoffset
+ raiseddata.height = height + yoffset
if trace_tweaking then
- report_tweak("taking %U from %U",target,original,weird,normal)
+ report_tweak("taking %U from %U",target,original,raised,normal)
end
end
end
@@ -2358,6 +2658,163 @@ 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.
+
+ -- Checked while watching/listening to Dave Matthews Band: The Central Park Concert
+ -- (with superb solos by Warren Haynes), a DVD I bought around when we started with the
+ -- LUATEX advanture.
+
+ local mirrors = {
+
+ [0x0002F] = true, -- slashes
+ [0x0005C] = true,
+ [0x000F7] = true,
+
+ [0x02032] = true, -- primes
+ [0x02033] = true,
+ [0x02034] = true,
+ [0x02057] = true,
+ [0x02035] = true,
+ [0x02036] = true,
+ [0x02037] = true,
+
+ [0x0221A] = true, -- radicals
+ [0x0221B] = true,
+ [0x0221C] = true,
+ [0x0221D] = true,
+
+ [0x0222B] = true, -- integrals
+ [0x0222C] = true,
+ [0x0222D] = true,
+ [0x0222E] = true,
+ [0x0222F] = true,
+ [0x02230] = true,
+ [0x02231] = true,
+ [0x02232] = true,
+ [0x02233] = true,
+
+ [0x02A0A] = true, -- seen in xits (to be checked)
+ [0x02A0B] = true,
+ [0x02A0C] = true,
+ [0x02A0D] = true,
+ [0x02A0E] = true,
+
+ [0x02140] = true,
+ [0x02201] = true,
+ [0x02202] = true,
+ [0x02203] = true,
+ [0x02204] = true,
+ [0x02211] = true,
+
+ [0x02239] = true,
+ [0x0225F] = true,
+ [0x0228C] = true,
+ [0x022A7] = true,
+ [0x022AA] = true,
+ [0x022AC] = true,
+ [0x022AD] = true,
+ [0x022AE] = true,
+ [0x022AF] = true,
+ [0x022F5] = true,
+ [0x022F8] = true,
+ [0x022F9] = true,
+ [0x022FF] = true,
+ [0x02320] = true,
+ [0x02321] = true,
+ [0x027C0] = true,
+ [0x029DC] = true,
+ [0x029F4] = true,
+
+ [0x02A0F] = true,
+ [0x02A10] = true,
+ [0x02A11] = true,
+ [0x02A12] = true,
+ [0x02A13] = true,
+ [0x02A14] = true,
+ [0x02A15] = true,
+ [0x02A16] = true,
+ [0x02A17] = true,
+ [0x02A18] = true,
+ [0x02A19] = true,
+ [0x02A1A] = true,
+ [0x02A1B] = true,
+ [0x02A1C] = true,
+ [0x02A20] = true,
+
+ [0x02A74] = true,
+ [0x02AA3] = true,
+ [0x02AE2] = true,
+ [0x02AE6] = true,
+ [0x1D715] = true,
+ }
+
+ local new = fonts.helpers.newprivateslot
+
+ local function add(target,original,characters,unicode,what)
+ local data = characters[unicode]
+ if data then
+ if not data.mirror then
+ local slot = new("mirror."..unicode)
+ local mirror = copytable(data)
+ data.mirror = slot
+ mirror.rorrim = unicode -- so we can check later
+ mirror.commands = {
+ { "offset", data.width, 0, unicode, -1, 1 }
+ }
+ if trace_tweaking then
+ report_tweak("adding mirror %U (%s)",target,original,unicode,what)
+ end
+ characters[slot] = mirror
+ 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")
+ end
+ end
+ local smaller = data.smaller
+ if smaller then
+ add(target,original,characters,"smaller")
+ end
+ local next = data.next
+ if next then
+ add(target,original,characters,next,"next")
+ end
+ end
+ end
+
+ -- todo: also check the rtlm table if present
+
+ function mathtweaks.addmirrors(target,original,parameters)
+ local characters = target.characters
+ for unicode, detail in sortedhash(characters) do
+ local data = chardata[unicode]
+ if data and data.mirror then
+ add(target,original,characters,unicode,"mirror")
+ end
+ end
+ for unicode, detail in sortedhash(mirrors) do
+ if characters[unicode] then
+ add(target,original,characters,unicode,"character")
+ elseif trace_tweaking then
+ report_tweak("ignoring mirror %U (%s)",target,original,unicode,what)
+ end
+ end
+ end
+
+end
+
+do
+
local reported = { }
function mathtweaks.version(target,original,parameters)
@@ -2380,6 +2837,215 @@ do
report_tweak()
end
reported[fontname] = true
+ target.tweakversion = version
+ end
+ end
+ end
+
+end
+
+do
+
+ function mathtweaks.diagnose(target,original,parameters)
+ local characters = target.characters
+ for k, v in sortedhash(characters) do
+ local italic = v.italic
+ if italic then
+ report_tweak("italics: %U %p",target,original,k,italic)
+ end
+ end
+-- inspect(characters[0xF0929])
+ end
+
+end
+
+do
+
+ function mathtweaks.setoptions(target,original,parameters)
+ local setlist = parameters.set or parameters.list
+ local resetlist = parameters.reset
+ if setlist or resetlist then
+ local properties = target.properties
+ local codes = tex.mathcontrolcodes
+ local oldcontrol = tex.get("mathfontcontrol")
+ local newcontrol = oldcontrol
+ -- todo: reset
+ if resetlist then
+ for i=1,#resetlist do
+ local v = tonumber(codes[resetlist[i]])
+ if v then
+ newcontrol = newcontrol & (not v)
+ end
+ end
+ end
+ if setlist then
+ for i=1,#setlist do
+ local v = tonumber(codes[setlist[i]])
+ if v then
+ newcontrol = newcontrol | v
+ end
+ end
+ end
+ newcontrol = newcontrol | codes.usefontcontrol
+ properties.mathcontrol = newcontrol
+ target.mathcontrol = newcontrol
+ if trace_tweaking then
+ report_tweak("forcing math font options 0x%08X instead of 0x08X",target,original,newcontrol,oldcontrol)
+ end
+ end
+ end
+
+end
+
+do
+
+ function mathtweaks.setovershoots(target,original,parameters)
+ local list = parameters.list
+ if list then
+ local characters = target.characters
+ local emwidth = target.parameters.quad
+ for i=1,#list do
+ local entry = list[i]
+ local target = entry.target
+ local top = entry.topovershoot
+ local quad = entry.quad
+ if target and top then
+ local range = blocks[target]
+ if range then
+ if quad then
+ quad = emwidth
+ end
+ for r = range.first, range.last do
+ local unicode = mathgaps[r] or r
+ local data = characters[unicode]
+ if data then
+ data.topovershoot = top * (quad or data.width or 0)
+ end
+ end
+ if trace_tweaking then
+ report_mathtweak("setting overshoots for %a",target)
+ end
+ end
+ end
+ end
+ end
+ end
+
+ -- there is no real need for thios but let's play nice with memory anyway
+
+ local efindex = 0
+ local effects = setmetatableindex (function (t,k)
+ efindex = efindex + 1
+ local v = "tweakreplacealphabets" .. efindex
+ local e = fonts.specifiers.presetcontext(v,"",k)
+ -- print(k,v,e)
+ t[k] = v
+ return v
+ end)
+
+ function mathtweaks.replacealphabets(target,original,parameters)
+ local feature = parameters.feature
+ local features = target.specification.features.normal
+ if not feature or features[feature] == true then
+ local list = parameters.list
+ if list then
+ local definedfont = fonts.definers.internal
+ local copiedglyph = fonts.handlers.vf.math.copy_glyph
+-- 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
+ -- compact: size = 655360
+ if not fonts then
+ fonts = { }
+ target.fonts = fonts
+ end
+ if #fonts == 0 then
+ fonts[1] = { id = 0, size = size } -- self, will be resolved later
+ end
+ for i=1,#list do
+ local entry = list[i]
+ local filename = entry.filename
+ local feature = entry.feature
+ local thesource = entry.source
+ local thetarget = entry.target or thesource
+ 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
+ if sourcerange and targetrange then
+ local firsttarget = targetrange.first
+ local firstsource = sourcerange.first
+ local lastsource = sourcerange.last or firstsource
+ if firstsource and firsttarget then
+ local offset = firsttarget - firstsource
+ local topovershoot = entry.topovershoot
+ if filename then
+ local rscale = entry.rscale or 1 -- todo
+ size = size * rscale -- maybe use scale in vf command
+ -- load font, todo: set language and script, the effect hack is ugly
+ local fullname = filename
+ local effect = features.effect
+ if effect then
+ fullname = fullname .. "*" .. effects["effect={"..effect.."}"]
+ end
+ local id = definedfont {
+ name = fullname,
+ size = size,
+ }
+ local chars = fontchars[id]
+ local dropin = fontdata[id]
+ local index = #fonts + 1
+ fonts[index] = { id = id, size = size }
+ -- copy characters
+ for s=firstsource,lastsource do
+ local t = s + offset
+ local sourceunicode = mathgaps[s] or s
+ local targetunicode = mathgaps[t] or t
+ if feature then
+ sourceunicode = getsubstitution(dropin,sourceunicode,feature,true,"math","dflt") or sourceunicode
+ end
+ if trace_tweaking then
+ report_mathtweak("copying %s %U from file %a to %s %U",thesource,sourceunicode,filename,thetarget,targetunicode)
+ end
+ characters[targetunicode] = copiedglyph(target,characters,chars,sourceunicode,index)
+ end
+ elseif feature then
+ for s=firstsource,lastsource do
+ local t = s + offset
+ local sourceunicode = mathgaps[s] or s
+ local targetunicode = mathgaps[t] or t
+ local variant = getsubstitution(original,sourceunicode,feature,true,"math","dflt")
+ local data = characters[variant]
+ if data then
+ if trace_tweaking then
+ report_mathtweak("copying %s %U from feature %a to %s %U",thesource,sourceunicode,feature,thetarget,targetunicode)
+ end
+ characters[targetunicode] = copytable(data)
+ end
+ end
+ else
+ for s=firstsource,lastsource do
+ local t = s + offset
+ local sourceunicode = mathgaps[s] or s
+ local targetunicode = mathgaps[t] or t
+ local data = characters[sourceunicode]
+ if data then
+ if trace_tweaking then
+ report_mathtweak("copying %s %U to %s %U",thesource,sourceunicode,thetarget,targetunicode)
+ end
+ characters[targetunicode] = copytable(data)
+ end
+ end
+ end
+ else
+ -- error
+ end
+ end
+ end
+ end
end
end
end
@@ -2418,7 +3084,10 @@ local function applytweaks(when,target,original)
if type(tweak) == "table" then
local action = mathtweaks[tweak.tweak or ""]
if action then
- if original then
+ local version = tweak.version
+ if version and version ~= target.tweakversion then
+ report_math("skipping tweak %a version %a",tweak.tweak,version)
+ elseif original then
action(target,original,tweak)
else
action(target,tweak)
@@ -2456,6 +3125,65 @@ function mathematics.tweakaftercopyingfont(target,original)
end
end
+do
+
+ local defaults = {
+ {
+ source = "uppercasescript",
+ target = "uppercasecalligraphic",
+ },
+ {
+ source = "lowercasescript",
+ target = "lowercasecalligraphic",
+ },
+ {
+ source = "uppercaseboldscript",
+ target = "uppercaseboldcalligraphic",
+ },
+ {
+ source = "lowercaseboldscript",
+ target = "lowercaseboldcalligraphic",
+ },
+ }
+
+ function mathematics.checkaftercopyingfont(target,original)
+ local mathparameters = target.mathparameters -- why not hasmath
+ if mathparameters then
+ local characters = target.characters
+ --
+ for i=1,#defaults do
+ -- we assume no ssty here yet .. todo
+ local default = defaults[i]
+ local block = blocks[default.target]
+ local first = block.first
+ local last = block.last
+ if not characters[mathgaps[first] or last] then
+ mathtweaks.replacealphabets(target,original,{
+ tweak = "replacealphabets",
+ list = { default }
+ })
+ end
+ end
+ --
+ local addvariant = mathematics.addvariant
+ local function register(old,new)
+ for i, cold in next, old do
+ local cnew = new[i]
+ addvariant(target,cold,cold,0xFE00)
+ addvariant(target,cnew,cnew,0xFE01)
+ addvariant(target,cnew,cold,0xFE00)
+ addvariant(target,cold,cnew,0xFE01)
+ end
+ end
+ local sr = mathematics.alphabets.sr.tf
+ local ca = mathematics.alphabets.ca.tf
+ register(sr.ucletters,ca.ucletters)
+ register(sr.lcletters,ca.lcletters)
+ end
+ end
+
+end
+
function mathematics.beforepassingfonttotex(target)
if use_math_goodies then
local mathparameters = target.mathparameters -- why not hasmath
@@ -2472,20 +3200,13 @@ sequencers.appendaction("mathparameters","system","mathematics.checkaccentbasehe
sequencers.appendaction("beforecopyingcharacters","system","mathematics.tweakbeforecopyingfont")
sequencers.appendaction("aftercopyingcharacters", "system","mathematics.tweakaftercopyingfont")
+sequencers.appendaction("aftercopyingcharacters", "system","mathematics.checkaftercopyingfont")
sequencers.appendaction("beforepassingfonttotex", "system","mathematics.beforepassingfonttotex")
-- no, it's a feature now (see good-mth):
--
-- sequencers.appendaction("aftercopyingcharacters", "system","mathematics.overloaddimensions")
--- helpers
-
-local getfontoffamily = tex.getfontoffamily
-
-local fontcharacters = fonts.hashes.characters
-local chardata = characters.data
-local extensibles = mathematics.extensibles
-
-- we use numbers at the tex end (otherwise we could stick to chars)
local e_left = extensibles.left
@@ -2657,7 +3378,7 @@ function mathematics.finishfallbacks(target,specification,fallbacks)
if trace_collecting then
report_math("adding fallback characters to font %a",specification.hash)
end
- local definedfont = fonts.definers.internal
+ ----- definedfont = fonts.definers.internal
local copiedglyph = fonts.handlers.vf.math.copy_glyph
local fonts = target.fonts
local size = specification.size -- target.size