diff options
21 files changed, 209 insertions, 56 deletions
diff --git a/doc/context/documents/general/manuals/luatex.pdf b/doc/context/documents/general/manuals/luatex.pdf Binary files differindex df24e245f..61ff94bfb 100644 --- a/doc/context/documents/general/manuals/luatex.pdf +++ b/doc/context/documents/general/manuals/luatex.pdf diff --git a/doc/context/sources/general/manuals/luatex/luatex.tex b/doc/context/sources/general/manuals/luatex/luatex.tex index da75ea3e4..a9524246b 100644 --- a/doc/context/sources/general/manuals/luatex/luatex.tex +++ b/doc/context/sources/general/manuals/luatex/luatex.tex @@ -27,6 +27,7 @@ \component luatex-fonts \component luatex-math \component luatex-nodes + \component luatex-callbacks \component luatex-tex \component luatex-graphics \component luatex-fontloader diff --git a/tex/context/base/context-version.pdf b/tex/context/base/context-version.pdf Binary files differindex 29b499468..08b6cca9d 100644 --- a/tex/context/base/context-version.pdf +++ b/tex/context/base/context-version.pdf diff --git a/tex/context/base/mkiv/cont-new.mkiv b/tex/context/base/mkiv/cont-new.mkiv index 381f35eb7..f597de6a8 100644 --- a/tex/context/base/mkiv/cont-new.mkiv +++ b/tex/context/base/mkiv/cont-new.mkiv @@ -11,7 +11,7 @@ %C therefore copyrighted by \PRAGMA. See mreadme.pdf for %C details. -\newcontextversion{2016.04.17 11:56} +\newcontextversion{2016.04.18 18:53} %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/mkiv/context.mkiv b/tex/context/base/mkiv/context.mkiv index e30d06432..14833fc2b 100644 --- a/tex/context/base/mkiv/context.mkiv +++ b/tex/context/base/mkiv/context.mkiv @@ -39,7 +39,7 @@ %D up and the dependencies are more consistent. \edef\contextformat {\jobname} -\edef\contextversion{2016.04.17 11:56} +\edef\contextversion{2016.04.18 18:53} \edef\contextkind {beta} %D For those who want to use this: diff --git a/tex/context/base/mkiv/font-col.lua b/tex/context/base/mkiv/font-col.lua index adcf374e2..cf1b60bb9 100644 --- a/tex/context/base/mkiv/font-col.lua +++ b/tex/context/base/mkiv/font-col.lua @@ -27,6 +27,7 @@ local setfield = nuts.setfield local setchar = nuts.setchar local traverse_id = nuts.traverse_id +local traverse_char = nuts.traverse_char local settings_to_hash = utilities.parsers.settings_to_hash @@ -256,7 +257,8 @@ end function collections.process(head) -- this way we keep feature processing local done = false - for n in traverse_id(glyph_code,tonut(head)) do + -- for n in traverse_id(glyph_code,tonut(head)) do + for n in traverse_char(tonut(head)) do local font = getfont(n) local vector = vectors[font] if vector then diff --git a/tex/context/base/mkiv/font-gbn.lua b/tex/context/base/mkiv/font-gbn.lua index a645a97e7..daa072b4b 100644 --- a/tex/context/base/mkiv/font-gbn.lua +++ b/tex/context/base/mkiv/font-gbn.lua @@ -20,6 +20,7 @@ local nuts = nodes.nuts -- context abstraction of direct nodes local traverse_id = nuts.traverse_id local remove_node = nuts.remove +local free_node = nuts.free local glyph_code = nodes.nodecodes.glyph local disc_code = nodes.nodecodes.disc @@ -30,11 +31,13 @@ local tonut = nuts.tonut local getfont = nuts.getfont local getchar = nuts.getchar local getid = nuts.getid +local getboth = nuts.getboth local getprev = nuts.getprev local getnext = nuts.getnext local getdisc = nuts.getdisc local setchar = nuts.setchar local setlink = nuts.setlink +local setprev = nuts.setprev -- 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 @@ -136,7 +139,26 @@ function nodes.handlers.nodepass(head) end if redundant then for i=1,#redundant do - remove_node(nuthead,redundant[i],true) + local r = redundant[i] + local p, n = getboth(r) + if r == nuthead then + nuthead = n + setprev(n) + else + setlink(p,n) + end + if b > 0 then + for i=1,b do + local bi = basefonts[i] + if r == bi[1] then + bi[1] = n + end + if r == bi[2] then + bi[2] = n + end + end + end + free_node(r) end end for d in traverse_id(disc_code,nuthead) do diff --git a/tex/context/base/mkiv/font-ini.mkvi b/tex/context/base/mkiv/font-ini.mkvi index 9ed4a0efc..7e5851b26 100644 --- a/tex/context/base/mkiv/font-ini.mkvi +++ b/tex/context/base/mkiv/font-ini.mkvi @@ -1456,7 +1456,7 @@ {\font_basics_define_body_font_a[#whatever][\s!rm][#specification]} \unexpanded\def\font_basics_define_body_font_c[#whatever][#dummya][#dummyb]% body|identifier - {\font_basics_define_body_font_a[bwhatever][\s!rm][]} + {\font_basics_define_body_font_a[#whatever][\s!rm][]} \unexpanded\def\font_basics_define_body_font_a[#whatever]% {\doifelsenumber{#whatever}% diff --git a/tex/context/base/mkiv/font-ots.lua b/tex/context/base/mkiv/font-ots.lua index c3e1f48bd..691187258 100644 --- a/tex/context/base/mkiv/font-ots.lua +++ b/tex/context/base/mkiv/font-ots.lua @@ -696,6 +696,9 @@ end function handlers.gsub_ligature(head,start,dataset,sequence,ligature) local current = getnext(start) + if not current then + return head, start, false, nil + end local stop = nil local startchar = getchar(start) if marks[startchar] then @@ -756,6 +759,28 @@ function handlers.gsub_ligature(head,start,dataset,sequence,ligature) -- kind of weird break elseif id == disc_code then + -- tricky .. we also need to do pre here + local replace = getfield(current,"replace") + if replace then + -- of{f-}{}{f}e o{f-}{}{f}fe o{-}{}{ff}e (oe and ff ligature) + -- we can end up here when we have a start run .. testruns start at a disc but + -- so here we have the other case: char + disc + while replace do + local char, id = ischar(replace,currentfont) + if char then + local lg = ligature[char] -- can there be multiple in a row? maybe in a bad font + if lg then + ligature = lg + replace = getnext(replace) + else + return head, start, false, false + end + else + return head, start, false, false + end + end + stop = current + end lastdisc = current current = getnext(current) else @@ -1281,6 +1306,7 @@ function chainprocs.gsub_ligature(head,start,stop,dataset,sequence,currentlookup local nofreplacements = 1 local skipmark = currentlookup.flags[1] -- sequence.flags? while current do + -- todo: ischar ... can there really be disc nodes here? local id = getid(current) if id == disc_code then if not discfound then @@ -2755,6 +2781,8 @@ local function kernrun(disc,k_run,font,attr,...) next = false end -- + -- we need to get rid of this nest mess some day .. has to be done otherwise + -- if pre then if k_run(pre,"injections",nil,font,attr,...) then done = true @@ -2762,7 +2790,7 @@ local function kernrun(disc,k_run,font,attr,...) if prev then local nest = getprev(pre) setlink(prev,pre) - if k_run(prevmarks,"preinjections",pre,font,attr,...) then -- getnext(pre)) + if k_run(prevmarks,"preinjections",pre,font,attr,...) then -- or prev? done = true end setprev(pre,nest) @@ -2860,7 +2888,7 @@ local function comprun(disc,c_run,...) setdisc(disc,pre,post,replace) end -- - return getnext(disc), done + return getnext(disc), renewed end local function testrun(disc,t_run,c_run,...) @@ -3000,8 +3028,9 @@ local nesting = 0 local function c_run_single(head,font,attr,lookupcache,step,dataset,sequence,rlmode,handler) local done = false - local start = sweephead[head] - if start then + local sweep = sweephead[head] + if sweep then + start = sweep sweephead[head] = nil else start = head @@ -3027,8 +3056,11 @@ local function c_run_single(head,font,attr,lookupcache,step,dataset,sequence,rlm end elseif char == false then return head, done + elseif sweep then + -- else we loose the rest + return head, done else - -- weird + -- in disc component start = getnext(start) end end @@ -3113,8 +3145,9 @@ end local function c_run_multiple(head,font,attr,steps,nofsteps,dataset,sequence,rlmode,handler) local done = false - local start = sweephead[head] - if start then + local sweep = sweephead[head] + if sweep then + start = sweep sweephead[head] = nil else start = head @@ -3154,8 +3187,11 @@ local function c_run_multiple(head,font,attr,steps,nofsteps,dataset,sequence,rlm elseif char == false then -- whatever glyph return head, done + elseif sweep then + -- else we loose the rest + return head, done else - -- very unlikely + -- in disc component start = getnext(start) end end diff --git a/tex/context/base/mkiv/font-oup.lua b/tex/context/base/mkiv/font-oup.lua index 59530af06..7edaaf683 100644 --- a/tex/context/base/mkiv/font-oup.lua +++ b/tex/context/base/mkiv/font-oup.lua @@ -9,7 +9,7 @@ if not modules then modules = { } end modules ['font-oup'] = { local next, type = next, type local P, R, S = lpeg.P, lpeg.R, lpeg.S local lpegmatch = lpeg.match -local insert, remove, copy = table.insert, table.remove, table.copy +local insert, remove, copy, unpack = table.insert, table.remove, table.copy, table.unpack local formatters = string.formatters local sortedkeys = table.sortedkeys @@ -737,8 +737,7 @@ local function stripredundant(fontdata) end function readers.getcomponents(fontdata) -- handy for resolving ligatures when names are missing - local resources = fontdata.resources - local descriptions = fontdata.descriptions + local resources = fontdata.resources if resources then local sequences = resources.sequences if sequences then @@ -761,7 +760,7 @@ function readers.getcomponents(fontdata) -- handy for resolving ligatures when n end end for i=1,#steps do - -- we actually had/have this in base mode + -- we actually had/have this in base mode local coverage = steps[i].coverage if coverage then for k, v in next, coverage do @@ -773,13 +772,25 @@ function readers.getcomponents(fontdata) -- handy for resolving ligatures when n end end if next(collected) then + -- remove self referring + -- for k, v in next, collected do + -- for i=1,#v do + -- local vi = v[i] + -- if vi == k then + -- -- report("removing self referring ligature @ slot %5X from collected (1)",k) + -- collected[k] = nil + -- end + -- end + -- end while true do local done = false for k, v in next, collected do for i=1,#v do local vi = v[i] if vi == k then + -- report("removing self referring ligature @ slot %5X from collected (2)",k) collected[k] = nil + break else local c = collected[vi] if c then @@ -787,7 +798,7 @@ function readers.getcomponents(fontdata) -- handy for resolving ligatures when n local t = { } local n = i - 1 for j=1,n do - t[j] = t[j] + t[j] = v[j] end for j=1,#c do n = n + 1 @@ -795,7 +806,7 @@ function readers.getcomponents(fontdata) -- handy for resolving ligatures when n end for j=i+1,#v do n = n + 1 - t[n] = t[j] + t[n] = v[j] end collected[k] = t break diff --git a/tex/context/base/mkiv/font-syn.lua b/tex/context/base/mkiv/font-syn.lua index 2d671c397..f27995212 100644 --- a/tex/context/base/mkiv/font-syn.lua +++ b/tex/context/base/mkiv/font-syn.lua @@ -73,7 +73,7 @@ fonts.treatments = treatments names.data = names.data or allocate { } -names.version = 1.130 +names.version = 1.131 names.basename = "names" names.saved = false names.loaded = false @@ -492,6 +492,7 @@ function names.getpaths(trace) end end end + sort(result) function names.getpaths() return result end @@ -932,7 +933,6 @@ local function unpackreferences() local data = names.data local specifications = data.specifications if specifications then --- for k, v in next, data.families do for k, v in sortedhash(data.families) do for i=1,#v do v[i] = specifications[v[i]] @@ -940,9 +940,7 @@ local function unpackreferences() end local mappings = data.mappings if mappings then --- for _, m in next, mappings do for _, m in sortedhash(mappings) do --- for k, v in next, m do for k, v in sortedhash(m) do m[k] = specifications[v] end @@ -950,9 +948,7 @@ local function unpackreferences() end local fallbacks = data.fallbacks if fallbacks then --- for _, f in next, fallbacks do for _, f in sortedhash(fallbacks) do --- for k, v in next, f do for k, v in sortedhash(f) do f[k] = specifications[v] end diff --git a/tex/context/base/mkiv/node-fin.lua b/tex/context/base/mkiv/node-fin.lua index 6572d1168..a2d63d38d 100644 --- a/tex/context/base/mkiv/node-fin.lua +++ b/tex/context/base/mkiv/node-fin.lua @@ -48,8 +48,6 @@ local vlist_code = nodecodes.vlist local normal_rule = rulecodes.normal -local pdfliteral_code = whatcodes.pdfliteral - local states = attributes.states local numbers = attributes.numbers local a_trigger = attributes.private('trigger') diff --git a/tex/context/base/mkiv/node-fnt.lua b/tex/context/base/mkiv/node-fnt.lua index c726cdb4c..7f0d23997 100644 --- a/tex/context/base/mkiv/node-fnt.lua +++ b/tex/context/base/mkiv/node-fnt.lua @@ -48,11 +48,13 @@ local getchar = nuts.getchar local getdisc = nuts.getdisc local getnext = nuts.getnext local getprev = nuts.getprev +local getboth = nuts.getboth local getfield = nuts.getfield ----- getdisc = nuts.getdisc local setchar = nuts.setchar local setlink = nuts.setlink local setfield = nuts.setfield +local setprev = nuts.setprev local isglyph = nuts.isglyph -- unchecked local ischar = nuts.ischar -- checked @@ -61,6 +63,7 @@ local traverse_id = nuts.traverse_id local traverse_char = nuts.traverse_char local remove_node = nuts.remove local protect_glyph = nuts.protect_glyph +local free_node = nuts.free local glyph_code = nodecodes.glyph local disc_code = nodecodes.disc @@ -292,12 +295,27 @@ function handlers.characters(head) end if redundant then - local front = nuthead == redundant[1] for i=1,#redundant do - nuthead = remove_node(nuthead,redundant[i],true) - end - if front then - head = tonode(nuthead) + local r = redundant[i] + local p, n = getboth(r) + if r == nuthead then + nuthead = n + setprev(n) + else + setlink(p,n) + end + if b > 0 then + for i=1,b do + local bi = basefonts[i] + if r == bi[1] then + bi[1] = n + end + if r == bi[2] then + bi[2] = n + end + end + end + free_node(r) end end diff --git a/tex/context/base/mkiv/scrn-bar.mkvi b/tex/context/base/mkiv/scrn-bar.mkvi index 862d257c0..2f21b0004 100644 --- a/tex/context/base/mkiv/scrn-bar.mkvi +++ b/tex/context/base/mkiv/scrn-bar.mkvi @@ -211,13 +211,13 @@ \normalexpanded{\directgotospecbox\noexpand\interactionbarparameter{\blackrule}[\v!firstpage]}% \hskip\emwidth \ifnum\realpageno>\plusone - \hskip\zeropoint\??plus\numexpr\realpageno-\plustwo\relax \s!sp\relax % cm gives overflow + \hskip\zeropoint\s!plus\numexpr\realpageno-\plustwo\relax \s!sp\relax % cm gives overflow \normalexpanded{\directgotospecbox\noexpand\interactionbarparameter{\blackrule}[\v!previouspage)]}% \fi \normalexpanded{\directgotospecbox\noexpand\interactionbarparameter{\blackrule}[page(\number\realpageno)]}% todo: \v!currentpage \ifnum\realpageno<\lastpage\relax \normalexpanded{\directgotospecbox\noexpand\interactionbarparameter{\blackrule}[\v!nextpage]}% - \hskip\zeropoint\??plus\numexpr\lastpage-\realpageno-\plusone\relax \s!sp\relax % cm gives overflow + \hskip\zeropoint\s!plus\numexpr\lastpage-\realpageno-\plusone\relax \s!sp\relax % cm gives overflow \fi \hskip\emwidth \normalexpanded{\directgotospecbox\noexpand\interactionbarparameter{\blackrule}[\v!lastpage]}% diff --git a/tex/context/base/mkiv/status-files.pdf b/tex/context/base/mkiv/status-files.pdf Binary files differindex 34a6ec049..4096b8195 100644 --- a/tex/context/base/mkiv/status-files.pdf +++ b/tex/context/base/mkiv/status-files.pdf diff --git a/tex/context/base/mkiv/status-lua.pdf b/tex/context/base/mkiv/status-lua.pdf Binary files differindex 1c52234ba..72e1e9a57 100644 --- a/tex/context/base/mkiv/status-lua.pdf +++ b/tex/context/base/mkiv/status-lua.pdf diff --git a/tex/context/base/mkiv/typo-brk.lua b/tex/context/base/mkiv/typo-brk.lua index 9fc248305..106bb4954 100644 --- a/tex/context/base/mkiv/typo-brk.lua +++ b/tex/context/base/mkiv/typo-brk.lua @@ -142,7 +142,10 @@ methods[6] = function(head,start,stop,settings,kern) local l = new_wordboundary() local d = new_disc() local r = new_wordboundary() - setfield(d,"attr",getfield(start,"attr")) -- otherwise basemode is forces and we crash + local a = getfield(start,"attr") + -- setfield(l,"attr",a) + setfield(d,"attr",a) -- otherwise basemode is forces and we crash + -- setfield(r,"attr",a) setlink(p,l) setlink(l,d) setlink(d,r) diff --git a/tex/context/interface/mkiv/i-context.pdf b/tex/context/interface/mkiv/i-context.pdf Binary files differindex 9a07f9e50..3141b961f 100644 --- a/tex/context/interface/mkiv/i-context.pdf +++ b/tex/context/interface/mkiv/i-context.pdf diff --git a/tex/context/interface/mkiv/i-readme.pdf b/tex/context/interface/mkiv/i-readme.pdf Binary files differindex b5001749e..45f72869c 100644 --- a/tex/context/interface/mkiv/i-readme.pdf +++ b/tex/context/interface/mkiv/i-readme.pdf diff --git a/tex/context/modules/mkiv/s-lingual-de.mkiv b/tex/context/modules/mkiv/s-lingual-de.mkiv index f01afa468..d5436e1e2 100644 --- a/tex/context/modules/mkiv/s-lingual-de.mkiv +++ b/tex/context/modules/mkiv/s-lingual-de.mkiv @@ -1,4 +1,15 @@ -% Some experimental code for Wolfgang to play with: +%D \module +%D [ file=s-lingual-de, +%D version=2016.04.17, +%D title=\CONTEXT\ Linguistic File, +%D subtitle=German TWeaks, +%D author=Hans Hagen, +%D date=\currentdate, +%D copyright={PRAGMA ADE \& \CONTEXT\ Development Team}] +%C +%C This module is part of the \CONTEXT\ macro||package and is +%C therefore copyrighted by \PRAGMA. See mreadme.pdf for +%C details. \startluacode fonts.handlers.otf.addfeature { @@ -12,21 +23,27 @@ \definefontfeature[sz][sz=yes] -\unexpanded\def\composedSZ {\overloaduppercase{0xDF}{0x1E9E}} -\unexpanded\def\decomposedSZ{\overloaduppercase{0xDF}{0x53,0x53}} +\unexpanded\def\enableuppercasesharps {\overloaduppercase{0xDF}{0x1E9E}} +\unexpanded\def\disableuppercasesharps{\overloaduppercase{0xDF}{0x53,0x53}} + +\installtexdirective + {fonts.uppercasesharps} + \enableuppercasesharps + \disableuppercasesharps \continueifinputfile{s-lingual-de.mkiv} \setupbodyfont[libertine] \starttext + \def\TestString{Buße Busse BUẞE BUSSE \WORD{Buße Busse}} %\definefontfeature[default][default][sz=yes] - \dorecurse{10} { - \decomposedSZ \WORD{Gruß}\par - \composedSZ \WORD{Gruß}\par + \dorecurse{5} { + \disableuppercasesharps + \TestString\par + \enableuppercasesharps + \TestString\par + {\addfeature{sz}\TestString}\par } - - \composedSZ - {\addfeature{sz}Straße \WORD{Straße} STRAẞE}\par - {Straße \WORD{Straße} STRAẞE}\par \stoptext + diff --git a/tex/generic/context/luatex/luatex-fonts-merged.lua b/tex/generic/context/luatex/luatex-fonts-merged.lua index 0d22a7390..1595733e1 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 : c:/data/develop/context/sources/luatex-fonts-merged.lua -- parent file : c:/data/develop/context/sources/luatex-fonts.lua --- merge date : 04/17/16 11:56:26 +-- merge date : 04/18/16 18:53:40 do -- begin closure to overcome local limits and interference @@ -13503,7 +13503,7 @@ if not modules then modules={} end modules ['font-oup']={ local next,type=next,type local P,R,S=lpeg.P,lpeg.R,lpeg.S local lpegmatch=lpeg.match -local insert,remove,copy=table.insert,table.remove,table.copy +local insert,remove,copy,unpack=table.insert,table.remove,table.copy,table.unpack local formatters=string.formatters local sortedkeys=table.sortedkeys local sortedhash=table.sortedhash @@ -14169,7 +14169,6 @@ local function stripredundant(fontdata) end function readers.getcomponents(fontdata) local resources=fontdata.resources - local descriptions=fontdata.descriptions if resources then local sequences=resources.sequences if sequences then @@ -14210,6 +14209,7 @@ function readers.getcomponents(fontdata) local vi=v[i] if vi==k then collected[k]=nil + break else local c=collected[vi] if c then @@ -14217,7 +14217,7 @@ function readers.getcomponents(fontdata) local t={} local n=i-1 for j=1,n do - t[j]=t[j] + t[j]=v[j] end for j=1,#c do n=n+1 @@ -14225,7 +14225,7 @@ function readers.getcomponents(fontdata) end for j=i+1,#v do n=n+1 - t[n]=t[j] + t[n]=v[j] end collected[k]=t break @@ -18678,6 +18678,9 @@ function handlers.gsub_multiple(head,start,dataset,sequence,multiple) end function handlers.gsub_ligature(head,start,dataset,sequence,ligature) local current=getnext(start) + if not current then + return head,start,false,nil + end local stop=nil local startchar=getchar(start) if marks[startchar] then @@ -18736,6 +18739,24 @@ function handlers.gsub_ligature(head,start,dataset,sequence,ligature) elseif char==false then break elseif id==disc_code then + local replace=getfield(current,"replace") + if replace then + while replace do + local char,id=ischar(replace,currentfont) + if char then + local lg=ligature[char] + if lg then + ligature=lg + replace=getnext(replace) + else + return head,start,false,false + end + else + return head,start,false,false + end + end + stop=current + end lastdisc=current current=getnext(current) else @@ -20539,7 +20560,7 @@ local function comprun(disc,c_run,...) if renewed then setdisc(disc,pre,post,replace) end - return getnext(disc),done + return getnext(disc),renewed end local function testrun(disc,t_run,c_run,...) if trace_testruns then @@ -20605,8 +20626,9 @@ end local nesting=0 local function c_run_single(head,font,attr,lookupcache,step,dataset,sequence,rlmode,handler) local done=false - local start=sweephead[head] - if start then + local sweep=sweephead[head] + if sweep then + start=sweep sweephead[head]=nil else start=head @@ -20632,6 +20654,8 @@ local function c_run_single(head,font,attr,lookupcache,step,dataset,sequence,rlm end elseif char==false then return head,done + elseif sweep then + return head,done else start=getnext(start) end @@ -20696,8 +20720,9 @@ local function k_run_single(sub,injection,last,font,attr,lookupcache,step,datase end local function c_run_multiple(head,font,attr,steps,nofsteps,dataset,sequence,rlmode,handler) local done=false - local start=sweephead[head] - if start then + local sweep=sweephead[head] + if sweep then + start=sweep sweephead[head]=nil else start=head @@ -20734,6 +20759,8 @@ local function c_run_multiple(head,font,attr,steps,nofsteps,dataset,sequence,rlm end elseif char==false then return head,done + elseif sweep then + return head,done else start=getnext(start) end @@ -23867,6 +23894,7 @@ local nodes=nodes local nuts=nodes.nuts local traverse_id=nuts.traverse_id local remove_node=nuts.remove +local free_node=nuts.free local glyph_code=nodes.nodecodes.glyph local disc_code=nodes.nodecodes.disc local tonode=nuts.tonode @@ -23874,11 +23902,13 @@ local tonut=nuts.tonut local getfont=nuts.getfont local getchar=nuts.getchar local getid=nuts.getid +local getboth=nuts.getboth local getprev=nuts.getprev local getnext=nuts.getnext local getdisc=nuts.getdisc local setchar=nuts.setchar local setlink=nuts.setlink +local setprev=nuts.setprev local n_ligaturing=node.ligaturing local n_kerning=node.kerning local ligaturing=nuts.ligaturing @@ -23968,7 +23998,26 @@ function nodes.handlers.nodepass(head) end if redundant then for i=1,#redundant do - remove_node(nuthead,redundant[i],true) + local r=redundant[i] + local p,n=getboth(r) + if r==nuthead then + nuthead=n + setprev(n) + else + setlink(p,n) + end + if b>0 then + for i=1,b do + local bi=basefonts[i] + if r==bi[1] then + bi[1]=n + end + if r==bi[2] then + bi[2]=n + end + end + end + free_node(r) end end for d in traverse_id(disc_code,nuthead) do |