From ddf162b67f0c057fefa7efb8c32fb0d0ac391bd1 Mon Sep 17 00:00:00 2001 From: Philipp Gesang Date: Sun, 14 Jul 2013 10:14:23 +0200 Subject: sync with Context as of 2013-07-14 --- luaotfload-basics-gen.lua | 22 +- luaotfload-basics-nod.lua | 31 +- luaotfload-merged.lua | 730 +++++++++++++++++++++++++--------------------- 3 files changed, 440 insertions(+), 343 deletions(-) diff --git a/luaotfload-basics-gen.lua b/luaotfload-basics-gen.lua index a5da2fd..26c1edc 100644 --- a/luaotfload-basics-gen.lua +++ b/luaotfload-basics-gen.lua @@ -149,19 +149,29 @@ do local cachepaths = kpse.expand_var('$TEXMFCACHE') or "" - -- quite like tex live or so + -- quite like tex live or so (the weird $TEXMFCACHE test seems to be needed on miktex) - if cachepaths == "$TEXMFCACHE" then + if cachepaths == "" or cachepaths == "$TEXMFCACHE" then cachepaths = kpse.expand_var('$TEXMFVAR') or "" end - -- this also happened to be used + -- this also happened to be used (the weird $TEXMFVAR test seems to be needed on miktex) - if cachepaths == "$TEXMFVAR" then + if cachepaths == "" or cachepaths == "$TEXMFVAR" then cachepaths = kpse.expand_var('$VARTEXMF') or "" end - -- and this is a last resort + -- and this is a last resort (hm, we could use TEMP or TEMPDIR) + + if cachepaths == "" then + local fallbacks = { "TMPDIR", "TEMPDIR", "TMP", "TEMP", "HOME", "HOMEPATH" } + for i=1,#fallbacks do + cachepaths = os.getenv(fallbacks[i]) or "" + if cachepath ~= "" and lfs.isdir(cachepath) then + break + end + end + end if cachepaths == "" then cachepaths = "." @@ -267,7 +277,7 @@ function caches.savedata(path,name,data) local luaname, lucname = makefullname(path,name) if luaname then texio.write(string.format("(save: %s)",luaname)) - table.tofile(luaname,data,true,{ reduce = true }) + table.tofile(luaname,data,true) if lucname and type(caches.compile) == "function" then os.remove(lucname) -- better be safe texio.write(string.format("(save: %s)",lucname)) diff --git a/luaotfload-basics-nod.lua b/luaotfload-basics-nod.lua index 5ab9df7..58b2789 100644 --- a/luaotfload-basics-nod.lua +++ b/luaotfload-basics-nod.lua @@ -88,17 +88,32 @@ function nodes.delete(head,current) return nodes.remove(head,current,true) end -nodes.before = node.insert_before -nodes.after = node.insert_after - function nodes.pool.kern(k) local n = new_node("kern",1) n.kern = k return n end -function nodes.endofmath(n) - for n in traverse_id(math_code,n.next) do - return n - end -end +-- experimental + +local getfield = node.getfield or function(n,tag) return n[tag] end end +local setfield = node.setfield or function(n,tag,value) n[tag] = value end end + +nodes.getfield = getfield +nodes.setfield = setfield + +nodes.getattr = getfield +nodes.setattr = setfield + +if node.getid then nodes.getid = node.getid else function nodes.getid (n) return getfield(n,"id") end end +if node.getsubtype then nodes.getsubtype = node.getsubtype else function nodes.getsubtype(n) return getfield(n,"subtype") end end +if node.getnext then nodes.getnext = node.getnext else function nodes.getnext (n) return getfield(n,"next") end end +if node.getprev then nodes.getprev = node.getprev else function nodes.getprev (n) return getfield(n,"prev") end end +if node.getchar then nodes.getchar = node.getchar else function nodes.getchar (n) return getfield(n,"char") end end +if node.getfont then nodes.getfont = node.getfont else function nodes.getfont (n) return getfield(n,"font") end end +if node.getlist then nodes.getlist = node.getlist else function nodes.getlist (n) return getfield(n,"list") end end + +function nodes.tonut (n) return n end +function nodes.tonode(n) return n end + +nodes.nuts = nodes -- we stay nodes diff --git a/luaotfload-merged.lua b/luaotfload-merged.lua index 52c199a..d7a1fab 100644 --- a/luaotfload-merged.lua +++ b/luaotfload-merged.lua @@ -1,6 +1,6 @@ -- merged file : luatex-fonts-merged.lua -- parent file : luatex-fonts.lua --- merge date : 06/10/13 12:24:08 +-- merge date : 07/12/13 19:10:11 do -- begin closure to overcome local limits and interference @@ -95,6 +95,7 @@ if not modules then modules={} end modules ['l-lpeg']={ license="see context related readme files" } lpeg=require("lpeg") +if not lpeg.print then function lpeg.print(...) print(lpeg.pcode(...)) end end local type,next,tostring=type,next,tostring local byte,char,gmatch,format=string.byte,string.char,string.gmatch,string.format local floor=math.floor @@ -213,7 +214,7 @@ patterns.decafloat=sign^-1*(digit^0*period*digit^1+digit^1*period*digit^0+digit^ patterns.propername=(uppercase+lowercase+underscore)*(uppercase+lowercase+underscore+digit)^0*endofstring patterns.somecontent=(anything-newline-space)^1 patterns.beginline=#(1-newline) -patterns.longtostring=Cs(whitespace^0/""*nonwhitespace^0*((whitespace^0/" "*(patterns.quoted+nonwhitespace)^1)^0)) +patterns.longtostring=Cs(whitespace^0/""*((patterns.quoted+nonwhitespace^1+whitespace^1/""*(P(-1)+Cc(" ")))^0)) local function anywhere(pattern) return P { P(pattern)+1*V(1) } end @@ -1066,6 +1067,7 @@ local noquotes,hexify,handle,reduce,compact,inline,functions local reserved=table.tohash { 'and','break','do','else','elseif','end','false','for','function','if', 'in','local','nil','not','or','repeat','return','then','true','until','while', + 'NaN','goto', } local function simple_table(t) if #t>0 then @@ -1691,6 +1693,7 @@ local function readall(f) return f:read('*all') else local done=f:seek("set",0) + local step if size<1024*1024 then step=1024*1024 elseif size>16*1024*1024 then @@ -2214,17 +2217,24 @@ end function file.joinpath(tab,separator) return tab and concat(tab,separator or io.pathseparator) end +local someslash=S("\\/") local stripper=Cs(P(fwslash)^0/""*reslasher) -local isnetwork=fwslash*fwslash*(1-fwslash)+(1-fwslash-colon)^1*colon +local isnetwork=someslash*someslash*(1-someslash)+(1-fwslash-colon)^1*colon local isroot=fwslash^1*-1 local hasroot=fwslash^1 +local reslasher=lpeg.replacer(S("\\/"),"/") local deslasher=lpeg.replacer(S("\\/")^1,"/") function file.join(...) local lst={... } local one=lst[1] if lpegmatch(isnetwork,one) then + local one=lpegmatch(reslasher,one) local two=lpegmatch(deslasher,concat(lst,"/",2)) - return one.."/"..two + if lpegmatch(hasroot,two) then + return one..two + else + return one.."/"..two + end elseif lpegmatch(isroot,one) then local two=lpegmatch(deslasher,concat(lst,"/",2)) if lpegmatch(hasroot,two) then @@ -2241,7 +2251,9 @@ end local drivespec=R("az","AZ")^1*colon local anchors=fwslash+drivespec local untouched=periods+(1-period)^1*P(-1) -local splitstarter=(Cs(drivespec*(bwslash/"/"+fwslash)^0)+Cc(false))*Ct(lpeg.splitat(S("/\\")^1)) +local mswindrive=Cs(drivespec*(bwslash/"/"+fwslash)^0) +local mswinuncpath=(bwslash+fwslash)*(bwslash+fwslash)*Cc("//") +local splitstarter=(mswindrive+mswinuncpath+Cc(false))*Ct(lpeg.splitat(S("/\\")^1)) local absolute=fwslash function file.collapsepath(str,anchor) if not str then @@ -2653,7 +2665,7 @@ local format_i=function(f) if f and f~="" then return format("format('%%%si',a%s)",f,n) else - return format("a%s",n) + return format("format('%%i',a%s)",n) end end local format_d=format_i @@ -3044,12 +3056,21 @@ if not caches.namespace or caches.namespace=="" or caches.namespace=="context" t end do local cachepaths=kpse.expand_var('$TEXMFCACHE') or "" - if cachepaths=="" or cachepaths == "$TEXMFCACHE" then + if cachepaths=="" or cachepaths=="$TEXMFCACHE" then cachepaths=kpse.expand_var('$TEXMFVAR') or "" end - if cachepaths=="" or cachepaths == "$TEXMFVAR" then + if cachepaths=="" or cachepaths=="$TEXMFVAR" then cachepaths=kpse.expand_var('$VARTEXMF') or "" end + if cachepaths=="" then + local fallbacks={ "TMPDIR","TEMPDIR","TMP","TEMP","HOME","HOMEPATH" } + for i=1,#fallbacks do + cachepaths=os.getenv(fallbacks[i]) or "" + if cachepath~="" and lfs.isdir(cachepath) then + break + end + end + end if cachepaths=="" then cachepaths="." end @@ -3143,7 +3164,7 @@ function caches.savedata(path,name,data) local luaname,lucname=makefullname(path,name) if luaname then texio.write(string.format("(save: %s)",luaname)) - table.tofile(luaname,data,true,{ reduce=false }) + table.tofile(luaname,data,true) if lucname and type(caches.compile)=="function" then os.remove(lucname) texio.write(string.format("(save: %s)",lucname)) @@ -3355,18 +3376,27 @@ end function nodes.delete(head,current) return nodes.remove(head,current,true) end -nodes.before=node.insert_before -nodes.after=node.insert_after function nodes.pool.kern(k) local n=new_node("kern",1) n.kern=k return n end -function nodes.endofmath(n) - for n in traverse_id(math_code,n.next) do - return n - end -end +local getfield=node.getfield or function(n,tag) return n[tag] end end +local setfield=node.setfield or function(n,tag,value) n[tag]=value end end +nodes.getfield=getfield +nodes.setfield=setfield +nodes.getattr=getfield +nodes.setattr=setfield +if node.getid then nodes.getid=node.getid else function nodes.getid (n) return getfield(n,"id") end end +if node.getsubtype then nodes.getsubtype=node.getsubtype else function nodes.getsubtype(n) return getfield(n,"subtype") end end +if node.getnext then nodes.getnext=node.getnext else function nodes.getnext (n) return getfield(n,"next") end end +if node.getprev then nodes.getprev=node.getprev else function nodes.getprev (n) return getfield(n,"prev") end end +if node.getchar then nodes.getchar=node.getchar else function nodes.getchar (n) return getfield(n,"char") end end +if node.getfont then nodes.getfont=node.getfont else function nodes.getfont (n) return getfield(n,"font") end end +if node.getlist then nodes.getlist=node.getlist else function nodes.getlist (n) return getfield(n,"list") end end +function nodes.tonut (n) return n end +function nodes.tonode(n) return n end +nodes.nuts=nodes end -- closure @@ -4415,7 +4445,8 @@ function constructors.collectprocessors(what,tfmdata,features,trace,report) local whathandler=handlers[what] local whatfeatures=whathandler.features local whatprocessors=whatfeatures.processors - local processors=whatprocessors[properties.mode] + local mode=properties.mode + local processors=whatprocessors[mode] if processors then for i=1,#processors do local step=processors[i] @@ -4432,7 +4463,7 @@ function constructors.collectprocessors(what,tfmdata,features,trace,report) end end elseif trace then - report("no feature processors for mode %a for font %a",mode,tfmdata.properties.fullname) + report("no feature processors for mode %a for font %a",mode,properties.fullname) end end return processes @@ -4443,7 +4474,8 @@ function constructors.applymanipulators(what,tfmdata,features,trace,report) local whathandler=handlers[what] local whatfeatures=whathandler.features local whatmanipulators=whatfeatures.manipulators - local manipulators=whatmanipulators[properties.mode] + local mode=properties.mode + local manipulators=whatmanipulators[mode] if manipulators then for i=1,#manipulators do local step=manipulators[i] @@ -4452,7 +4484,7 @@ function constructors.applymanipulators(what,tfmdata,features,trace,report) if value then local action=step.action if trace then - report("applying feature manipulator %a for mode %a for font %a",feature,mode,tfmdata.properties.fullname) + report("applying feature manipulator %a for mode %a for font %a",feature,mode,properties.fullname) end if action then action(tfmdata,feature,value) @@ -7527,11 +7559,24 @@ local injections=nodes.injections local nodecodes=nodes.nodecodes local glyph_code=nodecodes.glyph local kern_code=nodecodes.kern -local nodepool=nodes.pool +local nuts=nodes.nuts +local nodepool=nuts.pool local newkern=nodepool.kern -local traverse_id=node.traverse_id -local insert_node_before=node.insert_before -local insert_node_after=node.insert_after +local tonode=nuts.tonode +local tonut=nuts.tonut +local getfield=nuts.getfield +local getnext=nuts.getnext +local getprev=nuts.getprev +local getid=nuts.getid +local getattr=nuts.getattr +local getfont=nuts.getfont +local getsubtype=nuts.getsubtype +local getchar=nuts.getchar +local setfield=nuts.setfield +local setattr=nuts.setattr +local traverse_id=nuts.traverse_id +local insert_node_before=nuts.insert_before +local insert_node_after=nuts.insert_after local a_kernpair=attributes.private('kernpair') local a_ligacomp=attributes.private('ligacomp') local a_markbase=attributes.private('markbase') @@ -7550,21 +7595,21 @@ function injections.setcursive(start,nxt,factor,rlmode,exit,entry,tfmstart,tfmne local dx,dy=factor*(exit[1]-entry[1]),factor*(exit[2]-entry[2]) local ws,wn=tfmstart.width,tfmnext.width local bound=#cursives+1 - start[a_cursbase]=bound - nxt[a_curscurs]=bound + setattr(start,a_cursbase,bound) + setattr(nxt,a_curscurs,bound) cursives[bound]={ rlmode,dx,dy,ws,wn } return dx,dy,bound end function injections.setpair(current,factor,rlmode,r2lflag,spec,tfmchr) local x,y,w,h=factor*spec[1],factor*spec[2],factor*spec[3],factor*spec[4] if x~=0 or w~=0 or y~=0 or h~=0 then - local bound=current[a_kernpair] + local bound=getattr(current,a_kernpair) if bound then local kb=kerns[bound] kb[2],kb[3],kb[4],kb[5]=(kb[2] or 0)+x,(kb[3] or 0)+y,(kb[4] or 0)+w,(kb[5] or 0)+h else bound=#kerns+1 - current[a_kernpair]=bound + setattr(current,a_kernpair,bound) kerns[bound]={ rlmode,x,y,w,h,r2lflag,tfmchr.width } end return x,y,w,h,bound @@ -7575,7 +7620,7 @@ function injections.setkern(current,factor,rlmode,x,tfmchr) local dx=factor*x if dx~=0 then local bound=#kerns+1 - current[a_kernpair]=bound + setattr(current,a_kernpair,bound) kerns[bound]={ rlmode,dx } return dx,bound else @@ -7584,25 +7629,25 @@ function injections.setkern(current,factor,rlmode,x,tfmchr) end function injections.setmark(start,base,factor,rlmode,ba,ma,index) local dx,dy=factor*(ba[1]-ma[1]),factor*(ba[2]-ma[2]) - local bound=base[a_markbase] + local bound=getattr(base,a_markbase) local index=1 if bound then local mb=marks[bound] if mb then index=#mb+1 mb[index]={ dx,dy,rlmode } - start[a_markmark]=bound - start[a_markdone]=index + setattr(start,a_markmark,bound) + setattr(start,a_markdone,index) return dx,dy,bound else - report_injections("possible problem, %U is base mark without data (id %a)",base.char,bound) + report_injections("possible problem, %U is base mark without data (id %a)",getchar(base),bound) end end index=index or 1 bound=#marks+1 - base[a_markbase]=bound - start[a_markmark]=bound - start[a_markdone]=index + setattr(base,a_markbase,bound) + setattr(start,a_markmark,bound) + setattr(start,a_markdone,index) marks[bound]={ [index]={ dx,dy,rlmode } } return dx,dy,bound end @@ -7612,15 +7657,15 @@ end local function trace(head) report_injections("begin run") for n in traverse_id(glyph_code,head) do - if n.subtype<256 then - local kp=n[a_kernpair] - local mb=n[a_markbase] - local mm=n[a_markmark] - local md=n[a_markdone] - local cb=n[a_cursbase] - local cc=n[a_curscurs] - local char=n.char - report_injections("font %s, char %U, glyph %c",n.font,char,char) + if getsubtype(n)<256 then + local kp=getattr(n,a_kernpair) + local mb=getattr(n,a_markbase) + local mm=getattr(n,a_markmark) + local md=getattr(n,a_markdone) + local cb=getattr(n,a_cursbase) + local cc=getattr(n,a_curscurs) + local char=getchar(n) + report_injections("font %s, char %U, glyph %c",getfont(n),char,char) if kp then local k=kerns[kp] if k[3] then @@ -7661,21 +7706,23 @@ local function show_result(head) local current=head local skipping=false while current do - local id=current.id + local id=getid(current) if id==glyph_code then - report_injections("char: %C, width %p, xoffset %p, yoffset %p",current.char,current.width,current.xoffset,current.yoffset) + report_injections("char: %C, width %p, xoffset %p, yoffset %p", + getchar(current),getfield(current,"width"),getfield(current,"xoffset"),getfield(current,"yoffset")) skipping=false elseif id==kern_code then - report_injections("kern: %p",current.kern) + report_injections("kern: %p",getfield(current,"kern")) skipping=false elseif not skipping then report_injections() skipping=true end - current=current.next + current=getnext(current) end end function injections.handler(head,where,keep) + head=tonut(head) local has_marks,has_cursives,has_kerns=next(marks),next(cursives),next(kerns) if has_marks or has_cursives then if trace_injections then @@ -7685,17 +7732,18 @@ function injections.handler(head,where,keep) if has_kerns then local nf,tm=nil,nil for n in traverse_id(glyph_code,head) do - if n.subtype<256 then + if getsubtype(n)<256 then nofvalid=nofvalid+1 valid[nofvalid]=n - if n.font~=nf then - nf=n.font - tm=fontdata[nf].resources.marks + local f=getfont(n) + if f~=nf then + nf=f + tm=fontdata[nf].resources.marks end if tm then - mk[n]=tm[n.char] + mk[n]=tm[getchar(n)] end - local k=n[a_kernpair] + local k=getattr(n,a_kernpair) if k then local kk=kerns[k] if kk then @@ -7715,15 +7763,16 @@ function injections.handler(head,where,keep) else local nf,tm=nil,nil for n in traverse_id(glyph_code,head) do - if n.subtype<256 then + if getsubtype(n)<256 then nofvalid=nofvalid+1 valid[nofvalid]=n - if n.font~=nf then - nf=n.font + local f=getfont(n) + if f~=nf then + nf=f tm=fontdata[nf].resources.marks end if tm then - mk[n]=tm[n.char] + mk[n]=tm[getchar(n)] end end end @@ -7732,7 +7781,7 @@ function injections.handler(head,where,keep) local cx={} if has_kerns and next(ky) then for n,k in next,ky do - n.yoffset=k + setfield(n,"yoffset",k) end end if has_cursives then @@ -7741,9 +7790,9 @@ function injections.handler(head,where,keep) for i=1,nofvalid do local n=valid[i] if not mk[n] then - local n_cursbase=n[a_cursbase] + local n_cursbase=getattr(n,a_cursbase) if p_cursbase then - local n_curscurs=n[a_curscurs] + local n_curscurs=getattr(n,a_curscurs) if p_cursbase==n_curscurs then local c=cursives[n_curscurs] if c then @@ -7766,20 +7815,20 @@ function injections.handler(head,where,keep) end end elseif maxt>0 then - local ny=n.yoffset + local ny=getfield(n,"yoffset") for i=maxt,1,-1 do ny=ny+d[i] local ti=t[i] - ti.yoffset=ti.yoffset+ny + setfield(ti,"yoffset",getfield(ti,"yoffset")+ny) end maxt=0 end if not n_cursbase and maxt>0 then - local ny=n.yoffset + local ny=getfield(n,"yoffset") for i=maxt,1,-1 do ny=ny+d[i] local ti=t[i] - ti.yoffset=ny + setfield(ti,"yoffset",ny) end maxt=0 end @@ -7787,11 +7836,11 @@ function injections.handler(head,where,keep) end end if maxt>0 then - local ny=n.yoffset + local ny=getfield(n,"yoffset") for i=maxt,1,-1 do ny=ny+d[i] local ti=t[i] - ti.yoffset=ny + setfield(ti,"yoffset",ny) end maxt=0 end @@ -7802,46 +7851,52 @@ function injections.handler(head,where,keep) if has_marks then for i=1,nofvalid do local p=valid[i] - local p_markbase=p[a_markbase] + local p_markbase=getattr(p,a_markbase) if p_markbase then local mrks=marks[p_markbase] local nofmarks=#mrks - for n in traverse_id(glyph_code,p.next) do - local n_markmark=n[a_markmark] + for n in traverse_id(glyph_code,getnext(p)) do + local n_markmark=getattr(n,a_markmark) if p_markbase==n_markmark then - local index=n[a_markdone] or 1 + local index=getattr(n,a_markdone) or 1 local d=mrks[index] if d then local rlmode=d[3] local k=wx[p] + local px=getfield(p,"xoffset") + local ox=0 if k then local x=k[2] local w=k[4] if w then if rlmode and rlmode>=0 then - n.xoffset=p.xoffset-p.width+d[1]-(w-x) + ox=px-getfield(p,"width")+d[1]-(w-x) else - n.xoffset=p.xoffset-d[1]-x + ox=px-d[1]-x end else if rlmode and rlmode>=0 then - n.xoffset=p.xoffset-p.width+d[1] + ox=px-getfield(p,"width")+d[1] else - n.xoffset=p.xoffset-d[1]-x + ox=px-d[1]-x end end else if rlmode and rlmode>=0 then - n.xoffset=p.xoffset-p.width+d[1] + ox=px-getfield(p,"width")+d[1] else - n.xoffset=p.xoffset-d[1] + ox=px-d[1] end end + setfield(n,"xoffset",ox) + local py=getfield(p,"yoffset") + local oy=0 if mk[p] then - n.yoffset=p.yoffset+d[2] + oy=py+d[2] else - n.yoffset=n.yoffset+p.yoffset+d[2] + oy=getfield(n,"yoffset")+py+d[2] end + setfield(n,"yoffset",oy) if nofmarks==1 then break else @@ -7899,6 +7954,7 @@ function injections.handler(head,where,keep) if not keep then kerns={} end +head=tonode(head) return head,true elseif not keep then kerns,cursives,marks={},{},{} @@ -7908,14 +7964,14 @@ function injections.handler(head,where,keep) trace(head) end for n in traverse_id(glyph_code,head) do - if n.subtype<256 then - local k=n[a_kernpair] + if getsubtype(n)<256 then + local k=getattr(n,a_kernpair) if k then local kk=kerns[k] if kk then local rl,x,y,w=kk[1],kk[2] or 0,kk[3],kk[4] if y and y~=0 then - n.yoffset=y + setfield(n,"yoffset",y) end if w then local wx=w-x @@ -7946,10 +8002,10 @@ function injections.handler(head,where,keep) if not keep then kerns={} end - return head,true + return tonode(head),true else end - return head,false + return tonode(head),false end end -- closure @@ -7977,6 +8033,7 @@ analyzers.useunicodemarks=false local a_state=attributes.private('state') local nodecodes=nodes.nodecodes local glyph_code=nodecodes.glyph +local disc_code=nodecodes.disc local math_code=nodecodes.math local traverse_id=node.traverse_id local traverse_node_list=node.traverse @@ -8043,7 +8100,7 @@ function analyzers.setstate(head,font) first,last,n=nil,nil,0 end elseif id==disc_code then - current[a_state]=s_midi + current[a_state]=s_medi last=current else if first and first==last then @@ -8095,7 +8152,7 @@ local function analyzeprocessor(head,font,attr) end registerotffeature { name="analyze", - description="analysis of (for instance) character classes", + description="analysis of character classes", default=true, initializers={ node=analyzeinitializer, @@ -8358,12 +8415,25 @@ registertracker("otf.positions","otf.marks,otf.kerns,otf.cursive") registertracker("otf.actions","otf.replacements,otf.positions") registertracker("otf.injections","nodes.injections") registertracker("*otf.sample","otf.steps,otf.actions,otf.analyzing") -local insert_node_after=node.insert_after -local delete_node=nodes.delete -local copy_node=node.copy -local find_node_tail=node.tail or node.slide -local flush_node_list=node.flush_list -local end_of_math=node.end_of_math +local nuts=nodes.nuts +local tonode=nuts.tonode +local tonut=nuts.tonut +local getfield=nuts.getfield +local getnext=nuts.getnext +local getprev=nuts.getprev +local getid=nuts.getid +local getattr=nuts.getattr +local getfont=nuts.getfont +local getsubtype=nuts.getsubtype +local getchar=nuts.getchar +local setfield=nuts.setfield +local setattr=nuts.setattr +local insert_node_after=nuts.insert_after +local delete_node=nuts.delete +local copy_node=nuts.copy +local find_node_tail=nuts.tail +local flush_node_list=nuts.flush_list +local end_of_math=nuts.end_of_math local setmetatableindex=table.setmetatableindex local zwnj=0x200C local zwj=0x200D @@ -8472,83 +8542,83 @@ local function pref(kind,lookupname) return formatters["feature %a, lookup %a"](kind,lookupname) end local function copy_glyph(g) - local components=g.components + local components=getfield(g,"components") if components then - g.components=nil + setfield(g,"components",nil) local n=copy_node(g) - g.components=components + setfield(g,"components",components) return n else return copy_node(g) end end local function markstoligature(kind,lookupname,head,start,stop,char) - if start==stop and start.char==char then + if start==stop and getchar(start)==char then return head,start else - local prev=start.prev - local next=stop.next - start.prev=nil - stop.next=nil + local prev=getprev(start) + local next=getnext(stop) + setfield(start,"prev",nil) + setfield(stop,"next",nil) local base=copy_glyph(start) if head==start then head=base end - base.char=char - base.subtype=ligature_code - base.components=start + setfield(base,"char",char) + setfield(base,"subtype",ligature_code) + setfield(base,"components",start) if prev then - prev.next=base + setfield(prev,"next",base) end if next then - next.prev=base + setfield(next,"prev",base) end - base.next=next - base.prev=prev + setfield(base,"next",next) + setfield(base,"prev",prev) return head,base end end local function getcomponentindex(start) - if start.id~=glyph_code then + if getid(start)~=glyph_code then return 0 - elseif start.subtype==ligature_code then + elseif getsubtype(start)==ligature_code then local i=0 - local components=start.components + local components=getfield(start,"components") while components do i=i+getcomponentindex(components) - components=components.next + components=getnext(components) end return i - elseif not marks[start.char] then + elseif not marks[getchar(start)] then return 1 else return 0 end end local function toligature(kind,lookupname,head,start,stop,char,markflag,discfound) - if start==stop and start.char==char then - start.char=char + if start==stop and getchar(start)==char then + setfield(start,"char",char) return head,start end - local prev=start.prev - local next=stop.next - start.prev=nil - stop.next=nil + local prev=getprev(start) + local next=getnext(stop) + setfield(start,"prev",nil) + setfield(stop,"next",nil) local base=copy_glyph(start) if start==head then head=base end - base.char=char - base.subtype=ligature_code - base.components=start + setfield(base,"char",char) + setfield(base,"subtype",ligature_code) + setfield(base,"components",start) if prev then - prev.next=base + setfield(prev,"next",base) end if next then - next.prev=base + setfield(next,"prev",base) end - base.next=next - base.prev=prev + setfield(base,"next",next) + setfield(base,"prev",prev) if not discfound then local deletemarks=markflag~="mark" local components=start @@ -8557,42 +8627,42 @@ local function toligature(kind,lookupname,head,start,stop,char,markflag,discfoun local head=base local current=base while start do - local char=start.char + local char=getchar(start) if not marks[char] then baseindex=baseindex+componentindex componentindex=getcomponentindex(start) elseif not deletemarks then - start[a_ligacomp]=baseindex+(start[a_ligacomp] or componentindex) + setattr(start,a_ligacomp,baseindex+(getattr(start,a_ligacomp) or componentindex)) if trace_marks then - logwarning("%s: keep mark %s, gets index %s",pref(kind,lookupname),gref(char),start[a_ligacomp]) + logwarning("%s: keep mark %s, gets index %s",pref(kind,lookupname),gref(char),getattr(start,a_ligacomp)) end head,current=insert_node_after(head,current,copy_node(start)) elseif trace_marks then logwarning("%s: delete mark %s",pref(kind,lookupname),gref(char)) end - start=start.next + start=getnext(start) end - local start=current.next - while start and start.id==glyph_code do - local char=start.char + local start=getnext(current) + while start and getid(start)==glyph_code do + local char=getchar(start) if marks[char] then - start[a_ligacomp]=baseindex+(start[a_ligacomp] or componentindex) + setattr(start,a_ligacomp,baseindex+(getattr(start,a_ligacomp) or componentindex)) if trace_marks then - logwarning("%s: set mark %s, gets index %s",pref(kind,lookupname),gref(char),start[a_ligacomp]) + logwarning("%s: set mark %s, gets index %s",pref(kind,lookupname),gref(char),getattr(start,a_ligacomp)) end else break end - start=start.next + start=getnext(start) end end return head,base end function handlers.gsub_single(head,start,kind,lookupname,replacement) if trace_singles then - logprocess("%s: replacing %s by single %s",pref(kind,lookupname),gref(start.char),gref(replacement)) + logprocess("%s: replacing %s by single %s",pref(kind,lookupname),gref(getchar(start)),gref(replacement)) end - start.char=replacement + setfield(start,"char",replacement) return head,start,true end local function get_alternative_glyph(start,alternatives,value,trace_alternatives) @@ -8618,7 +8688,7 @@ local function get_alternative_glyph(start,alternatives,value,trace_alternatives return false,trace_alternatives and formatters["invalid value %a, %s"](value,"out of range") end elseif value==0 then - return start.char,trace_alternatives and formatters["invalid value %a, %s"](value,"no change") + return getchar(start),trace_alternatives and formatters["invalid value %a, %s"](value,"no change") elseif value<1 then return alternatives[1],trace_alternatives and formatters["invalid value %a, taking %a"](value,1) else @@ -8629,25 +8699,25 @@ end local function multiple_glyphs(head,start,multiple) local nofmultiples=#multiple if nofmultiples>0 then - start.char=multiple[1] + setfield(start,"char",multiple[1]) if nofmultiples>1 then - local sn=start.next + local sn=getnext(start) for k=2,nofmultiples do local n=copy_node(start) - n.char=multiple[k] - n.next=sn - n.prev=start + setfield(n,"char",multiple[k]) + setfield(n,"next",sn) + setfield(n,"prev",start) if sn then - sn.prev=n + setfield(sn,"prev",n) end - start.next=n + setfield(start,"next",n) start=n end end return head,start,true else if trace_multiples then - logprocess("no multiple for %s",gref(start.char)) + logprocess("no multiple for %s",gref(getchar(start))) end return head,start,false end @@ -8657,34 +8727,34 @@ function handlers.gsub_alternate(head,start,kind,lookupname,alternative,sequence local choice,comment=get_alternative_glyph(start,alternative,value,trace_alternatives) if choice then if trace_alternatives then - logprocess("%s: replacing %s by alternative %a to %s, %s",pref(kind,lookupname),gref(start.char),choice,gref(choice),comment) + logprocess("%s: replacing %s by alternative %a to %s, %s",pref(kind,lookupname),gref(getchar(start)),choice,gref(choice),comment) end - start.char=choice + setfield(start,"char",choice) else if trace_alternatives then - logwarning("%s: no variant %a for %s, %s",pref(kind,lookupname),value,gref(start.char),comment) + logwarning("%s: no variant %a for %s, %s",pref(kind,lookupname),value,gref(getchar(start)),comment) end end return head,start,true end function handlers.gsub_multiple(head,start,kind,lookupname,multiple) if trace_multiples then - logprocess("%s: replacing %s by multiple %s",pref(kind,lookupname),gref(start.char),gref(multiple)) + logprocess("%s: replacing %s by multiple %s",pref(kind,lookupname),gref(getchar(start)),gref(multiple)) end return multiple_glyphs(head,start,multiple) end function handlers.gsub_ligature(head,start,kind,lookupname,ligature,sequence) - local s,stop,discfound=start.next,nil,false - local startchar=start.char + local s,stop,discfound=getnext(start),nil,false + local startchar=getchar(start) if marks[startchar] then while s do - local id=s.id - if id==glyph_code and s.font==currentfont and s.subtype<256 then - local lg=ligature[s.char] + local id=getid(s) + if id==glyph_code and getfont(s)==currentfont and getsubtype(s)<256 then + local lg=ligature[getchar(s)] if lg then stop=s ligature=lg - s=s.next + s=getnext(s) else break end @@ -8696,9 +8766,9 @@ function handlers.gsub_ligature(head,start,kind,lookupname,ligature,sequence) local lig=ligature.ligature if lig then if trace_ligatures then - local stopchar=stop.char + local stopchar=getchar(stop) head,start=markstoligature(kind,lookupname,head,start,stop,lig) - logprocess("%s: replacing %s upto %s by ligature %s case 1",pref(kind,lookupname),gref(startchar),gref(stopchar),gref(start.char)) + logprocess("%s: replacing %s upto %s by ligature %s case 1",pref(kind,lookupname),gref(startchar),gref(stopchar),gref(getchar(start))) else head,start=markstoligature(kind,lookupname,head,start,stop,lig) end @@ -8709,18 +8779,18 @@ function handlers.gsub_ligature(head,start,kind,lookupname,ligature,sequence) else local skipmark=sequence.flags[1] while s do - local id=s.id - if id==glyph_code and s.subtype<256 then - if s.font==currentfont then - local char=s.char + local id=getid(s) + if id==glyph_code and getsubtype(s)<256 then + if getfont(s)==currentfont then + local char=getchar(s) if skipmark and marks[char] then - s=s.next + s=getnext(s) else local lg=ligature[char] if lg then stop=s ligature=lg - s=s.next + s=getnext(s) else break end @@ -8730,7 +8800,7 @@ function handlers.gsub_ligature(head,start,kind,lookupname,ligature,sequence) end elseif id==disc_code then discfound=true - s=s.next + s=getnext(s) else break end @@ -8739,9 +8809,9 @@ function handlers.gsub_ligature(head,start,kind,lookupname,ligature,sequence) local lig=ligature.ligature if lig then if trace_ligatures then - local stopchar=stop.char + local stopchar=getchar(stop) head,start=toligature(kind,lookupname,head,start,stop,lig,skipmark,discfound) - logprocess("%s: replacing %s upto %s by ligature %s case 2",pref(kind,lookupname),gref(startchar),gref(stopchar),gref(start.char)) + logprocess("%s: replacing %s upto %s by ligature %s case 2",pref(kind,lookupname),gref(startchar),gref(stopchar),gref(getchar(start))) else head,start=toligature(kind,lookupname,head,start,stop,lig,skipmark,discfound) end @@ -8753,16 +8823,16 @@ function handlers.gsub_ligature(head,start,kind,lookupname,ligature,sequence) return head,start,false end function handlers.gpos_mark2base(head,start,kind,lookupname,markanchors,sequence) - local markchar=start.char + local markchar=getchar(start) if marks[markchar] then - local base=start.prev - if base and base.id==glyph_code and base.font==currentfont and base.subtype<256 then - local basechar=base.char + local base=getprev(start) + if base and getid(base)==glyph_code and getfont(base)==currentfont and getsubtype(base)<256 then + local basechar=getchar(base) if marks[basechar] then while true do - base=base.prev - if base and base.id==glyph_code and base.font==currentfont and base.subtype<256 then - basechar=base.char + base=getprev(base) + if base and getid(base)==glyph_code and getfont(base)==currentfont and getsubtype(base)<256 then + basechar=getchar(base) if not marks[basechar] then break end @@ -8811,16 +8881,16 @@ function handlers.gpos_mark2base(head,start,kind,lookupname,markanchors,sequence return head,start,false end function handlers.gpos_mark2ligature(head,start,kind,lookupname,markanchors,sequence) - local markchar=start.char + local markchar=getchar(start) if marks[markchar] then - local base=start.prev - if base and base.id==glyph_code and base.font==currentfont and base.subtype<256 then - local basechar=base.char + local base=getprev(start) + if base and getid(base)==glyph_code and getfont(base)==currentfont and getsubtype(base)<256 then + local basechar=getchar(base) if marks[basechar] then while true do - base=base.prev - if base and base.id==glyph_code and base.font==currentfont and base.subtype<256 then - basechar=base.char + base=getprev(base) + if base and getid(base)==glyph_code and getfont(base)==currentfont and getsubtype(base)<256 then + basechar=getchar(base) if not marks[basechar] then break end @@ -8832,7 +8902,7 @@ function handlers.gpos_mark2ligature(head,start,kind,lookupname,markanchors,sequ end end end - local index=start[a_ligacomp] + local index=getattr(start,a_ligacomp) local baseanchors=descriptions[basechar] if baseanchors then baseanchors=baseanchors.anchors @@ -8877,22 +8947,22 @@ function handlers.gpos_mark2ligature(head,start,kind,lookupname,markanchors,sequ return head,start,false end function handlers.gpos_mark2mark(head,start,kind,lookupname,markanchors,sequence) - local markchar=start.char + local markchar=getchar(start) if marks[markchar] then - local base=start.prev - local slc=start[a_ligacomp] + local base=getprev(start) + local slc=getattr(start,a_ligacomp) if slc then while base do - local blc=base[a_ligacomp] + local blc=getattr(base,a_ligacomp) if blc and blc~=slc then - base=base.prev + base=getprev(base) else break end end end - if base and base.id==glyph_code and base.font==currentfont and base.subtype<256 then - local basechar=base.char + if base and getid(base)==glyph_code and getfont(base)==currentfont and getsubtype(base)<256 then + local basechar=getchar(base) local baseanchors=descriptions[basechar] if baseanchors then baseanchors=baseanchors.anchors @@ -8930,20 +9000,20 @@ function handlers.gpos_mark2mark(head,start,kind,lookupname,markanchors,sequence return head,start,false end function handlers.gpos_cursive(head,start,kind,lookupname,exitanchors,sequence) - local alreadydone=cursonce and start[a_cursbase] + local alreadydone=cursonce and getattr(start,a_cursbase) if not alreadydone then local done=false - local startchar=start.char + local startchar=getchar(start) if marks[startchar] then if trace_cursive then logprocess("%s: ignoring cursive for mark %s",pref(kind,lookupname),gref(startchar)) end else - local nxt=start.next - while not done and nxt and nxt.id==glyph_code and nxt.font==currentfont and nxt.subtype<256 do - local nextchar=nxt.char + local nxt=getnext(start) + while not done and nxt and getid(nxt)==glyph_code and getfont(nxt)==currentfont and getsubtype(nxt)<256 do + local nextchar=getchar(nxt) if marks[nextchar] then - nxt=nxt.next + nxt=getnext(nxt) else local entryanchors=descriptions[nextchar] if entryanchors then @@ -8977,13 +9047,13 @@ function handlers.gpos_cursive(head,start,kind,lookupname,exitanchors,sequence) return head,start,done else if trace_cursive and trace_details then - logprocess("%s, cursive %s is already done",pref(kind,lookupname),gref(start.char),alreadydone) + logprocess("%s, cursive %s is already done",pref(kind,lookupname),gref(getchar(start)),alreadydone) end return head,start,false end end function handlers.gpos_single(head,start,kind,lookupname,kerns,sequence) - local startchar=start.char + local startchar=getchar(start) local dx,dy,w,h=setpair(start,tfmdata.parameters.factor,rlmode,sequence.flags[4],kerns,characters[startchar]) if trace_kerns then logprocess("%s: shifting single %s by (%p,%p) and correction (%p,%p)",pref(kind,lookupname),gref(startchar),dx,dy,w,h) @@ -8991,19 +9061,19 @@ function handlers.gpos_single(head,start,kind,lookupname,kerns,sequence) return head,start,false end function handlers.gpos_pair(head,start,kind,lookupname,kerns,sequence) - local snext=start.next + local snext=getnext(start) if not snext then return head,start,false else local prev,done=start,false local factor=tfmdata.parameters.factor local lookuptype=lookuptypes[lookupname] - while snext and snext.id==glyph_code and snext.font==currentfont and snext.subtype<256 do - local nextchar=snext.char + while snext and getid(snext)==glyph_code and getfont(snext)==currentfont and getsubtype(snext)<256 do + local nextchar=getchar(snext) local krn=kerns[nextchar] if not krn and marks[nextchar] then prev=snext - snext=snext.next + snext=getnext(snext) else local krn=kerns[nextchar] if not krn then @@ -9011,14 +9081,14 @@ function handlers.gpos_pair(head,start,kind,lookupname,kerns,sequence) if lookuptype=="pair" then local a,b=krn[2],krn[3] if a and #a>0 then - local startchar=start.char + local startchar=getchar(start) local x,y,w,h=setpair(start,factor,rlmode,sequence.flags[4],a,characters[startchar]) if trace_kerns then logprocess("%s: shifting first of pair %s and %s by (%p,%p) and correction (%p,%p)",pref(kind,lookupname),gref(startchar),gref(nextchar),x,y,w,h) end end if b and #b>0 then - local startchar=start.char + local startchar=getchar(start) local x,y,w,h=setpair(snext,factor,rlmode,sequence.flags[4],b,characters[nextchar]) if trace_kerns then logprocess("%s: shifting second of pair %s and %s by (%p,%p) and correction (%p,%p)",pref(kind,lookupname),gref(startchar),gref(nextchar),x,y,w,h) @@ -9031,7 +9101,7 @@ function handlers.gpos_pair(head,start,kind,lookupname,kerns,sequence) elseif krn~=0 then local k=setkern(snext,factor,rlmode,krn) if trace_kerns then - logprocess("%s: inserting kern %s between %s and %s",pref(kind,lookupname),k,gref(prev.char),gref(nextchar)) + logprocess("%s: inserting kern %s between %s and %s",pref(kind,lookupname),k,gref(getchar(prev)),gref(nextchar)) end done=true end @@ -9066,13 +9136,13 @@ function chainmores.chainsub(head,start,stop,kind,chainname,currentcontext,looku return head,start,false end function chainprocs.reversesub(head,start,stop,kind,chainname,currentcontext,lookuphash,replacements) - local char=start.char + local char=getchar(start) local replacement=replacements[char] if replacement then if trace_singles then logprocess("%s: single reverse replacement of %s by %s",cref(kind,chainname),gref(char),gref(replacement)) end - start.char=replacement + setfield(start,"char",replacement) return head,start,true else return head,start,false @@ -9083,9 +9153,9 @@ local function delete_till_stop(start,stop,ignoremarks) if start==stop then elseif ignoremarks then repeat - local next=start.next - if not marks[next.char] then - local components=next.components + local next=getnext(start) + if not marks[getchar(next)] then + local components=getfield(next,"components") if components then flush_node_list(components) end @@ -9095,8 +9165,8 @@ local function delete_till_stop(start,stop,ignoremarks) until next==stop else repeat - local next=start.next - local components=next.components + local next=getnext(start) + local components=getfield(next,"components") if components then flush_node_list(components) end @@ -9113,8 +9183,8 @@ function chainprocs.gsub_single(head,start,stop,kind,chainname,currentcontext,lo logwarning("todo: check if we need to loop over the replacements: %s",concat(subtables," ")) end while current do - if current.id==glyph_code then - local currentchar=current.char + if getid(current)==glyph_code then + local currentchar=getchar(current) local lookupname=subtables[1] local replacement=lookuphash[lookupname] if not replacement then @@ -9131,14 +9201,14 @@ function chainprocs.gsub_single(head,start,stop,kind,chainname,currentcontext,lo if trace_singles then logprocess("%s: replacing single %s by %s",cref(kind,chainname,chainlookupname,lookupname,chainindex),gref(currentchar),gref(replacement)) end - current.char=replacement + setfield(current,"char",replacement) end end return head,start,true elseif current==stop then break else - current=current.next + current=getnext(current) end end return head,start,false @@ -9146,7 +9216,7 @@ end chainmores.gsub_single=chainprocs.gsub_single function chainprocs.gsub_multiple(head,start,stop,kind,chainname,currentcontext,lookuphash,currentlookup,chainlookupname) delete_till_stop(start,stop) - local startchar=start.char + local startchar=getchar(start) local subtables=currentlookup.subtables local lookupname=subtables[1] local replacements=lookuphash[lookupname] @@ -9175,8 +9245,8 @@ function chainprocs.gsub_alternate(head,start,stop,kind,chainname,currentcontext local subtables=currentlookup.subtables local value=featurevalue==true and tfmdata.shared.features[kind] or featurevalue while current do - if current.id==glyph_code then - local currentchar=current.char + if getid(current)==glyph_code then + local currentchar=getchar(current) local lookupname=subtables[1] local alternatives=lookuphash[lookupname] if not alternatives then @@ -9191,7 +9261,7 @@ function chainprocs.gsub_alternate(head,start,stop,kind,chainname,currentcontext if trace_alternatives then logprocess("%s: replacing %s by alternative %a to %s, %s",cref(kind,chainname,chainlookupname,lookupname),gref(char),choice,gref(choice),comment) end - start.char=choice + setfield(start,"char",choice) else if trace_alternatives then logwarning("%s: no variant %a for %s, %s",cref(kind,chainname,chainlookupname,lookupname),value,gref(char),comment) @@ -9205,14 +9275,14 @@ function chainprocs.gsub_alternate(head,start,stop,kind,chainname,currentcontext elseif current==stop then break else - current=current.next + current=getnext(current) end end return head,start,false end chainmores.gsub_alternate=chainprocs.gsub_alternate function chainprocs.gsub_ligature(head,start,stop,kind,chainname,currentcontext,lookuphash,currentlookup,chainlookupname,chainindex) - local startchar=start.char + local startchar=getchar(start) local subtables=currentlookup.subtables local lookupname=subtables[1] local ligatures=lookuphash[lookupname] @@ -9227,20 +9297,20 @@ function chainprocs.gsub_ligature(head,start,stop,kind,chainname,currentcontext, logwarning("%s: no ligatures starting with %s",cref(kind,chainname,chainlookupname,lookupname,chainindex),gref(startchar)) end else - local s=start.next + local s=getnext(start) local discfound=false local last=stop local nofreplacements=0 local skipmark=currentlookup.flags[1] while s do - local id=s.id + local id=getid(s) if id==disc_code then - s=s.next + s=getnext(s) discfound=true else - local schar=s.char + local schar=getchar(s) if skipmark and marks[schar] then - s=s.next + s=getnext(s) else local lg=ligatures[schar] if lg then @@ -9248,7 +9318,7 @@ function chainprocs.gsub_ligature(head,start,stop,kind,chainname,currentcontext, if s==stop then break else - s=s.next + s=getnext(s) end else break @@ -9265,7 +9335,7 @@ function chainprocs.gsub_ligature(head,start,stop,kind,chainname,currentcontext, if start==stop then logprocess("%s: replacing character %s by ligature %s case 3",cref(kind,chainname,chainlookupname,lookupname,chainindex),gref(startchar),gref(l2)) else - logprocess("%s: replacing character %s upto %s by ligature %s case 4",cref(kind,chainname,chainlookupname,lookupname,chainindex),gref(startchar),gref(stop.char),gref(l2)) + logprocess("%s: replacing character %s upto %s by ligature %s case 4",cref(kind,chainname,chainlookupname,lookupname,chainindex),gref(startchar),gref(getchar(stop)),gref(l2)) end end head,start=toligature(kind,lookupname,head,start,stop,l2,currentlookup.flags[1],discfound) @@ -9274,7 +9344,7 @@ function chainprocs.gsub_ligature(head,start,stop,kind,chainname,currentcontext, if start==stop then logwarning("%s: replacing character %s by ligature fails",cref(kind,chainname,chainlookupname,lookupname,chainindex),gref(startchar)) else - logwarning("%s: replacing character %s upto %s by ligature fails",cref(kind,chainname,chainlookupname,lookupname,chainindex),gref(startchar),gref(stop.char)) + logwarning("%s: replacing character %s upto %s by ligature fails",cref(kind,chainname,chainlookupname,lookupname,chainindex),gref(startchar),gref(getchar(stop))) end end end @@ -9283,7 +9353,7 @@ function chainprocs.gsub_ligature(head,start,stop,kind,chainname,currentcontext, end chainmores.gsub_ligature=chainprocs.gsub_ligature function chainprocs.gpos_mark2base(head,start,stop,kind,chainname,currentcontext,lookuphash,currentlookup,chainlookupname) - local markchar=start.char + local markchar=getchar(start) if marks[markchar] then local subtables=currentlookup.subtables local lookupname=subtables[1] @@ -9292,14 +9362,14 @@ function chainprocs.gpos_mark2base(head,start,stop,kind,chainname,currentcontext markanchors=markanchors[markchar] end if markanchors then - local base=start.prev - if base and base.id==glyph_code and base.font==currentfont and base.subtype<256 then - local basechar=base.char + local base=getprev(start) + if base and getid(base)==glyph_code and getfont(base)==currentfont and getsubtype(base)<256 then + local basechar=getchar(base) if marks[basechar] then while true do - base=base.prev - if base and base.id==glyph_code and base.font==currentfont and base.subtype<256 then - basechar=base.char + base=getprev(base) + if base and getid(base)==glyph_code and getfont(base)==currentfont and getsubtype(base)<256 then + basechar=getchar(base) if not marks[basechar] then break end @@ -9346,7 +9416,7 @@ function chainprocs.gpos_mark2base(head,start,stop,kind,chainname,currentcontext return head,start,false end function chainprocs.gpos_mark2ligature(head,start,stop,kind,chainname,currentcontext,lookuphash,currentlookup,chainlookupname) - local markchar=start.char + local markchar=getchar(start) if marks[markchar] then local subtables=currentlookup.subtables local lookupname=subtables[1] @@ -9355,14 +9425,14 @@ function chainprocs.gpos_mark2ligature(head,start,stop,kind,chainname,currentcon markanchors=markanchors[markchar] end if markanchors then - local base=start.prev - if base and base.id==glyph_code and base.font==currentfont and base.subtype<256 then - local basechar=base.char + local base=getprev(start) + if base and getid(base)==glyph_code and getfont(base)==currentfont and getsubtype(base)<256 then + local basechar=getchar(base) if marks[basechar] then while true do - base=base.prev - if base and base.id==glyph_code and base.font==currentfont and base.subtype<256 then - basechar=base.char + base=getprev(base) + if base and getid(base)==glyph_code and getfont(base)==currentfont and getsubtype(base)<256 then + basechar=getchar(base) if not marks[basechar] then break end @@ -9374,7 +9444,7 @@ function chainprocs.gpos_mark2ligature(head,start,stop,kind,chainname,currentcon end end end - local index=start[a_ligacomp] + local index=getattr(start,a_ligacomp) local baseanchors=descriptions[basechar].anchors if baseanchors then local baseanchors=baseanchors['baselig'] @@ -9413,7 +9483,7 @@ function chainprocs.gpos_mark2ligature(head,start,stop,kind,chainname,currentcon return head,start,false end function chainprocs.gpos_mark2mark(head,start,stop,kind,chainname,currentcontext,lookuphash,currentlookup,chainlookupname) - local markchar=start.char + local markchar=getchar(start) if marks[markchar] then local subtables=currentlookup.subtables local lookupname=subtables[1] @@ -9422,20 +9492,20 @@ function chainprocs.gpos_mark2mark(head,start,stop,kind,chainname,currentcontext markanchors=markanchors[markchar] end if markanchors then - local base=start.prev - local slc=start[a_ligacomp] + local base=getprev(start) + local slc=getattr(start,a_ligacomp) if slc then while base do - local blc=base[a_ligacomp] + local blc=getattr(base,a_ligacomp) if blc and blc~=slc then - base=base.prev + base=getprev(base) else break end end end - if base and base.id==glyph_code and base.font==currentfont and base.subtype<256 then - local basechar=base.char + if base and getid(base)==glyph_code and getfont(base)==currentfont and getsubtype(base)<256 then + local basechar=getchar(base) local baseanchors=descriptions[basechar].anchors if baseanchors then baseanchors=baseanchors['basemark'] @@ -9471,9 +9541,9 @@ function chainprocs.gpos_mark2mark(head,start,stop,kind,chainname,currentcontext return head,start,false end function chainprocs.gpos_cursive(head,start,stop,kind,chainname,currentcontext,lookuphash,currentlookup,chainlookupname) - local alreadydone=cursonce and start[a_cursbase] + local alreadydone=cursonce and getattr(start,a_cursbase) if not alreadydone then - local startchar=start.char + local startchar=getchar(start) local subtables=currentlookup.subtables local lookupname=subtables[1] local exitanchors=lookuphash[lookupname] @@ -9487,11 +9557,11 @@ function chainprocs.gpos_cursive(head,start,stop,kind,chainname,currentcontext,l logprocess("%s: ignoring cursive for mark %s",pref(kind,lookupname),gref(startchar)) end else - local nxt=start.next - while not done and nxt and nxt.id==glyph_code and nxt.font==currentfont and nxt.subtype<256 do - local nextchar=nxt.char + local nxt=getnext(start) + while not done and nxt and getid(nxt)==glyph_code and getfont(nxt)==currentfont and getsubtype(nxt)<256 do + local nextchar=getchar(nxt) if marks[nextchar] then - nxt=nxt.next + nxt=getnext(nxt) else local entryanchors=descriptions[nextchar] if entryanchors then @@ -9525,7 +9595,7 @@ function chainprocs.gpos_cursive(head,start,stop,kind,chainname,currentcontext,l return head,start,done else if trace_cursive and trace_details then - logprocess("%s, cursive %s is already done",pref(kind,lookupname),gref(start.char),alreadydone) + logprocess("%s, cursive %s is already done",pref(kind,lookupname),gref(getchar(start)),alreadydone) end return head,start,false end @@ -9533,7 +9603,7 @@ function chainprocs.gpos_cursive(head,start,stop,kind,chainname,currentcontext,l return head,start,false end function chainprocs.gpos_single(head,start,stop,kind,chainname,currentcontext,lookuphash,currentlookup,chainlookupname,chainindex,sequence) - local startchar=start.char + local startchar=getchar(start) local subtables=currentlookup.subtables local lookupname=subtables[1] local kerns=lookuphash[lookupname] @@ -9549,9 +9619,9 @@ function chainprocs.gpos_single(head,start,stop,kind,chainname,currentcontext,lo return head,start,false end function chainprocs.gpos_pair(head,start,stop,kind,chainname,currentcontext,lookuphash,currentlookup,chainlookupname,chainindex,sequence) - local snext=start.next + local snext=getnext(start) if snext then - local startchar=start.char + local startchar=getchar(start) local subtables=currentlookup.subtables local lookupname=subtables[1] local kerns=lookuphash[lookupname] @@ -9561,26 +9631,26 @@ function chainprocs.gpos_pair(head,start,stop,kind,chainname,currentcontext,look local lookuptype=lookuptypes[lookupname] local prev,done=start,false local factor=tfmdata.parameters.factor - while snext and snext.id==glyph_code and snext.font==currentfont and snext.subtype<256 do - local nextchar=snext.char + while snext and getid(snext)==glyph_code and getfont(snext)==currentfont and getsubtype(snext)<256 do + local nextchar=getchar(snext) local krn=kerns[nextchar] if not krn and marks[nextchar] then prev=snext - snext=snext.next + snext=getnext(snext) else if not krn then elseif type(krn)=="table" then if lookuptype=="pair" then local a,b=krn[2],krn[3] if a and #a>0 then - local startchar=start.char + local startchar=getchar(start) local x,y,w,h=setpair(start,factor,rlmode,sequence.flags[4],a,characters[startchar]) if trace_kerns then logprocess("%s: shifting first of pair %s and %s by (%p,%p) and correction (%p,%p)",cref(kind,chainname,chainlookupname),gref(startchar),gref(nextchar),x,y,w,h) end end if b and #b>0 then - local startchar=start.char + local startchar=getchar(start) local x,y,w,h=setpair(snext,factor,rlmode,sequence.flags[4],b,characters[nextchar]) if trace_kerns then logprocess("%s: shifting second of pair %s and %s by (%p,%p) and correction (%p,%p)",cref(kind,chainname,chainlookupname),gref(startchar),gref(nextchar),x,y,w,h) @@ -9592,7 +9662,7 @@ function chainprocs.gpos_pair(head,start,stop,kind,chainname,currentcontext,look if a and a~=0 then local k=setkern(snext,factor,rlmode,a) if trace_kerns then - logprocess("%s: inserting first kern %s between %s and %s",cref(kind,chainname,chainlookupname),k,gref(prev.char),gref(nextchar)) + logprocess("%s: inserting first kern %s between %s and %s",cref(kind,chainname,chainlookupname),k,gref(getchar(prev)),gref(nextchar)) end end if b and b~=0 then @@ -9603,7 +9673,7 @@ function chainprocs.gpos_pair(head,start,stop,kind,chainname,currentcontext,look elseif krn~=0 then local k=setkern(snext,factor,rlmode,krn) if trace_kerns then - logprocess("%s: inserting kern %s between %s and %s",cref(kind,chainname,chainlookupname),k,gref(prev.char),gref(nextchar)) + logprocess("%s: inserting kern %s between %s and %s",cref(kind,chainname,chainlookupname),k,gref(getchar(prev)),gref(nextchar)) end done=true end @@ -9640,7 +9710,7 @@ local function normal_handle_contextchain(head,start,kind,chainname,contexts,seq local seq=ck[3] local s=#seq if s==1 then - match=current.id==glyph_code and current.font==currentfont and current.subtype<256 and seq[1][current.char] + match=getid(current)==glyph_code and getfont(current)==currentfont and getsubtype(current)<256 and seq[1][getchar(current)] else local f,l=ck[4],ck[5] if f==1 and f==l then @@ -9648,13 +9718,13 @@ local function normal_handle_contextchain(head,start,kind,chainname,contexts,seq if f==l then else local n=f+1 - last=last.next + last=getnext(last) while n<=l do if last then - local id=last.id + local id=getid(last) if id==glyph_code then - if last.font==currentfont and last.subtype<256 then - local char=last.char + if getfont(last)==currentfont and getsubtype(last)<256 then + local char=getchar(last) local ccd=descriptions[char] if ccd then local class=ccd.class @@ -9663,10 +9733,10 @@ local function normal_handle_contextchain(head,start,kind,chainname,contexts,seq if trace_skips then show_skip(kind,chainname,char,ck,class) end - last=last.next + last=getnext(last) elseif seq[n][char] then if n1 then - local prev=start.prev + local prev=getprev(start) if prev then local n=f-1 while n>=1 do if prev then - local id=prev.id + local id=getid(prev) if id==glyph_code then - if prev.font==currentfont and prev.subtype<256 then - local char=prev.char + if getfont(prev)==currentfont and getsubtype(prev)<256 then + local char=getchar(prev) local ccd=descriptions[char] if ccd then local class=ccd.class @@ -9733,7 +9803,7 @@ local function normal_handle_contextchain(head,start,kind,chainname,contexts,seq match=false break end - prev=prev.prev + prev=getprev(prev) elseif seq[n][32] then n=n -1 else @@ -9753,15 +9823,15 @@ local function normal_handle_contextchain(head,start,kind,chainname,contexts,seq end end if match and s>l then - local current=last and last.next + local current=last and getnext(last) if current then local n=l+1 while n<=s do if current then - local id=current.id + local id=getid(current) if id==glyph_code then - if current.font==currentfont and current.subtype<256 then - local char=current.char + if getfont(current)==currentfont and getsubtype(current)<256 then + local char=getchar(current) local ccd=descriptions[char] if ccd then local class=ccd.class @@ -9791,7 +9861,7 @@ local function normal_handle_contextchain(head,start,kind,chainname,contexts,seq match=false break end - current=current.next + current=getnext(current) elseif seq[n][32] then n=n+1 else @@ -9814,7 +9884,7 @@ local function normal_handle_contextchain(head,start,kind,chainname,contexts,seq if match then if trace_contexts then local rule,lookuptype,f,l=ck[1],ck[2],ck[4],ck[5] - local char=start.char + local char=getchar(start) if ck[9] then logwarning("%s: rule %s matches at char %s for (%s,%s,%s) chars, lookuptype %a, %a => %a", cref(kind,chainname),rule,gref(char),f-1,l-f+1,s-l,lookuptype,ck[9],ck[10]) @@ -9844,12 +9914,12 @@ local function normal_handle_contextchain(head,start,kind,chainname,contexts,seq repeat if skipped then while true do - local char=start.char + local char=getchar(start) local ccd=descriptions[char] if ccd then local class=ccd.class if class==skipmark or class==skipligature or class==skipbase or (markclass and class=="mark" and not markclass[char]) then - start=start.next + start=getnext(start) else break end @@ -9874,7 +9944,7 @@ local function normal_handle_contextchain(head,start,kind,chainname,contexts,seq i=i+1 end if start then - start=start.next + start=getnext(start) else end until i>nofchainlookups @@ -10001,6 +10071,7 @@ local function featuresprocessor(head,font,attr) if not lookuphash then return head,false end + head=tonut(head) if trace_steps then checkstep(head) end @@ -10033,10 +10104,10 @@ local function featuresprocessor(head,font,attr) local handler=handlers[typ] local start=find_node_tail(head) while start do - local id=start.id + local id=getid(start) if id==glyph_code then - if start.font==font and start.subtype<256 then - local a=start[0] + if getfont(start)==font and getsubtype(start)<256 then + local a=getattr(start,0) if a then a=a==attr else @@ -10047,7 +10118,7 @@ local function featuresprocessor(head,font,attr) local lookupname=subtables[i] local lookupcache=lookuphash[lookupname] if lookupcache then - local lookupmatch=lookupcache[start.char] + local lookupmatch=lookupcache[getchar(start)] if lookupmatch then head,start,success=handler(head,start,dataset[4],lookupname,lookupmatch,sequence,lookuphash,i) if success then @@ -10058,15 +10129,15 @@ local function featuresprocessor(head,font,attr) report_missing_cache(typ,lookupname) end end - if start then start=start.prev end + if start then start=getprev(start) end else - start=start.prev + start=getprev(start) end else - start=start.prev + start=getprev(start) end else - start=start.prev + start=getprev(start) end end else @@ -10081,17 +10152,17 @@ local function featuresprocessor(head,font,attr) report_missing_cache(typ,lookupname) else while start do - local id=start.id + local id=getid(start) if id==glyph_code then - if start.font==font and start.subtype<256 then - local a=start[0] + if getfont(start)==font and getsubtype(start)<256 then + local a=getattr(start,0) if a then - a=(a==attr) and (not attribute or start[a_state]==attribute) + a=(a==attr) and (not attribute or getattr(start,a_state)==attribute) else - a=not attribute or start[a_state]==attribute + a=not attribute or getattr(start,a_state)==attribute end if a then - local lookupmatch=lookupcache[start.char] + local lookupmatch=lookupcache[getchar(start)] if lookupmatch then local ok head,start,ok=handler(head,start,dataset[4],lookupname,lookupmatch,sequence,lookuphash,1) @@ -10099,17 +10170,17 @@ local function featuresprocessor(head,font,attr) success=true end end - if start then start=start.next end + if start then start=getnext(start) end else - start=start.next + start=getnext(start) end else - start=start.next + start=getnext(start) end elseif id==whatsit_code then - local subtype=start.subtype + local subtype=getsubtype(start) if subtype==dir_code then - local dir=start.dir + local dir=getfield(start,"dir") if dir=="+TRT" or dir=="+TLT" then topstack=topstack+1 dirstack[topstack]=dir @@ -10128,7 +10199,7 @@ local function featuresprocessor(head,font,attr) report_process("directions after txtdir %a: parmode %a, txtmode %a, # stack %a, new dir %a",dir,rlparmode,rlmode,topstack,newdir) end elseif subtype==localpar_code then - local dir=start.dir + local dir=getfield(start,"dir") if dir=="TRT" then rlparmode=-1 elseif dir=="TLT" then @@ -10141,31 +10212,31 @@ local function featuresprocessor(head,font,attr) report_process("directions after pardir %a: parmode %a, txtmode %a",dir,rlparmode,rlmode) end end - start=start.next + start=getnext(start) elseif id==math_code then - start=end_of_math(start).next + start=getnext(end_of_math(start)) else - start=start.next + start=getnext(start) end end end else while start do - local id=start.id + local id=getid(start) if id==glyph_code then - if start.font==font and start.subtype<256 then - local a=start[0] + if getfont(start)==font and getsubtype(start)<256 then + local a=getattr(start,0) if a then - a=(a==attr) and (not attribute or start[a_state]==attribute) + a=(a==attr) and (not attribute or getattr(start,a_state)==attribute) else - a=not attribute or start[a_state]==attribute + a=not attribute or getattr(start,a_state)==attribute end if a then for i=1,ns do local lookupname=subtables[i] local lookupcache=lookuphash[lookupname] if lookupcache then - local lookupmatch=lookupcache[start.char] + local lookupmatch=lookupcache[getchar(start)] if lookupmatch then local ok head,start,ok=handler(head,start,dataset[4],lookupname,lookupmatch,sequence,lookuphash,i) @@ -10180,17 +10251,17 @@ local function featuresprocessor(head,font,attr) report_missing_cache(typ,lookupname) end end - if start then start=start.next end + if start then start=getnext(start) end else - start=start.next + start=getnext(start) end else - start=start.next + start=getnext(start) end elseif id==whatsit_code then - local subtype=start.subtype + local subtype=getsubtype(start) if subtype==dir_code then - local dir=start.dir + local dir=getfield(start,"dir") if dir=="+TRT" or dir=="+TLT" then topstack=topstack+1 dirstack[topstack]=dir @@ -10209,7 +10280,7 @@ local function featuresprocessor(head,font,attr) report_process("directions after txtdir %a: parmode %a, txtmode %a, # stack %a, new dir %a",dir,rlparmode,rlmode,topstack,newdir) end elseif subtype==localpar_code then - local dir=start.dir + local dir=getfield(start,"dir") if dir=="TRT" then rlparmode=-1 elseif dir=="TLT" then @@ -10222,11 +10293,11 @@ local function featuresprocessor(head,font,attr) report_process("directions after pardir %a: parmode %a, txtmode %a",dir,rlparmode,rlmode) end end - start=start.next + start=getnext(start) elseif id==math_code then - start=end_of_math(start).next + start=getnext(end_of_math(start)) else - start=start.next + start=getnext(start) end end end @@ -10238,6 +10309,7 @@ local function featuresprocessor(head,font,attr) registerstep(head) end end + head=tonode(head) return head,done end local function generic(lookupdata,lookupname,unicode,lookuphash) -- cgit v1.2.3