summaryrefslogtreecommitdiff
path: root/Master/texmf-dist/tex/context/base/math-fbk.lua
diff options
context:
space:
mode:
Diffstat (limited to 'Master/texmf-dist/tex/context/base/math-fbk.lua')
-rw-r--r--Master/texmf-dist/tex/context/base/math-fbk.lua274
1 files changed, 249 insertions, 25 deletions
diff --git a/Master/texmf-dist/tex/context/base/math-fbk.lua b/Master/texmf-dist/tex/context/base/math-fbk.lua
index eebc4e4e7d6..70a8ae8d61c 100644
--- a/Master/texmf-dist/tex/context/base/math-fbk.lua
+++ b/Master/texmf-dist/tex/context/base/math-fbk.lua
@@ -6,17 +6,21 @@ if not modules then modules = { } end modules ['math-fbk'] = {
license = "see context related readme files"
}
-local trace_fallbacks = false trackers.register("math.fallbacks", function(v) trace_fallbacks = v end)
+local trace_fallbacks = false trackers.register("math.fallbacks", function(v) trace_fallbacks = v end)
-local report_fallbacks = logs.reporter("math","fallbacks")
+local report_fallbacks = logs.reporter("math","fallbacks")
-local fallbacks = { }
-mathematics.fallbacks = fallbacks
+local formatters = string.formatters
+local fastcopy = table.fastcopy
+
+local fallbacks = { }
+mathematics.fallbacks = fallbacks
local virtualcharacters = { }
-local identifiers = fonts.hashes.identifiers
-local lastmathids = fonts.hashes.lastmathids
+local identifiers = fonts.hashes.identifiers
+local lastmathids = fonts.hashes.lastmathids
+local tounicode16 = fonts.mappings.tounicode16
-- we need a trick (todo): if we define scriptscript, script and text in
-- that order we could use their id's .. i.e. we could always add a font
@@ -25,6 +29,11 @@ local lastmathids = fonts.hashes.lastmathids
--
-- todo: use index 'true when luatex provides that feature (on the agenda)
+-- to be considered:
+--
+-- in luatex provide reserve_id (and pass id as field of tfmdata)
+-- in context define three sizes but pass them later i.e. do virtualize afterwards
+
function fallbacks.apply(target,original)
local mathparameters = target.mathparameters -- why not hasmath
if mathparameters then
@@ -39,7 +48,7 @@ function fallbacks.apply(target,original)
end
-- This is not okay yet ... we have no proper way to refer to 'self'
-- otherwise I will make my own id allocator).
-local self = #usedfonts == 0 and font.nextid() or nil -- will be true
+ local self = #usedfonts == 0 and font.nextid() or nil -- will be true
local textid, scriptid, scriptscriptid
local textindex, scriptindex, scriptscriptindex
local textdata, scriptdata, scriptscriptdata
@@ -48,26 +57,27 @@ local self = #usedfonts == 0 and font.nextid() or nil -- will be true
-- textid = nil -- self
-- scriptid = nil -- no smaller
-- scriptscriptid = nil -- no smaller
-textid = self
-scriptid = self
-scriptscriptid = self
+ textid = self
+ scriptid = self
+ scriptscriptid = self
elseif mathsize == 2 then
-- scriptsize
-- textid = nil -- self
-textid = self
+ textid = self
scriptid = lastmathids[3]
scriptscriptid = lastmathids[3]
else
-- textsize
-- textid = nil -- self
-textid = self
+ textid = self
scriptid = lastmathids[2]
scriptscriptid = lastmathids[3]
end
if textid then
textindex = #usedfonts + 1
usedfonts[textindex] = { id = textid }
- textdata = identifiers[textid]
+-- textdata = identifiers[textid] or target
+ textdata = target
else
textdata = target
end
@@ -87,8 +97,7 @@ textid = self
scriptscriptindex = scriptindex
scriptscriptdata = scriptdata
end
--- report_fallbacks("used textid: %s, used script id: %s, used scriptscript id: %s",
--- tostring(textid),tostring(scriptid),tostring(scriptscriptid))
+ -- report_fallbacks("used textid: %S, used script id: %S, used scriptscript id: %S",textid,scriptid,scriptscriptid)
local data = {
textdata = textdata,
scriptdata = scriptdata,
@@ -96,6 +105,9 @@ textid = self
textindex = textindex,
scriptindex = scriptindex,
scriptscriptindex = scriptscriptindex,
+ textid = textid,
+ scriptid = scriptid,
+ scriptscriptid = scriptscriptid,
characters = characters,
unicode = k,
target = target,
@@ -103,24 +115,30 @@ textid = self
size = size,
mathsize = mathsize,
}
--- inspect(usedfonts)
+ target.mathrelation = data
+ -- inspect(usedfonts)
for k, v in next, virtualcharacters do
if not characters[k] then
local tv = type(v)
+ local cd = nil
if tv == "table" then
- characters[k] = v
+ cd = v
elseif tv == "number" then
- characters[k] = characters[v]
+ cd = characters[v]
elseif tv == "function" then
- characters[k] = v(data)
+ cd = v(data)
end
- if trace_fallbacks then
- if characters[k] then
- report_fallbacks("extending font %a with %U",target.properties.fullname,k)
- end
+ if cd then
+ characters[k] = cd
+ else
+ -- something else
+ end
+ if trace_fallbacks and characters[k] then
+ report_fallbacks("extending math font %a with %U",target.properties.fullname,k)
end
end
end
+ data.unicode = nil
end
end
@@ -162,12 +180,12 @@ end
-- virtualcharacters[0x208B] = 0x002B
virtualcharacters[0x207A] = function(data)
- data.replacement = 0x2212
+ data.replacement = 0x002B
return raised(data)
end
virtualcharacters[0x207B] = function(data)
- data.replacement = 0x002B
+ data.replacement = 0x2212
return raised(data)
end
@@ -310,3 +328,209 @@ virtualcharacters[0xFE352] = function(data)
end
end
+-- we could move the defs from math-act here
+
+local function accent_to_extensible(target,newchr,original,oldchr,height,depth,swap,offset)
+ local characters = target.characters
+ local olddata = characters[oldchr]
+ -- brrr ... pagella has only next
+ if olddata and not olddata.commands and olddata.width > 0 then
+ local addprivate = fonts.helpers.addprivate
+ if swap then
+ swap = characters[swap]
+ height = swap.depth
+ depth = 0
+ else
+ height = height or 0
+ depth = depth or 0
+ end
+ local correction = swap and { "down", (olddata.height or 0) - height } or { "down", olddata.height + (offset or 0)}
+ local newdata = {
+ commands = { correction, { "slot", 1, oldchr } },
+ width = olddata.width,
+ height = height,
+ depth = depth,
+ }
+ local glyphdata = newdata
+ local nextglyph = olddata.next
+ while nextglyph do
+ local oldnextdata = characters[nextglyph]
+ if oldnextdata then
+ local newnextdata = {
+ commands = { correction, { "slot", 1, nextglyph } },
+ width = oldnextdata.width,
+ height = height,
+ depth = depth,
+ }
+ local newnextglyph = addprivate(target,formatters["M-N-%H"](nextglyph),newnextdata)
+ newdata.next = newnextglyph
+ local nextnextglyph = oldnextdata.next
+ if nextnextglyph == nextglyph then
+ break
+ else
+ olddata = oldnextdata
+ newdata = newnextdata
+ nextglyph = nextnextglyph
+ end
+ else
+ report_fallbacks("error in fallback: no valid next, slot %X",nextglyph)
+ break
+ end
+ end
+ local hv = olddata.horiz_variants
+ if hv then
+ hv = fastcopy(hv)
+ newdata.horiz_variants = hv
+ for i=1,#hv do
+ local hvi = hv[i]
+ local oldglyph = hvi.glyph
+ local olddata = characters[oldglyph]
+ if olddata then
+ local newdata = {
+ commands = { correction, { "slot", 1, oldglyph } },
+ width = olddata.width,
+ height = height,
+ depth = depth,
+ }
+ hvi.glyph = addprivate(target,formatters["M-H-%H"](oldglyph),newdata)
+ else
+ report_fallbacks("error in fallback: no valid horiz_variants, slot %X, index %i",oldglyph,i)
+ end
+ end
+ end
+ return glyphdata, true
+ else
+ return olddata, false
+ end
+end
+
+virtualcharacters[0x203E] = function(data) -- could be FE33E instead
+ local target = data.target
+ local height, depth = 0, 0
+ local mathparameters = target.mathparameters
+ if mathparameters then
+ height = mathparameters.OverbarVerticalGap
+ depth = mathparameters.UnderbarVerticalGap
+ else
+ height = target.parameters.xheight/4
+ depth = height
+ end
+ return accent_to_extensible(target,0x203E,data.original,0x0305,height,depth)
+end
+
+virtualcharacters[0xFE33E] = virtualcharacters[0x203E] -- convenient
+virtualcharacters[0xFE33F] = virtualcharacters[0x203E] -- convenient
+
+local function smashed(data,unicode,swap,private)
+ local target = data.target
+ local original = data.original
+ local chardata = target.characters[unicode]
+ if chardata and chardata.height > target.parameters.xheight then
+ return accent_to_extensible(target,private,original,unicode,0,0,swap)
+ else
+ return original.characters[unicode]
+ end
+end
+
+addextra(0xFE3DE, { description="EXTENSIBLE OF 0x03DE", unicodeslot=0xFE3DE, mathextensible = "r", mathstretch = "h" } )
+addextra(0xFE3DC, { description="EXTENSIBLE OF 0x03DC", unicodeslot=0xFE3DC, mathextensible = "r", mathstretch = "h" } )
+addextra(0xFE3B4, { description="EXTENSIBLE OF 0x03B4", unicodeslot=0xFE3B4, mathextensible = "r", mathstretch = "h" } )
+
+virtualcharacters[0xFE3DE] = function(data) return smashed(data,0x23DE,0x23DF,0xFE3DE) end
+virtualcharacters[0xFE3DC] = function(data) return smashed(data,0x23DC,0x23DD,0xFE3DC) end
+virtualcharacters[0xFE3B4] = function(data) return smashed(data,0x23B4,0x23B5,0xFE3B4) end
+
+addextra(0xFE3DF, { description="EXTENSIBLE OF 0x03DF", unicodeslot=0xFE3DF, mathextensible = "r", mathstretch = "h" } )
+addextra(0xFE3DD, { description="EXTENSIBLE OF 0x03DD", unicodeslot=0xFE3DD, mathextensible = "r", mathstretch = "h" } )
+addextra(0xFE3B5, { description="EXTENSIBLE OF 0x03B5", unicodeslot=0xFE3B5, mathextensible = "r", mathstretch = "h" } )
+
+virtualcharacters[0xFE3DF] = function(data) return data.target.characters[0x23DF] end
+virtualcharacters[0xFE3DD] = function(data) return data.target.characters[0x23DD] end
+virtualcharacters[0xFE3B5] = function(data) return data.target.characters[0x23B5] end
+
+-- todo: add some more .. numbers might change
+
+addextra(0xFE302, { description="EXTENSIBLE OF 0x0302", unicodeslot=0xFE302, mathstretch = "h" } )
+addextra(0xFE303, { description="EXTENSIBLE OF 0x0303", unicodeslot=0xFE303, mathstretch = "h" } )
+
+local function smashed(data,unicode,private)
+ local target = data.target
+ local height = target.parameters.xheight / 2
+ local c, done = accent_to_extensible(target,private,data.original,unicode,height,0,nil,-height)
+ if done then
+ c.top_accent = nil -- or maybe also all the others
+ end
+ return c
+end
+
+virtualcharacters[0xFE302] = function(data) return smashed(data,0x0302,0xFE302) end
+virtualcharacters[0xFE303] = function(data) return smashed(data,0x0303,0xFE303) end
+
+-- another crazy hack .. doesn't work as we define scrscr first .. we now have smaller
+-- primes so we have smaller primes for the moment, big ones will become an option
+
+local function smashed(data,unicode,optional)
+ local oldchar = data.characters[unicode]
+ if oldchar then
+ local height = 1.2 * data.target.parameters.xheight
+ local newchar = {
+ commands = {
+ { "down", oldchar.height - height },
+ { "char", unicode },
+ },
+ height = height,
+ width = oldchar.width,
+ }
+ return newchar
+ elseif not optional then
+ report_fallbacks("missing %U prime in font %a",unicode,data.target.properties.fullname)
+ end
+end
+
+addextra(0xFE932, { description="SMASHED PRIME 0x02032", unicodeslot=0xFE932 } )
+addextra(0xFE933, { description="SMASHED PRIME 0x02033", unicodeslot=0xFE933 } )
+addextra(0xFE934, { description="SMASHED PRIME 0x02034", unicodeslot=0xFE934 } )
+addextra(0xFE957, { description="SMASHED PRIME 0x02057", unicodeslot=0xFE957 } )
+
+addextra(0xFE935, { description="SMASHED BACKWARD PRIME 0x02035", unicodeslot=0xFE935 } )
+addextra(0xFE936, { description="SMASHED BACKWARD PRIME 0x02036", unicodeslot=0xFE936 } )
+addextra(0xFE937, { description="SMASHED BACKWARD PRIME 0x02037", unicodeslot=0xFE937 } )
+
+virtualcharacters[0xFE932] = function(data) return smashed(data,0x02032) end
+virtualcharacters[0xFE933] = function(data) return smashed(data,0x02033) end
+virtualcharacters[0xFE934] = function(data) return smashed(data,0x02034) end
+virtualcharacters[0xFE957] = function(data) return smashed(data,0x02057) end
+
+virtualcharacters[0xFE935] = function(data) return smashed(data,0x02035,true) end
+virtualcharacters[0xFE936] = function(data) return smashed(data,0x02036,true) end
+virtualcharacters[0xFE937] = function(data) return smashed(data,0x02037,true) end
+
+-- actuarian (beware: xits has an ugly one)
+
+addextra(0xFE940, { category = "mn", description="SMALL ANNUITY SYMBOL", unicodeslot=0xFE940, mathclass="topaccent", mathname="smallactuarial" })
+
+local function actuarian(data)
+ local characters = data.target.characters
+ local parameters = data.target.parameters
+ local basechar = characters[0x0078] -- x (0x0058 X) or 0x1D431
+ local linewidth = parameters.xheight / 10
+ local basewidth = basechar.width
+ local baseheight = basechar.height
+ return {
+ -- todo: add alttext
+ -- compromise: lm has large hooks e.g. \actuarial{a}
+ width = basewidth + 4 * linewidth,
+ tounicode = tounicode16(0x20E7),
+ commands = {
+ { "right", 2 * linewidth },
+ { "down", - baseheight - 3 * linewidth },
+ { "rule", linewidth, basewidth + 4 * linewidth },
+ { "right", -linewidth },
+ { "down", baseheight + 4 * linewidth },
+ { "rule", baseheight + 5 * linewidth, linewidth },
+ },
+ }
+end
+
+virtualcharacters[0x020E7] = actuarian -- checked
+virtualcharacters[0xFE940] = actuarian -- unchecked