diff options
author | Taco Hoekwater <taco@elvenkind.com> | 2011-06-01 08:54:21 +0000 |
---|---|---|
committer | Taco Hoekwater <taco@elvenkind.com> | 2011-06-01 08:54:21 +0000 |
commit | d7ccb42582f85acf30568913610ccf4d602023fb (patch) | |
tree | 7292e3545a420676878e7451b68892d360c62cb6 /Master/texmf-dist/tex/context/base/math-vfu.lua | |
parent | 2d62a6fe9b80def59c392268022f1f9a2d6e358f (diff) |
commit context 2011.05.18
git-svn-id: svn://tug.org/texlive/trunk@22719 c570f23f-e606-0410-a88d-b1316a301751
Diffstat (limited to 'Master/texmf-dist/tex/context/base/math-vfu.lua')
-rw-r--r-- | Master/texmf-dist/tex/context/base/math-vfu.lua | 626 |
1 files changed, 387 insertions, 239 deletions
diff --git a/Master/texmf-dist/tex/context/base/math-vfu.lua b/Master/texmf-dist/tex/context/base/math-vfu.lua index 5023e6b4d65..49bf00ffe92 100644 --- a/Master/texmf-dist/tex/context/base/math-vfu.lua +++ b/Master/texmf-dist/tex/context/base/math-vfu.lua @@ -11,42 +11,52 @@ if not modules then modules = { } end modules ['math-vfu'] = { -- characters report it to the ConTeXt mailing list. local type, next = type, next +local max = math.max + +local fonts, nodes, mathematics = fonts, nodes, mathematics local trace_virtual = false trackers.register("math.virtual", function(v) trace_virtual = v end) local trace_timings = false trackers.register("math.timings", function(v) trace_timings = v end) -fonts.enc.math = fonts.enc.math or { } +local report_virtual = logs.reporter("fonts","virtual math") -local shared = { } +local allocate = utilities.storage.allocate +local setmetatableindex = table.setmetatableindex -fonts.vf.math = fonts.vf.math or { } -fonts.vf.math.optional = false +local mathencodings = allocate() +fonts.encodings.math = mathencodings -- better is then: fonts.encodings.vectors +local vfmath = allocate() +fonts.handlers.vf.math = vfmath -local push, pop, back = { "push" }, { "pop" }, { "slot", 1, 0x2215 } +vfmath.optional = false -local function negate(main,characters,id,size,unicode,basecode) - if not characters[unicode] then - local basechar = characters[basecode] - if basechar then - local ht, wd = basechar.height, basechar.width - characters[unicode] = { - width = wd, - height = ht, - depth = basechar.depth, - italic = basechar.italic, - kerns = basechar.kerns, - commands = { - { "slot", 1, basecode }, - push, - { "down", ht/5}, - { "right", - wd/2}, - back, - push, - } - } - end - end -end +local shared = { } + +--~ local push, pop, back = { "push" }, { "pop" }, { "slot", 1, 0x2215 } + +--~ local function negate(main,characters,id,size,unicode,basecode) +--~ if not characters[unicode] then +--~ local basechar = characters[basecode] +--~ if basechar then +--~ local ht, wd = basechar.height, basechar.width +--~ characters[unicode] = { +--~ width = wd, +--~ height = ht, +--~ depth = basechar.depth, +--~ italic = basechar.italic, +--~ kerns = basechar.kerns, +--~ commands = { +--~ { "slot", 1, basecode }, +--~ push, +--~ { "down", ht/5}, +--~ { "right", - wd/2}, +--~ back, +--~ push, +--~ } +--~ } +--~ end +--~ end +--~ end --~ \Umathchardef\braceld="0 "1 "FF07A --~ \Umathchardef\bracerd="0 "1 "FF07B @@ -69,20 +79,19 @@ local function brace(main,characters,id,size,unicode,first,rule,left,right,rule, end local function arrow(main,characters,id,size,unicode,arrow,minus,isleft) - if characters[unicode] then - if isleft then - t = { - { extender = 0, glyph = arrow }, - { extender = 1, glyph = minus }, - } - else - t = { - { extender = 0, glyph = minus }, - { extender = 1, glyph = arrow }, - } - end - --~ main.characters[unicode] = { horiz_variants = t } - characters[unicode].horiz_variants = t + local chr = characters[unicode] + if not chr then + -- skip + elseif isleft then + chr.horiz_variants = { + { extender = 0, glyph = arrow }, + { extender = 1, glyph = minus }, + } + else + chr.horiz_variants = { + { extender = 0, glyph = minus }, + { extender = 1, glyph = arrow }, + } end end @@ -226,172 +235,312 @@ local function vertbar(main,characters,id,size,parent,scale,unicode) end end -function fonts.vf.math.alas(main,id,size) - local characters = main.characters - for i=0x7A,0x7D do - make(main,characters,id,size,i,1) +local function jointwo(main,characters,id,size,unicode,u1,d12,u2) + local c1, c2 = characters[u1], characters[u2] + if c1 and c2 then + local w1, w2 = c1.width, c2.width + local mu = size/18 + characters[unicode] = { + width = w1 + w2 - d12*mu, + height = max(c1.height or 0, c2.height or 0), + depth = max(c1.depth or 0, c2.depth or 0), + commands = { + { "slot", id, u1 }, + { "right", -d12*mu } , + { "slot", id, u2 }, + } + } end - brace (main,characters,id,size,0x23DE,0xFF17A,0xFF301,0xFF17D,0xFF17C,0xFF301,0xFF17B) - brace (main,characters,id,size,0x23DF,0xFF27C,0xFF401,0xFF27B,0xFF27A,0xFF401,0xFF27D) - parent (main,characters,id,size,0x23DC,0xFF17A,0xFF301,0xFF17B) - parent (main,characters,id,size,0x23DD,0xFF27C,0xFF401,0xFF27D) - negate (main,characters,id,size,0x2260,0x003D) - dots (main,characters,id,size,0x2026) -- ldots - dots (main,characters,id,size,0x22EE) -- vdots - dots (main,characters,id,size,0x22EF) -- cdots - dots (main,characters,id,size,0x22F1) -- ddots - dots (main,characters,id,size,0x22F0) -- udots - minus (main,characters,id,size,0xFF501) - arrow (main,characters,id,size,0x2190,0xFE190,0xFF501,true) -- left - arrow (main,characters,id,size,0x2192,0xFE192,0xFF501,false) -- right - vertbar(main,characters,id,size,0x0007C,0.10,0xFF601) -- big : 0.85 bodyfontsize - vertbar(main,characters,id,size,0xFF601,0.30,0xFF602) -- Big : 1.15 bodyfontsize - vertbar(main,characters,id,size,0xFF602,0.30,0xFF603) -- bigg : 1.45 bodyfontsize - vertbar(main,characters,id,size,0xFF603,0.30,0xFF604) -- Bigg : 1.75 bodyfontsize - vertbar(main,characters,id,size,0x02225,0.10,0xFF605) - vertbar(main,characters,id,size,0xFF605,0.30,0xFF606) - vertbar(main,characters,id,size,0xFF606,0.30,0xFF607) - vertbar(main,characters,id,size,0xFF607,0.30,0xFF608) end -local unique = 0 -- testcase: \startTEXpage \math{!\text{-}\text{-}\text{-}} \stopTEXpage - -function fonts.basecopy(tfmtable,name) - local characters, parameters, fullname = tfmtable.characters, tfmtable.parameters, tfmtable.fullname - local t, c, p = { }, { }, { } - for k, v in next, tfmtable do - t[k] = v - end - if characters then - for k, v in next, characters do - c[k] = v - end - t.characters = c - else - logs.report("math virtual","font %s has no characters",name) +local function jointhree(main,characters,id,size,unicode,u1,d12,u2,d23,u3) + local c1, c2, c3 = characters[u1], characters[u2], characters[u3] + if c1 and c2 and c3 then + local w1, w2, w3 = c1.width, c2.width, c3.width + local mu = size/18 + characters[unicode] = { + width = w1 + w2 + w3 - d12*mu - d23*mu, + height = max(c1.height or 0, c2.height or 0, c3.height or 0), + depth = max(c1.depth or 0, c2.depth or 0, c3.depth or 0), + commands = { + { "slot", id, u1 }, + { "right", - d12*mu } , + { "slot", id, u2 }, + { "right", - d23*mu }, + { "slot", id, u3 }, + } + } end - if parameters then - for k, v in next, parameters do - p[k] = v - end - t.parameters = p - else - logs.report("math virtual","font %s has no parameters",name) +end + +local function stack(main,characters,id,size,unicode,u1,d12,u2) + local c1, c2 = characters[u1], characters[u2] + if c1 and c2 then + local w1, w2 = c1.width, c2.width + local h1, h2 = c1.height, c2.height + local d1, d2 = c1.depth, c2.depth + local mu = size/18 + characters[unicode] = { + width = w1, + height = h1 + h2 + d12, + depth = d1, + commands = { + { "slot", id, u1 }, + { "right", - w1/2 - w2/2 } , + { "down", -h1 + d2 -d12*mu } , + { "slot", id, u2 }, + } + } end - -- tricky ... what if fullname does not exist - if fullname then - unique = unique + 1 - t.fullname = fullname .. "-" .. unique +end + +function vfmath.addmissing(main,id,size) + local characters = main.characters + local shared = main.shared + local variables = main.goodies.mathematics and main.goodies.mathematics.variables or { } + local joinrelfactor = variables.joinrelfactor or 3 + for i=0x7A,0x7D do + make(main,characters,id,size,i,1) end - return t + brace (main,characters,id,size,0x23DE,0xFF17A,0xFF301,0xFF17D,0xFF17C,0xFF301,0xFF17B) + brace (main,characters,id,size,0x23DF,0xFF27C,0xFF401,0xFF27B,0xFF27A,0xFF401,0xFF27D) + parent (main,characters,id,size,0x23DC,0xFF17A,0xFF301,0xFF17B) + parent (main,characters,id,size,0x23DD,0xFF27C,0xFF401,0xFF27D) + -- negate (main,characters,id,size,0x2260,0x003D) + dots (main,characters,id,size,0x2026) -- ldots + dots (main,characters,id,size,0x22EE) -- vdots + dots (main,characters,id,size,0x22EF) -- cdots + dots (main,characters,id,size,0x22F1) -- ddots + dots (main,characters,id,size,0x22F0) -- udots + minus (main,characters,id,size,0xFF501) + arrow (main,characters,id,size,0x2190,0xFE190,0xFF501,true) -- left + arrow (main,characters,id,size,0x2192,0xFE192,0xFF501,false) -- right + vertbar (main,characters,id,size,0x0007C,0.10,0xFF601) -- big : 0.85 bodyfontsize + vertbar (main,characters,id,size,0xFF601,0.30,0xFF602) -- Big : 1.15 bodyfontsize + vertbar (main,characters,id,size,0xFF602,0.30,0xFF603) -- bigg : 1.45 bodyfontsize + vertbar (main,characters,id,size,0xFF603,0.30,0xFF604) -- Bigg : 1.75 bodyfontsize + vertbar (main,characters,id,size,0x02016,0.10,0xFF605) + vertbar (main,characters,id,size,0xFF605,0.30,0xFF606) + vertbar (main,characters,id,size,0xFF606,0.30,0xFF607) + vertbar (main,characters,id,size,0xFF607,0.30,0xFF608) + jointwo (main,characters,id,size,0x21A6,0xFE321,0,0x02192) -- \mapstochar\rightarrow + jointwo (main,characters,id,size,0x21A9,0x02190,joinrelfactor,0xFE323) -- \leftarrow\joinrel\rhook + jointwo (main,characters,id,size,0x21AA,0xFE322,joinrelfactor,0x02192) -- \lhook\joinrel\rightarrow + stack (main,characters,id,size,0x2259,0x0003D,3,0x02227) -- \buildrel\wedge\over= + jointwo (main,characters,id,size,0x22C8,0x022B3,joinrelfactor,0x022B2) -- \mathrel\triangleright\joinrel\mathrel\triangleleft (4 looks better than 3) + jointwo (main,characters,id,size,0x2260,0x00338,0,0x0003D) -- \not\equal + jointwo (main,characters,id,size,0x2284,0x00338,0,0x02282) -- \not\subset + jointwo (main,characters,id,size,0x2285,0x00338,0,0x02283) -- \not\supset + jointwo (main,characters,id,size,0x22A7,0x0007C,joinrelfactor,0x0003D) -- \mathrel|\joinrel= + jointwo (main,characters,id,size,0x27F5,0x02190,joinrelfactor,0x0002D) -- \leftarrow\joinrel\relbar + jointwo (main,characters,id,size,0x27F6,0x0002D,joinrelfactor,0x02192) -- \relbar\joinrel\rightarrow + jointwo (main,characters,id,size,0x27F7,0x02190,joinrelfactor,0x02192) -- \leftarrow\joinrel\rightarrow + jointwo (main,characters,id,size,0x27F8,0x021D0,joinrelfactor,0x0003D) -- \Leftarrow\joinrel\Relbar + jointwo (main,characters,id,size,0x27F9,0x0003D,joinrelfactor,0x021D2) -- \Relbar\joinrel\Rightarrow + jointwo (main,characters,id,size,0x27FA,0x021D0,joinrelfactor,0x021D2) -- \Leftarrow\joinrel\Rightarrow + jointhree(main,characters,id,size,0x27FB,0x02190,joinrelfactor,0x0002D,0,0xFE324) -- \leftarrow\joinrel\relbar\mapsfromchar + jointhree(main,characters,id,size,0x27FC,0xFE321,0,0x0002D,joinrelfactor,0x02192) -- \mapstochar\relbar\joinrel\rightarrow end +local unique = 0 -- testcase: \startTEXpage \math{!\text{-}\text{-}\text{-}} \stopTEXpage + local reported = { } -local reverse -- index -> unicode +local reverse = { } -- index -> unicode -function fonts.vf.math.define(specification,set) - if not reverse then - reverse = { } - for k, v in next, fonts.enc.math do - local r = { } - for u, i in next, v do - r[i] = u - end - reverse[k] = r - end +setmetatableindex(reverse, function(t,name) + if trace_virtual then + report_virtual("initializing math vector '%s'",name) + end + local m, r = mathencodings[name], { } + for u, i in next, m do + r[i] = u end + reverse[name] = r + return r +end) + +function vfmath.define(specification,set,goodies) local name = specification.name -- symbolic name local size = specification.size -- given size - local fnt, lst, main = { }, { }, nil + local loaded, fontlist, main = { }, { }, nil local start = (trace_virtual or trace_timings) and os.clock() local okset, n = { }, 0 for s=1,#set do local ss = set[s] local ssname = ss.name - if ss.optional and fonts.vf.math.optional then + if ss.optional and vfmath.optional then if trace_virtual then - logs.report("math virtual","loading font %s subfont %s with name %s at %s is skipped",name,s,ssname,size) + report_virtual("loading font %s subfont %s with name %s at %s is skipped",name,s,ssname,size) end else - if ss.features then ssname = ssname .. "*" .. ss.features end - if ss.main then main = s end - local f, id = fonts.tfm.read_and_define(ssname,size) - if not f then - logs.report("math virtual","loading font %s subfont %s with name %s at %s is skipped, not found",name,s,ssname,size) + if ss.features then + ssname = ssname .. "*" .. ss.features + end + if ss.main then + main = s + end + local f, id = fonts.constructors.readanddefine(ssname,size) + if not f or id == 0 then + report_virtual("loading font %s subfont %s with name %s at %s is skipped, not found",name,s,ssname,size) else n = n + 1 okset[n] = ss - fnt[n] = f - lst[n] = { id = id, size = size } + loaded[n] = f + fontlist[n] = { id = id, size = size } if not shared[s] then shared[n] = { } end if trace_virtual then - logs.report("math virtual","loading font %s subfont %s with name %s at %s as id %s using encoding %s",name,s,ssname,size,id,ss.vector or "none") + report_virtual("loading font %s subfont %s with name %s at %s as id %s using encoding %s",name,s,ssname,size,id,ss.vector or "none") + end + if not ss.checked then + ss.checked = true + local vector = mathencodings[ss.vector] + if vector then + -- we resolve named glyphs only once as we can assume that vectors + -- are unique to a font set (when we read an afm we get those names + -- mapped onto the private area) + for unicode, index in next, vector do + if not tonumber(index) then + local u = f.unicodes + u = u and u[index] + if u then + if trace_virtual then + report_virtual("resolving name %s to %s",index,u) + end + else + report_virtual("unable to resolve name %s",index) + end + vector[unicode] = u + end + end + end end end end end - -- beware, fnt[1] is already passed to tex (we need to make a simple copy then .. todo) - main = fonts.basecopy(fnt[1],name) - main.name, main.fonts, main.virtualized, main.math_parameters = name, lst, true, { } - local characters, descriptions = main.characters, main.descriptions - local mp = main.parameters - if mp then - mp.x_height = mp.x_height or 0 + -- beware, loaded[1] is already passed to tex (we need to make a simple copy then .. todo) + local parent = loaded[1] -- a text font + local characters = { } + local parameters = { } + local mathparameters = { } + local descriptions = { } + local metadata = { } + local properties = { } + local goodies = { } + local main = { + metadata = metadata, + properties = properties, + characters = characters, + descriptions = descriptions, + parameters = parameters, + mathparameters = mathparameters, + fonts = fontlist, + goodies = goodies, + } + -- + -- + for key, value in next, parent do + if type(value) ~= "table" then + main[key] = value + end + end + -- + if parent.characters then + for unicode, character in next, parent.characters do + characters[unicode] = character + end + else + report_virtual("font %s has no characters",name) + end + -- + if parent.parameters then + for key, value in next, parent.parameters do + parameters[key] = value + end + else + report_virtual("font %s has no parameters",name) + end + -- + local description = { name = "<unset>" } + setmetatableindex(descriptions,function() return description end) + -- + if parent.properties then + setmetatableindex(properties,parent.properties) end + -- + if parent.goodies then + setmetatableindex(goodies,parent.goodies) + end + -- + properties.virtualized = true + properties.italic_correction = true + properties.has_math = true + -- + local fullname = properties.fullname -- parent via mt + if fullname then + unique = unique + 1 + properties.fullname = fullname .. "-" .. unique + end + -- + -- we need to set some values in main as well (still?) + -- + main.fullname = properties.fullname + main.type = "virtual" + main.nomath = false + -- + parameters.x_height = parameters.x_height or 0 + -- local already_reported = false for s=1,n do - local ss, fs = okset[s], fnt[s] + local ss, fs = okset[s], loaded[s] if not fs then -- skip, error - elseif ss.optional and fonts.vf.math.optional then + elseif ss.optional and vfmath.optional then -- skip, redundant else - local mm, fp = main.math_parameters, fs.parameters - if mm and fp and mp then - if ss.extension then - mm.math_x_height = fp.x_height or 0 -- math_x_height height of x - mm.default_rule_thickness = fp[ 8] or 0 -- default_rule_thickness thickness of \over bars - mm.big_op_spacing1 = fp[ 9] or 0 -- big_op_spacing1 minimum clearance above a displayed op - mm.big_op_spacing2 = fp[10] or 0 -- big_op_spacing2 minimum clearance below a displayed op - mm.big_op_spacing3 = fp[11] or 0 -- big_op_spacing3 minimum baselineskip above displayed op - mm.big_op_spacing4 = fp[12] or 0 -- big_op_spacing4 minimum baselineskip below displayed op - mm.big_op_spacing5 = fp[13] or 0 -- big_op_spacing5 padding above and below displayed limits - -- logs.report("math virtual","loading and virtualizing font %s at size %s, setting ex parameters",name,size) - elseif ss.parameters then - mp.x_height = fp.x_height or mp.x_height - mm.x_height = mm.x_height or fp.x_height or 0 -- x_height height of x - mm.num1 = fp[ 8] or 0 -- num1 numerator shift-up in display styles - mm.num2 = fp[ 9] or 0 -- num2 numerator shift-up in non-display, non-\atop - mm.num3 = fp[10] or 0 -- num3 numerator shift-up in non-display \atop - mm.denom1 = fp[11] or 0 -- denom1 denominator shift-down in display styles - mm.denom2 = fp[12] or 0 -- denom2 denominator shift-down in non-display styles - mm.sup1 = fp[13] or 0 -- sup1 superscript shift-up in uncramped display style - mm.sup2 = fp[14] or 0 -- sup2 superscript shift-up in uncramped non-display - mm.sup3 = fp[15] or 0 -- sup3 superscript shift-up in cramped styles - mm.sub1 = fp[16] or 0 -- sub1 subscript shift-down if superscript is absent - mm.sub2 = fp[17] or 0 -- sub2 subscript shift-down if superscript is present - mm.sup_drop = fp[18] or 0 -- sup_drop superscript baseline below top of large box - mm.sub_drop = fp[19] or 0 -- sub_drop subscript baseline below bottom of large box - mm.delim1 = fp[20] or 0 -- delim1 size of \atopwithdelims delimiters in display styles - mm.delim2 = fp[21] or 0 -- delim2 size of \atopwithdelims delimiters in non-displays - mm.axis_height = fp[22] or 0 -- axis_height height of fraction lines above the baseline - -- logs.report("math virtual","loading and virtualizing font %s at size %s, setting sy parameters",name,size) - end - else - logs.report("math virtual","font %s, no parameters set",name) + local newparameters = fs.parameters + if not newparameters then + report_virtual("font %s, no parameters set",name) + elseif ss.extension then + mathparameters.math_x_height = newparameters.x_height or 0 -- math_x_height : height of x + mathparameters.default_rule_thickness = newparameters[ 8] or 0 -- default_rule_thickness : thickness of \over bars + mathparameters.big_op_spacing1 = newparameters[ 9] or 0 -- big_op_spacing1 : minimum clearance above a displayed op + mathparameters.big_op_spacing2 = newparameters[10] or 0 -- big_op_spacing2 : minimum clearance below a displayed op + mathparameters.big_op_spacing3 = newparameters[11] or 0 -- big_op_spacing3 : minimum baselineskip above displayed op + mathparameters.big_op_spacing4 = newparameters[12] or 0 -- big_op_spacing4 : minimum baselineskip below displayed op + mathparameters.big_op_spacing5 = newparameters[13] or 0 -- big_op_spacing5 : padding above and below displayed limits + -- report_virtual("loading and virtualizing font %s at size %s, setting ex parameters",name,size) + elseif ss.parameters then + mathparameters.x_height = newparameters.x_height or mathparameters.x_height + mathparameters.x_height = mathparameters.x_height or fp.x_height or 0 -- x_height : height of x + mathparameters.num1 = newparameters[ 8] or 0 -- num1 : numerator shift-up in display styles + mathparameters.num2 = newparameters[ 9] or 0 -- num2 : numerator shift-up in non-display, non-\atop + mathparameters.num3 = newparameters[10] or 0 -- num3 : numerator shift-up in non-display \atop + mathparameters.denom1 = newparameters[11] or 0 -- denom1 : denominator shift-down in display styles + mathparameters.denom2 = newparameters[12] or 0 -- denom2 : denominator shift-down in non-display styles + mathparameters.sup1 = newparameters[13] or 0 -- sup1 : superscript shift-up in uncramped display style + mathparameters.sup2 = newparameters[14] or 0 -- sup2 : superscript shift-up in uncramped non-display + mathparameters.sup3 = newparameters[15] or 0 -- sup3 : superscript shift-up in cramped styles + mathparameters.sub1 = newparameters[16] or 0 -- sub1 : subscript shift-down if superscript is absent + mathparameters.sub2 = newparameters[17] or 0 -- sub2 : subscript shift-down if superscript is present + mathparameters.sup_drop = newparameters[18] or 0 -- sup_drop : superscript baseline below top of large box + mathparameters.sub_drop = newparameters[19] or 0 -- sub_drop : subscript baseline below bottom of large box + mathparameters.delim1 = newparameters[20] or 0 -- delim1 : size of \atopwithdelims delimiters in display styles + mathparameters.delim2 = newparameters[21] or 0 -- delim2 : size of \atopwithdelims delimiters in non-displays + mathparameters.axis_height = newparameters[22] or 0 -- axis_height : height of fraction lines above the baseline + -- report_virtual("loading and virtualizing font %s at size %s, setting sy parameters",name,size) end local vectorname = ss.vector if vectorname then local offset = 0xFF000 - local vector = fonts.enc.math[vectorname] + local vector = mathencodings[vectorname] local rotcev = reverse[vectorname] - if vector then + if vector and rotcev then local fc, fd, si = fs.characters, fs.descriptions, shared[s] local skewchar = ss.skewchar for unicode, index in next, vector do local fci = fc[index] if not fci then - local fontname = fs.name or "unknown" + local fontname = fs.properties.name or "unknown" local rf = reported[fontname] if not rf then rf = { } reported[fontname] = rf end local rv = rf[vectorname] @@ -399,9 +548,9 @@ function fonts.vf.math.define(specification,set) local ru = rv[unicode] if not ru then if trace_virtual then - logs.report("math virtual", "unicode point U+%05X has no index %04X in vector %s for font %s",unicode,index,vectorname,fontname) + report_virtual( "unicode point U+%05X has no index %04X in vector %s for font %s",unicode,index,vectorname,fontname) elseif not already_reported then - logs.report("math virtual", "the mapping is incomplete for '%s' at %s",name,number.topoints(size)) + report_virtual( "the mapping is incomplete for '%s' at %s",name,number.topoints(size)) already_reported = true end rv[unicode] = true @@ -413,13 +562,17 @@ function fonts.vf.math.define(specification,set) si[index] = ref end local kerns = fci.kerns + local width = fci.width + local italic = fci.italic + -- if italic then + -- width = width + italic -- old interpretation of otf math specs + -- end if kerns then - local width = fci.width local krn = { } - for k=1,#kerns do + for k, v in next, kerns do -- kerns is sparse local rk = rotcev[k] if rk then - krn[rk] = kerns[k] + krn[rk] = v -- kerns[k] end end if not next(krn) then @@ -429,7 +582,7 @@ function fonts.vf.math.define(specification,set) width = width, height = fci.height, depth = fci.depth, - italic = fci.italic, + italic = italic, kerns = krn, commands = ref, } @@ -442,10 +595,10 @@ function fonts.vf.math.define(specification,set) characters[unicode] = t else characters[unicode] = { - width = fci.width, + width = width, height = fci.height, depth = fci.depth, - italic = fci.italic, + italic = italic, commands = ref, } end @@ -453,7 +606,7 @@ function fonts.vf.math.define(specification,set) end if ss.extension then -- todo: if multiple ex, then 256 offsets per instance - local extension = fonts.enc.math["large-to-small"] + local extension = mathencodings["large-to-small"] local variants_done = fs.variants_done for index, fci in next, fc do -- the raw ex file if type(index) == "number" then @@ -507,31 +660,10 @@ function fonts.vf.math.define(specification,set) local cu = characters[unicode] if cu then cu.next = offset + index - --~ local n, c, d = unicode, cu, { } - --~ print("START", unicode) - --~ while n do - --~ n = c.next - --~ if n then - --~ print("NEXT", n) - --~ c = characters[n] - --~ if not c then - --~ print("EXIT") - --~ elseif d[n] then - --~ print("LOOP") - --~ break - --~ end - --~ d[n] = true - --~ end - --~ end else local fci = fc[index] if not fci then ---~ characters[unicode] = { ---~ width = 0, ---~ height = 0, ---~ depth = 0, ---~ index = 0, ---~ } + -- do nothing else local ref = si[index] if not ref then @@ -541,8 +673,11 @@ function fonts.vf.math.define(specification,set) local kerns = fci.kerns if kerns then local krn = { } - for k=1,#kerns do - krn[offset + k] = kerns[k] +--~ for k=1,#kerns do +--~ krn[offset + k] = kerns[k] +--~ end + for k, v in next, kerns do -- is kerns sparse? + krn[offset + k] = v end characters[unicode] = { width = fci.width, @@ -567,36 +702,44 @@ function fonts.vf.math.define(specification,set) end end end + else + report_virtual("error in loading %s: problematic vector %s",name,vectorname) end end mathematics.extras.copy(main) --not needed here (yet) end end - lst[#lst+1] = { id = font.nextid(), size = size } - if mp then -- weak catch - fonts.vf.math.alas(main,#lst,size) - end + -- + fontlist[#fontlist+1] = { + id = font.nextid(), + size = size, + } + -- + main.mathparameters = mathparameters -- still traditional ones + vfmath.addmissing(main,#fontlist,size) + mathematics.addfallbacks(main) + -- + main.properties.math_is_scaled = true -- signal + fonts.constructors.assignmathparameters(main,main) + -- + main.MathConstants = main.mathparameters -- we directly pass it to TeX (bypasses the scaler) so this is needed + -- if trace_virtual or trace_timings then - logs.report("math virtual","loading and virtualizing font %s at size %s took %0.3f seconds",name,size,os.clock()-start) + report_virtual("loading and virtualizing font %s at size %s took %0.3f seconds",name,size,os.clock()-start) end - main.has_italic = true - main.type = "virtual" -- not needed - mathematics.scaleparameters(main,main,1) - main.nomath = false ---~ print(table.serialize(characters[0x222B])) ---~ print(main.fontname,table.serialize(main.MathConstants)) + -- return main end -function mathematics.make_font(name, set) - fonts.define.methods[name] = function(specification) - return fonts.vf.math.define(specification,set) +function mathematics.makefont(name,set,goodies) + fonts.definers.methods.variants[name] = function(specification) + return vfmath.define(specification,set,goodies) end end -- varphi is part of the alphabet, contrary to the other var*s' -fonts.enc.math["large-to-small"] = { +mathencodings["large-to-small"] = { [0x00028] = 0x00, -- ( [0x00029] = 0x01, -- ) [0x0005B] = 0x02, -- [ @@ -640,7 +783,7 @@ fonts.enc.math["large-to-small"] = { [0x02044] = 0x0E, -- / } -fonts.enc.math["tex-ex"] = { +mathencodings["tex-ex"] = { [0x0220F] = 0x51, -- prod [0x0222B] = 0x52, -- intop [0x02210] = 0x60, -- coprod @@ -660,7 +803,7 @@ fonts.enc.math["tex-ex"] = { -- only math stuff is needed, since we always use an lm or gyre -- font as main font -fonts.enc.math["tex-mr"] = { +mathencodings["tex-mr"] = { [0x00393] = 0x00, -- Gamma [0x00394] = 0x01, -- Delta [0x00398] = 0x02, -- Theta @@ -715,11 +858,11 @@ fonts.enc.math["tex-mr"] = { -- [0x000A8] = 0x7F, -- [math]ddot } -fonts.enc.math["tex-mr-missing"] = { +mathencodings["tex-mr-missing"] = { [0x02236] = 0x3A, -- colon } -fonts.enc.math["tex-mi"] = { +mathencodings["tex-mi"] = { [0x1D6E4] = 0x00, -- Gamma [0x1D6E5] = 0x01, -- Delta [0x1D6E9] = 0x02, -- Theta @@ -803,8 +946,7 @@ fonts.enc.math["tex-mi"] = { -- 0x7F, -- (no idea what that could be) } - -fonts.enc.math["tex-it"] = { +mathencodings["tex-it"] = { -- [0x1D434] = 0x41, -- A [0x1D6E2] = 0x41, -- Alpha -- [0x1D435] = 0x42, -- B @@ -874,14 +1016,14 @@ fonts.enc.math["tex-it"] = { -- [0x1D467] = 0x7A, -- z } -fonts.enc.math["tex-ss"] = { } -fonts.enc.math["tex-tt"] = { } -fonts.enc.math["tex-bf"] = { } -fonts.enc.math["tex-bi"] = { } -fonts.enc.math["tex-fraktur"] = { } -fonts.enc.math["tex-fraktur-bold"] = { } +mathencodings["tex-ss"] = { } +mathencodings["tex-tt"] = { } +mathencodings["tex-bf"] = { } +mathencodings["tex-bi"] = { } +mathencodings["tex-fraktur"] = { } +mathencodings["tex-fraktur-bold"] = { } -function fonts.vf.math.set_letters(font_encoding, name, uppercase, lowercase) +function vfmath.setletters(font_encoding, name, uppercase, lowercase) local enc = font_encoding[name] for i = 0,25 do enc[uppercase+i] = i + 0x41 @@ -889,14 +1031,14 @@ function fonts.vf.math.set_letters(font_encoding, name, uppercase, lowercase) end end -function fonts.vf.math.set_digits(font_encoding, name, digits) +function vfmath.setdigits(font_encoding, name, digits) local enc = font_encoding[name] for i = 0,9 do enc[digits+i] = i + 0x30 end end -fonts.enc.math["tex-sy"] = { +mathencodings["tex-sy"] = { [0x0002D] = 0x00, -- - [0x02212] = 0x00, -- - -- [0x02201] = 0x00, -- complement @@ -1015,7 +1157,8 @@ fonts.enc.math["tex-sy"] = { [0x027E8] = 0x68, -- <, langle [0x027E9] = 0x69, -- >, rangle [0x0007C] = 0x6A, -- |, mid, lvert, rvert - [0x02225] = 0x6B, -- parallel, Vert, lVert, rVert, arrowvert + [0x02225] = 0x6B, -- parallel + -- [0x02016] = 0x00, -- Vert, lVert, rVert, arrowvert, Arrowvert [0x02195] = 0x6C, -- updownarrow [0x021D5] = 0x6D, -- Updownarrow [0x0005C] = 0x6E, -- \, backslash, setminus @@ -1044,7 +1187,7 @@ fonts.enc.math["tex-sy"] = { -- column, while in the second column we show the tex/ams names. As usual -- it costs hours to figure out such a table. -fonts.enc.math["tex-ma"] = { +mathencodings["tex-ma"] = { [0x022A1] = 0x00, -- squaredot \boxdot [0x0229E] = 0x01, -- squareplus \boxplus [0x022A0] = 0x02, -- squaremultiply \boxtimes @@ -1178,7 +1321,7 @@ fonts.enc.math["tex-ma"] = { [0x0229D] = 0x7F, -- circleminus \circleddash } -fonts.enc.math["tex-mb"] = { +mathencodings["tex-mb"] = { -- [0x0] = 0x00, -- lessornotequal \lvertneqq -- [0x0] = 0x01, -- greaterornotequal \gvertneqq [0x02270] = 0x02, -- notlessequal \nleq @@ -1304,7 +1447,12 @@ fonts.enc.math["tex-mb"] = { [0x003F6] = 0x7F, -- epsiloninv \backepsilon } -fonts.enc.math["tex-fraktur"] = { +mathencodings["tex-mc"] = { + -- this file has no tfm so it gets mapped in the private space + [0xFE324] = "mapsfromchar", +} + +mathencodings["tex-fraktur"] = { -- [0x1D504] = 0x41, -- A (fraktur A) -- [0x1D505] = 0x42, -- B [0x0212D] = 0x43, -- C @@ -1361,19 +1509,19 @@ fonts.enc.math["tex-fraktur"] = { -- now that all other vectors are defined ... -fonts.vf.math.set_letters(fonts.enc.math, "tex-it", 0x1D434, 0x1D44E) -fonts.vf.math.set_letters(fonts.enc.math, "tex-ss", 0x1D5A0, 0x1D5BA) -fonts.vf.math.set_letters(fonts.enc.math, "tex-tt", 0x1D670, 0x1D68A) -fonts.vf.math.set_letters(fonts.enc.math, "tex-bf", 0x1D400, 0x1D41A) -fonts.vf.math.set_letters(fonts.enc.math, "tex-bi", 0x1D468, 0x1D482) -fonts.vf.math.set_letters(fonts.enc.math, "tex-fraktur", 0x1D504, 0x1D51E) -fonts.vf.math.set_letters(fonts.enc.math, "tex-fraktur-bold", 0x1D56C, 0x1D586) +vfmath.setletters(mathencodings, "tex-it", 0x1D434, 0x1D44E) +vfmath.setletters(mathencodings, "tex-ss", 0x1D5A0, 0x1D5BA) +vfmath.setletters(mathencodings, "tex-tt", 0x1D670, 0x1D68A) +vfmath.setletters(mathencodings, "tex-bf", 0x1D400, 0x1D41A) +vfmath.setletters(mathencodings, "tex-bi", 0x1D468, 0x1D482) +vfmath.setletters(mathencodings, "tex-fraktur", 0x1D504, 0x1D51E) +vfmath.setletters(mathencodings, "tex-fraktur-bold", 0x1D56C, 0x1D586) -fonts.vf.math.set_digits (fonts.enc.math, "tex-ss", 0x1D7E2) -fonts.vf.math.set_digits (fonts.enc.math, "tex-tt", 0x1D7F6) -fonts.vf.math.set_digits (fonts.enc.math, "tex-bf", 0x1D7CE) +vfmath.setdigits (mathencodings, "tex-ss", 0x1D7E2) +vfmath.setdigits (mathencodings, "tex-tt", 0x1D7F6) +vfmath.setdigits (mathencodings, "tex-bf", 0x1D7CE) --- fonts.vf.math.set_digits (fonts.enc.math, "tex-bi", 0x1D7CE) +-- vfmath.setdigits (mathencodings, "tex-bi", 0x1D7CE) -- todo: add ss, tt, bf etc vectors -- todo: we can make ss tt etc an option |