summaryrefslogtreecommitdiff
path: root/tex
diff options
context:
space:
mode:
authorContext Git Mirror Bot <phg42.2a@gmail.com>2014-12-08 23:15:04 +0100
committerContext Git Mirror Bot <phg42.2a@gmail.com>2014-12-08 23:15:04 +0100
commit7d25823db5c96e6877dd74158bb9847ec2666268 (patch)
tree2c2f3bbc9651a3f9b37d3086e889773d13004549 /tex
parentaae07c73a75ada5ade71c9e3125df190e3235abc (diff)
downloadcontext-7d25823db5c96e6877dd74158bb9847ec2666268.tar.gz
2014-12-08 22:17:00
Diffstat (limited to 'tex')
-rw-r--r--tex/context/base/cont-new.mkiv2
-rw-r--r--tex/context/base/context-version.pdfbin4389 -> 4387 bytes
-rw-r--r--tex/context/base/context.mkiv2
-rw-r--r--tex/context/base/font-ota.lua4
-rw-r--r--tex/context/base/lang-hyp.lua7
-rw-r--r--tex/context/base/node-fnt.lua100
-rw-r--r--tex/context/base/node-pro.lua6
-rw-r--r--tex/context/base/node-tex.lua38
-rw-r--r--tex/context/base/status-files.pdfbin24645 -> 24652 bytes
-rw-r--r--tex/context/base/status-lua.pdfbin344542 -> 344593 bytes
-rw-r--r--tex/context/base/task-ini.lua20
-rw-r--r--tex/context/base/typo-cap.lua349
-rw-r--r--tex/context/base/typo-cap.mkiv9
-rw-r--r--tex/context/base/typo-itc.lua318
-rw-r--r--tex/context/base/typo-krn.lua46
-rw-r--r--tex/generic/context/luatex/luatex-fonts-cbk.lua53
-rw-r--r--tex/generic/context/luatex/luatex-fonts-merged.lua46
17 files changed, 677 insertions, 323 deletions
diff --git a/tex/context/base/cont-new.mkiv b/tex/context/base/cont-new.mkiv
index 532ace65a..0c4bd8612 100644
--- a/tex/context/base/cont-new.mkiv
+++ b/tex/context/base/cont-new.mkiv
@@ -11,7 +11,7 @@
%C therefore copyrighted by \PRAGMA. See mreadme.pdf for
%C details.
-\newcontextversion{2014.12.06 14:20}
+\newcontextversion{2014.12.08 22:14}
%D This file is loaded at runtime, thereby providing an excellent place for
%D hacks, patches, extensions and new features.
diff --git a/tex/context/base/context-version.pdf b/tex/context/base/context-version.pdf
index a5639e8be..44daebfd8 100644
--- a/tex/context/base/context-version.pdf
+++ b/tex/context/base/context-version.pdf
Binary files differ
diff --git a/tex/context/base/context.mkiv b/tex/context/base/context.mkiv
index 063ea144a..da307b178 100644
--- a/tex/context/base/context.mkiv
+++ b/tex/context/base/context.mkiv
@@ -28,7 +28,7 @@
%D up and the dependencies are more consistent.
\edef\contextformat {\jobname}
-\edef\contextversion{2014.12.06 14:20}
+\edef\contextversion{2014.12.08 22:14}
\edef\contextkind {beta}
%D For those who want to use this:
diff --git a/tex/context/base/font-ota.lua b/tex/context/base/font-ota.lua
index 9db52a3c5..1f1534870 100644
--- a/tex/context/base/font-ota.lua
+++ b/tex/context/base/font-ota.lua
@@ -143,7 +143,9 @@ function analyzers.setstate(head,font) -- we can skip math
first, last, n = nil, nil, 0
end
elseif id == disc_code then
- -- always in the middle
+ -- always in the middle .. it doesn't make much sense to assign a property
+ -- here ... we might at some point decide to flag the components when present
+ -- but even then it's kind of bogus
setprop(current,a_state,s_medi)
last = current
else -- finish
diff --git a/tex/context/base/lang-hyp.lua b/tex/context/base/lang-hyp.lua
index 58a8bffcf..d6217857b 100644
--- a/tex/context/base/lang-hyp.lua
+++ b/tex/context/base/lang-hyp.lua
@@ -160,9 +160,12 @@ local function unregister_pattern(patterns,specials,str)
specials[k] = nil
end
+local p_lower = lpeg.patterns.utf8lower
+
local function register_exception(exceptions,str,specification)
- local k = lpegmatch(make_hashkey_e,str)
- local v = lpegmatch(make_pattern_e,str)
+ local l = lpegmatch(p_lower,str)
+ local k = lpegmatch(make_hashkey_e,l)
+ local v = lpegmatch(make_pattern_e,l)
exceptions[k] = v
end
diff --git a/tex/context/base/node-fnt.lua b/tex/context/base/node-fnt.lua
index 0ab0867dc..1dd944403 100644
--- a/tex/context/base/node-fnt.lua
+++ b/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")
@@ -117,14 +120,22 @@ fonts.hashes.processes = fontprocesses
-- 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 = builders.kernel.ligaturing
-local kerning = builders.kernel.kerning
+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, basefonts = { }, { }, { }
- local a, u, b, prevfont, prevattr, done, basefont = 0, 0, 0, nil, 0, false, nil
+
+ 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()
@@ -145,7 +156,10 @@ function handlers.characters(head)
n = getnext(n)
end
end
- for n in traverse_id(glyph_code,tonut(head)) do
+
+ 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
@@ -164,7 +178,7 @@ function handlers.characters(head)
if fd then
used[attr] = fd[attr]
a = a + 1
- else
+ elseif force_basepass then
b = b + 1
basefont = { tonode(n), nil }
basefonts[b] = basefont
@@ -177,7 +191,7 @@ function handlers.characters(head)
if fp then
usedfonts[font] = fp
u = u + 1
- else
+ elseif force_basepass then
b = b + 1
basefont = { tonode(n), nil }
basefonts[b] = basefont
@@ -188,8 +202,63 @@ function handlers.characters(head)
prevattr = attr
end
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
+ end
+
+ end
+
if trace_fontrun then
report_fonts()
report_fonts("statics : %s",u > 0 and concat(keys(usedfonts)," ") or "none")
@@ -249,11 +318,18 @@ function handlers.characters(head)
if b == 0 then
-- skip
elseif b == 1 then
+ -- only one font
local range = basefonts[1]
local start, stop = range[1], range[2]
- ligaturing(start,stop)
- kerning(start,stop)
+ if stop then
+ ligaturing(start,stop)
+ kerning(start,stop)
+ else
+ ligaturing(start)
+ kerning(start)
+ end
else
+ -- multiple fonts
for i=1,b do
local range = basefonts[i]
local start, stop = range[1], range[2]
diff --git a/tex/context/base/node-pro.lua b/tex/context/base/node-pro.lua
index 2cc00601c..27e349893 100644
--- a/tex/context/base/node-pro.lua
+++ b/tex/context/base/node-pro.lua
@@ -55,7 +55,7 @@ do
return concat(t)
end
- local function tracer(what,state,head,groupcode,before,after,show)
+ function processors.tracer(what,state,head,groupcode,before,after,show)
if not groupcode then
groupcode = "unknown"
elseif groupcode == "" then
@@ -69,10 +69,10 @@ do
end
end
- processors.tracer = tracer
-
end
+local tracer = processors.tracer
+
processors.enabled = true -- this will become a proper state (like trackers)
function processors.pre_linebreak_filter(head,groupcode) -- ,size,packtype,direction
diff --git a/tex/context/base/node-tex.lua b/tex/context/base/node-tex.lua
index 9f6df031b..8f4a65450 100644
--- a/tex/context/base/node-tex.lua
+++ b/tex/context/base/node-tex.lua
@@ -6,37 +6,33 @@ if not modules then modules = { } end modules ['node-tex'] = {
license = "see context related readme files"
}
-local format = string.format
+builders = builders or { }
+local kernel = builders.kernel or { }
+builders.kernel = kernel
-builders = builders or { }
-builders.kernel = builders.kernel or { }
-local kernel = builders.kernel
+local hyphenate = lang.hyphenate
+local ligaturing = node.ligaturing
+local kerning = node.kerning
-local hyphenate, ligaturing, kerning = lang.hyphenate, node.ligaturing, node.kerning
+kernel.originals = {
+ hyphenate = hyphenate,
+ ligaturing = ligaturing,
+ kerning = kerning,
+}
function kernel.hyphenation(head)
local done = hyphenate(head)
return head, done
end
-function kernel.ligaturing(head,tail)
- if tail then
- local head, tail, done = ligaturing(head,tail)
- return head, done
- else -- sensitive for second arg nil
- local head, tail, done = ligaturing(head)
- return head, done
- end
+function kernel.ligaturing(head)
+ local head, tail, done = ligaturing(head)
+ return head, done
end
-function kernel.kerning(head,tail)
- if tail then
- local head, tail, done = kerning(head,tail)
- return head, done
- else -- sensitive for second arg nil
- local head, tail, done = kerning(head)
- return head, done
- end
+function kernel.kerning(head)
+ local head, tail, done = kerning(head)
+ return head, done
end
callbacks.register('hyphenate' , false, "normal hyphenation routine, called elsewhere")
diff --git a/tex/context/base/status-files.pdf b/tex/context/base/status-files.pdf
index efc5834d0..d32c3dc6c 100644
--- a/tex/context/base/status-files.pdf
+++ b/tex/context/base/status-files.pdf
Binary files differ
diff --git a/tex/context/base/status-lua.pdf b/tex/context/base/status-lua.pdf
index 832bbf225..68290ae02 100644
--- a/tex/context/base/status-lua.pdf
+++ b/tex/context/base/status-lua.pdf
Binary files differ
diff --git a/tex/context/base/task-ini.lua b/tex/context/base/task-ini.lua
index 3db0c2d6e..4087caafe 100644
--- a/tex/context/base/task-ini.lua
+++ b/tex/context/base/task-ini.lua
@@ -21,6 +21,7 @@ local tasks = nodes.tasks
local prependaction = tasks.prependaction
local appendaction = tasks.appendaction
local disableaction = tasks.disableaction
+local enableaction = tasks.enableaction
local freezegroup = tasks.freezegroup
local freezecallbacks = callbacks.freeze
@@ -48,8 +49,8 @@ appendaction("processors", "fonts", "builders.paragraphs.solutions.split
appendaction("processors", "fonts", "nodes.handlers.characters") -- maybe todo
appendaction("processors", "fonts", "nodes.injections.handler") -- maybe todo
appendaction("processors", "fonts", "nodes.handlers.protectglyphs", nil, "nohead") -- maybe todo
-------------("processors", "fonts", "builders.kernel.ligaturing") -- always on (could be selective: if only node mode)
-------------("processors", "fonts", "builders.kernel.kerning") -- always on (could be selective: if only node mode)
+appendaction("processors", "fonts", "builders.kernel.ligaturing") -- always on (could be selective: if only node mode)
+appendaction("processors", "fonts", "builders.kernel.kerning") -- always on (could be selective: if only node mode)
appendaction("processors", "fonts", "nodes.handlers.stripping") -- disabled (might move)
------------("processors", "fonts", "typesetters.italics.handler") -- disabled (after otf/kern handling)
@@ -219,3 +220,18 @@ freezegroup("vboxbuilders", "normalizers")
freezegroup("math", "normalizers")
freezegroup("math", "builders")
+
+-- new: disabled here
+
+disableaction("processors", "builders.kernel.ligaturing")
+disableaction("processors", "builders.kernel.kerning")
+
+directives.register("nodes.basepass", function(v)
+ if v then
+ disableaction("processors", "builders.kernel.ligaturing")
+ disableaction("processors", "builders.kernel.kerning")
+ else
+ enableaction("processors", "builders.kernel.ligaturing")
+ enableaction("processors", "builders.kernel.kerning")
+ end
+end)
diff --git a/tex/context/base/typo-cap.lua b/tex/context/base/typo-cap.lua
index 4b424e5a4..fdc7740de 100644
--- a/tex/context/base/typo-cap.lua
+++ b/tex/context/base/typo-cap.lua
@@ -33,6 +33,9 @@ local getchar = nuts.getchar
local copy_node = nuts.copy
local end_of_math = nuts.end_of_math
+local traverse_nodes = nuts.traverse
+local traverse_id = nuts.traverse_id
+local insert_after = nuts.insert_after
local nodecodes = nodes.nodecodes
local skipcodes = nodes.skipcodes
@@ -72,6 +75,8 @@ local a_cases = attributes.private("case")
local extract = bit32.extract
local run = 0 -- a trick to make neighbouring ranges work
+local blocked = { }
+
local function set(tag,font)
if run == 2^6 then
run = 1
@@ -104,88 +109,40 @@ end
--
-- \WORD {far too \Word{many \WORD{more \word{pushed} in between} useless} words}
-local uccodes = characters.uccodes
-local lccodes = characters.lccodes
+local uccodes = characters.uccodes
+local lccodes = characters.lccodes
+local categories = characters.categories
-- true false true == mixed
-local function helper(start,attr,lastfont,n,codes,special,once,keepother)
+local function replacer(start,codes)
local char = getchar(start)
local dc = codes[char]
if dc then
local fnt = getfont(start)
- if keepother and dc == char then
- local lfa = lastfont[n]
- if lfa then
- setfield(start,"font",lfa)
- return start, true
- else
- return start, false
- end
- else
- if special then
- local lfa = lastfont[n]
- if lfa then
- local previd = getid(getprev(start))
- if previd ~= glyph_code and previd ~= disc_code then
- fnt = lfa
- setfield(start,"font",lfa)
- end
+ local ifc = fontchar[fnt]
+ if type(dc) == "table" then
+ for i=1,#dc do
+ if not ifc[dc[i]] then
+ return start, false
end
end
- local ifc = fontchar[fnt]
- if type(dc) == "table" then
- local ok = true
- for i=1,#dc do
- -- could be cached in font
- if not ifc[dc[i]] then
- ok = false
- break
- end
+ for i=#dc,1,-1 do
+ local chr = dc[i]
+ if i == 1 then
+ setfield(start,"char",chr)
+ else
+ local g = copy_node(start)
+ setfield(g,"char",chr)
+ insert_after(start,start,g)
end
- if ok then
- -- todo: use generic injector
- local prev = start
- local original = start
- for i=1,#dc do
- local chr = dc[i]
- prev = start
- if i == 1 then
- setfield(start,"char",chr)
- else
- local g = copy_node(original)
- setfield(g,"char",chr)
- local next = getnext(start)
- setfield(g,"prev",start)
- if next then
- setfield(g,"next",next)
- setfield(start,"next",g)
- setfield(next,"prev",g)
- end
- start = g
- end
- end
- if once then
- lastfont[n] = false
- end
- return prev, true
- end
- if once then
- lastfont[n] = false
- end
- return start, false
- elseif ifc[dc] then
- setfield(start,"char",dc)
- if once then
- lastfont[n] = false
- end
- return start, true
end
+ return start, true
+ elseif ifc[dc] then
+ setfield(start,"char",dc)
+ return start, true
end
end
- if once then
- lastfont[n] = false
- end
return start, false
end
@@ -206,147 +163,147 @@ end
cases.register = register
-local function WORD(start,attr,lastfont,n)
+local function WORD(start,attr,lastfont,n,count,where,first)
lastfont[n] = false
- return helper(start,attr,lastfont,n,uccodes)
+ return replacer(first or start,uccodes)
end
-local function word(start,attr,lastfont,n)
+local function word(start,attr,lastfont,n,count,where,first)
lastfont[n] = false
- return helper(start,attr,lastfont,n,lccodes)
-end
-
-local function blockrest(start)
- local n = getnext(start)
- while n do
- local id = getid(n)
- if id == glyph_code or id == disc_node and getattr(n,a_cases) == attr then
- setattr(n,a_cases,unsetvalue)
- else
- -- break -- we can have nested mess
- end
- n = getnext(n)
- end
+ return replacer(first or start,lccodes)
end
-local function Word(start,attr,lastfont,n) -- looks quite complex
- lastfont[n] = false
- local prev = getprev(start)
- if prev and getid(prev) == kern_code and getsubtype(prev) == kerning_code then
- prev = getprev(prev)
- end
- if not prev then
- blockrest(start)
- return helper(start,attr,lastfont,n,uccodes)
+local function Words(start,attr,lastfont,n,count,where,first) -- looks quite complex
+ if where == "post" then
+ return
end
- local previd = getid(prev)
- if previd ~= glyph_code and previd ~= disc_code then
- -- only the first character is treated
- blockrest(start)
- -- we could return the last in the range and save some scanning
- -- but why bother
- return helper(start,attr,lastfont,n,uccodes)
+ if count == 1 and where ~= "post" then
+ replacer(first or start,uccodes)
+ return start, true, true
else
- return start, false
+ return start, false, true
end
end
-local function Words(start,attr,lastfont,n)
- lastfont[n] = false
- local prev = getprev(start)
- if prev and getid(prev) == kern_code and getsubtype(prev) == kerning_code then
- prev = getprev(prev)
- end
- if not prev then
- return helper(start,attr,lastfont,n,uccodes)
+local function Word(start,attr,lastfont,n,count,where,first)
+ blocked[attr] = true
+ return Words(start,attr,lastfont,n,count,where,first)
+end
+
+local function camel(start,attr,lastfont,n,count,where,first)
+ local _, done_1 = word(start,attr,lastfont,n,count,where,first)
+ local _, done_2 = Words(start,attr,lastfont,n,count,where,first)
+ return start, done_1 or done_2, true
+end
+
+local function mixed(start,attr,lastfont,n,count,where,first)
+ if where == "post" then
+ return
end
- local previd = getid(prev)
- if previd ~= glyph_code and previd ~= disc_code then
- return helper(start,attr,lastfont,n,uccodes)
+ local used = first or start
+ local char = getchar(first)
+ local dc = uccodes[char]
+ if not dc then
+ return start, false, true
+ elseif dc == char then
+ local lfa = lastfont[n]
+ if lfa then
+ setfield(first,"font",lfa)
+ return start, true, true
+ else
+ return start, false, true
+ end
else
- return start, false
+ replacer(first or start,uccodes)
+ return start, true, true
end
end
-local function capital(start,attr,lastfont,n) -- 3
- return helper(start,attr,lastfont,n,uccodes,true,true)
-end
-
-local function Capital(start,attr,lastfont,n) -- 4
- return helper(start,attr,lastfont,n,uccodes,true,false)
+local function Capital(start,attr,lastfont,n,count,where,first,once) -- 3
+ local used = first or start
+ if count == 1 and where ~= "post" then
+ local lfa = lastfont[n]
+ if lfa then
+ local dc = uccodes[getchar(used)]
+ if dc then
+ setfield(used,"font",lfa)
+ end
+ end
+ end
+ local s, d, c = replacer(first or start,uccodes)
+ if once then
+ lastfont[n] = false -- here
+ end
+ return start, d, c
end
-local function mixed(start,attr,lastfont,n)
- return helper(start,attr,lastfont,n,uccodes,false,false,true)
+local function capital(start,attr,lastfont,n,where,count,first,count) -- 4
+ return Capital(start,attr,lastfont,n,where,count,first,true)
end
-local function none(start,attr,lastfont,n)
- return start, false
+local function none(start,attr,lastfont,n,count,where,first)
+ return start, false, true
end
-local function random(start,attr,lastfont,n)
+local function random(start,attr,lastfont,n,count,where,first)
+ local used = first or start
+ local char = getchar(used)
+ local font = getfont(used)
+ local tfm = fontchar[font]
lastfont[n] = false
- local ch = getchar(start)
- local tfm = fontchar[getfont(start)]
- if lccodes[ch] then
+ local kind = categories[char]
+ if kind == "lu" then
while true do
- local d = chardata[randomnumber(1,0xFFFF)]
- if d then
- local uc = uccodes[d]
- if uc and tfm[uc] then -- this also intercepts tables
- setfield(start,"char",uc)
- return start, true
- end
+ local n = randomnumber(0x41,0x5A)
+ if tfm[n] then -- this also intercepts tables
+ setfield(used,"char",n)
+ return start, true
end
end
- elseif uccodes[ch] then
+ elseif kind == "ll" then
while true do
- local d = chardata[randomnumber(1,0xFFFF)]
- if d then
- local lc = lccodes[d]
- if lc and tfm[lc] then -- this also intercepts tables
- setfield(start,"char",lc)
- return start, true
- end
+ local n = randomnumber(0x61,0x7A)
+ if tfm[n] then -- this also intercepts tables
+ setfield(used,"char",n)
+ return start, true
end
end
end
return start, false
end
-local function camel(start,attr,lastfont,n)
- local start, done_1 = word(start,attr,lastfont,n)
- local start, done_2 = Words(start,attr,lastfont,n)
- return start, done_1 or done_2
-end
-
-register(variables.WORD, WORD) -- 1
-register(variables.word, word) -- 2
-register(variables.Word, Word) -- 3
-register(variables.Words, Words) -- 4
-register(variables.capital, capital) -- 5
-register(variables.Capital, Capital) -- 6
-register(variables.none, none) -- 7 (dummy)
-register(variables.random, random) -- 8
-register(variables.mixed, mixed) -- 9
-register(variables.camel, camel) -- 10
+register(variables.WORD, WORD) -- 1
+register(variables.word, word) -- 2
+register(variables.Word, Word) -- 3
+register(variables.Words, Words) -- 4
+register(variables.capital,capital) -- 5
+register(variables.Capital,Capital) -- 6
+register(variables.none, none) -- 7 (dummy)
+register(variables.random, random) -- 8
+register(variables.mixed, mixed) -- 9
+register(variables.camel, camel) -- 10
-register(variables.cap, variables.capital) -- clone
-register(variables.Cap, variables.Capital) -- clone
+register(variables.cap, variables.capital) -- clone
+register(variables.Cap, variables.Capital) -- clone
function cases.handler(head) -- not real fast but also not used on much data
- head = tonut(head)
local lastfont = { }
local lastattr = nil
local done = false
- local start = head
+ local start = tonut(head)
+ local count = 0
+ local previd = nil
+ local prev = nil
while start do -- while because start can jump ahead
local id = getid(start)
if id == glyph_code then
local attr = getattr(start,a_cases)
- if attr and attr > 0 then
+ if attr and attr > 0 and not blocked[attr] then
if attr ~= lastattr then
lastattr = attr
+ count = 1
+ else
+ count = count + 1
end
setattr(start,a_cases,unsetvalue)
local n, id, m = get(attr)
@@ -355,7 +312,7 @@ function cases.handler(head) -- not real fast but also not used on much data
end
local action = actions[n] -- map back to low number
if action then
- start, ok = action(start,attr,lastfont,n)
+ start, ok = action(start,attr,lastfont,n,count)
if ok then
done = true
end
@@ -368,9 +325,10 @@ function cases.handler(head) -- not real fast but also not used on much data
end
elseif id == disc_code then
local attr = getattr(start,a_cases)
- if attr and attr > 0 then
+ if attr and attr > 0 and not blocked[attr] then
if attr ~= lastattr then
lastattr = attr
+ count = 0
end
setattr(start,a_cases,unsetvalue)
local n, id, m = get(attr)
@@ -381,28 +339,73 @@ function cases.handler(head) -- not real fast but also not used on much data
if action then
local replace = getfield(start,"replace")
if replace then
- action(replace,attr,lastfont,n)
+ local cnt = count
+ for g in traverse_id(glyph_code,replace) do
+ cnt = cnt + 1
+ -- setattr(g,a_cases,unsetvalue)
+ local _, _, quit = action(start,attr,lastfont,n,cnt,"replace",g)
+ if quit then break end
+ end
end
local pre = getfield(start,"pre")
if pre then
- action(pre,attr,lastfont,n)
+ local cnt = count
+ for g in traverse_id(glyph_code,pre) do
+ cnt = cnt + 1
+ -- setattr(g,a_cases,unsetvalue)
+ local _, _, quit = action(start,attr,lastfont,n,cnt,"pre",g)
+ if quit then break end
+ end
end
local post = getfield(start,"post")
if post then
- action(post,attr,lastfont,n)
+ local cnt = count
+ for g in traverse_id(glyph_code,post) do
+ cnt = cnt + 1
+ -- setattr(g,a_cases,unsetvalue)
+ local _, _, quit = action(start,attr,lastfont,n,cnt,"post",g)
+ if quit then break end
+ end
end
end
+ count = count + 1
end
elseif id == math_code then
start = end_of_math(start)
+ count = 0
+ elseif prev_id == kern_code and getsubtype(prev) == kerning_code then
+ -- still inside a word ...nomally kerns are added later
+ else
+ count = 0
end
- if start then -- why test
- start = getnext(start)
+ if start then
+ prev = start
+ previd = id
+ start = getnext(start)
end
end
- return tonode(head), done
+ return head, done
end
+-- function cases.handler(head) -- let's assume head doesn't change ... no reason
+-- local done = false
+-- local lastfont = { }
+-- for first, last, size, attr in nuts.words(tonut(head),a_cases) do
+-- local n, id, m = get(attr)
+-- if lastfont[n] == nil then
+-- lastfont[n] = id
+-- end
+-- local action = actions[n]
+-- if action then
+-- local _, ok = action(first,attr,lastfont,n)
+-- if ok then
+-- done = true
+-- end
+-- end
+-- end
+-- return head, done
+-- end
+
local enabled = false
function cases.set(n,id)
diff --git a/tex/context/base/typo-cap.mkiv b/tex/context/base/typo-cap.mkiv
index 9394cd7d0..eef4951fb 100644
--- a/tex/context/base/typo-cap.mkiv
+++ b/tex/context/base/typo-cap.mkiv
@@ -166,17 +166,20 @@
%
% here we keep the \groupedcommand
+% \def\typo_capitals_set_fake#1%
+% {\edef\currentcapitals{#1}%
+% \scratchcounter\fontid\font
+% \usecapitalsstyleparameter\c!style
+% \ctxcommand{setcharactercasing("\currentcapitals",\number\scratchcounter,\number\fontid\font)}}
+
\def\typo_capitals_set_fake#1%
{\edef\currentcapitals{#1}%
- %\setcharactercasing[\currentcapitals]%
\ctxcommand{setcharactercasing("\currentcapitals",\number\fontid\font)}%
- \signalcharacter % retain current style
\usecapitalsstyleparameter\c!style}
\def\typo_capitals_set_real#1%
{\edef\currentcapitals{#1}%
\sc
- %\setcharactercasing[\currentcapitals]}
\ctxcommand{setcharactercasing("\currentcapitals",\number\fontid\font)}}
\unexpanded\def\pseudosmallcapped{\groupedcommand{\typo_capitals_set_fake\v!WORD }\donothing} % all upper
diff --git a/tex/context/base/typo-itc.lua b/tex/context/base/typo-itc.lua
index 7373c0321..60352120e 100644
--- a/tex/context/base/typo-itc.lua
+++ b/tex/context/base/typo-itc.lua
@@ -42,6 +42,7 @@ local setattr = nuts.setattr
local insert_node_after = nuts.insert_after
local delete_node = nuts.delete
local end_of_math = nuts.end_of_math
+local find_tail = nuts.tail
local texgetattribute = tex.getattribute
local texsetattribute = tex.setattribute
@@ -98,16 +99,55 @@ end
-- todo: clear attribute
+local function okay(data,current,font,prevchar,previtalic,char,what)
+ if not data then
+ if trace_italics then
+ report_italics("ignoring %p between %s italic %C and italic %C",previtalic,what,prevchar,char)
+ end
+ return false
+ end
+ if threshold then
+ local ht = getfield(current,"height")
+ local ex = exheights[font]
+ local th = threshold * ex
+ if ht <= th then
+ if trace_italics then
+ report_italics("ignoring correction between %s italic %C and regular %C, height %p less than threshold %p",prevchar,what,char,ht,th)
+ end
+ return false
+ end
+ end
+ if trace_italics then
+ report_italics("inserting %p between %s italic %C and regular %C",previtalic,what,prevchar,char)
+ end
+ return true
+end
+
function italics.handler(head)
- head = tonut(head)
- local done = false
- local italic = 0
- local lastfont = nil
- local lastattr = nil
- local previous = nil
- local prevchar = nil
- local current = head
- local inserted = nil
+
+ local prev = nil
+ local prevchar = nil
+ local prevhead = tonut(head)
+ local previtalic = 0
+ local previnserted = nil
+
+ local replace = nil
+ local replacechar = nil
+ local replacehead = nil
+ local replaceitalic = 0
+ local replaceinserted = nil
+
+ local post = nil
+ local postchar = nil
+ local posthead = nil
+ local postitalic = 0
+ local postinserted = nil
+
+ local current = prevhead
+ local done = false
+ local lastfont = nil
+ local lastattr = nil
+
while current do
local id = getid(current)
if id == glyph_code then
@@ -115,40 +155,45 @@ function italics.handler(head)
local char = getchar(current)
local data = italicsdata[font]
if font ~= lastfont then
- if italic ~= 0 then
- if data then
- if trace_italics then
- report_italics("ignoring %p between italic %C and italic %C",italic,prevchar,char)
+ if previtalic ~= 0 then
+ if okay(data,current,font,prevchar,previtalic,char,"glyph") then
+ insert_node_after(prevhead,prev,new_correction_kern(previtalic))
+ done = true
+ end
+ elseif previnserted and data then
+ if trace_italics then
+ report_italics("deleting last correction before %s %C",char,"glyph")
+ end
+ delete_node(prevhead,previnserted)
+ else
+ --
+ if replaceitalic ~= 0 then
+ if okay(data,replace,font,replacechar,replaceitalic,char,"replace") then
+ insert_node_after(replacehead,replace,new_correction_kern(replaceitalic))
+ done = true
end
- else
- local okay = true
- if threshold then
- local ht = getfield(current,"height")
- local ex = exheights[font]
- local th = threshold * ex
- if ht <= th then
- if trace_italics then
- report_italics("ignoring correction between italic %C and regular %C, height %p less than threshold %p",prevchar,char,ht,th)
- end
- okay = false
- end
+ replaceitalic = 0
+ elseif replaceinserted and data then
+ if trace_italics then
+ report_italics("deleting last correction before %s %C","replace",char)
end
- if okay then
- if trace_italics then
- report_italics("inserting %p between italic %C and regular %C",italic,prevchar,char)
- end
- insert_node_after(head,previous,new_correction_kern(italic))
+ delete_node(replacehead,replaceinserted)
+ end
+ --
+ if postitalic ~= 0 then
+ if okay(data,post,font,postchar,postitalic,char,"post") then
+ insert_node_after(posthead,post,new_correction_kern(postitalic))
done = true
end
+ postitalic = 0
+ elseif postinserted and data then
+ if trace_italics then
+ report_italics("deleting last correction before %s %C","post",char)
+ end
+ delete_node(posthead,postinserted)
end
- elseif inserted and data then
- if trace_italics then
- report_italics("deleting last correction before %C",char)
- end
- delete_node(head,inserted)
- else
- -- nothing
end
+ --
lastfont = font
end
if data then
@@ -157,63 +202,196 @@ function italics.handler(head)
local cd = data[char]
if not cd then
-- this really can happen
- italic = 0
+ previtalic = 0
else
- italic = cd.italic or cd.italic_correction
- if not italic then
- italic = setitalicinfont(font,char) -- calculated once
- -- italic = 0
+ previtalic = cd.italic or cd.italic_correction
+ if not previtalic then
+ previtalic = setitalicinfont(font,char) -- calculated once
+ -- previtalic = 0
end
- if italic ~= 0 then
+ if previtalic ~= 0 then
lastfont = font
lastattr = attr
- previous = current
+ prev = current
+ -- prevhead = head
prevchar = char
end
end
else
- italic = 0
+ previtalic = 0
end
else
- italic = 0
+ previtalic = 0
end
- inserted = nil
+ previnserted = nil
+ replaceinserted = nil
+ postinserted = nil
elseif id == disc_code then
- -- skip
- elseif id == kern_code then
- inserted = nil
- italic = 0
+ replace = getfield(current,"replace")
+ if replace then
+ local current = find_tail(replace)
+ local font = getfont(current)
+ local char = getchar(current)
+ local data = italicsdata[font]
+ if data then
+ local attr = forcedvariant or getattr(current,a_italics)
+ if attr and attr > 0 then
+ local cd = data[char]
+ if not cd then
+ -- this really can happen
+ replaceitalic = 0
+ else
+ replaceitalic = cd.italic or cd.italic_correction
+ if not replaceitalic then
+ replaceitalic = setitalicinfont(font,char) -- calculated once
+ -- replaceitalic = 0
+ end
+ if replaceitalic ~= 0 then
+ lastfont = font
+ lastattr = attr
+ replacechar = char
+ replacehead = replace
+ replace = current
+ end
+ end
+ else
+ replaceitalic = 0
+ end
+ else
+ replaceitalic = 0
+ end
+ replaceinserted = nil
+ end
+ local post = getfield(current,"post")
+ if post then
+ local current = find_tail(post)
+ local font = getfont(current)
+ local char = getchar(current)
+ local data = italicsdata[font]
+ if data then
+ local attr = forcedvariant or getattr(current,a_italics)
+ if attr and attr > 0 then
+ local cd = data[char]
+ if not cd then
+ -- this really can happen
+ postitalic = 0
+ else
+ postitalic = cd.italic or cd.italic_correction
+ if not postitalic then
+ postitalic = setitalicinfont(font,char) -- calculated once
+ -- postitalic = 0
+ end
+ if postitalic ~= 0 then
+ lastfont = font
+ lastattr = attr
+ postchar = char
+ posthead = post
+ post = current
+ end
+ end
+ else
+ postitalic = 0
+ end
+ else
+ postitalic = 0
+ end
+ postinserted = nil
+ end
+ elseif id == kern_code then -- how about fontkern ?
+ previnserted = nil
+ previtalic = 0
+ replaceinserted = nil
+ replaceitalic = 0
+ postinserted = nil
+ postitalic = 0
elseif id == glue_code then
- if italic ~= 0 then
+ if previtalic ~= 0 then
if trace_italics then
- report_italics("inserting %p between italic %C and glue",italic,prevchar)
+ report_italics("inserting %p between %s italic %C and glue",previtalic,"glyph",prevchar)
+ end
+ previnserted = new_correction_glue(previtalic) -- maybe just add ? else problem with penalties
+ previtalic = 0
+ done = true
+ insert_node_after(prevhead,prev,previnserted)
+ else
+ if replaceitalic ~= 0 then
+ if trace_italics then
+ report_italics("inserting %p between %s italic %C and glue",replaceitalic,"replace",replacechar)
+ end
+ replaceinserted = new_correction_kern(replaceitalic) -- needs to be a kern
+ replaceitalic = 0
+ done = true
+ insert_node_after(replacehead,replace,replaceinserted)
+ end
+ if postitalic ~= 0 then
+ if trace_italics then
+ report_italics("inserting %p between %s italic %C and glue",postitalic,"post",postchar)
+ end
+ postinserted = new_correction_kern(postitalic) -- needs to be a kern
+ postitalic = 0
+ done = true
+ insert_node_after(posthead,post,postinserted)
end
- inserted = new_correction_glue(italic) -- maybe just add ? else problem with penalties
- insert_node_after(head,previous,inserted)
- italic = 0
- done = true
end
elseif id == math_code then
current = end_of_math(current)
- elseif italic ~= 0 then
- if trace_italics then
- report_italics("inserting %p between italic %C and whatever",italic,prevchar)
+ else
+ if previtalic ~= 0 then
+ if trace_italics then
+ report_italics("inserting %p between %s italic %C and whatever",previtalic,"glyph",prevchar)
+ end
+ insert_node_after(prevhead,prev,new_correction_kern(previtalic))
+ previnserted = nil
+ previtalic = 0
+ done = true
+ else
+ if replaceitalic ~= 0 then
+ if trace_italics then
+ report_italics("inserting %p between %s italic %C and whatever",replaceritalic,"replace",replacechar)
+ end
+ insert_node_after(replacehead,replace,new_correction_kern(replaceitalic))
+ replaceitalic = 0
+ replaceinserted = nil
+ done = true
+ end
+ if postitalic ~= 0 then
+ if trace_italics then
+ report_italics("inserting %p between %s italic %C and whatever",postitalic,"post",postchar)
+ end
+ insert_node_after(posthead,post,new_correction_kern(postitalic))
+ postinserted = nil
+ postitalic = 0
+ done = true
+ end
end
- inserted = nil
- insert_node_after(head,previous,new_correction_kern(italic))
- italic = 0
- done = true
end
current = getnext(current)
end
- if italic ~= 0 and lastattr > 1 then -- more control is needed here
- if trace_italics then
- report_italics("inserting %p between italic %C and end of list",italic,prevchar)
+ if lastattr and lastattr > 1 then -- more control is needed here
+ if previtalic ~= 0 then
+ if trace_italics then
+ report_italics("inserting %p between %s italic %C and end of list",previtalic,"glyph",prevchar)
+ end
+ insert_node_after(prevhead,prev,new_correction_kern(previtalic))
+ done = true
+ else
+ if replaceitalic ~= 0 then
+ if trace_italics then
+ report_italics("inserting %p between %s italic %C and end of list",replaceitalic,"replace",replacechar)
+ end
+ insert_node_after(replacehead,replace,new_correction_kern(replaceitalic))
+ done = true
+ end
+ if postitalic ~= 0 then
+ if trace_italics then
+ report_italics("inserting %p between %s italic %C and end of list",postitalic,"post",postchar)
+ end
+ insert_node_after(posthead,post,new_correction_kern(postitalic))
+ done = true
+ end
end
- insert_node_after(head,previous,new_correction_kern(italic))
- done = true
end
- return tonode(head), done
+ return head, done
end
local enable
diff --git a/tex/context/base/typo-krn.lua b/tex/context/base/typo-krn.lua
index a8ffe557b..5729c72c0 100644
--- a/tex/context/base/typo-krn.lua
+++ b/tex/context/base/typo-krn.lua
@@ -206,10 +206,12 @@ end
-- needs checking ... base mode / node mode -- also use insert_before/after etc
local function do_process(head,force) -- todo: glue so that we can fully stretch
- local start, done, lastfont = head, false, nil
+ local start = head
+ local done = false
+ local lastfont = nil
local keepligature = kerns.keepligature
local keeptogether = kerns.keeptogether
- local fillup = false
+ local fillup = false
while start do
-- faster to test for attr first
local attr = force or getattr(start,a_kerns)
@@ -217,7 +219,7 @@ local function do_process(head,force) -- todo: glue so that we can fully stretch
setattr(start,a_kerns,unsetvalue)
local krn = mapping[attr]
if krn == v_max then
- krn = .25
+ krn = .25
fillup = true
else
fillup = false
@@ -233,8 +235,9 @@ local function do_process(head,force) -- todo: glue so that we can fully stretch
-- keep 'm
else
c = do_process(c,attr)
- local s = start
- local p, n = getprev(s), getnext(s)
+ local s = start
+ local p = getprev(s)
+ local n = getnext(s)
local tail = find_node_tail(c)
if p then
setfield(p,"next",c)
@@ -293,11 +296,14 @@ local function do_process(head,force) -- todo: glue so that we can fully stretch
-- a bit too complicated, we can best not copy and just calculate
-- but we could have multiple glyphs involved so ...
local disc = prev -- disc
- local prv, nxt = getprev(disc), getnext(disc)
+ local prv = getprev(disc)
+ local nxt = getnext(disc)
if getsubtype(disc) == discretionary_code then
-- maybe we should forget about this variant as there is no glue
- -- possible
- local pre, post, replace = getfield(disc,"pre"), getfield(disc,"post"), getfield(disc,"replace")
+ -- possible .. hardly used so a copy doesn't hurt much
+ local pre = getfield(disc,"pre")
+ local post = getfield(disc,"post")
+ local replace = getfield(disc,"replace")
if pre and prv then -- must pair with getprev(start)
local before = copy_node(prv)
setfield(pre,"prev",before)
@@ -311,7 +317,7 @@ local function do_process(head,force) -- todo: glue so that we can fully stretch
end
if post and nxt then -- must pair with start
local after = copy_node(nxt)
- local tail = find_node_tail(post)
+ local tail = find_node_tail(post)
setfield(tail,"next",after)
setfield(after,"prev",tail)
setfield(after,"next",nil)
@@ -322,8 +328,8 @@ local function do_process(head,force) -- todo: glue so that we can fully stretch
end
if replace and prv and nxt then -- must pair with start and start.prev
local before = copy_node(prv)
- local after = copy_node(nxt)
- local tail = find_node_tail(replace)
+ local after = copy_node(nxt)
+ local tail = find_node_tail(replace)
setfield(replace,"prev",before)
setfield(before,"next",replace)
setfield(before,"prev",nil)
@@ -338,9 +344,10 @@ local function do_process(head,force) -- todo: glue so that we can fully stretch
free_node(after)
free_node(before)
elseif prv and getid(prv) == glyph_code and getfont(prv) == lastfont then
- local prevchar, lastchar = getchar(prv), getchar(start)
- local kerns = chardata[lastfont][prevchar].kerns
- local kern = kerns and kerns[lastchar] or 0
+ local prevchar = getchar(prv)
+ local lastchar = getchar(start)
+ local kerns = chardata[lastfont][prevchar].kerns
+ local kern = kerns and kerns[lastchar] or 0
krn = kern + quaddata[lastfont]*krn -- here
setfield(disc,"replace",kern_injector(false,krn)) -- only kerns permitted, no glue
else
@@ -351,9 +358,10 @@ local function do_process(head,force) -- todo: glue so that we can fully stretch
-- this one happens in most cases: automatic (-), explicit (\-), regular (patterns)
if prv and getid(prv) == glyph_code and getfont(prv) == lastfont then
-- the normal case
- local prevchar, lastchar = getchar(prv), getchar(start)
- local kerns = chardata[lastfont][prevchar].kerns
- local kern = kerns and kerns[lastchar] or 0
+ local prevchar = getchar(prv)
+ local lastchar = getchar(start)
+ local kerns = chardata[lastfont][prevchar].kerns
+ local kern = kerns and kerns[lastchar] or 0
krn = kern + quaddata[lastfont]*krn
else
krn = quaddata[lastfont]*krn
@@ -368,7 +376,9 @@ local function do_process(head,force) -- todo: glue so that we can fully stretch
local s = getfield(start,"spec")
local w = getfield(s,"width")
if w > 0 then
- local width, stretch, shrink = w+gluefactor*w*krn, getfield(s,"stretch"), getfield(s,"shrink")
+ local width = w+gluefactor*w*krn
+ local stretch = getfield(s,"stretch")
+ local shrink = getfield(s,"shrink")
setfield(start,"spec",spec_injector(fillup,width,stretch*width/w,shrink*width/w))
done = true
end
diff --git a/tex/generic/context/luatex/luatex-fonts-cbk.lua b/tex/generic/context/luatex/luatex-fonts-cbk.lua
index 8632701d8..965b96893 100644
--- a/tex/generic/context/luatex/luatex-fonts-cbk.lua
+++ b/tex/generic/context/luatex/luatex-fonts-cbk.lua
@@ -18,21 +18,28 @@ local nodes = nodes
local traverse_id = node.traverse_id
local glyph_code = nodes.nodecodes.glyph
+local disc_code = nodes.nodecodes.disc
-- 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 ligaturing = node.ligaturing
+local kerning = node.kerning
-function node.ligaturing() texio.write_nl("warning: node.ligaturing is already applied") end
-function node.kerning () texio.write_nl("warning: node.kerning is already applied") end
+local basepass = true
+
+function nodes.handlers.setbasepass(v)
+ basepass = v
+end
function nodes.handlers.characters(head)
local fontdata = fonts.hashes.identifiers
if fontdata then
- local usedfonts, basefonts, prevfont, basefont = { }, { }, nil, 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
@@ -49,7 +56,7 @@ function nodes.handlers.characters(head)
local processors = shared.processes
if processors and #processors > 0 then
usedfonts[font] = processors
- else
+ elseif basepass then
basefont = { n, nil }
basefonts[#basefonts+1] = basefont
end
@@ -58,6 +65,30 @@ function nodes.handlers.characters(head)
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 next(usedfonts) then
for font, processors in next, usedfonts do
for i=1,#processors do
@@ -65,7 +96,7 @@ function nodes.handlers.characters(head)
end
end
end
- if #basefonts > 0 then
+ if basepass and #basefonts > 0 then
for i=1,#basefonts do
local range = basefonts[i]
local start, stop = range[1], range[2]
@@ -85,11 +116,13 @@ function nodes.handlers.characters(head)
end
function nodes.simple_font_handler(head)
--- lang.hyphenate(head)
+ -- lang.hyphenate(head)
head = nodes.handlers.characters(head)
nodes.injections.handler(head)
+ if not basepass then
+ head = ligaturing(head)
+ head = kerning(head)
+ end
nodes.handlers.protectglyphs(head)
- -- head = node.ligaturing(head)
- -- head = node.kerning(head)
return head
end
diff --git a/tex/generic/context/luatex/luatex-fonts-merged.lua b/tex/generic/context/luatex/luatex-fonts-merged.lua
index e9c66382f..c000451c7 100644
--- a/tex/generic/context/luatex/luatex-fonts-merged.lua
+++ b/tex/generic/context/luatex/luatex-fonts-merged.lua
@@ -1,6 +1,6 @@
-- merged file : luatex-fonts-merged.lua
-- parent file : luatex-fonts.lua
--- merge date : 12/06/14 14:20:08
+-- merge date : 12/08/14 22:14:53
do -- begin closure to overcome local limits and interference
@@ -14560,14 +14560,20 @@ local fonts=fonts
local nodes=nodes
local traverse_id=node.traverse_id
local glyph_code=nodes.nodecodes.glyph
+local disc_code=nodes.nodecodes.disc
local ligaturing=node.ligaturing
local kerning=node.kerning
-function node.ligaturing() texio.write_nl("warning: node.ligaturing is already applied") end
-function node.kerning () texio.write_nl("warning: node.kerning is already applied") end
+local basepass=true
+function nodes.handlers.setbasepass(v)
+ basepass=v
+end
function nodes.handlers.characters(head)
local fontdata=fonts.hashes.identifiers
if fontdata then
- local usedfonts,basefonts,prevfont,basefont={},{},nil,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
@@ -14584,7 +14590,7 @@ function nodes.handlers.characters(head)
local processors=shared.processes
if processors and #processors>0 then
usedfonts[font]=processors
- else
+ elseif basepass then
basefont={ n,nil }
basefonts[#basefonts+1]=basefont
end
@@ -14593,6 +14599,30 @@ function nodes.handlers.characters(head)
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
+ 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 next(usedfonts) then
for font,processors in next,usedfonts do
for i=1,#processors do
@@ -14600,7 +14630,7 @@ function nodes.handlers.characters(head)
end
end
end
- if #basefonts>0 then
+ if basepass and #basefonts>0 then
for i=1,#basefonts do
local range=basefonts[i]
local start,stop=range[1],range[2]
@@ -14621,6 +14651,10 @@ end
function nodes.simple_font_handler(head)
head=nodes.handlers.characters(head)
nodes.injections.handler(head)
+ if not basepass then
+ head=ligaturing(head)
+ head=kerning(head)
+ end
nodes.handlers.protectglyphs(head)
return head
end