diff options
author | Karl Berry <karl@freefriends.org> | 2021-03-06 21:58:15 +0000 |
---|---|---|
committer | Karl Berry <karl@freefriends.org> | 2021-03-06 21:58:15 +0000 |
commit | 974640d66e61e81cb197ad96fdff7b08343e4c5a (patch) | |
tree | 2e1f75f32f312b7f24ba82b4590ae230bcd6f399 /Master/texmf-dist/tex/context/base/mkxl/good-mth.lmt | |
parent | b4fa72e61230aca75f7f6fbf988821f71edfb6b2 (diff) |
context
git-svn-id: svn://tug.org/texlive/trunk@58167 c570f23f-e606-0410-a88d-b1316a301751
Diffstat (limited to 'Master/texmf-dist/tex/context/base/mkxl/good-mth.lmt')
-rw-r--r-- | Master/texmf-dist/tex/context/base/mkxl/good-mth.lmt | 464 |
1 files changed, 464 insertions, 0 deletions
diff --git a/Master/texmf-dist/tex/context/base/mkxl/good-mth.lmt b/Master/texmf-dist/tex/context/base/mkxl/good-mth.lmt new file mode 100644 index 00000000000..87b6787df6a --- /dev/null +++ b/Master/texmf-dist/tex/context/base/mkxl/good-mth.lmt @@ -0,0 +1,464 @@ +if not modules then modules = { } end modules ['good-mth'] = { + version = 1.000, + comment = "companion to font-lib.mkiv", + author = "Hans Hagen, PRAGMA-ADE, Hasselt NL", + copyright = "PRAGMA ADE / ConTeXt Development Team", + license = "see context related readme files" +} + +local type, next, tonumber, unpack = type, next, tonumber, unpack +local ceil = math.ceil +local match = string.match + +local fonts = fonts + +local trace_goodies = false trackers.register("fonts.goodies", function(v) trace_goodies = v end) +local report_goodies = logs.reporter("fonts","goodies") + +local registerotffeature = fonts.handlers.otf.features.register + +local fontgoodies = fonts.goodies or { } + +local fontcharacters = fonts.hashes.characters + +local trace_defining = false trackers.register("math.defining", function(v) trace_defining = v end) + +local report_math = logs.reporter("mathematics","initializing") + +local nuts = nodes.nuts + +local setlink = nuts.setlink + +local nodepool = nuts.pool + +local new_kern = nodepool.kern +local new_glyph = nodepool.glyph +local new_hlist = nodepool.hlist +local new_vlist = nodepool.vlist + +local insert_node_after = nuts.insert_after + +local helpers = fonts.helpers +local upcommand = helpers.commands.up +local rightcommand = helpers.commands.right +local charcommand = helpers.commands.char +local prependcommands = helpers.prependcommands + +-- experiment, we have to load the definitions immediately as they precede +-- the definition so they need to be initialized in the typescript + +local function withscriptcode(tfmdata,unicode,data,action) + if type(unicode) == "string" then + local p, u = match(unicode,"^(.-):(.-)$") + if u then + u = tonumber(u) + if u then + local slots = fonts.helpers.mathscriptslots(tfmdata,u) + if slots then + if p == "*" then + action(u,data) + for i=1,#slots do + action(slots[i],data) + end + else + p = tonumber(p) + if p then + action(slots[p],data) + end + end + end + end + end + else + action(unicode,data) + end +end + +local function finalize(tfmdata,feature,value) +-- if tfmdata.mathparameters then -- funny, cambria text has this + local goodies = tfmdata.goodies + if goodies then + local virtualized = mathematics.virtualized + for i=1,#goodies do + local goodie = goodies[i] + local mathematics = goodie.mathematics + local dimensions = mathematics and mathematics.dimensions + if dimensions then + if trace_defining then + report_math("overloading dimensions in %a @ %p",tfmdata.properties.fullname,tfmdata.parameters.size) + end + local characters = tfmdata.characters + local descriptions = tfmdata.descriptions + local parameters = tfmdata.parameters + local factor = parameters.factor + local hfactor = parameters.hfactor + local vfactor = parameters.vfactor + -- + tfmdata.type = "virtual" + tfmdata.properties.virtualized = true + -- + local function overloadone(unicode,data) + local character = characters[unicode] + if not character then + local c = virtualized[unicode] + if c then + character = characters[c] + end + end + if character then + local width = data.width + local height = data.height + local depth = data.depth + if trace_defining and (width or height or depth) then + report_math("overloading dimensions of %C, width %p, height %p, depth %p", + unicode,width or 0,height or 0,depth or 0) + end + if width then character.width = width * hfactor end + if height then character.height = height * vfactor end + if depth then character.depth = depth * vfactor end + -- + local xoffset = data.xoffset + local yoffset = data.yoffset + if xoffset == "llx" then + local d = descriptions[unicode] + if d then + xoffset = - d.boundingbox[1] * hfactor + character.width = character.width + xoffset + xoffset = rightcommand[xoffset] + else + xoffset = nil + end + elseif xoffset and xoffset ~= 0 then + xoffset = rightcommand[xoffset * hfactor] + else + xoffset = nil + end + if yoffset and yoffset ~= 0 then + yoffset = upcommand[yoffset * vfactor] + else + yoffset = nil + end + if xoffset or yoffset then + local commands = characters.commands + if commands then + prependcommands(commands,yoffset,xoffset) + else + local slot = charcommand[unicode] + if xoffset and yoffset then + character.commands = { xoffset, yoffset, slot } + elseif xoffset then + character.commands = { xoffset, slot } + else + character.commands = { yoffset, slot } + end + end + end + elseif trace_defining then + report_math("no overloading dimensions of %C, not in font",unicode) + end + end + local function overload(dimensions) + for unicode, data in next, dimensions do + withscriptcode(tfmdata,unicode,data,overloadone) + end + end + if value == nil then + value = { "default" } + end + if value == "all" or value == true then + for name, value in next, dimensions do + overload(value) + end + else + if type(value) == "string" then + value = utilities.parsers.settings_to_array(value) + end + if type(value) == "table" then + for i=1,#value do + local d = dimensions[value[i]] + if d then + overload(d) + end + end + end + end + end + end + end +end + +registerotffeature { + name = "mathdimensions", + description = "manipulate math dimensions", + -- default = true, + manipulators = { + base = finalize, + node = finalize, + } +} + +local function initialize(goodies) + local mathgoodies = goodies.mathematics + if mathgoodies then + local virtuals = mathgoodies.virtuals + local mapfiles = mathgoodies.mapfiles + local maplines = mathgoodies.maplines + if virtuals then + for name, specification in next, virtuals do + -- beware, they are all constructed ... we should be more selective + mathematics.makefont(name,specification,goodies) + end + end + if mapfiles then + for i=1,#mapfiles do + fonts.mappings.loadfile(mapfiles[i]) -- todo: backend function + end + end + if maplines then + for i=1,#maplines do + fonts.mappings.loadline(maplines[i]) -- todo: backend function + end + end + end +end + +fontgoodies.register("mathematics", initialize) + +-- local enabled = false directives.register("fontgoodies.mathkerning",function(v) enabled = v end) + +local function initialize(tfmdata) +-- if enabled and tfmdata.mathparameters then -- funny, cambria text has this + if tfmdata.mathparameters then -- funny, cambria text has this + local goodies = tfmdata.goodies + if goodies then + local characters = tfmdata.characters + if characters[0x1D44E] then -- 119886 + -- we have at least an italic a + for i=1,#goodies do + local mathgoodies = goodies[i].mathematics + if mathgoodies then + local kerns = mathgoodies.kerns + if kerns then + local function kernone(unicode,data) + local chardata = characters[unicode] + if chardata and (not chardata.mathkerns or data.force) then + chardata.mathkerns = data + end + end + for unicode, data in next, kerns do + withscriptcode(tfmdata,unicode,data,kernone) + end + return + end + end + end + else + return -- no proper math font anyway + end + end + end +end + +registerotffeature { + name = "mathkerns", + description = "math kerns", + -- default = true, + initializers = { + base = initialize, + node = initialize, + } +} + +-- math italics (not really needed) +-- +-- it would be nice to have a \noitalics\font option + +local function initialize(tfmdata) + local goodies = tfmdata.goodies + if goodies then + local shared = tfmdata.shared + for i=1,#goodies do + local mathgoodies = goodies[i].mathematics + if mathgoodies then + local mathitalics = mathgoodies.italics + if mathitalics then + local properties = tfmdata.properties + if properties.setitalics then + mathitalics = mathitalics[file.nameonly(properties.name)] or mathitalics + if mathitalics then + if trace_goodies then + report_goodies("loading mathitalics for font %a",properties.name) + end + local corrections = mathitalics.corrections + local defaultfactor = mathitalics.defaultfactor + -- properties.mathitalic_defaultfactor = defaultfactor -- we inherit outer one anyway (name will change) + if corrections then + fontgoodies.registerpostprocessor(tfmdata, function(tfmdata) -- this is another tfmdata (a copy) + -- better make a helper so that we have less code being defined + local properties = tfmdata.properties + local parameters = tfmdata.parameters + local characters = tfmdata.characters + properties.mathitalic_defaultfactor = defaultfactor + properties.mathitalic_defaultvalue = defaultfactor * parameters.quad + if trace_goodies then + report_goodies("assigning mathitalics for font %a",properties.name) + end + local quad = parameters.quad + local hfactor = parameters.hfactor + for k, v in next, corrections do + local c = characters[k] + if c then + if v > -1 and v < 1 then + c.italic = v * quad + else + c.italic = v * hfactor + end + else + report_goodies("invalid mathitalics entry %U for font %a",k,properties.name) + end + end + end) + end + return -- maybe not as these can accumulate + end + end + end + end + end + end +end + +registerotffeature { + name = "mathitalics", + description = "additional math italic corrections", + -- default = true, + initializers = { + base = initialize, + node = initialize, + } +} + +-- fontgoodies.register("mathitalics", initialize) + +local function mathradicalaction(n,h,v,font,mchar,echar) + local characters = fontcharacters[font] + local mchardata = characters[mchar] + local echardata = characters[echar] + local ewidth = echardata.width + local mwidth = mchardata.width + local delta = h - ewidth + local glyph = new_glyph(font,echar) + local head = glyph + if delta > 0 then + local count = ceil(delta/mwidth) + local kern = (delta - count * mwidth) / count + for i=1,count do + local k = new_kern(kern) + local g = new_glyph(font,mchar) + setlink(k,head) + setlink(g,k) + head = g + end + end + local height = mchardata.height + local list = new_hlist(head) + local kern = new_kern(height-v) + list = setlink(kern,list) + local list = new_vlist(kern) + insert_node_after(n,n,list) +end + +local function mathhruleaction(n,h,v,font,bchar,mchar,echar) + local characters = fontcharacters[font] + local bchardata = characters[bchar] + local mchardata = characters[mchar] + local echardata = characters[echar] + local bwidth = bchardata.width + local mwidth = mchardata.width + local ewidth = echardata.width + local delta = h - ewidth - bwidth + local glyph = new_glyph(font,echar) + local head = glyph + if delta > 0 then + local count = ceil(delta/mwidth) + local kern = (delta - count * mwidth) / (count+1) + for i=1,count do + local k = new_kern(kern) + local g = new_glyph(font,mchar) + setlink(k,head) + setlink(g,k) + head = g + end + local k = new_kern(kern) + setlink(k,head) + head = k + end + local g = new_glyph(font,bchar) + setlink(g,head) + head = g + local height = mchardata.height + local list = new_hlist(head) + local kern = new_kern(height-v) + list = setlink(kern,list) + local list = new_vlist(kern) + insert_node_after(n,n,list) +end + +local function initialize(tfmdata) + local goodies = tfmdata.goodies + if goodies then + local resources = tfmdata.resources + local ruledata = { } + for i=1,#goodies do + local mathematics = goodies[i].mathematics + if mathematics then + local rules = mathematics.rules + if rules then + for tag, name in next, rules do + ruledata[tag] = name + end + end + end + end + if next(ruledata) then + local characters = tfmdata.characters + local unicodes = resources.unicodes + if characters and unicodes then + local mathruleactions = resources.mathruleactions + if not mathruleactions then + mathruleactions = { } + resources.mathruleactions = mathruleactions + end + -- + local mchar = unicodes[ruledata["radical.extender"] or false] + local echar = unicodes[ruledata["radical.end"] or false] + if mchar and echar then + mathruleactions.radicalaction = function(n,h,v,font) + mathradicalaction(n,h,v,font,mchar,echar) + end + end + -- + local bchar = unicodes[ruledata["hrule.begin"] or false] + local mchar = unicodes[ruledata["hrule.extender"] or false] + local echar = unicodes[ruledata["hrule.end"] or false] + if bchar and mchar and echar then + mathruleactions.hruleaction = function(n,h,v,font) + mathhruleaction(n,h,v,font,bchar,mchar,echar) + end + end + -- not that nice but we need to register it at the tex end + -- context.enablemathrules("\\fontclass") + end + end + end +end + +registerotffeature { + name = "mathrules", + description = "check math rules", + default = true, + initializers = { + base = initialize, + node = initialize, + } +} |