From b8b264a266beed6f95e53ea1801bd96f345fc745 Mon Sep 17 00:00:00 2001 From: Philipp Gesang Date: Mon, 18 Apr 2016 20:24:16 +0200 Subject: [fontloader] sync with Context as of 2016-04-18 --- src/fontloader/misc/fontloader-font-gbn.lua | 24 ++++++++- src/fontloader/misc/fontloader-font-ots.lua | 60 +++++++++++++++------ src/fontloader/misc/fontloader-font-oup.lua | 23 +++++--- src/fontloader/runtime/fontloader-reference.lua | 71 +++++++++++++++++++++---- 4 files changed, 145 insertions(+), 33 deletions(-) diff --git a/src/fontloader/misc/fontloader-font-gbn.lua b/src/fontloader/misc/fontloader-font-gbn.lua index a645a97..daa072b 100644 --- a/src/fontloader/misc/fontloader-font-gbn.lua +++ b/src/fontloader/misc/fontloader-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/src/fontloader/misc/fontloader-font-ots.lua b/src/fontloader/misc/fontloader-font-ots.lua index 0a438d5..6911872 100644 --- a/src/fontloader/misc/fontloader-font-ots.lua +++ b/src/fontloader/misc/fontloader-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,14 +759,30 @@ function handlers.gsub_ligature(head,start,dataset,sequence,ligature) -- kind of weird break elseif id == disc_code then - if getfield(current,"replace") then - -- this only happens when we didn't normalize ... in a future version we will - -- assume normalization of disc nodes - break - else - lastdisc=current - current=getnext(current) + -- 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 break end @@ -1287,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 @@ -2761,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 @@ -2768,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) @@ -2866,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,...) @@ -3006,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 @@ -3033,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 @@ -3119,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 @@ -3160,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/src/fontloader/misc/fontloader-font-oup.lua b/src/fontloader/misc/fontloader-font-oup.lua index 59530af..7edaaf6 100644 --- a/src/fontloader/misc/fontloader-font-oup.lua +++ b/src/fontloader/misc/fontloader-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/src/fontloader/runtime/fontloader-reference.lua b/src/fontloader/runtime/fontloader-reference.lua index 0d22a73..1595733 100644 --- a/src/fontloader/runtime/fontloader-reference.lua +++ b/src/fontloader/runtime/fontloader-reference.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 -- cgit v1.2.3