summaryrefslogtreecommitdiff
path: root/tex/generic/context/luatex/luatex-fonts-cbk.lua
diff options
context:
space:
mode:
Diffstat (limited to 'tex/generic/context/luatex/luatex-fonts-cbk.lua')
-rw-r--r--tex/generic/context/luatex/luatex-fonts-cbk.lua117
1 files changed, 104 insertions, 13 deletions
diff --git a/tex/generic/context/luatex/luatex-fonts-cbk.lua b/tex/generic/context/luatex/luatex-fonts-cbk.lua
index 9db94f65e..ce19c8811 100644
--- a/tex/generic/context/luatex/luatex-fonts-cbk.lua
+++ b/tex/generic/context/luatex/luatex-fonts-cbk.lua
@@ -18,14 +18,51 @@ local nodes = nodes
local traverse_id = node.traverse_id
local glyph_code = nodes.nodecodes.glyph
+local disc_code = nodes.nodecodes.disc
-function nodes.handlers.characters(head)
+-- from now on we apply ligaturing and kerning here because it might interfere with complex
+-- opentype discretionary handling where the base ligature pass expect some weird extra
+-- pointers (which then confuse the tail slider that has some checking built in)
+
+local ligaturing = node.ligaturing
+local kerning = node.kerning
+
+local basepass = true
+
+local function l_warning() texio.write_nl("warning: node.ligaturing called directly") l_warning = nil end
+local function k_warning() texio.write_nl("warning: node.kerning called directly") k_warning = nil end
+
+function node.ligaturing(...)
+ if basepass and l_warning then
+ l_warning()
+ end
+ return ligaturing(...)
+end
+
+function node.kerning(...)
+ if basepass and k_warning then
+ k_warning()
+ end
+ return kerning(...)
+end
+
+function nodes.handlers.setbasepass(v)
+ basepass = v
+end
+
+function nodes.handlers.nodepass(head)
local fontdata = fonts.hashes.identifiers
if fontdata then
- local usedfonts, done, prevfont = { }, false, nil
+ local usedfonts = { }
+ local basefonts = { }
+ local prevfont = nil
+ local basefont = nil
for n in traverse_id(glyph_code,head) do
local font = n.font
if font ~= prevfont then
+ if basefont then
+ basefont[2] = n.prev
+ end
prevfont = font
local used = usedfonts[font]
if not used then
@@ -36,18 +73,57 @@ function nodes.handlers.characters(head)
local processors = shared.processes
if processors and #processors > 0 then
usedfonts[font] = processors
- done = true
+ elseif basepass then
+ basefont = { n, nil }
+ basefonts[#basefonts+1] = basefont
+ end
+ end
+ end
+ end
+ end
+ end
+ for d in traverse_id(disc_code,head) do
+ local r = d.replace
+ if r then
+ for n in traverse_id(glyph_code,r) do
+ local font = n.font
+ if font ~= prevfont then
+ prevfont = font
+ local used = usedfonts[font]
+ if not used then
+ local tfmdata = fontdata[font] --
+ if tfmdata then
+ local shared = tfmdata.shared -- we need to check shared, only when same features
+ if shared then
+ local processors = shared.processes
+ if processors and #processors > 0 then
+ usedfonts[font] = processors
+ end
+ end
end
end
end
end
end
end
- if done then
+ if next(usedfonts) then
for font, processors in next, usedfonts do
for i=1,#processors do
- local h, d = processors[i](head,font,0)
- head, done = h or head, done or d
+ head = processors[i](head,font,0) or head
+ end
+ end
+ end
+ if basepass and #basefonts > 0 then
+ for i=1,#basefonts 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
+ start = ligaturing(start)
+ start = kerning(start)
end
end
end
@@ -57,12 +133,27 @@ function nodes.handlers.characters(head)
end
end
+function nodes.handlers.basepass(head)
+ if not basepass then
+ head = ligaturing(head)
+ head = kerning(head)
+ end
+ return head, true
+end
+
+local nodepass = nodes.handlers.nodepass
+local basepass = nodes.handlers.basepass
+local injectpass = nodes.injections.handler
+local protectpass = nodes.handlers.protectglyphs
+
function nodes.simple_font_handler(head)
--- lang.hyphenate(head)
- head = nodes.handlers.characters(head)
- nodes.injections.handler(head)
- nodes.handlers.protectglyphs(head)
- head = node.ligaturing(head)
- head = node.kerning(head)
- return head
+ if head then
+ head = nodepass(head)
+ head = injectpass(head)
+ head = basepass(head)
+ protectpass(head)
+ return head, true
+ else
+ return head, false
+ end
end