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.lua283
1 files changed, 220 insertions, 63 deletions
diff --git a/tex/context/base/node-fnt.lua b/tex/context/base/node-fnt.lua
index 54359117e..6d5ed6ca0 100644
--- a/tex/context/base/node-fnt.lua
+++ b/tex/context/base/node-fnt.lua
@@ -48,12 +48,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)
@@ -75,8 +94,8 @@ fonts.hashes.processes = fontprocesses
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()
@@ -107,16 +126,8 @@ 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
- end
+ used[attr] = setfontdynamics[font][attr]
+ a = a + 1
end
else
local used = usedfonts[font]
@@ -125,9 +136,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 +150,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 +178,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 +206,178 @@ 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