summaryrefslogtreecommitdiff
path: root/tex/context/base/math-vfu.lua
diff options
context:
space:
mode:
authorMarius <mariausol@gmail.com>2013-10-20 01:21:09 +0300
committerMarius <mariausol@gmail.com>2013-10-20 01:21:09 +0300
commitb8ac6d7b7fdb16293c28034c349efd5b0b7b20b3 (patch)
tree0e9051dbe21b4e9cfc72fe594df5b0fe7bc511f3 /tex/context/base/math-vfu.lua
parent965214d981e6129b782c67adcaf3a81aedcb0bac (diff)
downloadcontext-b8ac6d7b7fdb16293c28034c349efd5b0b7b20b3.tar.gz
beta 2013.10.20 07:09
Diffstat (limited to 'tex/context/base/math-vfu.lua')
-rw-r--r--tex/context/base/math-vfu.lua485
1 files changed, 316 insertions, 169 deletions
diff --git a/tex/context/base/math-vfu.lua b/tex/context/base/math-vfu.lua
index 2f7c0507b..6d9a9f903 100644
--- a/tex/context/base/math-vfu.lua
+++ b/tex/context/base/math-vfu.lua
@@ -26,6 +26,7 @@ local type, next = type, next
local max = math.max
local format = string.format
local utfchar = utf.char
+local fastcopy = table.copy
local fonts, nodes, mathematics = fonts, nodes, mathematics
@@ -38,6 +39,7 @@ local report_virtual = logs.reporter("fonts","virtual math")
local allocate = utilities.storage.allocate
local setmetatableindex = table.setmetatableindex
+local formatters = string.formatters
local mathencodings = allocate()
fonts.encodings.math = mathencodings -- better is then: fonts.encodings.vectors
@@ -199,21 +201,44 @@ end
-- { "node", nodeinjections.transform(.7,0,0,.7) },
-- commands[#commands+1] = { "node", nodeinjections.restore() }
-local done = { }
+-- local done = { }
+--
+-- local function raise(main,characters,id,size,unicode,private,n,id_of_smaller) -- this is a real fake mess
+-- local raised = characters[private]
+-- if raised then
+-- if not done[unicode] then
+-- report_virtual("temporary too large %U due to issues in luatex backend",unicode)
+-- done[unicode] = true
+-- end
+-- local up = 0.85 * main.parameters.x_height
+-- local slot = { "slot", id, private }
+-- local commands = {
+-- push,
+-- { "down", - up },
+-- -- { "scale", .7, 0, 0, .7 },
+-- slot,
+-- }
+-- for i=2,n do
+-- commands[#commands+1] = slot
+-- end
+-- commands[#commands+1] = pop
+-- characters[unicode] = {
+-- width = .7 * n * raised.width,
+-- height = .7 * (raised.height + up),
+-- depth = .7 * (raised.depth - up),
+-- commands = commands,
+-- }
+-- end
+-- end
-local function raise(main,characters,id,size,unicode,private,n) -- this is a real fake mess
- local raised = characters[private]
+local function raise(main,characters,id,size,unicode,private,n,id_of_smaller) -- this is a real fake mess
+ local raised = fonts.hashes.characters[main.fonts[id_of_smaller].id][private] -- characters[private]
if raised then
- if not done[unicode] then
- report_virtual("temporary too large %U due to issues in luatex backend",unicode)
- done[unicode] = true
- end
local up = 0.85 * main.parameters.x_height
- local slot = { "slot", id, private }
+ local slot = { "slot", id_of_smaller, private }
local commands = {
push,
{ "down", - up },
- -- { "scale", .7, 0, 0, .7 },
slot,
}
for i=2,n do
@@ -221,9 +246,10 @@ local function raise(main,characters,id,size,unicode,private,n) -- this is a rea
end
commands[#commands+1] = pop
characters[unicode] = {
- width = .7 * n * raised.width,
- height = .7 * (raised.height + up),
- depth = .7 * (raised.depth - up),
+ width = n * raised.width,
+ height = (raised.height or 0) + up,
+ depth = (raised.depth or 0) - up,
+ italic = raised.italic,
commands = commands,
}
end
@@ -406,7 +432,25 @@ local function repeated(main,characters,id,size,unicode,u,n,private,fraction) --
end
end
+-- we use the fact that context defines the smallest sizes first .. a real dirty and ugly hack
+
+local data_of_smaller = nil
+local size_of_smaller = 0
+
function vfmath.addmissing(main,id,size)
+
+ local id_of_smaller = nil
+
+ if size < size_of_smaller or size_of_smaller == 0 then
+ data_of_smaller = main.fonts[id]
+ id_of_smaller = id
+ else
+ id_of_smaller = #main.fonts + 1
+ main.fonts[id_of_smaller] = data_of_smaller
+ end
+
+ -- here id is the index in fonts (normally 14 or so) and that slot points to self
+
local characters = main.characters
local shared = main.shared
local variables = main.goodies.mathematics and main.goodies.mathematics.variables or { }
@@ -504,9 +548,11 @@ function vfmath.addmissing(main,id,size)
repeated(main,characters,id,size,0x222C,0x222B,2,0xFF800,1/3)
repeated(main,characters,id,size,0x222D,0x222B,3,0xFF810,1/3)
- -- raise (main,characters,id,size,0x02032,0xFE325,1) -- prime
- -- raise (main,characters,id,size,0x02033,0xFE325,2) -- double prime
- -- raise (main,characters,id,size,0x02034,0xFE325,3) -- triple prime
+ characters[0xFE325] = fastcopy(characters[0x2032])
+
+ raise (main,characters,id,size,0x02032,0xFE325,1,id_of_smaller) -- prime
+ raise (main,characters,id,size,0x02033,0xFE325,2,id_of_smaller) -- double prime
+ raise (main,characters,id,size,0x02034,0xFE325,3,id_of_smaller) -- triple prime
-- there are more (needs discussion first):
@@ -515,6 +561,9 @@ function vfmath.addmissing(main,id,size)
characters[0x02B9] = characters[0x2032] -- we're nice
+ data_of_smaller = main.fonts[id]
+ size_of_smaller = size
+
end
local unique = 0 -- testcase: \startTEXpage \math{!\text{-}\text{-}\text{-}} \stopTEXpage
@@ -534,6 +583,82 @@ setmetatableindex(reverse, function(t,name)
return r
end)
+local function copy_glyph(main,target,original,unicode,slot)
+ local addprivate = fonts.helpers.addprivate
+ local olddata = original[unicode]
+ if olddata then
+ local newdata = {
+ width = olddata.width,
+ height = olddata.height,
+ depth = olddata.depth,
+ italic = olddata.italic,
+ kerns = olddata.kerns,
+ commands = { { "slot", slot, unicode } },
+ }
+ local glyphdata = newdata
+ local nextglyph = olddata.next
+ while nextglyph do
+ local oldnextdata = original[nextglyph]
+ local newnextdata = {
+ commands = { { "slot", slot, nextglyph } },
+ width = oldnextdata.width,
+ height = oldnextdata.height,
+ depth = oldnextdata.depth,
+ }
+ local newnextglyph = addprivate(main,formatters["M-N-%H"](nextglyph),newnextdata)
+ newdata.next = newnextglyph
+-- report_virtual("copied next: %X",newdata.next)
+ local nextnextglyph = oldnextdata.next
+ if nextnextglyph == nextglyph then
+ break
+ else
+ olddata = oldnextdata
+ newdata = newnextdata
+ nextglyph = nextnextglyph
+ 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 = original[oldglyph]
+ local newdata = {
+ commands = { { "slot", slot, oldglyph } },
+ width = olddata.width,
+ height = olddata.height,
+ depth = olddata.depth,
+ }
+ hvi.glyph = addprivate(main,formatters["M-H-%H"](oldglyph),newdata)
+-- report_virtual("copied h variant: %X at index %i",hvi.glyph,i)
+ end
+ end
+ local vv = olddata.vert_variants
+ if vv then
+ vv = fastcopy(vv)
+ newdata.vert_variants = vv
+ for i=1,#vv do
+ local vvi = vv[i]
+ local oldglyph = vvi.glyph
+ local olddata = original[oldglyph]
+ local newdata = {
+ commands = { { "slot", slot, oldglyph } },
+ width = olddata.width,
+ height = olddata.height,
+ depth = olddata.depth,
+ }
+ vvi.glyph = addprivate(main,formatters["M-V-%H"](oldglyph),newdata)
+-- report_virtual("copied v variant: %X at index %i",vvi.glyph,i)
+ end
+ end
+ return newdata
+ end
+end
+
+vfmath.copy_glyph = copy_glyph
+
function vfmath.define(specification,set,goodies)
local name = specification.name -- symbolic name
local size = specification.size -- given size
@@ -576,7 +701,7 @@ function vfmath.define(specification,set,goodies)
shared[n] = { }
end
if trace_virtual then
- report_virtual("loading font %a subfont %s with name %a at %p as id %s using encoding %p",name,s,ssname,size,id,ss.vector)
+ report_virtual("loading font %a subfont %s with name %a at %p as id %s using encoding %a",name,s,ssname,size,id,ss.vector)
end
if not ss.checked then
ss.checked = true
@@ -677,6 +802,7 @@ function vfmath.define(specification,set,goodies)
parameters.x_height = parameters.x_height or 0
--
local already_reported = false
+ local parameters_done = false
for s=1,n do
local ss, fs = okset[s], loaded[s]
if not fs then
@@ -685,7 +811,13 @@ function vfmath.define(specification,set,goodies)
-- skip, redundant
else
local newparameters = fs.parameters
- if not newparameters then
+ local newmathparameters = fs.mathparameters
+ if newmathparameters then
+ if not parameters_done or ss.parameters then
+ mathparameters = newmathparameters
+ parameters_done = true
+ end
+ elseif not newparameters then
report_virtual("no parameters set in font %a",name)
elseif ss.extension then
mathparameters.math_x_height = newparameters.x_height or 0 -- math_x_height : height of x
@@ -716,187 +848,202 @@ function vfmath.define(specification,set,goodies)
mathparameters.axis_height = newparameters[22] or 0 -- axis_height : height of fraction lines above the baseline
-- report_virtual("loading and virtualizing font %a at size %p, setting sy parameters",name,size)
end
- local vectorname = ss.vector
- if vectorname then
- local offset = 0xFF000
- local vector = mathencodings[vectorname]
- local rotcev = reverse[vectorname]
- local isextension = ss.extension
- 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.properties.name or "unknown"
- local rf = reported[fontname]
- if not rf then rf = { } reported[fontname] = rf end
- local rv = rf[vectorname]
- if not rv then rv = { } rf[vectorname] = rv end
- local ru = rv[unicode]
- if not ru then
- if trace_virtual then
- report_virtual("unicode slot %U has no index %H in vector %a for font %a",unicode,index,vectorname,fontname)
- elseif not already_reported then
- report_virtual("the mapping is incomplete for %a at %p",name,size)
- already_reported = true
- end
- rv[unicode] = true
- end
- else
- local ref = si[index]
- if not ref then
- ref = { { 'slot', s, index } }
- si[index] = ref
- end
- local kerns = fci.kerns
- local width = fci.width
- local italic = fci.italic
- if italic and italic > 0 then
- -- int_a^b
- if isextension then
- width = width + italic -- for obscure reasons the integral as a width + italic correction
- end
- end
- if kerns then
- local krn = { }
- for k, v in next, kerns do -- kerns is sparse
- local rk = rotcev[k]
- if rk then
- krn[rk] = v -- kerns[k]
- end
- end
- if not next(krn) then
- krn = nil
- end
- local t = {
- width = width,
- height = fci.height,
- depth = fci.depth,
- italic = italic,
- kerns = krn,
- commands = ref,
- }
- if skewchar then
- local k = kerns[skewchar]
- if k then
- t.top_accent = width/2 + k
+ if ss.overlay then
+ local fc = fs.characters
+ local first = ss.first
+ if first then
+ local last = ss.last or first
+ for unicode = first, last do
+ characters[unicode] = copy_glyph(main,characters,fc,unicode,s)
+ end
+ else
+ for unicode, data in next, fc do
+ characters[unicode] = copy_glyph(main,characters,fc,unicode,s)
+ end
+ end
+ else
+ local vectorname = ss.vector
+ if vectorname then
+ local offset = 0xFF000
+ local vector = mathencodings[vectorname]
+ local rotcev = reverse[vectorname]
+ local isextension = ss.extension
+ 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.properties.name or "unknown"
+ local rf = reported[fontname]
+ if not rf then rf = { } reported[fontname] = rf end
+ local rv = rf[vectorname]
+ if not rv then rv = { } rf[vectorname] = rv end
+ local ru = rv[unicode]
+ if not ru then
+ if trace_virtual then
+ report_virtual("unicode slot %U has no index %H in vector %a for font %a",unicode,index,vectorname,fontname)
+ elseif not already_reported then
+ report_virtual("the mapping is incomplete for %a at %p",name,size)
+ already_reported = true
end
+ rv[unicode] = true
end
- characters[unicode] = t
else
- characters[unicode] = {
- width = width,
- height = fci.height,
- depth = fci.depth,
- italic = italic,
- commands = ref,
- }
- end
- end
- end
- if isextension then
- -- todo: if multiple ex, then 256 offsets per instance
- 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
local ref = si[index]
if not ref then
ref = { { 'slot', s, index } }
si[index] = ref
end
+ local kerns = fci.kerns
+ local width = fci.width
local italic = fci.italic
- local t = {
- width = fci.width,
- height = fci.height,
- depth = fci.depth,
- italic = italic,
- commands = ref,
- }
- local n = fci.next
- if n then
- t.next = offset + n
- elseif variants_done then
- local vv = fci.vert_variants
- if vv then
- t.vert_variants = vv
- end
- local hv = fci.horiz_variants
- if hv then
- t.horiz_variants = hv
+ if italic and italic > 0 then
+ -- int_a^b
+ if isextension then
+ width = width + italic -- for obscure reasons the integral as a width + italic correction
end
- else
- local vv = fci.vert_variants
- if vv then
- for i=1,#vv do
- local vvi = vv[i]
- vvi.glyph = vvi.glyph + offset
+ end
+ if kerns then
+ local krn = { }
+ for k, v in next, kerns do -- kerns is sparse
+ local rk = rotcev[k]
+ if rk then
+ krn[rk] = v -- kerns[k]
end
- t.vert_variants = vv
end
- local hv = fci.horiz_variants
- if hv then
- for i=1,#hv do
- local hvi = hv[i]
- hvi.glyph = hvi.glyph + offset
+ if not next(krn) then
+ krn = nil
+ end
+ local t = {
+ width = width,
+ height = fci.height,
+ depth = fci.depth,
+ italic = italic,
+ kerns = krn,
+ commands = ref,
+ }
+ if skewchar then
+ local k = kerns[skewchar]
+ if k then
+ t.top_accent = width/2 + k
end
- t.horiz_variants = hv
end
+ characters[unicode] = t
+ else
+ characters[unicode] = {
+ width = width,
+ height = fci.height,
+ depth = fci.depth,
+ italic = italic,
+ commands = ref,
+ }
end
- characters[offset + index] = t
end
end
- fs.variants_done = true
- for unicode, index in next, extension do
- local cu = characters[unicode]
- if cu then
- cu.next = offset + index
- else
- local fci = fc[index]
- if not fci then
- -- do nothing
- else
- -- probably never entered
+ if isextension then
+ -- todo: if multiple ex, then 256 offsets per instance
+ 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
local ref = si[index]
if not ref then
ref = { { 'slot', s, index } }
si[index] = ref
end
- local kerns = fci.kerns
- if kerns then
- local krn = { }
- -- 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
+ local italic = fci.italic
+ local t = {
+ width = fci.width,
+ height = fci.height,
+ depth = fci.depth,
+ italic = italic,
+ commands = ref,
+ }
+ local n = fci.next
+ if n then
+ t.next = offset + n
+ elseif variants_done then
+ local vv = fci.vert_variants
+ if vv then
+ t.vert_variants = vv
+ end
+ local hv = fci.horiz_variants
+ if hv then
+ t.horiz_variants = hv
end
- characters[unicode] = {
- width = fci.width,
- height = fci.height,
- depth = fci.depth,
- italic = fci.italic,
- commands = ref,
- kerns = krn,
- next = offset + index,
- }
else
- characters[unicode] = {
- width = fci.width,
- height = fci.height,
- depth = fci.depth,
- italic = fci.italic,
- commands = ref,
- next = offset + index,
- }
+ local vv = fci.vert_variants
+ if vv then
+ for i=1,#vv do
+ local vvi = vv[i]
+ vvi.glyph = vvi.glyph + offset
+ end
+ t.vert_variants = vv
+ end
+ local hv = fci.horiz_variants
+ if hv then
+ for i=1,#hv do
+ local hvi = hv[i]
+ hvi.glyph = hvi.glyph + offset
+ end
+ t.horiz_variants = hv
+ end
+ end
+ characters[offset + index] = t
+ end
+ end
+ fs.variants_done = true
+ for unicode, index in next, extension do
+ local cu = characters[unicode]
+ if cu then
+ cu.next = offset + index
+ else
+ local fci = fc[index]
+ if not fci then
+ -- do nothing
+ else
+ -- probably never entered
+ local ref = si[index]
+ if not ref then
+ ref = { { 'slot', s, index } }
+ si[index] = ref
+ end
+ local kerns = fci.kerns
+ if kerns then
+ local krn = { }
+ -- 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,
+ height = fci.height,
+ depth = fci.depth,
+ italic = fci.italic,
+ commands = ref,
+ kerns = krn,
+ next = offset + index,
+ }
+ else
+ characters[unicode] = {
+ width = fci.width,
+ height = fci.height,
+ depth = fci.depth,
+ italic = fci.italic,
+ commands = ref,
+ next = offset + index,
+ }
+ end
end
end
end
end
+ else
+ report_virtual("error in loading %a, problematic vector %a",name,vectorname)
end
- else
- report_virtual("error in loading %a, problematic vector %a",name,vectorname)
end
end
mathematics.extras.copy(main) --not needed here (yet)