summaryrefslogtreecommitdiff
path: root/tex/context/base/node-fnt.lua
diff options
context:
space:
mode:
Diffstat (limited to 'tex/context/base/node-fnt.lua')
-rw-r--r--tex/context/base/node-fnt.lua297
1 files changed, 233 insertions, 64 deletions
diff --git a/tex/context/base/node-fnt.lua b/tex/context/base/node-fnt.lua
index 54359117e..2f59d513c 100644
--- a/tex/context/base/node-fnt.lua
+++ b/tex/context/base/node-fnt.lua
@@ -30,6 +30,7 @@ local nodecodes = nodes.nodecodes
local handlers = nodes.handlers
local glyph_code = nodecodes.glyph
+local disc_code = nodecodes.disc
local setmetatableindex = table.setmetatableindex
@@ -48,12 +49,31 @@ local run = 0
local setfontdynamics = { }
local fontprocesses = { }
+-- setmetatableindex(setfontdynamics, function(t,font)
+-- local tfmdata = fontdata[font]
+-- local shared = tfmdata.shared
+-- local v = shared and shared.dynamics and otf.setdynamics or false
+-- t[font] = v
+-- return v
+-- end)
+
setmetatableindex(setfontdynamics, function(t,font)
local tfmdata = fontdata[font]
local shared = tfmdata.shared
- local v = shared and shared.dynamics and otf.setdynamics or false
- t[font] = v
- return v
+ local f = shared and shared.dynamics and otf.setdynamics or false
+ if f then
+ local v = { }
+ t[font] = v
+ setmetatableindex(v,function(t,k)
+ local v = f(font,k)
+ t[k] = v
+ return v
+ end)
+ return v
+ else
+ t[font] = false
+ return false
+ end
end)
setmetatableindex(fontprocesses, function(t,font)
@@ -72,11 +92,18 @@ end)
fonts.hashes.setdynamics = setfontdynamics
fonts.hashes.processes = fontprocesses
+-- if we forget about basemode we don't need to test too much here and we can consider running
+-- over sub-ranges .. this involves a bit more initializations but who cares .. in that case we
+-- also need to use the stop criterium (we already use head too) ... we cannot use traverse
+-- then, so i'll test it on some local clone first ... the only pitfall is changed directions
+-- inside a run which means that we need to keep track of this which in turn complicates matters
+-- in a way i don't like
+
function handlers.characters(head)
-- either next or not, but definitely no already processed list
starttiming(nodes)
- local usedfonts, attrfonts, done = { }, { }, false
- local a, u, prevfont, prevattr = 0, 0, nil, 0
+ local usedfonts, attrfonts = { }, { }
+ local a, u, prevfont, prevattr, done = 0, 0, nil, 0, false
if trace_fontrun then
run = run + 1
report_fonts()
@@ -88,9 +115,11 @@ function handlers.characters(head)
if id == glyph_code then
local font = n.font
local attr = n[0] or 0
- report_fonts("font %03i, dynamic %03i, glyph %s",font,attr,utf.char(n.char))
+ report_fonts("font %03i, dynamic %03i, glyph %C",font,attr,n.char)
+ elseif id == disc_code then
+ report_fonts("[disc] %s",nodes.listtoutf(n,true,false,n))
else
- report_fonts("[%s]",nodecodes[n.id])
+ report_fonts("[%s]",nodecodes[id])
end
n = n.next
end
@@ -107,15 +136,10 @@ function handlers.characters(head)
attrfonts[font] = used
end
if not used[attr] then
- local sd = setfontdynamics[font]
- if sd then -- always true ?
- local d = sd(font,attr) -- can we cache this one?
- if d then
- used[attr] = d
- a = a + 1
- else
- -- can't happen ... otherwise best use nil/false distinction
- end
+ local fd = setfontdynamics[font]
+ if fd then
+ used[attr] = fd[attr]
+ a = a + 1
end
end
else
@@ -125,9 +149,7 @@ function handlers.characters(head)
if fp then
usedfonts[font] = fp
u = u + 1
- else
- -- can't happen ... otherwise best use nil/false distinction
- end
+ end
end
end
prevfont = font
@@ -141,34 +163,25 @@ function handlers.characters(head)
report_fonts("dynamics: %s",(a > 0 and concat(keys(attrfonts)," ")) or "none")
report_fonts()
end
+ -- in context we always have at least 2 processors
if u == 0 then
-- skip
elseif u == 1 then
local font, processors = next(usedfonts)
- local n = #processors
- if n > 0 then
- local h, d = processors[1](head,font,0)
- head = h or head
- done = done or d
- if n > 1 then
- for i=2,n do
- local h, d = processors[i](head,font,0)
- head = h or head
- done = done or d
- end
+ for i=1,#processors do
+ local h, d = processors[i](head,font,0)
+ if d then
+ head = h or head
+ done = true
end
end
else
for font, processors in next, usedfonts do
- local n = #processors
- local h, d = processors[1](head,font,0)
- head = h or head
- done = done or d
- if n > 1 then
- for i=2,n do
- local h, d = processors[i](head,font,0)
+ for i=1,#processors do
+ local h, d = processors[i](head,font,0)
+ if d then
head = h or head
- done = done or d
+ done = true
end
end
end
@@ -178,38 +191,22 @@ function handlers.characters(head)
elseif a == 1 then
local font, dynamics = next(attrfonts)
for attribute, processors in next, dynamics do -- attr can switch in between
- local n = #processors
- if n == 0 then
- report_fonts("no processors associated with dynamic %s",attribute)
- else
- local h, d = processors[1](head,font,attribute)
- head = h or head
- done = done or d
- if n > 1 then
- for i=2,n do
- local h, d = processors[i](head,font,attribute)
- head = h or head
- done = done or d
- end
+ for i=1,#processors do
+ local h, d = processors[i](head,font,attribute)
+ if d then
+ head = h or head
+ done = true
end
end
end
else
for font, dynamics in next, attrfonts do
for attribute, processors in next, dynamics do -- attr can switch in between
- local n = #processors
- if n == 0 then
- report_fonts("no processors associated with dynamic %s",attribute)
- else
- local h, d = processors[1](head,font,attribute)
- head = h or head
- done = done or d
- if n > 1 then
- for i=2,n do
- local h, d = processors[i](head,font,attribute)
- head = h or head
- done = done or d
- end
+ for i=1,#processors do
+ local h, d = processors[i](head,font,attribute)
+ if d then
+ head = h or head
+ done = true
end
end
end
@@ -222,5 +219,177 @@ function handlers.characters(head)
return head, true
end
+-- local formatters = string.formatters
+
+-- local function make(processors,font,attribute)
+-- _G.__temp = processors
+-- local t = { }
+-- for i=1,#processors do
+-- if processors[i] then
+-- t[#t+1] = formatters["local p_%s = _G.__temp[%s]"](i,i)
+-- end
+-- end
+-- t[#t+1] = "return function(head,done)"
+-- if #processors == 1 then
+-- t[#t+1] = formatters["return p_%s(head,%s,%s)"](1,font,attribute or 0)
+-- else
+-- for i=1,#processors do
+-- if processors[i] then
+-- t[#t+1] = formatters["local h,d=p_%s(head,%s,%s) if d then head=h or head done=true end"](i,font,attribute or 0)
+-- end
+-- end
+-- t[#t+1] = "return head, done"
+-- end
+-- t[#t+1] = "end"
+-- t = concat(t,"\n")
+-- t = load(t)(processors)
+-- _G.__temp = nil
+-- return t
+-- end
+
+-- setmetatableindex(fontprocesses, function(t,font)
+-- local tfmdata = fontdata[font]
+-- local shared = tfmdata.shared -- we need to check shared, only when same features
+-- local processes = shared and shared.processes
+-- if processes and #processes > 0 then
+-- processes = make(processes,font,0)
+-- t[font] = processes
+-- return processes
+-- else
+-- t[font] = false
+-- return false
+-- end
+-- end)
+
+-- setmetatableindex(setfontdynamics, function(t,font)
+-- local tfmdata = fontdata[font]
+-- local shared = tfmdata.shared
+-- local f = shared and shared.dynamics and otf.setdynamics or false
+-- if f then
+-- local v = { }
+-- t[font] = v
+-- setmetatableindex(v,function(t,k)
+-- local v = f(font,k)
+-- v = make(v,font,k)
+-- t[k] = v
+-- return v
+-- end)
+-- return v
+-- else
+-- t[font] = false
+-- return false
+-- end
+-- end)
+
+-- function handlers.characters(head)
+-- -- either next or not, but definitely no already processed list
+-- starttiming(nodes)
+-- local usedfonts, attrfonts
+-- local a, u, prevfont, prevattr, done = 0, 0, nil, 0, false
+-- if trace_fontrun then
+-- run = run + 1
+-- report_fonts()
+-- report_fonts("checking node list, run %s",run)
+-- report_fonts()
+-- local n = head
+-- while n do
+-- local id = n.id
+-- if id == glyph_code then
+-- local font = n.font
+-- local attr = n[0] or 0
+-- report_fonts("font %03i, dynamic %03i, glyph %s",font,attr,utf.char(n.char))
+-- else
+-- report_fonts("[%s]",nodecodes[n.id])
+-- end
+-- n = n.next
+-- end
+-- end
+-- for n in traverse_id(glyph_code,head) do
+-- -- if n.subtype<256 then -- all are 1
+-- local font = n.font
+-- local attr = n[0] or 0 -- zero attribute is reserved for fonts in context
+-- if font ~= prevfont or attr ~= prevattr then
+-- if attr > 0 then
+-- if not attrfonts then
+-- attrfonts = {
+-- [font] = {
+-- [attr] = setfontdynamics[font][attr]
+-- }
+-- }
+-- a = 1
+-- else
+-- local used = attrfonts[font]
+-- if not used then
+-- attrfonts[font] = {
+-- [attr] = setfontdynamics[font][attr]
+-- }
+-- a = a + 1
+-- elseif not used[attr] then
+-- used[attr] = setfontdynamics[font][attr]
+-- a = a + 1
+-- end
+-- end
+-- else
+-- if not usedfonts then
+-- local fp = fontprocesses[font]
+-- if fp then
+-- usedfonts = {
+-- [font] = fp
+-- }
+-- u = 1
+-- end
+-- else
+-- local used = usedfonts[font]
+-- if not used then
+-- local fp = fontprocesses[font]
+-- if fp then
+-- usedfonts[font] = fp
+-- u = u + 1
+-- end
+-- end
+-- end
+-- end
+-- prevfont = font
+-- prevattr = attr
+-- end
+-- -- end
+-- end
+-- if trace_fontrun then
+-- report_fonts()
+-- report_fonts("statics : %s",(u > 0 and concat(keys(usedfonts)," ")) or "none")
+-- report_fonts("dynamics: %s",(a > 0 and concat(keys(attrfonts)," ")) or "none")
+-- report_fonts()
+-- end
+-- if not usedfonts then
+-- -- skip
+-- elseif u == 1 then
+-- local font, processors = next(usedfonts)
+-- head, done = processors(head,done)
+-- else
+-- for font, processors in next, usedfonts do
+-- head, done = processors(head,done)
+-- end
+-- end
+-- if not attrfonts then
+-- -- skip
+-- elseif a == 1 then
+-- local font, dynamics = next(attrfonts)
+-- for attribute, processors in next, dynamics do
+-- head, done = processors(head,done)
+-- end
+-- else
+-- for font, dynamics in next, attrfonts do
+-- for attribute, processors in next, dynamics do
+-- head, done = processors(head,done)
+-- end
+-- end
+-- end
+-- stoptiming(nodes)
+-- if trace_characters then
+-- nodes.report(head,done)
+-- end
+-- return head, true
+-- end
+
handlers.protectglyphs = node.protect_glyphs
handlers.unprotectglyphs = node.unprotect_glyphs