diff options
Diffstat (limited to 'Master/texmf-dist/tex/context/base/node-fnt.lua')
-rw-r--r-- | Master/texmf-dist/tex/context/base/node-fnt.lua | 336 |
1 files changed, 260 insertions, 76 deletions
diff --git a/Master/texmf-dist/tex/context/base/node-fnt.lua b/Master/texmf-dist/tex/context/base/node-fnt.lua index 54359117e81..7000c4fd7ac 100644 --- a/Master/texmf-dist/tex/context/base/node-fnt.lua +++ b/Master/texmf-dist/tex/context/base/node-fnt.lua @@ -23,13 +23,26 @@ local fontdata = fonthashes.identifiers local otf = fonts.handlers.otf -local traverse_id = node.traverse_id local starttiming = statistics.starttiming local stoptiming = statistics.stoptiming + local nodecodes = nodes.nodecodes local handlers = nodes.handlers +local nuts = nodes.nuts +local tonut = nuts.tonut + +local getattr = nuts.getattr +local getid = nuts.getid +local getfont = nuts.getfont +local getsubtype = nuts.getsubtype +local getchar = nuts.getchar +local getnext = nuts.getnext + +local traverse_id = nuts.traverse_id + local glyph_code = nodecodes.glyph +local disc_code = nodecodes.disc local setmetatableindex = table.setmetatableindex @@ -48,12 +61,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,33 +104,42 @@ 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() report_fonts("checking node list, run %s",run) report_fonts() - local n = head + local n = tonut(head) while n do - local id = n.id + local id = getid(n) 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)) + local font = getfont(n) + local attr = getattr(n,0) or 0 + report_fonts("font %03i, dynamic %03i, glyph %C",font,attr,getchar(n)) + 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 + n = getnext(n) 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 + for n in traverse_id(glyph_code,tonut(head)) do + -- if getsubtype(n) <256 then -- all are 1 + local font = getfont(n) + local attr = getattr(n,0) or 0 -- zero attribute is reserved for fonts in context if font ~= prevfont or attr ~= prevattr then if attr > 0 then local used = attrfonts[font] @@ -107,15 +148,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 +161,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 +175,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 +203,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 +231,180 @@ function handlers.characters(head) return head, true end -handlers.protectglyphs = node.protect_glyphs -handlers.unprotectglyphs = node.unprotect_glyphs +-- 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 + +local d_protect_glyphs = nuts.protect_glyphs +local d_unprotect_glyphs = nuts.unprotect_glyphs + +handlers.protectglyphs = function(n) return d_protect_glyphs (tonut(n)) end +handlers.unprotectglyphs = function(n) return d_unprotect_glyphs(tonut(n)) end |