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 | 212 |
1 files changed, 179 insertions, 33 deletions
diff --git a/Master/texmf-dist/tex/context/base/node-fnt.lua b/Master/texmf-dist/tex/context/base/node-fnt.lua index 7000c4fd7ac..774a687186a 100644 --- a/Master/texmf-dist/tex/context/base/node-fnt.lua +++ b/Master/texmf-dist/tex/context/base/node-fnt.lua @@ -13,8 +13,11 @@ local concat, keys = table.concat, table.keys local nodes, node, fonts = nodes, node, fonts -local trace_characters = false trackers.register("nodes.characters", function(v) trace_characters = v end) -local trace_fontrun = false trackers.register("nodes.fontrun", function(v) trace_fontrun = v end) +local trace_characters = false trackers .register("nodes.characters", function(v) trace_characters = v end) +local trace_fontrun = false trackers .register("nodes.fontrun", function(v) trace_fontrun = v end) + +local force_discrun = true directives.register("nodes.discrun", function(v) force_discrun = v end) +local force_basepass = true directives.register("nodes.basepass", function(v) force_basepass = v end) local report_fonts = logs.reporter("fonts","processing") @@ -31,6 +34,7 @@ local handlers = nodes.handlers local nuts = nodes.nuts local tonut = nuts.tonut +local tonode = nuts.tonode local getattr = nuts.getattr local getid = nuts.getid @@ -38,6 +42,8 @@ local getfont = nuts.getfont local getsubtype = nuts.getsubtype local getchar = nuts.getchar local getnext = nuts.getnext +local getprev = nuts.getprev +local getfield = nuts.getfield local traverse_id = nuts.traverse_id @@ -111,11 +117,25 @@ fonts.hashes.processes = fontprocesses -- 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 +-- we need to deal with the basemode fonts here and can only run over ranges as we +-- otherwise get luatex craches due to all kind of asserts in the disc/lig builder + +local ligaturing = node.ligaturing +local kerning = node.kerning + 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 + + local usedfonts = { } + local attrfonts = { } + local basefonts = { } + local a, u, b = 0, 0, 0 + local basefont = nil + local prevfont = nil + local prevattr = 0 + local done = false + if trace_fontrun then run = run + 1 report_fonts() @@ -136,43 +156,114 @@ function handlers.characters(head) n = getnext(n) end end - 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] - if not used then - used = { } - attrfonts[font] = used + + local nuthead = tonut(head) + + for n in traverse_id(glyph_code,nuthead) 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 basefont then + basefont[2] = tonode(getprev(n)) -- todo, save p end - if not used[attr] then - local fd = setfontdynamics[font] - if fd then - used[attr] = fd[attr] - a = a + 1 + if attr > 0 then + local used = attrfonts[font] + if not used then + used = { } + attrfonts[font] = used + end + if not used[attr] then + local fd = setfontdynamics[font] + if fd then + used[attr] = fd[attr] + a = a + 1 + elseif force_basepass then + b = b + 1 + basefont = { tonode(n), nil } + basefonts[b] = basefont + end + end + else + local used = usedfonts[font] + if not used then + local fp = fontprocesses[font] + if fp then + usedfonts[font] = fp + u = u + 1 + elseif force_basepass then + b = b + 1 + basefont = { tonode(n), nil } + basefonts[b] = basefont + end end end - else - local used = usedfonts[font] - if not used then - local fp = fontprocesses[font] - if fp then - usedfonts[font] = fp - u = u + 1 - end + prevfont = font + prevattr = attr + end + end + end + + -- could be an optional pass : seldom needed, only for documentation as a discretionary + -- with pre/post/replace will normally not occur on it's own + + if force_discrun then + + -- basefont is not supported in disc only runs ... it would mean a lot of + -- ranges .. we could try to run basemode as a separate processor run but + -- not for now (we can consider it when the new node code is tested + + -- local prevfont = nil + -- local prevattr = 0 + + for d in traverse_id(disc_code,nuthead) do + -- we could use first_glyph + local r = getfield(n,"replace") -- good enough + if r then + for n in traverse_id(glyph_code,r) 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] + if not used then + used = { } + attrfonts[font] = used + end + if not used[attr] then + local fd = setfontdynamics[font] + if fd then + used[attr] = fd[attr] + a = a + 1 + end + 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 + prevfont = font + prevattr = attr + end + end + break 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("statics : %s",u > 0 and concat(keys(usedfonts)," ") or "none") + report_fonts("dynamics: %s",a > 0 and concat(keys(attrfonts)," ") or "none") + report_fonts("built-in: %s",b > 0 and b or "none") report_fonts() end -- in context we always have at least 2 processors @@ -224,6 +315,49 @@ function handlers.characters(head) end end end + if b == 0 then + -- skip + elseif b == 1 then + -- only one font + local front = head == start + local range = basefonts[1] + local start = range[1] + local stop = range[2] + if stop then + start, stop = ligaturing(start,stop) + start, stop = kerning(start,stop) + elseif start then -- safeguard + start = ligaturing(start) + start = kerning(start) + else + -- something bad happened + end + if front then + -- shouldn't happen + head = start + end + else + -- multiple fonts + local front = head == start + for i=1,b do + local range = basefonts[i] + local start = range[1] + local stop = range[2] + if stop then + start, stop = ligaturing(start,stop) + start, stop = kerning(start,stop) + elseif start then -- safeguard + start = ligaturing(start) + start = kerning(start) + else + -- something bad happened + end + end + if front then + -- shouldn't happen + head = start + end + end stoptiming(nodes) if trace_characters then nodes.report(head,done) @@ -292,7 +426,9 @@ end -- return false -- end -- end) - +-- +-- -- TODO: basepasses! +-- -- function handlers.characters(head) -- -- either next or not, but definitely no already processed list -- starttiming(nodes) @@ -408,3 +544,13 @@ 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 + +-- function handlers.protectglyphs(h) +-- local h = tonut(h) +-- for n in traverse_id(disc_code,h) do +-- local d = getfield(n,"pre") if d then d_protect_glyphs(d) end +-- local d = getfield(n,"post") if d then d_protect_glyphs(d) end +-- local d = getfield(n,"replace") if d then d_protect_glyphs(d) end +-- end +-- return d_protect_glyphs(h) +-- end |