summaryrefslogtreecommitdiff
path: root/tex/context/base/mkiv/node-fnt.lua
diff options
context:
space:
mode:
Diffstat (limited to 'tex/context/base/mkiv/node-fnt.lua')
-rw-r--r--tex/context/base/mkiv/node-fnt.lua258
1 files changed, 137 insertions, 121 deletions
diff --git a/tex/context/base/mkiv/node-fnt.lua b/tex/context/base/mkiv/node-fnt.lua
index 8aa088f88..f846f996d 100644
--- a/tex/context/base/mkiv/node-fnt.lua
+++ b/tex/context/base/mkiv/node-fnt.lua
@@ -56,7 +56,7 @@ local getfield = nuts.getfield
----- getdisc = nuts.getdisc
local setchar = nuts.setchar
local setlink = nuts.setlink
-local setfield = nuts.setfield
+local setnext = nuts.setnext
local setprev = nuts.setprev
local isglyph = nuts.isglyph -- unchecked
@@ -71,6 +71,9 @@ local disc_code = nodecodes.disc
local boundary_code = nodecodes.boundary
local word_boundary = nodes.boundarycodes.word
+local protect_glyphs = nuts.protect_glyphs
+local unprotect_glyphs = nuts.unprotect_glyphs
+
local setmetatableindex = table.setmetatableindex
-- some tests with using an array of dynamics[id] and processes[id] demonstrated
@@ -140,28 +143,28 @@ local ligaturing = nuts.ligaturing
local kerning = nuts.kerning
-- -- -- this will go away
-
-local disccodes = nodes.disccodes
-local explicit_code = disccodes.explicit
-local automatic_code = disccodes.automatic
-local expanders = nil
-
-function fonts.setdiscexpansion(v)
- if v == nil or v == true then
- expanders = languages and languages.expanders
- elseif type(v) == "table" then
- expanders = v
- else
- expanders = false
- end
-end
-
-function fonts.getdiscexpansion()
- return expanders and true or false
-end
-
-fonts.setdiscexpansion(true)
-
+--
+-- local disccodes = nodes.disccodes
+-- local explicit_code = disccodes.explicit
+-- local automatic_code = disccodes.automatic
+-- local expanders = nil
+--
+-- function fonts.setdiscexpansion(v)
+-- if v == nil or v == true then
+-- expanders = languages and languages.expanders
+-- elseif type(v) == "table" then
+-- expanders = v
+-- else
+-- expanders = false
+-- end
+-- end
+--
+-- function fonts.getdiscexpansion()
+-- return expanders and true or false
+-- end
+--
+-- fonts.setdiscexpansion(true)
+--
-- -- -- till here
local function start_trace(head)
@@ -193,9 +196,9 @@ local function stop_trace(u,usedfonts,a,attrfonts,b,basefonts,r,redundant,e,expa
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("removed : %s",r > 0 and r or "none")
-if expanders then
- report_fonts("expanded: %s",e > 0 and e or "none")
-end
+ -- if expanders then
+ -- report_fonts("expanded: %s",e > 0 and e or "none")
+ -- end
report_fonts()
end
@@ -212,8 +215,10 @@ function handlers.characters(head,groupcode,size,packtype,direction)
local done = false
local variants = nil
local redundant = nil
- local none = false
local nuthead = tonut(head)
+ local lastfont = nil
+ local lastproc = nil
+ local lastnone = nil
local a, u, b, r, e = 0, 0, 0, 0, 0
@@ -224,54 +229,91 @@ function handlers.characters(head,groupcode,size,packtype,direction)
-- There is no gain in checking for a single glyph and then having a fast path. On the
-- metafun manual (with some 2500 single char lists) the difference is just noise.
+ local function protectnone()
+ protect_glyphs(firstnone,lastnone)
+ firstnone = nil
+ end
+
+ local function setnone(n)
+ if firstnone then
+ protectnone()
+ end
+ if basefont then
+ basefont[2] = getprev(n)
+ basefont = false
+ end
+ if not firstnone then
+ firstnone = n
+ end
+ lastnone = n
+ end
+
+ local function setbase(n)
+ if firstnone then
+ protectnone()
+ end
+ if force_basepass then
+ if basefont then
+ basefont[2] = getprev(n)
+ end
+ b = b + 1
+ basefont = { n, false }
+ basefonts[b] = basefont
+ end
+ end
+
+ local function setnode(n,font,attr) -- we could use prevfont and prevattr when we set then first
+ if firstnone then
+ protectnone()
+ end
+ if basefont then
+ basefont[2] = getprev(n)
+ basefont = false
+ end
+ 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
+ lastfont = font
+ lastproc = fontprocesses[font]
+ if lastproc then
+ usedfonts[font] = lastproc
+ u = u + 1
+ end
+ end
+ end
+ end
+
for n in traverse_char(nuthead) do
local font = getfont(n)
- local attr = (none and prevattr) or getattr(n,0) or 0 -- zero attribute is reserved for fonts in context
+ -- local attr = (none and prevattr) or getattr(n,0) or 0 -- zero attribute is reserved for fonts in context
+ local attr = getattr(n,0) or 0 -- zero attribute is reserved for fonts in context
if font ~= prevfont or attr ~= prevattr then
prevfont = font
prevattr = attr
variants = fontvariants[font]
- none = fontmodes[font] == "none"
- if none then
- -- skip
- -- variants = false
- protect_glyph(n)
+ local fontmode = fontmodes[font]
+ if fontmode == "none" then
+ setnone(n)
+ elseif fontmode == "base" then
+ setbase(n)
else
- if basefont then
- basefont[2] = getprev(n)
- end
- 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 = { n, false }
- 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 = { n, false }
- basefonts[b] = basefont
- end
- end
- end
+ setnode(n,font,attr)
end
+ elseif firstnone then
+ lastnone = n
end
if variants then
local char = getchar(n)
@@ -309,6 +351,10 @@ function handlers.characters(head,groupcode,size,packtype,direction)
end
end
+ if firstnone then
+ protectnone()
+ end
+
if force_boundaryrun then
-- we can inject wordboundaries and then let the hyphenator do its work
@@ -376,49 +422,35 @@ function handlers.characters(head,groupcode,size,packtype,direction)
local none = false
for n in traverse_char(r) do
local font = getfont(n)
- local attr = (none and prevattr) or getattr(n,0) or 0 -- zero attribute is reserved for fonts in context
+ local attr = getattr(n,0) or 0 -- zero attribute is reserved for fonts in context
if font ~= prevfont or attr ~= prevattr then
prevfont = font
prevattr = attr
- none = fontmodes[font] == "none" -- very unlikely that we run into disc nodes in none mode
- if none then
- -- skip
- -- variants = false
- protect_glyph(n)
- elseif 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
+ local fontmode = fontmodes[font]
+ if fontmode == "none" then
+ setnone(n)
+ elseif fontmode == "base" then
+ setbase(n)
else
- local used = usedfonts[font]
- if not used then
- local fp = fontprocesses[font]
- if fp then
- usedfonts[font] = fp
- u = u + 1
- end
- end
+ setnode(n,font,attr)
end
+ elseif firstnone then
+ -- lastnone = n
+ lastnone = nil
end
-- we assume one font for now (and if there are more and we get into issues then
-- we can always remove the break)
break
end
- elseif expanders then
- local subtype = getsubtype(d)
- if subtype == automatic_code or subtype == explicit_code then
- expanders[subtype](d)
- e = e + 1
+ if firstnone then
+ protectnone()
end
+ -- elseif expanders then
+ -- local subtype = getsubtype(d)
+ -- if subtype == automatic_code or subtype == explicit_code then
+ -- expanders[subtype](d)
+ -- e = e + 1
+ -- end
end
end
@@ -432,11 +464,9 @@ function handlers.characters(head,groupcode,size,packtype,direction)
if u == 0 then
-- skip
elseif u == 1 then
- local font, processors = next(usedfonts)
- -- local attr = a == 0 and false or 0 -- 0 is the savest way
local attr = a > 0 and 0 or false -- 0 is the savest way
- for i=1,#processors do
- local h, d = processors[i](head,font,attr,direction)
+ for i=1,#lastproc do
+ local h, d = lastproc[i](head,lastfont,attr,direction)
if d then
if h then
head = h
@@ -449,7 +479,7 @@ function handlers.characters(head,groupcode,size,packtype,direction)
local attr = a > 0 and 0 or false -- 0 is the savest way
for font, processors in next, usedfonts do -- unordered
for i=1,#processors do
- local h, d = processors[i](head,font,attr,direction)
+ local h, d = processors[i](head,font,attr,direction,u)
if d then
if h then
head = h
@@ -478,7 +508,7 @@ function handlers.characters(head,groupcode,size,packtype,direction)
for font, dynamics in next, attrfonts do
for attribute, processors in next, dynamics do -- unordered, attr can switch in between
for i=1,#processors do
- local h, d = processors[i](head,font,attribute,direction)
+ local h, d = processors[i](head,font,attribute,direction,a)
if d then
if h then
head = h
@@ -549,19 +579,5 @@ function handlers.characters(head,groupcode,size,packtype,direction)
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
-
--- function handlers.protectglyphs(h)
--- local h = tonut(h)
--- for n in traverse_id(disc_code,h) do
--- local pre, post, replace = getdisc(n)
--- if pre then d_protect_glyphs(pre) end
--- if post then d_protect_glyphs(post) end
--- if replace then d_protect_glyphs(replace) end
--- end
--- return d_protect_glyphs(h)
--- end
+handlers.protectglyphs = function(n) protect_glyphs (tonut(n)) return n, true end
+handlers.unprotectglyphs = function(n) unprotect_glyphs(tonut(n)) return n, true end