From 0da55392b876cef55845157c4bfb8244d84c6450 Mon Sep 17 00:00:00 2001 From: Hans Hagen Date: Wed, 1 Mar 2017 13:51:17 +0100 Subject: 2017-03-01 13:47:00 --- tex/generic/context/luatex/luatex-fonts-merged.lua | 715 ++++++++++++--------- 1 file changed, 418 insertions(+), 297 deletions(-) (limited to 'tex/generic') diff --git a/tex/generic/context/luatex/luatex-fonts-merged.lua b/tex/generic/context/luatex/luatex-fonts-merged.lua index 52344aa26..2690045cf 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 : 02/25/17 16:24:36 +-- merge date : 03/01/17 13:40:58 do -- begin closure to overcome local limits and interference @@ -2059,44 +2059,30 @@ if string.find(os.getenv("PATH"),";",1,true) then else io.fileseparator,io.pathseparator="/",":" end -local function readall(f) - return f:read("*all") -end +local large=2^24 +local medium=large/16 +local small=medium/8 local function readall(f) local size=f:seek("end") - if size==0 then - return "" - end - f:seek("set",0) - if size<1024*1024 then - return f:read('*all') + if size>0 then + f:seek("set",0) + return f:read(size) else - local step - if size>16*1024*1024 then - step=16*1024*1024 - else - step=floor(size/(1024*1024))*1024*1024/8 - end - local data={} - while true do - local r=f:read(step) - if not r then - return concat(data) - else - data[#data+1]=r - end - end + return "" end end io.readall=readall function io.loaddata(filename,textmode) local f=open(filename,(textmode and 'r') or 'rb') if f then - local data=readall(f) - f:close() - if #data>0 then - return data + local size=f:seek("end") + local data=nil + if size>0 then + f:seek("set",0) + data=f:read(size) end + f:close() + return data end end function io.copydata(source,target,action) @@ -2105,37 +2091,14 @@ function io.copydata(source,target,action) local g=open(target,"wb") if g then local size=f:seek("end") - if size==0 then - else + if size>0 then f:seek("set",0) - if size<1024*1024 then - local data=f:read('*all') - if action then - data=action(data) - end - if data then - g:write(data) - end - else - local step - if size>16*1024*1024 then - step=16*1024*1024 - else - step=floor(size/(1024*1024))*1024*1024/8 - end - while true do - local data=f:read(step) - if data then - if action then - data=action(data) - end - if data then - g:write(data) - end - else - break - end - end + local data=f:read(size) + if action then + data=action(data) + end + if data then + g:write(data) end end g:close() @@ -2161,29 +2124,59 @@ function io.savedata(filename,data,joiner) return false end end -function io.loadlines(filename,n) - local f=open(filename,'r') - if not f then - elseif n then - local lines={} - for i=1,n do - local line=f:read("*lines") - if line then - lines[#lines+1]=line - else - break +if fio.readline then + local readline=fio.readline + function io.loadlines(filename,n) + local f=open(filename,'r') + if not f then + elseif n then + local lines={} + for i=1,n do + local line=readline(f) + if line then + lines[i]=line + else + break + end + end + f:close() + lines=concat(lines,"\n") + if #lines>0 then + return lines + end + else + local line=readline(f) + f:close() + if line and #line>0 then + return line end end - f:close() - lines=concat(lines,"\n") - if #lines>0 then - return lines - end - else - local line=f:read("*line") or "" - f:close() - if #line>0 then - return line + end +else + function io.loadlines(filename,n) + local f=open(filename,'r') + if not f then + elseif n then + local lines={} + for i=1,n do + local line=f:read("*lines") + if line then + lines[i]=line + else + break + end + end + f:close() + lines=concat(lines,"\n") + if #lines>0 then + return lines + end + else + local line=f:read("*line") or "" + f:close() + if #line>0 then + return line + end end end end @@ -2344,7 +2337,7 @@ function io.ask(question,default,options) end end end -local function readnumber(f,n,m) +local function readnumber(f,n,m) if m then f:seek("set",n) n=m @@ -2353,31 +2346,31 @@ local function readnumber(f,n,m) return byte(f:read(1)) elseif n==2 then local a,b=byte(f:read(2),1,2) - return 256*a+b + return 0x100*a+b elseif n==3 then local a,b,c=byte(f:read(3),1,3) - return 256*256*a+256*b+c + return 0x10000*a+0x100*b+c elseif n==4 then local a,b,c,d=byte(f:read(4),1,4) - return 256*256*256*a+256*256*b+256*c+d + return 0x1000000*a+0x10000*b+0x100*c+d elseif n==8 then local a,b=readnumber(f,4),readnumber(f,4) - return 256*a+b + return 0x100*a+b elseif n==12 then local a,b,c=readnumber(f,4),readnumber(f,4),readnumber(f,4) - return 256*256*a+256*b+c + return 0x10000*a+0x100*b+c elseif n==-2 then local b,a=byte(f:read(2),1,2) - return 256*a+b + return 0x100*a+b elseif n==-3 then local c,b,a=byte(f:read(3),1,3) - return 256*256*a+256*b+c + return 0x10000*a+0x100*b+c elseif n==-4 then local d,c,b,a=byte(f:read(4),1,4) - return 256*256*256*a+256*256*b+256*c+d + return 0x1000000*a+0x10000*b+0x100*c+d elseif n==-8 then local h,g,f,e,d,c,b,a=byte(f:read(8),1,8) - return 256*256*256*256*256*256*256*a+256*256*256*256*256*256*b+256*256*256*256*256*c+256*256*256*256*d+256*256*256*e+256*256*f+256*g+h + return 0x100000000000000*a+0x1000000000000*b+0x10000000000*c+0x100000000*d+0x1000000*e+0x10000*f+0x100*g+h else return 0 end @@ -4302,6 +4295,10 @@ end function files.readbytes(f,n) return byte(f:read(n),1,n) end +function files.readbytetable(f,n) + local s=f:read(n or 1) + return { byte(s,1,#s) } +end function files.readchar(f) return f:read(1) end @@ -4390,21 +4387,12 @@ function files.readcardinal4le(f) end function files.readinteger4(f) local a,b,c,d=byte(f:read(4),1,4) - local n=0x1000000*a+0x10000*b+0x100*c+d - if n>=0x8000000 then - return n-0x100000000 + if a>=0x80 then + return 0x1000000*a+0x10000*b+0x100*c+d-0x100000000 else - return n + return 0x1000000*a+0x10000*b+0x100*c+d end end - function files.readinteger4(f) - local a,b,c,d=byte(f:read(4),1,4) - if a>=0x80 then - return 0x1000000*a+0x10000*b+0x100*c+d-0x100000000 - else - return 0x1000000*a+0x10000*b+0x100*c+d - end - end function files.readinteger4le(f) local d,c,b,a=byte(f:read(4),1,4) local n=0x1000000*a+0x10000*b+0x100*c+d @@ -4416,11 +4404,10 @@ function files.readinteger4le(f) end function files.readfixed4(f) local a,b,c,d=byte(f:read(4),1,4) - local n=0x100*a+b - if n>=0x8000 then - return n-0x10000+(0x100*c+d)/0xFFFF + if a>=0x80 then + return (0x1000000*a+0x10000*b+0x100*c+d-0x100000000)/65536.0 else - return n+(0x100*c+d)/0xFFFF + return (0x1000000*a+0x10000*b+0x100*c+d)/65536.0 end end if extract then @@ -4465,6 +4452,34 @@ end function files.writebyte(f,b) f:write(char(b)) end +if fio and fio.readcardinal1 then + files.readcardinal1=fio.readcardinal1 + files.readcardinal2=fio.readcardinal2 + files.readcardinal3=fio.readcardinal3 + files.readcardinal4=fio.readcardinal4 + files.readinteger1=fio.readinteger1 + files.readinteger2=fio.readinteger2 + files.readinteger3=fio.readinteger3 + files.readinteger4=fio.readinteger4 + files.readfixed4=fio.readfixed4 + files.read2dot14=fio.read2dot14 + files.setposition=fio.setposition + files.getposition=fio.getposition + files.readbyte=files.readcardinel1 + files.readsignedbyte=files.readinteger1 + files.readcardinal=files.readcardinal1 + files.readinteger=files.readinteger1 + local skipposition=fio.skipposition + files.skipposition=skipposition + files.readbytes=fio.readbytes + files.readbytetable=fio.readbytetable + function files.skipshort(f,n) + skipposition(f,2*(n or 1)) + end + function files.skiplong(f,n) + skipposition(f,4*(n or 1)) + end +end end -- closure @@ -8106,10 +8121,10 @@ local readulong=streamreader.readcardinal4 local readshort=streamreader.readinteger2 local readlong=streamreader.readinteger4 local readfixed=streamreader.readfixed4 +local read2dot14=streamreader.read2dot14 local readfword=readshort local readufword=readushort local readoffset=readushort -local read2dot14=streamreader.read2dot14 function streamreader.readtag(f) return lower(stripstring(readstring(f,4))) end @@ -9421,12 +9436,18 @@ local function prepareglyps(fontdata) fontdata.glyphs=glyphs fontdata.mapping={} end +local function readtable(tag,f,fontdata,specification) + local reader=readers[tag] + if reader then + reader(f,fontdata,specification) + end +end local function readdata(f,offset,specification) local fontdata=loadtables(f,specification,offset) if specification.glyphs then prepareglyps(fontdata) end - readers["name"](f,fontdata,specification) + readtable("name",f,fontdata,specification) local askedname=specification.askedname if askedname then local fullname=getname(fontdata,"fullname") or "" @@ -9436,27 +9457,27 @@ local function readdata(f,offset,specification) return end end - readers["os/2"](f,fontdata,specification) - readers["head"](f,fontdata,specification) - readers["maxp"](f,fontdata,specification) - readers["hhea"](f,fontdata,specification) - readers["vhea"](f,fontdata,specification) - readers["hmtx"](f,fontdata,specification) - readers["vmtx"](f,fontdata,specification) - readers["vorg"](f,fontdata,specification) - readers["post"](f,fontdata,specification) - readers["cff" ](f,fontdata,specification) - readers["cmap"](f,fontdata,specification) - readers["loca"](f,fontdata,specification) - readers["glyf"](f,fontdata,specification) - readers["colr"](f,fontdata,specification) - readers["cpal"](f,fontdata,specification) - readers["svg" ](f,fontdata,specification) - readers["kern"](f,fontdata,specification) - readers["gdef"](f,fontdata,specification) - readers["gsub"](f,fontdata,specification) - readers["gpos"](f,fontdata,specification) - readers["math"](f,fontdata,specification) + readtable("os/2",f,fontdata,specification) + readtable("head",f,fontdata,specification) + readtable("maxp",f,fontdata,specification) + readtable("hhea",f,fontdata,specification) + readtable("vhea",f,fontdata,specification) + readtable("hmtx",f,fontdata,specification) + readtable("vmtx",f,fontdata,specification) + readtable("vorg",f,fontdata,specification) + readtable("post",f,fontdata,specification) + readtable("cff",f,fontdata,specification) + readtable("cmap",f,fontdata,specification) + readtable("loca",f,fontdata,specification) + readtable("glyf",f,fontdata,specification) + readtable("colr",f,fontdata,specification) + readtable("cpal",f,fontdata,specification) + readtable("svg",f,fontdata,specification) + readtable("kern",f,fontdata,specification) + readtable("gdef",f,fontdata,specification) + readtable("gsub",f,fontdata,specification) + readtable("gpos",f,fontdata,specification) + readtable("math",f,fontdata,specification) fontdata.locations=nil fontdata.tables=nil fontdata.cidmaps=nil @@ -9725,13 +9746,12 @@ if not modules then modules={} end modules ['font-cff']={ local next,type,tonumber=next,type,tonumber local byte=string.byte local concat,remove=table.concat,table.remove -local floor,abs,round,ceil=math.floor,math.abs,math.round,math.ceil +local floor,abs,round,ceil,min,max=math.floor,math.abs,math.round,math.ceil,math.min,math.max local P,C,R,S,C,Cs,Ct=lpeg.P,lpeg.C,lpeg.R,lpeg.S,lpeg.C,lpeg.Cs,lpeg.Ct local lpegmatch=lpeg.match local formatters=string.formatters local readers=fonts.handlers.otf.readers local streamreader=readers.streamreader -local readbytes=streamreader.readbytes local readstring=streamreader.readstring local readbyte=streamreader.readcardinal1 local readushort=streamreader.readcardinal2 @@ -9739,6 +9759,7 @@ local readuint=streamreader.readcardinal3 local readulong=streamreader.readcardinal4 local setposition=streamreader.setposition local getposition=streamreader.getposition +local readbytetable=streamreader.readbytetable local setmetatableindex=table.setmetatableindex local trace_charstrings=false trackers.register("fonts.cff.charstrings",function(v) trace_charstrings=v end) local report=logs.reporter("otf reader","cff") @@ -10140,14 +10161,14 @@ do report("%w%-10s : %s",depth*2,where,tostring(value)) end end - local function moveto(x,y) + local function moveto() if keepcurve then r=r+1 result[r]={ x,y,"m" } end if checked then - if xxmax then xmax=x end - if yymax then ymax=y end + if x>xmax then xmax=x elseif xymax then ymax=y elseif yxmax then + xmax=x + elseif xymax then + ymax=y + elseif yxmax then xmax=x end - if yymax then ymax=y end + if x>xmax then xmax=x elseif xymax then ymax=y elseif yxmax then + xmax=x + elseif xymax then + ymax=y + elseif yxmax then xmax=x1 end - if y1ymax then ymax=y1 end + if x1>xmax then xmax=x1 elseif x1ymax then ymax=y1 elseif y1xmax then xmax=x2 end - if y2ymax then ymax=y2 end - if x3xmax then xmax=x3 end - if y3ymax then ymax=y3 end + if x2>xmax then xmax=x2 elseif x2ymax then ymax=y2 elseif y2xmax then xmax=x3 elseif x3ymax then ymax=y3 elseif y32 then - if not width then + if not width then + if top>2 then width=stack[1] if trace_charstrings then showvalue("width",width) end + else + width=true end - elseif not width then - width=true end if trace_charstrings then showstate("rmoveto") @@ -10209,43 +10298,43 @@ do x=x+stack[top-1] y=y+stack[top] top=0 - moveto(x,y) + moveto() end local function hmoveto() - if top>1 then - if not width then + if not width then + if top>1 then width=stack[1] if trace_charstrings then showvalue("width",width) end + else + width=true end - elseif not width then - width=true end if trace_charstrings then showstate("hmoveto") end x=x+stack[top] top=0 - moveto(x,y) + xmoveto() end local function vmoveto() - if top>1 then - if not width then + if not width then + if top>1 then width=stack[1] if trace_charstrings then showvalue("width",width) end + else + width=true end - elseif not width then - width=true end if trace_charstrings then showstate("vmoveto") end y=y+stack[top] top=0 - moveto(x,y) + ymoveto() end local function rlineto() if trace_charstrings then @@ -10254,20 +10343,7 @@ do for i=1,top,2 do x=x+stack[i] y=y+stack[i+1] - lineto(x,y) - end - top=0 - end - local function xlineto(swap) - for i=1,top do - if swap then - x=x+stack[i] - swap=false - else - y=y+stack[i] - swap=true - end - lineto(x,y) + lineto() end top=0 end @@ -10275,13 +10351,47 @@ do if trace_charstrings then showstate("hlineto") end - xlineto(true) + if top==1 then + x=x+stack[1] + xlineto() + else + local swap=true + for i=1,top do + if swap then + x=x+stack[i] + xlineto() + swap=false + else + y=y+stack[i] + ylineto() + swap=true + end + end + end + top=0 end local function vlineto() if trace_charstrings then showstate("vlineto") end - xlineto(false) + if top==1 then + y=y+stack[1] + ylineto() + else + local swap=false + for i=1,top do + if swap then + x=x+stack[i] + xlineto() + swap=false + else + y=y+stack[i] + ylineto() + swap=true + end + end + end + top=0 end local function rrcurveto() if trace_charstrings then @@ -10292,8 +10402,8 @@ do local ay=y+stack[i+1] local bx=ax+stack[i+2] local by=ay+stack[i+3] - x=bx+stack[i+4] - y=by+stack[i+5] + x=bx+stack[i+4] + y=by+stack[i+5] curveto(ax,ay,bx,by,x,y) end top=0 @@ -10304,15 +10414,15 @@ do end local s=1 if top%2~=0 then - y=y+stack[1] + y=y+stack[1] s=2 end for i=s,top,4 do - local ax=x+stack[i] + local ax=x+stack[i] local ay=y local bx=ax+stack[i+1] local by=ay+stack[i+2] - x=bx+stack[i+3] + x=bx+stack[i+3] y=by curveto(ax,ay,bx,by,x,y) end @@ -10325,16 +10435,16 @@ do local s=1 local d=0 if top%2~=0 then - d=stack[1] + d=stack[1] s=2 end for i=s,top,4 do local ax=x+d - local ay=y+stack[i] + local ay=y+stack[i] local bx=ax+stack[i+1] local by=ay+stack[i+2] x=bx - y=by+stack[i+3] + y=by+stack[i+3] curveto(ax,ay,bx,by,x,y) d=0 end @@ -10345,7 +10455,6 @@ do if last then top=top-1 end - local sw=swap for i=1,top,4 do local ax,ay,bx,by if swap then @@ -10404,7 +10513,7 @@ do end x=x+stack[top-1] y=y+stack[top] - lineto(x,y) + lineto() top=0 end local function rlinecurve() @@ -10415,7 +10524,7 @@ do for i=1,top-6,2 do x=x+stack[i] y=y+stack[i+1] - lineto(x,y) + lineto() end end local ax=x+stack[top-5] @@ -10451,7 +10560,7 @@ do if trace_charstrings then showstate("hflex") end - local ax=x+stack[1] + local ax=x+stack[1] local ay=y local bx=ax+stack[2] local by=ay+stack[3] @@ -10688,8 +10797,8 @@ do [036]=hflex1, [037]=flex1, } - local p_bytes=Ct((P(1)/byte)^0) - local function call(scope,list,bias,process) + local process + local function call(scope,list,bias) depth=depth+1 if top==0 then showstate(formatters["unknown %s call"](scope)) @@ -10702,10 +10811,6 @@ do end local tab=list[index] if tab then - if type(tab)=="string" then - tab=lpegmatch(p_bytes,tab) - list[index]=tab - end process(tab) else showstate(formatters["unknown %s call %i"](scope,index)) @@ -10714,50 +10819,52 @@ do end depth=depth-1 end - local function process(tab) + process=function(tab) local i=1 local n=#tab while i<=n do local t=tab[i] - if t>=32 and t<=246 then - top=top+1 - stack[top]=t-139 - i=i+1 - elseif t>=247 and t<=250 then - top=top+1 - stack[top]=(t-247)*256+tab[i+1]+108 - i=i+2 - elseif t>=251 and t<=254 then - top=top+1 - stack[top]=-(t-251)*256-tab[i+1]-108 - i=i+2 + if t>=32 then + if t<=246 then + top=top+1 + stack[top]=t-139 + i=i+1 + elseif t<=250 then + top=top+1 + stack[top]=t*256-63124+tab[i+1] + i=i+2 + elseif t<=254 then + top=top+1 + stack[top]=-t*256+64148-tab[i+1] + i=i+2 + else + local n=0x100*tab[i+1]+tab[i+2] + top=top+1 + if n>=0x8000 then + stack[top]=n-0x10000+(0x100*tab[i+3]+tab[i+4])/0xFFFF + else + stack[top]=n+(0x100*tab[i+3]+tab[i+4])/0xFFFF + end + i=i+5 + end elseif t==28 then top=top+1 local n=0x100*tab[i+1]+tab[i+2] if n>=0x8000 then - stack[top]=n-0xFFFF-1 + stack[top]=n-0x10000 else stack[top]=n end i=i+3 - elseif t==255 then - local n=0x100*tab[i+1]+tab[i+2] - top=top+1 - if n>=0x8000 then - stack[top]=n-0xFFFF-1+(0x100*tab[i+3]+tab[i+4])/0xFFFF - else - stack[top]=n+(0x100*tab[i+3]+tab[i+4])/0xFFFF - end - i=i+5 elseif t==11 then if trace_charstrings then showstate("return") end return elseif t==10 then - call("local",locals,localbias,process) + call("local",locals,localbias) i=i+1 - elseif t==14 then + elseif t==14 then if width then elseif top>0 then width=stack[1] @@ -10772,7 +10879,7 @@ do end return elseif t==29 then - call("global",globals,globalbias,process) + call("global",globals,globalbias) i=i+1 elseif t==12 then i=i+1 @@ -10833,9 +10940,7 @@ do local defaultwidth=private.data.defaultwidthx or 0 for i=1,#charstrings do local tab=charstrings[i] - if type(tab)=="string" then - tab=lpegmatch(p_bytes,tab) - end + tab={ byte(tab,1,#tab) } local index=i-1 x=0 y=0 @@ -10861,14 +10966,7 @@ do width=nominalwidth+width end local glyph=glyphs[index] - if not glyph then - glyphs[index]={ - segments=doshapes~=false and result or nil, - boundingbox=boundingbox, - width=width, - name=charset[index], - } - else + if glyph then glyph.segments=doshapes~=false and result or nil glyph.boundingbox=boundingbox if not glyph.width then @@ -10877,6 +10975,19 @@ do if charset and not glyph.name then glyph.name=charset[index] end + elseif doshapes then + glyphs[index]={ + segments=result, + boundingbox=boundingbox, + width=width, + name=charset[index], + } + else + glyphs[index]={ + boundingbox=boundingbox, + width=width, + name=charset[index], + } end if trace_charstrings then report("width: %s",tostring(width)) @@ -10896,9 +11007,7 @@ do globalbias,localbias=setbias(globals,locals) local nominalwidth=private and private.data.nominalwidthx or 0 local defaultwidth=private and private.data.defaultwidthx or 0 - if type(tab)=="string" then - tab=lpegmatch(p_bytes,tab) - end + tab={ byte(tab,1,#tab) } x=0 y=0 width=false @@ -10924,14 +11033,7 @@ do end index=index-1 local glyph=glyphs[index] - if not glyph then - glyphs[index]={ - segments=doshapes~=false and result or nil, - boundingbox=boundingbox, - width=width, - name=charset[index], - } - else + if glyph then glyph.segments=doshapes~=false and result or nil glyph.boundingbox=boundingbox if not glyph.width then @@ -10940,6 +11042,19 @@ do if charset and not glyph.name then glyph.name=charset[index] end + elseif doshapes then + glyphs[index]={ + segments=result, + boundingbox=boundingbox, + width=width, + name=charset[index], + } + else + glyphs[index]={ + boundingbox=boundingbox, + width=width, + name=charset[index], + } end if trace_charstrings then report("width: %s",tostring(width)) @@ -10955,7 +11070,7 @@ end local function readglobals(f,data) local routines=readlengths(f) for i=1,#routines do - routines[i]=readstring(f,routines[i]) + routines[i]=readbytetable(f,routines[i]) end data.routines=routines end @@ -11013,7 +11128,7 @@ local function readlocals(f,data,dictionary) setposition(f,header.offset+private.offset+subroutineoffset) local subroutines=readlengths(f) for i=1,#subroutines do - subroutines[i]=readstring(f,subroutines[i]) + subroutines[i]=readbytetable(f,subroutines[i]) end dictionary.subroutines=subroutines private.data.subroutines=nil @@ -11131,6 +11246,7 @@ local function readfdselect(f,data,glyphs,doshapes,version) end for i=1,#charstrings do parsecharstring(data,dictionaries[fdindex[i]+1],charstrings[i],glyphs,i,doshapes,version) +charstrings[i]=nil end resetcharstrings() end @@ -11638,18 +11754,18 @@ local readers=fonts.handlers.otf.readers local streamreader=readers.streamreader local setposition=streamreader.setposition local getposition=streamreader.getposition -local skipshort=streamreader.skipshort -local skipbytes=streamreader.skip local readushort=streamreader.readcardinal2 local readulong=streamreader.readcardinal4 +local readinteger=streamreader.readinteger1 local readshort=streamreader.readinteger2 -local readfword=readshort local readstring=streamreader.readstring local readtag=streamreader.readtag local readbytes=streamreader.readbytes local readfixed=streamreader.readfixed4 local read2dot14=streamreader.read2dot14 -local readinteger=streamreader.readinteger1 +local skipshort=streamreader.skipshort +local skipbytes=streamreader.skip +local readfword=readshort local gsubhandlers={} local gposhandlers={} local lookupidoffset=-1 @@ -13168,57 +13284,61 @@ do report("ignoring global kern table using gpos kern feature") return end - report("adding global kern table as gpos feature %a",name) setposition(f,datatable.offset) local version=readushort(f) local noftables=readushort(f) - local kerns=setmetatableindex("table") - for i=1,noftables do - local version=readushort(f) - local length=readushort(f) - local coverage=readushort(f) - local format=bit32.rshift(coverage,8) - if format==0 then - local nofpairs=readushort(f) - local searchrange=readushort(f) - local entryselector=readushort(f) - local rangeshift=readushort(f) - for i=1,nofpairs do - kerns[readushort(f)][readushort(f)]=readfword(f) - end - elseif format==2 then + if noftables>1 then + report("adding global kern table as gpos feature %a",name) + local kerns=setmetatableindex("table") + for i=1,noftables do + local version=readushort(f) + local length=readushort(f) + local coverage=readushort(f) + local format=bit32.rshift(coverage,8) + if format==0 then + local nofpairs=readushort(f) + local searchrange=readushort(f) + local entryselector=readushort(f) + local rangeshift=readushort(f) + for i=1,nofpairs do + kerns[readushort(f)][readushort(f)]=readfword(f) + end + elseif format==2 then + else + end + end + local feature={ dflt={ dflt=true } } + if not features then + fontdata.features={ gpos={ [name]=feature } } + elseif not gposfeatures then + fontdata.features.gpos={ [name]=feature } else + gposfeatures[name]=feature end - end - local feature={ dflt={ dflt=true } } - if not features then - fontdata.features={ gpos={ [name]=feature } } - elseif not gposfeatures then - fontdata.features.gpos={ [name]=feature } + local sequences=fontdata.sequences + if not sequences then + sequences={} + fontdata.sequences=sequences + end + local nofsequences=#sequences+1 + sequences[nofsequences]={ + index=nofsequences, + name=name, + steps={ + { + coverage=kerns, + format="kern", + }, + }, + nofsteps=1, + type="gpos_pair", + flags={ false,false,false,false }, + order={ name }, + features={ [name]=feature }, + } else - gposfeatures[name]=feature - end - local sequences=fontdata.sequences - if not sequences then - sequences={} - fontdata.sequences=sequences + report("ignoring empty kern table of feature %a",name) end - local nofsequences=#sequences+1 - sequences[nofsequences]={ - index=nofsequences, - name=name, - steps={ - { - coverage=kerns, - format="kern", - }, - }, - nofsteps=1, - type="gpos_pair", - flags={ false,false,false,false }, - order={ name }, - features={ [name]=feature }, - } end function readers.gsub(f,fontdata,specification) if specification.details then @@ -21594,7 +21714,7 @@ end otf.helpers=otf.helpers or {} otf.helpers.txtdirstate=txtdirstate otf.helpers.pardirstate=pardirstate -local function featuresprocessor(head,font,attr) +local function featuresprocessor(head,font,attr,direction) local sequences=sequencelists[font] if not sequencelists then return head,false @@ -21620,7 +21740,7 @@ local function featuresprocessor(head,font,attr) if trace_steps then checkstep(head) end - local rlmode=0 + local initialrl=direction=="TRT" and -1 or 0 local done=false local datasets=otf.dataset(tfmdata,font,attr) local dirstack={} @@ -21629,7 +21749,7 @@ local function featuresprocessor(head,font,attr) local dataset=datasets[s] local attribute=dataset[2] local sequence=dataset[3] - local rlparmode=0 + local rlparmode=initialrl local topstack=0 local typ=sequence.type local gpossing=typ=="gpos_single" or typ=="gpos_pair" @@ -21646,6 +21766,7 @@ local function featuresprocessor(head,font,attr) end elseif typ=="gsub_reversecontextchain" then local start=find_node_tail(head) + local rlmode=0 while start do local char=ischar(start,font) if char then @@ -21682,8 +21803,8 @@ local function featuresprocessor(head,font,attr) end end else - local start=head - rlmode=0 + local start=head + local rlmode=initialrl if nofsteps==1 then local step=steps[1] local lookupcache=step.coverage @@ -25156,8 +25277,8 @@ do end local setroutine=function(str,position,index,size) local forward=position+tonumber(size) - local stream=sub(str,position+1,forward) - routines[index]=decrypt(stream,4330,4) + local stream=decrypt(sub(str,position+1,forward),4330,4) + routines[index]={ byte(stream,1,#stream) } return forward end local setvector=function(str,position,name,size) -- cgit v1.2.3