diff options
author | Karl Berry <karl@freefriends.org> | 2020-02-03 22:30:09 +0000 |
---|---|---|
committer | Karl Berry <karl@freefriends.org> | 2020-02-03 22:30:09 +0000 |
commit | 80eeb8a04335539fde455e00d5cfde4e2c7ed5c6 (patch) | |
tree | b35ac34b9cccd54d049c68d5d808b9ed48bab65e /Master/texmf-dist/tex/luatex | |
parent | ca44d57bbfaa45d580f466e5dff1b3a9cccd49f6 (diff) |
luaotfload (3feb20)
git-svn-id: svn://tug.org/texlive/trunk@53652 c570f23f-e606-0410-a88d-b1316a301751
Diffstat (limited to 'Master/texmf-dist/tex/luatex')
45 files changed, 1558 insertions, 613 deletions
diff --git a/Master/texmf-dist/tex/luatex/luaotfload/fontloader-2019-10-29.lua b/Master/texmf-dist/tex/luatex/luaotfload/fontloader-2020-01-26.lua index dc98bd56969..be8fefacfe2 100644 --- a/Master/texmf-dist/tex/luatex/luaotfload/fontloader-2019-10-29.lua +++ b/Master/texmf-dist/tex/luatex/luaotfload/fontloader-2020-01-26.lua @@ -1,9 +1,9 @@ --[[info----------------------------------------------------------------------- Luaotfload fontloader package - build 2019-10-29 22:02:47 + build 2020-02-02 22:46:14 ------------------------------------------------------------------------------- - © 2019 PRAGMA ADE / ConTeXt Development Team + © 2020 PRAGMA ADE / ConTeXt Development Team The code in this file is provided under the GPL v2.0 license. See the file COPYING in the Luaotfload repository for details. @@ -62,7 +62,7 @@ --info]]----------------------------------------------------------------------- -do --- [luaotfload, fontloader-2019-10-29.lua scope for “data-con” 7ce546725b1550f655c78ac9d69419ca] --- +do --- [luaotfload, fontloader-2020-02-02.lua scope for “data-con” de6ae0997b0e70a23bcc9afff5d8b072] --- if not modules then modules={} end modules ['data-con']={ version=1.100, @@ -71,6 +71,7 @@ if not modules then modules={} end modules ['data-con']={ copyright="PRAGMA ADE / ConTeXt Development Team", license="see context related readme files" } +local setmetatable=setmetatable local format,lower,gsub=string.format,string.lower,string.gsub local trace_cache=false trackers.register("resolvers.cache",function(v) trace_cache=v end) local trace_containers=false trackers.register("resolvers.containers",function(v) trace_containers=v end) @@ -78,16 +79,21 @@ local trace_storage=false trackers.register("resolvers.storage",function(v) tra containers=containers or {} local containers=containers containers.usecache=true +local getwritablepath=caches.getwritablepath +local getreadablepaths=caches.getreadablepaths +local cacheiswritable=caches.is_writable +local loaddatafromcache=caches.loaddata +local savedataincache=caches.savedata local report_containers=logs.reporter("resolvers","containers") local allocated={} local mt={ __index=function(t,k) if k=="writable" then - local writable=caches.getwritablepath(t.category,t.subcategory) or { "." } + local writable=getwritablepath(t.category,t.subcategory) or { "." } t.writable=writable return writable elseif k=="readables" then - local readables=caches.getreadablepaths(t.category,t.subcategory) or { "." } + local readables=getreadablepaths(t.category,t.subcategory) or { "." } t.readables=readables return readables end @@ -118,7 +124,7 @@ function containers.define(category,subcategory,version,enabled) end end function containers.is_usable(container,name) - return container.enabled and caches and caches.is_writable(container.writable,name) + return container.enabled and caches and cacheiswritable(container.writable,name) end function containers.is_valid(container,name) if name and name~="" then @@ -132,7 +138,7 @@ function containers.read(container,name) local storage=container.storage local stored=storage[name] if not stored and container.enabled and caches and containers.usecache then - stored=caches.loaddata(container.readables,name,container.writable) + stored=loaddatafromcache(container.readables,name,container.writable) if stored and stored.cache_version==container.version then if trace_cache or trace_containers then report_containers("action %a, category %a, name %a","load",container.subcategory,name) @@ -148,17 +154,20 @@ function containers.read(container,name) end return stored end -function containers.write(container,name,data) +function containers.write(container,name,data,fast) if data then data.cache_version=container.version if container.enabled and caches then - local unique,shared=data.unique,data.shared - data.unique,data.shared=nil,nil - caches.savedata(container.writable,name,data) + local unique=data.unique + local shared=data.shared + data.unique=nil + data.shared=nil + savedataincache(container.writable,name,data,fast) if trace_cache or trace_containers then report_containers("action %a, category %a, name %a","save",container.subcategory,name) end - data.unique,data.shared=unique,shared + data.unique=unique + data.shared=shared end if trace_cache or trace_containers then report_containers("action %a, category %a, name %a","store",container.subcategory,name) @@ -174,10 +183,10 @@ function containers.cleanname(name) return (gsub(lower(name),"[^%w\128-\255]+","-")) end -end --- [luaotfload, fontloader-2019-10-29.lua scope for “data-con”] --- +end --- [luaotfload, fontloader-2020-02-02.lua scope for “data-con”] --- -do --- [luaotfload, fontloader-2019-10-29.lua scope for “basics-nod” c05f47077c709bbf12a8758852dc4e06] --- +do --- [luaotfload, fontloader-2020-02-02.lua scope for “basics-nod” 4ce2f7c752fdc4c1d6d9f74e8cd50be8] --- if not modules then modules={} end modules ['luatex-fonts-nod']={ version=1.001, @@ -393,11 +402,18 @@ if not nuts.setreplace then setfield(n,"replace",h) end end +do + local getsubtype=nuts.getsubtype + function nuts.start_of_par(n) + local s=getsubtype(n) + return s==0 or s==2 + end +end -end --- [luaotfload, fontloader-2019-10-29.lua scope for “basics-nod”] --- +end --- [luaotfload, fontloader-2020-02-02.lua scope for “basics-nod”] --- -do --- [luaotfload, fontloader-2019-10-29.lua scope for “basics-chr” 58b7ef0c486e06090b362971b9f85e27] --- +do --- [luaotfload, fontloader-2020-02-02.lua scope for “basics-chr” 58b7ef0c486e06090b362971b9f85e27] --- characters=characters or {} @@ -4007,10 +4023,10 @@ characters.indicgroups={ }, } -end --- [luaotfload, fontloader-2019-10-29.lua scope for “basics-chr”] --- +end --- [luaotfload, fontloader-2020-02-02.lua scope for “basics-chr”] --- -do --- [luaotfload, fontloader-2019-10-29.lua scope for “font-ini” 4299a02110bbd7c0d27e131235c5319d] --- +do --- [luaotfload, fontloader-2020-02-02.lua scope for “font-ini” 4dee96e1e1474d324dd126bd5d375df8] --- if not modules then modules={} end modules ['font-ini']={ version=1.001, @@ -4047,11 +4063,14 @@ fonts.privateoffsets={ mathbase=0xFF000, keepnames=false, } +if node and not tex.getfontoffamily then + tex.getfontoffamily=node.family_font +end -end --- [luaotfload, fontloader-2019-10-29.lua scope for “font-ini”] --- +end --- [luaotfload, fontloader-2020-02-02.lua scope for “font-ini”] --- -do --- [luaotfload, fontloader-2019-10-29.lua scope for “fonts-mis” bc9eb43c27f63ce9d0fff67e104fe1c6] --- +do --- [luaotfload, fontloader-2020-02-02.lua scope for “fonts-mis” bc9eb43c27f63ce9d0fff67e104fe1c6] --- if not modules then modules={} end modules ['luatex-font-mis']={ version=1.001, @@ -4083,10 +4102,10 @@ function font.each() return table.sortedhash(fonts.hashes.identifiers) end -end --- [luaotfload, fontloader-2019-10-29.lua scope for “fonts-mis”] --- +end --- [luaotfload, fontloader-2020-02-02.lua scope for “fonts-mis”] --- -do --- [luaotfload, fontloader-2019-10-29.lua scope for “font-con” 8b35e7c2203d5b57c61942e07cee2c0a] --- +do --- [luaotfload, fontloader-2020-02-02.lua scope for “font-con” b436bf6880a56216445779ac68fee877] --- if not modules then modules={} end modules ['font-con']={ version=1.001, @@ -4114,13 +4133,13 @@ fonts.handlers=handlers local allocate=utilities.storage.allocate local setmetatableindex=table.setmetatableindex constructors.dontembed=allocate() -constructors.autocleanup=true constructors.namemode="fullpath" constructors.version=1.01 constructors.cache=containers.define("fonts","constructors",constructors.version,false) constructors.privateoffset=fonts.privateoffsets.textbase or 0xF0000 constructors.cacheintex=true constructors.addtounicode=true +constructors.fixprotrusion=true local designsizes=allocate() constructors.designsizes=designsizes local loadedfonts=allocate() @@ -4172,11 +4191,6 @@ function constructors.getmathparameter(tfmdata,name) end end function constructors.cleanuptable(tfmdata) - if constructors.autocleanup and tfmdata.properties.virtualized then - for k,v in next,tfmdata.characters do - if v.commands then v.commands=nil end - end - end end function constructors.calculatescale(tfmdata,scaledpoints) local parameters=tfmdata.parameters @@ -4403,6 +4417,7 @@ function constructors.scale(tfmdata,specification) properties.direction=direction target.size=scaledpoints target.encodingbytes=properties.encodingbytes or 1 + target.subfont=properties.subfont target.embedding=properties.embedding or "subset" target.tounicode=1 target.cidinfo=properties.cidinfo @@ -4512,7 +4527,7 @@ function constructors.scale(tfmdata,specification) targetparameters.descender=delta*descender end constructors.enhanceparameters(targetparameters) - local protrusionfactor=(targetquad~=0 and 1000/targetquad) or 0 + local protrusionfactor=constructors.fixprotrusion and ((targetquad~=0 and 1000/targetquad) or 1) or 1 local scaledwidth=defaultwidth*hdelta local scaledheight=defaultheight*vdelta local scaleddepth=defaultdepth*vdelta @@ -4895,6 +4910,7 @@ function constructors.finalize(tfmdata) properties.name=properties.name or tfmdata.name properties.psname=properties.psname or tfmdata.psname properties.encodingbytes=tfmdata.encodingbytes or 1 + properties.subfont=tfmdata.subfont or nil properties.embedding=tfmdata.embedding or "subset" properties.tounicode=tfmdata.tounicode or 1 properties.cidinfo=tfmdata.cidinfo or nil @@ -4920,6 +4936,7 @@ function constructors.finalize(tfmdata) tfmdata.name=nil tfmdata.psname=nil tfmdata.encodingbytes=nil + tfmdata.subfont=nil tfmdata.embedding=nil tfmdata.tounicode=nil tfmdata.cidinfo=nil @@ -5430,10 +5447,10 @@ function constructors.addcoreunicodes(unicodes) return unicodes end -end --- [luaotfload, fontloader-2019-10-29.lua scope for “font-con”] --- +end --- [luaotfload, fontloader-2020-02-02.lua scope for “font-con”] --- -do --- [luaotfload, fontloader-2019-10-29.lua scope for “fonts-enc” 3e71a54297e8f85a1ac438bb0f20dd79] --- +do --- [luaotfload, fontloader-2020-02-02.lua scope for “fonts-enc” 3e71a54297e8f85a1ac438bb0f20dd79] --- if not modules then modules={} end modules ['luatex-font-enc']={ version=1.001, @@ -5502,10 +5519,10 @@ function encodings.load(filename) return containers.write(encodings.cache,name,data) end -end --- [luaotfload, fontloader-2019-10-29.lua scope for “fonts-enc”] --- +end --- [luaotfload, fontloader-2020-02-02.lua scope for “fonts-enc”] --- -do --- [luaotfload, fontloader-2019-10-29.lua scope for “font-cid” 4d87988efa86020a14708ee03c23415f] --- +do --- [luaotfload, fontloader-2020-02-02.lua scope for “font-cid” 4d87988efa86020a14708ee03c23415f] --- if not modules then modules={} end modules ['font-cid']={ version=1.001, @@ -5656,10 +5673,10 @@ function cid.getmap(specification) return found end -end --- [luaotfload, fontloader-2019-10-29.lua scope for “font-cid”] --- +end --- [luaotfload, fontloader-2020-02-02.lua scope for “font-cid”] --- -do --- [luaotfload, fontloader-2019-10-29.lua scope for “font-map” f486746e90fe972de4b73e208ac7cbb2] --- +do --- [luaotfload, fontloader-2020-02-02.lua scope for “font-map” f486746e90fe972de4b73e208ac7cbb2] --- if not modules then modules={} end modules ['font-map']={ version=1.001, @@ -6047,10 +6064,10 @@ function mappings.addtounicode(data,filename,checklookups,forceligatures) end end -end --- [luaotfload, fontloader-2019-10-29.lua scope for “font-map”] --- +end --- [luaotfload, fontloader-2020-02-02.lua scope for “font-map”] --- -do --- [luaotfload, fontloader-2019-10-29.lua scope for “font-vfc” 94937140f2c909e9c831ba021f1ab303] --- +do --- [luaotfload, fontloader-2020-02-02.lua scope for “font-vfc” 94937140f2c909e9c831ba021f1ab303] --- if not modules then modules={} end modules ['font-vfc']={ version=1.001, @@ -6148,10 +6165,10 @@ helpers.commands=utilities.storage.allocate { dummy=dummy, } -end --- [luaotfload, fontloader-2019-10-29.lua scope for “font-vfc”] --- +end --- [luaotfload, fontloader-2020-02-02.lua scope for “font-vfc”] --- -do --- [luaotfload, fontloader-2019-10-29.lua scope for “font-otr” b1c03925c949027c86f781785fa7a208] --- +do --- [luaotfload, fontloader-2020-02-02.lua scope for “font-otr” d96724dcb40c673ac294df7044a39925] --- if not modules then modules={} end modules ['font-otr']={ version=1.001, @@ -6160,7 +6177,7 @@ if not modules then modules={} end modules ['font-otr']={ copyright="PRAGMA ADE / ConTeXt Development Team", license="see context related readme files" } -local next,type,tonumber=next,type,tonumber +local next,type,tonumber,rawget=next,type,tonumber,rawget local byte,lower,char,gsub=string.byte,string.lower,string.char,string.gsub local fullstrip=string.fullstrip local floor,round=math.floor,math.round @@ -8001,10 +8018,10 @@ function readers.extend(fontdata) end end -end --- [luaotfload, fontloader-2019-10-29.lua scope for “font-otr”] --- +end --- [luaotfload, fontloader-2020-02-02.lua scope for “font-otr”] --- -do --- [luaotfload, fontloader-2019-10-29.lua scope for “font-oti” dbae7722baae24d917a17176553825cf] --- +do --- [luaotfload, fontloader-2020-02-02.lua scope for “font-oti” dbae7722baae24d917a17176553825cf] --- if not modules then modules={} end modules ['font-oti']={ version=1.001, @@ -8147,10 +8164,10 @@ function otffeatures.checkeddefaultlanguage(featuretype,autolanguage,languages) end end -end --- [luaotfload, fontloader-2019-10-29.lua scope for “font-oti”] --- +end --- [luaotfload, fontloader-2020-02-02.lua scope for “font-oti”] --- -do --- [luaotfload, fontloader-2019-10-29.lua scope for “font-ott” aba6d8335a5f38a5a62d3631492f3392] --- +do --- [luaotfload, fontloader-2020-02-02.lua scope for “font-ott” aba6d8335a5f38a5a62d3631492f3392] --- if not modules then modules={} end modules ["font-ott"]={ version=1.001, @@ -9269,10 +9286,10 @@ function otffeatures.normalize(features,wrap) end end -end --- [luaotfload, fontloader-2019-10-29.lua scope for “font-ott”] --- +end --- [luaotfload, fontloader-2020-02-02.lua scope for “font-ott”] --- -do --- [luaotfload, fontloader-2019-10-29.lua scope for “font-cff” 98d5a660ea803b65cb883c009ecf3c0b] --- +do --- [luaotfload, fontloader-2020-02-02.lua scope for “font-cff” c769020b41b39418f703347f3d328bc7] --- if not modules then modules={} end modules ['font-cff']={ version=1.001, @@ -9282,7 +9299,7 @@ if not modules then modules={} end modules ['font-cff']={ license="see context related readme files" } local next,type,tonumber,rawget=next,type,tonumber,rawget -local byte,char,gmatch=string.byte,string.char,string.gmatch +local byte,char,gmatch,sub=string.byte,string.char,string.gmatch,string.sub local concat,remove,unpack=table.concat,table.remove,table.unpack 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 @@ -9389,6 +9406,37 @@ local defaultstrings={ [0]= "Thornsmall","Ydieresissmall","001.000","001.001","001.002","001.003", "Black","Bold","Book","Light","Medium","Regular","Roman","Semibold", } +local standardnames={ [0]= + false,false,false,false,false,false,false,false,false,false,false, + false,false,false,false,false,false,false,false,false,false,false, + false,false,false,false,false,false,false,false,false,false, + "space","exclam","quotedbl","numbersign","dollar","percent", + "ampersand","quoteright","parenleft","parenright","asterisk","plus", + "comma","hyphen","period","slash","zero","one","two","three","four", + "five","six","seven","eight","nine","colon","semicolon","less", + "equal","greater","question","at","A","B","C","D","E","F","G","H", + "I","J","K","L","M","N","O","P","Q","R","S","T","U","V","W", + "X","Y","Z","bracketleft","backslash","bracketright","asciicircum", + "underscore","quoteleft","a","b","c","d","e","f","g","h","i","j", + "k","l","m","n","o","p","q","r","s","t","u","v","w","x","y", + "z","braceleft","bar","braceright","asciitilde",false,false,false, + false,false,false,false,false,false,false,false,false,false,false, + false,false,false,false,false,false,false,false,false,false,false, + false,false,false,false,false,false,false,false,false,"exclamdown", + "cent","sterling","fraction","yen","florin","section","currency", + "quotesingle","quotedblleft","guillemotleft","guilsinglleft", + "guilsinglright","fi","fl",false,"endash","dagger","daggerdbl", + "periodcentered",false,"paragraph","bullet","quotesinglbase", + "quotedblbase","quotedblright","guillemotright","ellipsis","perthousand", + false,"questiondown",false,"grave","acute","circumflex","tilde", + "macron","breve","dotaccent","dieresis",false,"ring","cedilla",false, + "hungarumlaut","ogonek","caron","emdash",false,false,false,false, + false,false,false,false,false,false,false,false,false,false,false, + false,"AE",false,"ordfeminine",false,false,false,false,"Lslash", + "Oslash","OE","ordmasculine",false,false,false,false,false,"ae", + false,false,false,"dotlessi",false,false,"lslash","oslash","oe", + "germandbls",false,false,false,false +} local cffreaders={ readbyte, readushort, @@ -9750,6 +9798,7 @@ do local x=0 local y=0 local width=false + local lsb=0 local r=0 local stems=0 local globalbias=0 @@ -9773,6 +9822,9 @@ do local factors=false local axis=false local vsindex=0 + local justpass=false + local seacs={} + local procidx=nil local function showstate(where) report("%w%-10s : [%s] n=%i",depth*2,where,concat(stack," ",1,top),top) end @@ -10312,14 +10364,14 @@ do top=0 end local function divide() - if version==1 then + if version=="cff" then local d=stack[top] top=top-1 stack[top]=stack[top]/d end end local function closepath() - if version==1 then + if version=="cff" then if trace_charstrings then showstate("closepath") end @@ -10327,54 +10379,73 @@ do top=0 end local function hsbw() - if version==1 then + if version=="cff" then if trace_charstrings then showstate("hsbw") end + lsb=stack[top-1] or 0 width=stack[top] end top=0 end - local function seac() - if version==1 then + local function sbw() + if version=="cff" then if trace_charstrings then - showstate("seac") + showstate("sbw") end + lsb=stack[top-3] + width=stack[top-1] end top=0 end - local function sbw() - if version==1 then + local function seac() + if version=="cff" then if trace_charstrings then - showstate("sbw") + showstate("seac") end - width=stack[top-1] end top=0 end + local popped=3 + local hints=3 local function callothersubr() - if version==1 then + if version=="cff" then if trace_charstrings then - showstate("callothersubr (unsupported)") + showstate("callothersubr") + end + if stack[top]==hints then + popped=stack[top-2] + else + popped=3 + end + local t=stack[top-1] + if t then + top=top-(t+2) + if top<0 then + top=0 + end + else + top=0 end + else + top=0 end - top=0 end local function pop() - if version==1 then + if version=="cff" then if trace_charstrings then - showstate("pop (unsupported)") + showstate("pop") end top=top+1 - stack[top]=0 + stack[top]=popped else top=0 end end local function setcurrentpoint() - if version==1 then + if version=="cff" then if trace_charstrings then - showstate("pop (unsupported)") + showstate("setcurrentpoint (unsupported)") end x=x+stack[top-1] y=y+stack[top] @@ -10500,6 +10571,39 @@ do vhcurveto, hvcurveto, } + local reverse={ [0]="unsupported", + "getstem", + "unsupported", + "getstem", + "vmoveto", + "rlineto", + "hlineto", + "vlineto", + "rrcurveto", + "unsupported", + "unsupported", + "unsupported", + "unsupported", + "hsbw", + "unsupported", + "setvsindex", + "blend", + "unsupported", + "getstem", + "getmask", + "getmask", + "rmoveto", + "hmoveto", + "getstem", + "rcurveline", + "rlinecurve", + "vvcurveto", + "hhcurveto", + "unsupported", + "unsupported", + "vhcurveto", + "hvcurveto", + } local subactions={ [000]=dotsection, [001]=getstem3, @@ -10613,7 +10717,7 @@ do local function call(scope,list,bias) depth=depth+1 if top==0 then - showstate(formatters["unknown %s call %s"](scope,"?")) + showstate(formatters["unknown %s call %s, case %s"](scope,"?",1)) top=0 else local index=stack[top]+bias @@ -10625,13 +10729,12 @@ do if tab then process(tab) else - showstate(formatters["unknown %s call %s"](scope,index)) + showstate(formatters["unknown %s call %s, case %s"](scope,index,2)) top=0 end end depth=depth-1 end - local justpass=false process=function(tab) local i=1 local n=#tab @@ -10702,6 +10805,17 @@ do r=r+1;result[r]=chars[12] r=r+1;result[r]=chars[t] top=0 + elseif t==6 then + seacs[procidx]={ + asb=stack[1], + adx=stack[2], + ady=stack[3], + base=stack[4], + accent=stack[5], + width=width, + lsb=lsb, + } + top=0 else local a=subactions[t] if a then @@ -10731,44 +10845,52 @@ do i=i+s+1 elseif t==1 or t==3 or t==18 or operation==23 then p_getstem() -if true then - if top>0 then - for i=1,top do - r=r+1;result[r]=encode[stack[i]] + if true then + if top>0 then + for i=1,top do + r=r+1;result[r]=encode[stack[i]] + end + top=0 end + r=r+1;result[r]=chars[t] + else top=0 end - r=r+1;result[r]=chars[t] -else - top=0 -end i=i+1 elseif t==19 or t==20 then local s=p_getmask() or 0 -if true then - if top>0 then - for i=1,top do - r=r+1;result[r]=encode[stack[i]] + if true then + if top>0 then + for i=1,top do + r=r+1;result[r]=encode[stack[i]] + end + top=0 end + r=r+1;result[r]=chars[t] + for j=1,s do + i=i+1 + r=r+1;result[r]=chars[tab[i]] + end + else + i=i+s top=0 end - r=r+1;result[r]=chars[t] - for j=1,s do - i=i+1 - r=r+1;result[r]=chars[tab[i]] - end -else - i=i+s - top=0 -end i=i+1 elseif t==9 then top=0 i=i+1 elseif t==13 then - local s=hsbw() or 0 - i=i+s+1 + hsbw() + if version=="cff" then + r=r+1;result[r]=encode[lsb] + r=r+1;result[r]=chars[22] + else + end + i=i+1 else + if trace_charstrings then + showstate(reverse[t] or "<action>") + end if top>0 then for i=1,top do r=r+1;result[r]=encode[stack[i]] @@ -10789,7 +10911,7 @@ end end else if trace_charstrings then - showvalue("<action>",t) + showstate(reverse[t] or "<action>") end top=0 i=i+1 @@ -10808,7 +10930,7 @@ end ((l<1240 and 107) or (l<33900 and 1131) or 32768)+1 end end - local function processshape(tab,index) + local function processshape(tab,index,hack) if not tab then glyphs[index]={ boundingbox={ 0,0,0,0 }, @@ -10821,10 +10943,13 @@ end x=0 y=0 width=false + lsb=0 r=0 top=0 stems=0 result={} + popped=3 + procidx=index xmin=0 xmax=0 ymin=0 @@ -10838,6 +10963,9 @@ end updateregions(vsindex) end process(tab) + if hack then + return x,y + end local boundingbox={ round(xmin), round(ymin), @@ -10892,6 +11020,8 @@ end axis=false regions=data.regions justpass=streams==true + popped=3 + seacs={} if regions then regions={ regions } axis=data.factors or false @@ -10905,6 +11035,8 @@ end locals=false globals=false strings=false + popped=3 + seacs={} end local function setwidths(private) if not private then @@ -10934,6 +11066,29 @@ end for index=1,#charstrings do processshape(charstrings[index],index-1) end + if justpass and next(seacs) then + local charset=data.dictionaries[1].charset + if charset then + local lookup=table.swapped(charset) + for index,v in next,seacs do + local bindex=lookup[standardnames[v.base]] + local aindex=lookup[standardnames[v.accent]] + local bglyph=bindex and glyphs[bindex] + local aglyph=aindex and glyphs[aindex] + if bglyph and aglyph then + local jp=justpass + justpass=false + local x,y=processshape(charstrings[bindex+1],bindex,true) + justpass=jp + local base=bglyph.stream + local accent=aglyph.stream + local moveto=encode[-x-v.asb+v.adx]..chars[22]..encode[-y+v.ady]..chars[ 4] + base=sub(base,1,#base-1) + glyphs[index].stream=base..moveto..accent + end + end + end + end stopparsing(fontdata,data) else report("no charstrings") @@ -10950,6 +11105,7 @@ end vsindex=dictionary.vsindex or 0 glyphs=glphs or {} justpass=streams==true + seacs={} globalbias,localbias=setbias(globals,locals,nobias) nominalwidth,defaultwidth=setwidths(dictionary.private) processshape(tab,index-1) @@ -11296,10 +11452,10 @@ function readers.cffcheck(filename) end end -end --- [luaotfload, fontloader-2019-10-29.lua scope for “font-cff”] --- +end --- [luaotfload, fontloader-2020-02-02.lua scope for “font-cff”] --- -do --- [luaotfload, fontloader-2019-10-29.lua scope for “font-ttf” 44e61cef50dab9b1aaf48130f9367c34] --- +do --- [luaotfload, fontloader-2020-02-02.lua scope for “font-ttf” 44e61cef50dab9b1aaf48130f9367c34] --- if not modules then modules={} end modules ['font-ttf']={ version=1.001, @@ -12469,10 +12625,10 @@ function readers.gvar(f,fontdata,specification,glyphdata,shapedata) end end -end --- [luaotfload, fontloader-2019-10-29.lua scope for “font-ttf”] --- +end --- [luaotfload, fontloader-2020-02-02.lua scope for “font-ttf”] --- -do --- [luaotfload, fontloader-2019-10-29.lua scope for “font-dsp” 5d3db0184c903829b2c5bddcb8cdb14c] --- +do --- [luaotfload, fontloader-2020-02-02.lua scope for “font-dsp” 5d3db0184c903829b2c5bddcb8cdb14c] --- if not modules then modules={} end modules ['font-dsp']={ version=1.001, @@ -15719,10 +15875,10 @@ function readers.mvar(f,fontdata,specification) end end -end --- [luaotfload, fontloader-2019-10-29.lua scope for “font-dsp”] --- +end --- [luaotfload, fontloader-2020-02-02.lua scope for “font-dsp”] --- -do --- [luaotfload, fontloader-2019-10-29.lua scope for “font-oup” 0cef35af01739f52fd09feb5401192ae] --- +do --- [luaotfload, fontloader-2020-02-02.lua scope for “font-oup” 0cef35af01739f52fd09feb5401192ae] --- if not modules then modules={} end modules ['font-oup']={ version=1.001, @@ -18363,10 +18519,10 @@ function readers.expand(data) expandlookups(sublookups) end -end --- [luaotfload, fontloader-2019-10-29.lua scope for “font-oup”] --- +end --- [luaotfload, fontloader-2020-02-02.lua scope for “font-oup”] --- -do --- [luaotfload, fontloader-2019-10-29.lua scope for “font-otl” ec0241b7465a7713e53c246e8e9fb2a8] --- +do --- [luaotfload, fontloader-2020-02-02.lua scope for “font-otl” ec0241b7465a7713e53c246e8e9fb2a8] --- if not modules then modules={} end modules ['font-otl']={ version=1.001, @@ -19070,10 +19226,10 @@ otf.coverup={ end } -end --- [luaotfload, fontloader-2019-10-29.lua scope for “font-otl”] --- +end --- [luaotfload, fontloader-2020-02-02.lua scope for “font-otl”] --- -do --- [luaotfload, fontloader-2019-10-29.lua scope for “font-oto” 52804afd96f4be005f513a012b874668] --- +do --- [luaotfload, fontloader-2020-02-02.lua scope for “font-oto” 24238a7c600d090a8ee88312321dd9b3] --- if not modules then modules={} end modules ['font-oto']={ version=1.001, @@ -19085,7 +19241,7 @@ if not modules then modules={} end modules ['font-oto']={ local concat,unpack=table.concat,table.unpack local insert,remove=table.insert,table.remove local format,gmatch,gsub,find,match,lower,strip=string.format,string.gmatch,string.gsub,string.find,string.match,string.lower,string.strip -local type,next,tonumber,tostring,rawget=type,next,tonumber,tostring,rawget +local type,next,tonumber,tostring=type,next,tonumber,tostring local trace_baseinit=false trackers.register("otf.baseinit",function(v) trace_baseinit=v end) local trace_singles=false trackers.register("otf.singles",function(v) trace_singles=v end) local trace_multiples=false trackers.register("otf.multiples",function(v) trace_multiples=v end) @@ -19531,10 +19687,10 @@ registerotffeature { } otf.basemodeinitializer=featuresinitializer -end --- [luaotfload, fontloader-2019-10-29.lua scope for “font-oto”] --- +end --- [luaotfload, fontloader-2020-02-02.lua scope for “font-oto”] --- -do --- [luaotfload, fontloader-2019-10-29.lua scope for “font-otj” 66c7a910d95d4a52b81061de776898e1] --- +do --- [luaotfload, fontloader-2020-02-02.lua scope for “font-otj” 66c7a910d95d4a52b81061de776898e1] --- if not modules then modules={} end modules ['font-otj']={ version=1.001, @@ -20991,10 +21147,10 @@ function injections.handler(head,where) end end -end --- [luaotfload, fontloader-2019-10-29.lua scope for “font-otj”] --- +end --- [luaotfload, fontloader-2020-02-02.lua scope for “font-otj”] --- -do --- [luaotfload, fontloader-2019-10-29.lua scope for “font-ota” d6dfb94563d6a52675e274b2e673e4a6] --- +do --- [luaotfload, fontloader-2020-02-02.lua scope for “font-ota” d6dfb94563d6a52675e274b2e673e4a6] --- if not modules then modules={} end modules ['font-ota']={ version=1.001, @@ -21371,10 +21527,10 @@ directives.register("otf.analyze.useunicodemarks",function(v) analyzers.useunicodemarks=v end) -end --- [luaotfload, fontloader-2019-10-29.lua scope for “font-ota”] --- +end --- [luaotfload, fontloader-2020-02-02.lua scope for “font-ota”] --- -do --- [luaotfload, fontloader-2019-10-29.lua scope for “font-ots” d6a0ce4b40cd4ee1895e2248dcf87d37] --- +do --- [luaotfload, fontloader-2020-02-02.lua scope for “font-ots” d0107799ec82da7f96dafe9626c5ee7f] --- if not modules then modules={} end modules ['font-ots']={ version=1.001, @@ -21466,6 +21622,7 @@ local find_node_tail=nuts.tail local flush_node_list=nuts.flush_list local flush_node=nuts.flush_node local end_of_math=nuts.end_of_math +local start_of_par=nuts.start_of_par local setmetatable=setmetatable local setmetatableindex=table.setmetatableindex local nextnode=nuts.traversers.node @@ -24436,7 +24593,7 @@ do checkstep(head) end local initialrl=0 - if getid(head)==localpar_code and getsubtype(head)==0 then + if getid(head)==localpar_code and start_of_par(head) then initialrl=pardirstate(head) elseif direction==1 or direction=="TRT" then initialrl=-1 @@ -24768,19 +24925,25 @@ registerotffeature { plug=otf.pluginprocessor, } } +local function markinitializer(tfmdata,value) + local properties=tfmdata.properties + properties.checkmarks=value +end +registerotffeature { + name="checkmarks", + description="check mark widths", + default=true, + initializers={ + node=markinitializer, + }, +} otf.handlers=handlers +if context then + return +else +end local setspacekerns=nodes.injections.setspacekerns if not setspacekerns then os.exit() end -local tag="kern" -if fontfeatures then - function handlers.trigger_space_kerns(head,dataset,sequence,initialrl,font,attr) - local features=fontfeatures[font] - local enabled=features and features.spacekern and features[tag] - if enabled then - setspacekerns(font,sequence) - end - return head,enabled - end -else +local tag="kern" function handlers.trigger_space_kerns(head,dataset,sequence,initialrl,font,attr) local shared=fontdata[font].shared local features=shared and shared.features @@ -24790,7 +24953,6 @@ else end return head,enabled end -end local function hasspacekerns(data) local resources=data.resources local sequences=resources.sequences @@ -24975,23 +25137,11 @@ registerotffeature { node=spaceinitializer, }, } -local function markinitializer(tfmdata,value) - local properties=tfmdata.properties - properties.checkmarks=value -end -registerotffeature { - name="checkmarks", - description="check mark widths", - default=true, - initializers={ - node=markinitializer, - }, -} -end --- [luaotfload, fontloader-2019-10-29.lua scope for “font-ots”] --- +end --- [luaotfload, fontloader-2020-02-02.lua scope for “font-ots”] --- -do --- [luaotfload, fontloader-2019-10-29.lua scope for “font-osd” 39e92f6e575741646d75ea79e3be87f3] --- +do --- [luaotfload, fontloader-2020-02-02.lua scope for “font-osd” 39e92f6e575741646d75ea79e3be87f3] --- if not modules then modules={} end modules ['font-osd']={ version=1.001, @@ -27423,10 +27573,10 @@ for i=1,nofscripts do methods[scripts_two[i]]=method_two end -end --- [luaotfload, fontloader-2019-10-29.lua scope for “font-osd”] --- +end --- [luaotfload, fontloader-2020-02-02.lua scope for “font-osd”] --- -do --- [luaotfload, fontloader-2019-10-29.lua scope for “font-ocl” ba40df1a92b9b42a5c70d20c28f44759] --- +do --- [luaotfload, fontloader-2020-02-02.lua scope for “font-ocl” c1f4cbea3c4ec5002a04fc637b135711] --- if not modules then modules={} end modules ['font-ocl']={ version=1.001, @@ -27740,7 +27890,6 @@ do local pdfshapes={} local inkscape=runner() if inkscape then - local indices=fonts.getindices(tfmdata) local descriptions=tfmdata.descriptions local nofshapes=#svgshapes local f_svgfile=formatters["temp-otf-svg-shape-%i.svg"] @@ -27964,10 +28113,10 @@ if context then } end -end --- [luaotfload, fontloader-2019-10-29.lua scope for “font-ocl”] --- +end --- [luaotfload, fontloader-2020-02-02.lua scope for “font-ocl”] --- -do --- [luaotfload, fontloader-2019-10-29.lua scope for “font-otc” 1204a2fdc436e644127c0aa38ab69607] --- +do --- [luaotfload, fontloader-2020-02-02.lua scope for “font-otc” 1204a2fdc436e644127c0aa38ab69607] --- if not modules then modules={} end modules ['font-otc']={ version=1.001, @@ -28724,10 +28873,10 @@ end otf.enhancers.enhance=enhance otf.enhancers.register("check extra features",enhance) -end --- [luaotfload, fontloader-2019-10-29.lua scope for “font-otc”] --- +end --- [luaotfload, fontloader-2020-02-02.lua scope for “font-otc”] --- -do --- [luaotfload, fontloader-2019-10-29.lua scope for “font-onr” d4d2449b4084e6afb1837ae5835082cc] --- +do --- [luaotfload, fontloader-2020-02-02.lua scope for “font-onr” 22572ec0f86f53631e14b6d1ed43ee51] --- if not modules then modules={} end modules ['font-onr']={ version=1.001, @@ -28737,7 +28886,7 @@ if not modules then modules={} end modules ['font-onr']={ license="see context related readme files" } local fonts,logs,trackers,resolvers=fonts,logs,trackers,resolvers -local next,type,tonumber,rawget,rawset=next,type,tonumber,rawget,rawset +local next,type,tonumber,rawset=next,type,tonumber,rawset local match,lower,gsub,strip,find=string.match,string.lower,string.gsub,string.strip,string.find local char,byte,sub=string.char,string.byte,string.sub local abs=math.abs @@ -29099,10 +29248,10 @@ function readers.getinfo(filename) end end -end --- [luaotfload, fontloader-2019-10-29.lua scope for “font-onr”] --- +end --- [luaotfload, fontloader-2020-02-02.lua scope for “font-onr”] --- -do --- [luaotfload, fontloader-2019-10-29.lua scope for “font-one” 987c5c5ed3754ad2feab80985067d59e] --- +do --- [luaotfload, fontloader-2020-02-02.lua scope for “font-one” 987c5c5ed3754ad2feab80985067d59e] --- if not modules then modules={} end modules ['font-one']={ version=1.001, @@ -29813,10 +29962,10 @@ registerafmenhancer("normalize features",enhance_normalize_features) registerafmenhancer("check extra features",otfenhancers.enhance) registerafmenhancer("fix names",enhance_fix_names) -end --- [luaotfload, fontloader-2019-10-29.lua scope for “font-one”] --- +end --- [luaotfload, fontloader-2020-02-02.lua scope for “font-one”] --- -do --- [luaotfload, fontloader-2019-10-29.lua scope for “font-afk” 54d554530e75c57c56ee76234724e26d] --- +do --- [luaotfload, fontloader-2020-02-02.lua scope for “font-afk” 54d554530e75c57c56ee76234724e26d] --- if not modules then modules={} end modules ['font-afk']={ version=1.001, @@ -29983,10 +30132,10 @@ fonts.handlers.afm.helpdata={ } } -end --- [luaotfload, fontloader-2019-10-29.lua scope for “font-afk”] --- +end --- [luaotfload, fontloader-2020-02-02.lua scope for “font-afk”] --- -do --- [luaotfload, fontloader-2019-10-29.lua scope for “fonts-tfm” 3bbba3214fd0b8c6f35ad85592fc2917] --- +do --- [luaotfload, fontloader-2020-02-02.lua scope for “fonts-tfm” 3bbba3214fd0b8c6f35ad85592fc2917] --- if not modules then modules={} end modules ['luatex-fonts-tfm']={ version=1.001, @@ -30501,10 +30650,10 @@ registertfmfeature { } } -end --- [luaotfload, fontloader-2019-10-29.lua scope for “fonts-tfm”] --- +end --- [luaotfload, fontloader-2020-02-02.lua scope for “fonts-tfm”] --- -do --- [luaotfload, fontloader-2019-10-29.lua scope for “font-lua” 55b281fb98f7bd848fc19928f376f647] --- +do --- [luaotfload, fontloader-2020-02-02.lua scope for “font-lua” 55b281fb98f7bd848fc19928f376f647] --- if not modules then modules={} end modules ['font-lua']={ version=1.001, @@ -30544,10 +30693,10 @@ function readers.lua(specification) return check_lua(specification,fullname) end -end --- [luaotfload, fontloader-2019-10-29.lua scope for “font-lua”] --- +end --- [luaotfload, fontloader-2020-02-02.lua scope for “font-lua”] --- -do --- [luaotfload, fontloader-2019-10-29.lua scope for “font-def” f66c365dae4499f982d8bf16e5d37de3] --- +do --- [luaotfload, fontloader-2020-02-02.lua scope for “font-def” c525b9f55da1c736a1f6939c0a6f8f00] --- if not modules then modules={} end modules ['font-def']={ version=1.001, @@ -30579,7 +30728,6 @@ local variants=allocate() specifiers.variants=variants definers.methods=definers.methods or {} local internalized=allocate() -local lastdefined=nil local loadedfonts=constructors.loadedfonts local designsizes=constructors.designsizes local resolvefile=fontgoodies and fontgoodies.filenames and fontgoodies.filenames.resolve or function(s) return s end @@ -30878,9 +31026,6 @@ function constructors.readanddefine(name,size) end return fontdata[id],id end -function definers.current() - return lastdefined -end function definers.registered(hash) local id=internalized[hash] return id,id and fontdata[id] @@ -30931,7 +31076,6 @@ function definers.read(specification,size,id) end end end - lastdefined=tfmdata or id if not tfmdata then report_defining("unknown font %a, loading aborted",specification.name) elseif trace_defining and type(tfmdata)=="table" then @@ -30947,12 +31091,14 @@ end function font.getfont(id) return fontdata[id] end -callbacks.register('define_font',definers.read,"definition of fonts (tfmdata preparation)") +if not context then + callbacks.register('define_font',definers.read,"definition of fonts (tfmdata preparation)") +end -end --- [luaotfload, fontloader-2019-10-29.lua scope for “font-def”] --- +end --- [luaotfload, fontloader-2020-02-02.lua scope for “font-def”] --- -do --- [luaotfload, fontloader-2019-10-29.lua scope for “fonts-def” 5ad79120ebc5e60f4d322fb3ee13bffe] --- +do --- [luaotfload, fontloader-2020-02-02.lua scope for “fonts-def” 5ad79120ebc5e60f4d322fb3ee13bffe] --- if not modules then modules={} end modules ['luatex-fonts-def']={ version=1.001, @@ -31033,10 +31179,10 @@ function fonts.definers.applypostprocessors(tfmdata) return tfmdata end -end --- [luaotfload, fontloader-2019-10-29.lua scope for “fonts-def”] --- +end --- [luaotfload, fontloader-2020-02-02.lua scope for “fonts-def”] --- -do --- [luaotfload, fontloader-2019-10-29.lua scope for “fonts-ext” 01015ab3758cdc2af29394e6d502a91a] --- +do --- [luaotfload, fontloader-2020-02-02.lua scope for “fonts-ext” 01015ab3758cdc2af29394e6d502a91a] --- if not modules then modules={} end modules ['luatex-fonts-ext']={ version=1.001, @@ -31222,10 +31368,10 @@ registerotffeature { } } -end --- [luaotfload, fontloader-2019-10-29.lua scope for “fonts-ext”] --- +end --- [luaotfload, fontloader-2020-02-02.lua scope for “fonts-ext”] --- -do --- [luaotfload, fontloader-2019-10-29.lua scope for “font-imp-tex” 77c374b0ef00c2fb12188ec42beb4257] --- +do --- [luaotfload, fontloader-2020-02-02.lua scope for “font-imp-tex” 77c374b0ef00c2fb12188ec42beb4257] --- if not modules then modules={} end modules ['font-imp-tex']={ version=1.001, @@ -31324,10 +31470,10 @@ registerotffeature { description="arabic digits", } -end --- [luaotfload, fontloader-2019-10-29.lua scope for “font-imp-tex”] --- +end --- [luaotfload, fontloader-2020-02-02.lua scope for “font-imp-tex”] --- -do --- [luaotfload, fontloader-2019-10-29.lua scope for “font-imp-ligatures” 043daa4fcccf2560868da359d71d3a4a] --- +do --- [luaotfload, fontloader-2020-02-02.lua scope for “font-imp-ligatures” 043daa4fcccf2560868da359d71d3a4a] --- if not modules then modules={} end modules ['font-imp-ligatures']={ version=1.001, @@ -31441,10 +31587,10 @@ if context then } end -end --- [luaotfload, fontloader-2019-10-29.lua scope for “font-imp-ligatures”] --- +end --- [luaotfload, fontloader-2020-02-02.lua scope for “font-imp-ligatures”] --- -do --- [luaotfload, fontloader-2019-10-29.lua scope for “font-imp-italics” fe1ca80fb5ea4a2f8d2d5c484e7ba913] --- +do --- [luaotfload, fontloader-2020-02-02.lua scope for “font-imp-italics” fe1ca80fb5ea4a2f8d2d5c484e7ba913] --- if not modules then modules={} end modules ['font-imp-italics']={ version=1.001, @@ -31550,10 +31696,10 @@ if context then registerafmfeature(dimensions_specification) end -end --- [luaotfload, fontloader-2019-10-29.lua scope for “font-imp-italics”] --- +end --- [luaotfload, fontloader-2020-02-02.lua scope for “font-imp-italics”] --- -do --- [luaotfload, fontloader-2019-10-29.lua scope for “font-imp-effects” 73a660359a0ec71e44cc2b7225a715ac] --- +do --- [luaotfload, fontloader-2020-02-02.lua scope for “font-imp-effects” 73a660359a0ec71e44cc2b7225a715ac] --- if not modules then modules={} end modules ['font-imp-effects']={ version=1.001, @@ -31910,10 +32056,10 @@ local specification={ registerotffeature(specification) registerafmfeature(specification) -end --- [luaotfload, fontloader-2019-10-29.lua scope for “font-imp-effects”] --- +end --- [luaotfload, fontloader-2020-02-02.lua scope for “font-imp-effects”] --- -do --- [luaotfload, fontloader-2019-10-29.lua scope for “fonts-lig” b9dbe77ce747d4c35bb2a20ffbe5aa51] --- +do --- [luaotfload, fontloader-2020-02-02.lua scope for “fonts-lig” b9dbe77ce747d4c35bb2a20ffbe5aa51] --- fonts.handlers.otf.addfeature { @@ -33982,10 +34128,10 @@ fonts.handlers.otf.addfeature { ["type"]="ligature", } -end --- [luaotfload, fontloader-2019-10-29.lua scope for “fonts-lig”] --- +end --- [luaotfload, fontloader-2020-02-02.lua scope for “fonts-lig”] --- -do --- [luaotfload, fontloader-2019-10-29.lua scope for “fonts-gbn” d25472d54c4841db43a745764a63533e] --- +do --- [luaotfload, fontloader-2020-02-02.lua scope for “fonts-gbn” d25472d54c4841db43a745764a63533e] --- if not modules then modules={} end modules ['luatex-fonts-gbn']={ version=1.001, @@ -34250,7 +34396,7 @@ function nodes.simple_font_handler(head,groupcode,size,packtype,direction) return head end -end --- [luaotfload, fontloader-2019-10-29.lua scope for “fonts-gbn”] --- +end --- [luaotfload, fontloader-2020-02-02.lua scope for “fonts-gbn”] --- --- vim:ft=lua:sw=2:ts=8:et:tw=79 diff --git a/Master/texmf-dist/tex/luatex/luaotfload/fontloader-basics-gen.lua b/Master/texmf-dist/tex/luatex/luaotfload/fontloader-basics-gen.lua index 3959ca02221..f52fec69676 100644 --- a/Master/texmf-dist/tex/luatex/luaotfload/fontloader-basics-gen.lua +++ b/Master/texmf-dist/tex/luatex/luaotfload/fontloader-basics-gen.lua @@ -189,7 +189,7 @@ local readables = { } local usingjit = jit if not caches.namespace or caches.namespace == "" or caches.namespace == "context" then - caches.namespace = 'generic' + caches.namespace = 'generic-dev' end do diff --git a/Master/texmf-dist/tex/luatex/luaotfload/fontloader-basics-nod.lua b/Master/texmf-dist/tex/luatex/luaotfload/fontloader-basics-nod.lua index 172fcc7f7ed..be82277bd49 100644 --- a/Master/texmf-dist/tex/luatex/luaotfload/fontloader-basics-nod.lua +++ b/Master/texmf-dist/tex/luatex/luaotfload/fontloader-basics-nod.lua @@ -279,3 +279,14 @@ if not nuts.setreplace then end end + +do + + local getsubtype = nuts.getsubtype + + function nuts.start_of_par(n) + local s = getsubtype(n) + return s == 0 or s == 2 -- sorry, hardcoded, won't change anyway + end + +end diff --git a/Master/texmf-dist/tex/luatex/luaotfload/fontloader-data-con.lua b/Master/texmf-dist/tex/luatex/luaotfload/fontloader-data-con.lua index c79fca7c5c1..ec2251b3534 100644 --- a/Master/texmf-dist/tex/luatex/luaotfload/fontloader-data-con.lua +++ b/Master/texmf-dist/tex/luatex/luaotfload/fontloader-data-con.lua @@ -6,6 +6,7 @@ if not modules then modules = { } end modules ['data-con'] = { license = "see context related readme files" } +local setmetatable = setmetatable local format, lower, gsub = string.format, string.lower, string.gsub local trace_cache = false trackers.register("resolvers.cache", function(v) trace_cache = v end) @@ -13,21 +14,28 @@ local trace_containers = false trackers.register("resolvers.containers", functi local trace_storage = false trackers.register("resolvers.storage", function(v) trace_storage = v end) --[[ldx-- -<p>Once we found ourselves defining similar cache constructs -several times, containers were introduced. Containers are used -to collect tables in memory and reuse them when possible based -on (unique) hashes (to be provided by the calling function).</p> +<p>Once we found ourselves defining similar cache constructs several times, +containers were introduced. Containers are used to collect tables in memory and +reuse them when possible based on (unique) hashes (to be provided by the calling +function).</p> -<p>Caching to disk is disabled by default. Version numbers are -stored in the saved table which makes it possible to change the -table structures without bothering about the disk cache.</p> +<p>Caching to disk is disabled by default. Version numbers are stored in the +saved table which makes it possible to change the table structures without +bothering about the disk cache.</p> -<p>Examples of usage can be found in the font related code.</p> +<p>Examples of usage can be found in the font related code. This code is not +ideal but we need it in generic too so we compromise.</p> --ldx]]-- -containers = containers or { } -local containers = containers -containers.usecache = true +containers = containers or { } +local containers = containers +containers.usecache = true + +local getwritablepath = caches.getwritablepath +local getreadablepaths = caches.getreadablepaths +local cacheiswritable = caches.is_writable +local loaddatafromcache = caches.loaddata +local savedataincache = caches.savedata local report_containers = logs.reporter("resolvers","containers") @@ -36,11 +44,11 @@ local allocated = { } local mt = { __index = function(t,k) if k == "writable" then - local writable = caches.getwritablepath(t.category,t.subcategory) or { "." } + local writable = getwritablepath(t.category,t.subcategory) or { "." } t.writable = writable return writable elseif k == "readables" then - local readables = caches.getreadablepaths(t.category,t.subcategory) or { "." } + local readables = getreadablepaths(t.category,t.subcategory) or { "." } t.readables = readables return readables end @@ -64,8 +72,8 @@ function containers.define(category, subcategory, version, enabled) enabled = enabled, version = version or math.pi, -- after all, this is TeX trace = false, - -- writable = caches.getwritablepath and caches.getwritablepath (category,subcategory) or { "." }, - -- readables = caches.getreadablepaths and caches.getreadablepaths(category,subcategory) or { "." }, + -- writable = getwritablepath and getwritablepath (category,subcategory) or { "." }, + -- readables = getreadablepaths and getreadablepaths(category,subcategory) or { "." }, } setmetatable(s,mt) c[subcategory] = s @@ -75,7 +83,7 @@ function containers.define(category, subcategory, version, enabled) end function containers.is_usable(container,name) - return container.enabled and caches and caches.is_writable(container.writable, name) + return container.enabled and caches and cacheiswritable(container.writable, name) end function containers.is_valid(container,name) @@ -91,7 +99,7 @@ function containers.read(container,name) local storage = container.storage local stored = storage[name] if not stored and container.enabled and caches and containers.usecache then - stored = caches.loaddata(container.readables,name,container.writable) + stored = loaddatafromcache(container.readables,name,container.writable) if stored and stored.cache_version == container.version then if trace_cache or trace_containers then report_containers("action %a, category %a, name %a","load",container.subcategory,name) @@ -108,17 +116,20 @@ function containers.read(container,name) return stored end -function containers.write(container, name, data) +function containers.write(container, name, data, fast) if data then data.cache_version = container.version if container.enabled and caches then - local unique, shared = data.unique, data.shared - data.unique, data.shared = nil, nil - caches.savedata(container.writable, name, data) + local unique = data.unique + local shared = data.shared + data.unique = nil + data.shared = nil + savedataincache(container.writable, name, data, fast) if trace_cache or trace_containers then report_containers("action %a, category %a, name %a","save",container.subcategory,name) end - data.unique, data.shared = unique, shared + data.unique = unique + data.shared = shared end if trace_cache or trace_containers then report_containers("action %a, category %a, name %a","store",container.subcategory,name) diff --git a/Master/texmf-dist/tex/luatex/luaotfload/fontloader-font-cff.lua b/Master/texmf-dist/tex/luatex/luaotfload/fontloader-font-cff.lua index a19acc1a1dc..5f79ba7a332 100644 --- a/Master/texmf-dist/tex/luatex/luaotfload/fontloader-font-cff.lua +++ b/Master/texmf-dist/tex/luatex/luaotfload/fontloader-font-cff.lua @@ -27,7 +27,7 @@ if not modules then modules = { } end modules ['font-cff'] = { -- the other hand, we can now feed back cff2 stuff. local next, type, tonumber, rawget = next, type, tonumber, rawget -local byte, char, gmatch = string.byte, string.char, string.gmatch +local byte, char, gmatch, sub = string.byte, string.char, string.gmatch, string.sub local concat, remove, unpack = table.concat, table.remove, table.unpack 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 @@ -145,6 +145,38 @@ local defaultstrings = { [0] = -- taken from ff "Black", "Bold", "Book", "Light", "Medium", "Regular", "Roman", "Semibold", } +local standardnames = { [0] = -- needed for seac + false, false, false, false, false, false, false, false, false, false, false, + false, false, false, false, false, false, false, false, false, false, false, + false, false, false, false, false, false, false, false, false, false, + "space", "exclam", "quotedbl", "numbersign", "dollar", "percent", + "ampersand", "quoteright", "parenleft", "parenright", "asterisk", "plus", + "comma", "hyphen", "period", "slash", "zero", "one", "two", "three", "four", + "five", "six", "seven", "eight", "nine", "colon", "semicolon", "less", + "equal", "greater", "question", "at", "A", "B", "C", "D", "E", "F", "G", "H", + "I", "J", "K", "L", "M", "N", "O", "P", "Q", "R", "S", "T", "U", "V", "W", + "X", "Y", "Z", "bracketleft", "backslash", "bracketright", "asciicircum", + "underscore", "quoteleft", "a", "b", "c", "d", "e", "f", "g", "h", "i", "j", + "k", "l", "m", "n", "o", "p", "q", "r", "s", "t", "u", "v", "w", "x", "y", + "z", "braceleft", "bar", "braceright", "asciitilde", false, false, false, + false, false, false, false, false, false, false, false, false, false, false, + false, false, false, false, false, false, false, false, false, false, false, + false, false, false, false, false, false, false, false, false, "exclamdown", + "cent", "sterling", "fraction", "yen", "florin", "section", "currency", + "quotesingle", "quotedblleft", "guillemotleft", "guilsinglleft", + "guilsinglright", "fi", "fl", false, "endash", "dagger", "daggerdbl", + "periodcentered", false, "paragraph", "bullet", "quotesinglbase", + "quotedblbase", "quotedblright", "guillemotright", "ellipsis", "perthousand", + false, "questiondown", false, "grave", "acute", "circumflex", "tilde", + "macron", "breve", "dotaccent", "dieresis", false, "ring", "cedilla", false, + "hungarumlaut", "ogonek", "caron", "emdash", false, false, false, false, + false, false, false, false, false, false, false, false, false, false, false, + false, "AE", false, "ordfeminine", false, false, false, false, "Lslash", + "Oslash", "OE", "ordmasculine", false, false, false, false, false, "ae", + false, false, false, "dotlessi", false, false, "lslash", "oslash", "oe", + "germandbls", false, false, false, false +} + local cffreaders = { readbyte, readushort, @@ -655,6 +687,7 @@ do local x = 0 local y = 0 local width = false + local lsb = 0 local r = 0 local stems = 0 local globalbias = 0 @@ -678,6 +711,9 @@ do local factors = false local axis = false local vsindex = 0 + local justpass = false + local seacs = { } + local procidx = nil local function showstate(where) report("%w%-10s : [%s] n=%i",depth*2,where,concat(stack," ",1,top),top) @@ -1264,7 +1300,7 @@ do end local function divide() - if version == 1 then + if version == "cff" then local d = stack[top] top = top - 1 stack[top] = stack[top] / d @@ -1272,7 +1308,7 @@ do end local function closepath() - if version == 1 then + if version == "cff" then if trace_charstrings then showstate("closepath") end @@ -1281,65 +1317,90 @@ do end local function hsbw() - if version == 1 then + if version == "cff" then if trace_charstrings then showstate("hsbw") end - -- lsb = stack[top-1] + lsb = stack[top-1] or 0 width = stack[top] end top = 0 end - local function seac() - if version == 1 then + local function sbw() + if version == "cff" then if trace_charstrings then - showstate("seac") + showstate("sbw") end + lsb = stack[top-3] + width = stack[top-1] end top = 0 end - local function sbw() - if version == 1 then + -- asb adx ady bchar achar seac (accented characters) + + local function seac() + if version == "cff" then if trace_charstrings then - showstate("sbw") + showstate("seac") end - width = stack[top-1] end top = 0 end - -- these are probably used for special cases i.e. call out to postscript + -- These are probably used for special cases i.e. call out to the + -- postscript interpreter (p 61 of the spec as well as chapter 8). + -- + -- This needs checking (I have to ask Taco next time we meet.) + + local popped = 3 + local hints = 3 + + -- arg1 ... argn n othersubr# <callothersubr> (on postscript stack) local function callothersubr() - if version == 1 then - -- we don't support this (ok, we could mimick these othersubs) + if version == "cff" then if trace_charstrings then - showstate("callothersubr (unsupported)") + showstate("callothersubr") + end + if stack[top] == hints then + popped = stack[top-2] + else + popped = 3 end + local t = stack[top-1] + if t then + top = top - (t + 2) + if top < 0 then + top = 0 + end + else + top = 0 + end + else + top = 0 end - top = 0 end + -- <pop> number (from postscript stack) + local function pop() - if version == 1 then - -- we don't support this + if version == "cff" then if trace_charstrings then - showstate("pop (unsupported)") + showstate("pop") end top = top + 1 - stack[top] = 0 -- a dummy + stack[top] = popped else top = 0 end end local function setcurrentpoint() - if version == 1 then - -- we don't support this + if version == "cff" then if trace_charstrings then - showstate("pop (unsupported)") + showstate("setcurrentpoint (unsupported)") end x = x + stack[top-1] y = y + stack[top] @@ -1489,6 +1550,41 @@ do hvcurveto, -- 31 } + local reverse = { [0] = + "unsupported", + "getstem", + "unsupported", + "getstem", + "vmoveto", + "rlineto", + "hlineto", + "vlineto", + "rrcurveto", + "unsupported", + "unsupported", + "unsupported", + "unsupported", + "hsbw", + "unsupported", + "setvsindex", + "blend", + "unsupported", + "getstem", + "getmask", + "getmask", + "rmoveto", + "hmoveto", + "getstem", + "rcurveline", + "rlinecurve", + "vvcurveto", + "hhcurveto", + "unsupported", + "unsupported", + "vhcurveto", + "hvcurveto", + } + local subactions = { -- cff 1 [000] = dotsection, @@ -1540,6 +1636,7 @@ do for i=1132,2048 do t[i] = char(28,band(rshift(i,8),0xFF),band(i,0xFF)) end + -- we could inline some ... setmetatableindex(encode,function(t,k) -- 16.16-bit signed fixed value local r = round(k) @@ -1625,7 +1722,7 @@ do local function call(scope,list,bias) -- ,process) depth = depth + 1 if top == 0 then - showstate(formatters["unknown %s call %s"](scope,"?")) + showstate(formatters["unknown %s call %s, case %s"](scope,"?",1)) top = 0 else local index = stack[top] + bias @@ -1637,7 +1734,7 @@ do if tab then process(tab) else - showstate(formatters["unknown %s call %s"](scope,index)) + showstate(formatters["unknown %s call %s, case %s"](scope,index,2)) top = 0 end end @@ -1646,8 +1743,6 @@ do -- precompiling and reuse is much slower than redoing the calls - local justpass = false - -- local function decode(str) -- local a, b, c, d, e = byte(str,1,5) -- if a == 28 then @@ -1765,6 +1860,17 @@ do r = r + 1 ; result[r] = chars[12] r = r + 1 ; result[r] = chars[t] top = 0 + elseif t == 6 then + seacs[procidx] = { + asb = stack[1], + adx = stack[2], + ady = stack[3], + base = stack[4], + accent = stack[5], + width = width, + lsb = lsb, + } + top = 0 else local a = subactions[t] if a then @@ -1796,46 +1902,56 @@ do -- cff 1: (when cff2 strip them) elseif t == 1 or t == 3 or t == 18 or operation == 23 then p_getstem() -- at the start -if true then - if top > 0 then - for i=1,top do - r = r + 1 ; result[r] = encode[stack[i]] + if true then + if top > 0 then + for i=1,top do + r = r + 1 ; result[r] = encode[stack[i]] + end + top = 0 end + r = r + 1 ; result[r] = chars[t] + else top = 0 end - r = r + 1 ; result[r] = chars[t] -else - top = 0 -end i = i + 1 -- cff 1: (when cff2 strip them) elseif t == 19 or t == 20 then local s = p_getmask() or 0 -- after the stems -if true then - if top > 0 then - for i=1,top do - r = r + 1 ; result[r] = encode[stack[i]] + if true then + if top > 0 then + for i=1,top do + r = r + 1 ; result[r] = encode[stack[i]] + end + top = 0 + end + r = r + 1 ; result[r] = chars[t] + for j=1,s do + i = i + 1 + r = r + 1 ; result[r] = chars[tab[i]] end + else + i = i + s top = 0 end - r = r + 1 ; result[r] = chars[t] - for j=1,s do - i = i + 1 - r = r + 1 ; result[r] = chars[tab[i]] - end -else - i = i + s - top = 0 -end i = i + 1 -- cff 1: closepath elseif t == 9 then top = 0 i = i + 1 elseif t == 13 then - local s = hsbw() or 0 - i = i + s + 1 + hsbw() + if version == "cff" then + -- we do a moveto over lsb + r = r + 1 ; result[r] = encode[lsb] + r = r + 1 ; result[r] = chars[22] + else + -- lsb is supposed to be zero + end + i = i + 1 else + if trace_charstrings then + showstate(reverse[t] or "<action>") + end if top > 0 then for i=1,top do r = r + 1 ; result[r] = encode[stack[i]] @@ -1856,7 +1972,7 @@ end end else if trace_charstrings then - showvalue("<action>",t) + showstate(reverse[t] or "<action>") end top = 0 i = i + 1 @@ -1915,7 +2031,7 @@ end end end - local function processshape(tab,index) + local function processshape(tab,index,hack) if not tab then glyphs[index] = { @@ -1931,10 +2047,13 @@ end x = 0 y = 0 width = false + lsb = 0 r = 0 top = 0 stems = 0 result = { } -- we could reuse it when only boundingbox calculations are needed + popped = 3 + procidx = index xmin = 0 xmax = 0 @@ -1952,6 +2071,10 @@ end process(tab) + if hack then + return x, y + end + local boundingbox = { round(xmin), round(ymin), @@ -2016,6 +2139,8 @@ end axis = false regions = data.regions justpass = streams == true + popped = 3 + seacs = { } if regions then regions = { regions } -- needs checking axis = data.factors or false @@ -2030,6 +2155,8 @@ end locals = false globals = false strings = false + popped = 3 + seacs = { } end local function setwidths(private) @@ -2064,7 +2191,35 @@ end startparsing(fontdata,data,streams) for index=1,#charstrings do processshape(charstrings[index],index-1) --- charstrings[index] = nil -- free memory (what if used more often?) + end + if justpass and next(seacs) then + -- old type 1 stuff ... seacs + local charset = data.dictionaries[1].charset + if charset then + local lookup = table.swapped(charset) + for index, v in next, seacs do + local bindex = lookup[standardnames[v.base]] + local aindex = lookup[standardnames[v.accent]] + local bglyph = bindex and glyphs[bindex] + local aglyph = aindex and glyphs[aindex] + if bglyph and aglyph then + -- this is a real ugly hack but we seldom enter this branch (e.g. old lbr) + local jp = justpass + justpass = false + local x, y = processshape(charstrings[bindex+1],bindex,true) + justpass = jp + -- + local base = bglyph.stream + local accent = aglyph.stream + local moveto = encode[-x-v.asb+v.adx] .. chars[22] + .. encode[-y +v.ady] .. chars[ 4] + -- prune an endchar + base = sub(base,1,#base-1) + -- combine them + glyphs[index].stream = base .. moveto .. accent + end + end + end end stopparsing(fontdata,data) else @@ -2085,6 +2240,7 @@ end glyphs = glphs or { } justpass = streams == true + seacs = { } globalbias, localbias = setbias(globals,locals,nobias) nominalwidth, defaultwidth = setwidths(dictionary.private) diff --git a/Master/texmf-dist/tex/luatex/luaotfload/fontloader-font-con.lua b/Master/texmf-dist/tex/luatex/luaotfload/fontloader-font-con.lua index 652794142b5..e42d20d4e1f 100644 --- a/Master/texmf-dist/tex/luatex/luaotfload/fontloader-font-con.lua +++ b/Master/texmf-dist/tex/luatex/luaotfload/fontloader-font-con.lua @@ -40,7 +40,6 @@ local setmetatableindex = table.setmetatableindex -- will be directives constructors.dontembed = allocate() -constructors.autocleanup = true constructors.namemode = "fullpath" -- will be a function constructors.version = 1.01 @@ -51,6 +50,8 @@ constructors.cacheintex = true -- so we see the original table in fonts.fon constructors.addtounicode = true +constructors.fixprotrusion = true + -- This might become an interface: local designsizes = allocate() @@ -134,21 +135,10 @@ make this profitable and the <l n='lua'/> based variant was just faster. A days wasted day but an experience richer.</p> --ldx]]-- --- we can get rid of the tfm instance when we have fast access to the --- scaled character dimensions at the tex end, e.g. a fontobject.width --- actually we already have some of that now as virtual keys in glyphs --- --- flushing the kern and ligature tables from memory saves a lot (only --- base mode) but it complicates vf building where the new characters --- demand this data .. solution: functions that access them - function constructors.cleanuptable(tfmdata) - if constructors.autocleanup and tfmdata.properties.virtualized then - for k, v in next, tfmdata.characters do - if v.commands then v.commands = nil end - -- if v.kerns then v.kerns = nil end - end - end + -- This no longer makes sense because the addition of font.getcopy and its + -- possible usage in generic implicates that we need to return the whole + -- lot now. end -- experimental, sharing kerns (unscaled and scaled) saves memory @@ -466,6 +456,7 @@ function constructors.scale(tfmdata,specification) target.size = scaledpoints -- target.encodingbytes = properties.encodingbytes or 1 + target.subfont = properties.subfont target.embedding = properties.embedding or "subset" target.tounicode = 1 target.cidinfo = properties.cidinfo @@ -598,7 +589,10 @@ function constructors.scale(tfmdata,specification) -- constructors.enhanceparameters(targetparameters) -- official copies for us, now virtual -- - local protrusionfactor = (targetquad ~= 0 and 1000/targetquad) or 0 + -- I need to fix this in luatex ... get rid of quad there so that we can omit this here. + -- + local protrusionfactor = constructors.fixprotrusion and ((targetquad ~= 0 and 1000/targetquad) or 1) or 1 + -- local scaledwidth = defaultwidth * hdelta local scaledheight = defaultheight * vdelta local scaleddepth = defaultdepth * vdelta @@ -1034,6 +1028,7 @@ function constructors.finalize(tfmdata) properties.psname = properties.psname or tfmdata.psname -- properties.encodingbytes = tfmdata.encodingbytes or 1 + properties.subfont = tfmdata.subfont or nil properties.embedding = tfmdata.embedding or "subset" properties.tounicode = tfmdata.tounicode or 1 properties.cidinfo = tfmdata.cidinfo or nil @@ -1067,6 +1062,7 @@ function constructors.finalize(tfmdata) tfmdata.psname = nil -- tfmdata.encodingbytes = nil + tfmdata.subfont = nil tfmdata.embedding = nil tfmdata.tounicode = nil tfmdata.cidinfo = nil diff --git a/Master/texmf-dist/tex/luatex/luaotfload/fontloader-font-def.lua b/Master/texmf-dist/tex/luatex/luaotfload/fontloader-font-def.lua index f3d0f818718..e287bf79ce5 100644 --- a/Master/texmf-dist/tex/luatex/luaotfload/fontloader-font-def.lua +++ b/Master/texmf-dist/tex/luatex/luaotfload/fontloader-font-def.lua @@ -45,7 +45,6 @@ specifiers.variants = variants definers.methods = definers.methods or { } local internalized = allocate() -- internal tex numbers (private) -local lastdefined = nil -- we don't want this one to end up in s-tra-02 local loadedfonts = constructors.loadedfonts local designsizes = constructors.designsizes @@ -455,10 +454,6 @@ not gain much. By the way, passing id's back to in the callback was introduced later in the development.</p> --ldx]]-- -function definers.current() -- or maybe current - return lastdefined -end - function definers.registered(hash) local id = internalized[hash] return id, id and fontdata[id] @@ -511,7 +506,6 @@ function definers.read(specification,size,id) -- id can be optional, name can al end end end - lastdefined = tfmdata or id -- todo ! ! ! ! ! if not tfmdata then -- or id? report_defining( "unknown font %a, loading aborted",specification.name) elseif trace_defining and type(tfmdata) == "table" then @@ -533,4 +527,6 @@ end <p>We overload the <l n='tfm'/> reader.</p> --ldx]]-- -callbacks.register('define_font', definers.read, "definition of fonts (tfmdata preparation)") +if not context then + callbacks.register('define_font', definers.read, "definition of fonts (tfmdata preparation)") +end diff --git a/Master/texmf-dist/tex/luatex/luaotfload/fontloader-font-ini.lua b/Master/texmf-dist/tex/luatex/luaotfload/fontloader-font-ini.lua index 462e30bf909..8bab6d90295 100644 --- a/Master/texmf-dist/tex/luatex/luaotfload/fontloader-font-ini.lua +++ b/Master/texmf-dist/tex/luatex/luaotfload/fontloader-font-ini.lua @@ -52,3 +52,7 @@ fonts.privateoffsets = { mathbase = 0xFF000, -- used for hidden (virtual math) keepnames = false, -- when set to true names are always kept (not for context) } + +if node and not tex.getfontoffamily then + tex.getfontoffamily = node.family_font -- we moved this +end diff --git a/Master/texmf-dist/tex/luatex/luaotfload/fontloader-font-ocl.lua b/Master/texmf-dist/tex/luatex/luaotfload/fontloader-font-ocl.lua index 3752203fa22..77e1538f94d 100644 --- a/Master/texmf-dist/tex/luatex/luaotfload/fontloader-font-ocl.lua +++ b/Master/texmf-dist/tex/luatex/luaotfload/fontloader-font-ocl.lua @@ -363,7 +363,6 @@ local function pdftovirtual(tfmdata,pdfshapes,kind) -- kind = png|svg local actuale = { "pdf", "page", e } -- saves tables -- local vfimage = lpdf and lpdf.vfimage or function(wd,ht,dp,data,name) - -- needed for generic (if used there at all) local name = storepdfdata(data) return { "image", { filename = name, width = wd, height = ht, depth = dp } } end @@ -439,6 +438,8 @@ do local xmlfirst = xml.first function otfsvg.filterglyph(entry,index) + -- we only support decompression in lmtx, so one needs to wipe the + -- cache when invalid xml is reported local svg = xmlconvert(entry.data) local root = svg and xmlfirst(svg,"/svg[@id='glyph"..index.."']") local data = root and tostring(root) @@ -483,7 +484,7 @@ do local pdfshapes = { } local inkscape = runner() if inkscape then - local indices = fonts.getindices(tfmdata) + -- local indices = fonts.getindices(tfmdata) local descriptions = tfmdata.descriptions local nofshapes = #svgshapes local f_svgfile = formatters["temp-otf-svg-shape-%i.svg"] diff --git a/Master/texmf-dist/tex/luatex/luaotfload/fontloader-font-onr.lua b/Master/texmf-dist/tex/luatex/luaotfload/fontloader-font-onr.lua index 188aaf6449b..fc6bead5889 100644 --- a/Master/texmf-dist/tex/luatex/luaotfload/fontloader-font-onr.lua +++ b/Master/texmf-dist/tex/luatex/luaotfload/fontloader-font-onr.lua @@ -21,7 +21,7 @@ add features.</p> local fonts, logs, trackers, resolvers = fonts, logs, trackers, resolvers -local next, type, tonumber, rawget, rawset = next, type, tonumber, rawget, rawset +local next, type, tonumber, rawset = next, type, tonumber, rawset local match, lower, gsub, strip, find = string.match, string.lower, string.gsub, string.strip, string.find local char, byte, sub = string.char, string.byte, string.sub local abs = math.abs diff --git a/Master/texmf-dist/tex/luatex/luaotfload/fontloader-font-oto.lua b/Master/texmf-dist/tex/luatex/luaotfload/fontloader-font-oto.lua index 4d112ac3160..6f5f2fb418f 100644 --- a/Master/texmf-dist/tex/luatex/luaotfload/fontloader-font-oto.lua +++ b/Master/texmf-dist/tex/luatex/luaotfload/fontloader-font-oto.lua @@ -9,7 +9,7 @@ if not modules then modules = { } end modules ['font-oto'] = { -- original tex local concat, unpack = table.concat, table.unpack local insert, remove = table.insert, table.remove local format, gmatch, gsub, find, match, lower, strip = string.format, string.gmatch, string.gsub, string.find, string.match, string.lower, string.strip -local type, next, tonumber, tostring, rawget = type, next, tonumber, tostring, rawget +local type, next, tonumber, tostring = type, next, tonumber, tostring local trace_baseinit = false trackers.register("otf.baseinit", function(v) trace_baseinit = v end) local trace_singles = false trackers.register("otf.singles", function(v) trace_singles = v end) diff --git a/Master/texmf-dist/tex/luatex/luaotfload/fontloader-font-otr.lua b/Master/texmf-dist/tex/luatex/luaotfload/fontloader-font-otr.lua index 4fe0a6a9765..e726053202f 100644 --- a/Master/texmf-dist/tex/luatex/luaotfload/fontloader-font-otr.lua +++ b/Master/texmf-dist/tex/luatex/luaotfload/fontloader-font-otr.lua @@ -65,7 +65,7 @@ if not modules then modules = { } end modules ['font-otr'] = { -- require("char-ini") -- end -local next, type, tonumber = next, type, tonumber +local next, type, tonumber, rawget = next, type, tonumber, rawget local byte, lower, char, gsub = string.byte, string.lower, string.char, string.gsub local fullstrip = string.fullstrip local floor, round = math.floor, math.round diff --git a/Master/texmf-dist/tex/luatex/luaotfload/fontloader-font-ots.lua b/Master/texmf-dist/tex/luatex/luaotfload/fontloader-font-ots.lua index 5091fd76570..c4f89c156be 100644 --- a/Master/texmf-dist/tex/luatex/luaotfload/fontloader-font-ots.lua +++ b/Master/texmf-dist/tex/luatex/luaotfload/fontloader-font-ots.lua @@ -213,6 +213,7 @@ local find_node_tail = nuts.tail local flush_node_list = nuts.flush_list local flush_node = nuts.flush_node local end_of_math = nuts.end_of_math +local start_of_par = nuts.start_of_par local setmetatable = setmetatable local setmetatableindex = table.setmetatableindex @@ -3804,7 +3805,7 @@ do local initialrl = 0 - if getid(head) == localpar_code and getsubtype(head) == 0 then + if getid(head) == localpar_code and start_of_par(head) then initialrl = pardirstate(head) elseif direction == 1 or direction == "TRT" then initialrl = -1 @@ -3958,7 +3959,7 @@ do elseif id == dir_code then topstack, rlmode = txtdirstate(start,dirstack,topstack,rlparmode) start = getnext(start) - -- elseif id == localpar_code then + -- elseif id == localpar_code and start_of_par(start) then -- rlparmode, rlmode = pardirstate(start) -- start = getnext(start) else @@ -4042,7 +4043,7 @@ do elseif id == dir_code then topstack, rlmode = txtdirstate(start,dirstack,topstack,rlparmode) start = getnext(start) - -- elseif id == localpar_code then + -- elseif id == localpar_code and start_of_par(start) then -- rlparmode, rlmode = pardirstate(start) -- start = getnext(start) else @@ -4153,7 +4154,7 @@ do elseif id == dir_code then topstack, rlmode = txtdirstate(start,dirstack,topstack,rlparmode) start = getnext(start) - -- elseif id == localpar_code then + -- elseif id == localpar_code and start_of_par(start) then -- rlparmode, rlmode = pardirstate(start) -- start = getnext(start) else @@ -4234,9 +4235,26 @@ registerotffeature { } } +-- Moved here (up) a bit. This doesn't really belong in generic so it will +-- move to a context module some day. + +local function markinitializer(tfmdata,value) + local properties = tfmdata.properties + properties.checkmarks = value +end + +registerotffeature { + name = "checkmarks", + description = "check mark widths", + default = true, + initializers = { + node = markinitializer, + }, +} + -- This can be used for extra handlers, but should be used with care! We implement one -- here but some more can be found in the osd (script devanagary) file. Now watch out: --- when a handlers has steps, it is called as the other ones, but when we have no steps, +-- when a handler has steps, it is called as the other ones, but when we have no steps, -- we use a different call: -- -- function(head,dataset,sequence,initialrl,font,attr) @@ -4247,22 +4265,28 @@ registerotffeature { otf.handlers = handlers +if context then + return +else + -- todo: move the following code someplace else +end + local setspacekerns = nodes.injections.setspacekerns if not setspacekerns then os.exit() end -local tag = "kern" -- maybe some day a merge +local tag = "kern" -if fontfeatures then +-- if fontfeatures then - function handlers.trigger_space_kerns(head,dataset,sequence,initialrl,font,attr) - local features = fontfeatures[font] - local enabled = features and features.spacekern and features[tag] - if enabled then - setspacekerns(font,sequence) - end - return head, enabled - end +-- function handlers.trigger_space_kerns(head,dataset,sequence,initialrl,font,attr) +-- local features = fontfeatures[font] +-- local enabled = features and features.spacekern and features[tag] +-- if enabled then +-- setspacekerns(font,sequence) +-- end +-- return head, enabled +-- end -else -- generic (no hashes) +-- else -- generic (no hashes) function handlers.trigger_space_kerns(head,dataset,sequence,initialrl,font,attr) local shared = fontdata[font].shared @@ -4274,7 +4298,7 @@ else -- generic (no hashes) return head, enabled end -end +-- end -- There are fonts out there that change the space but we don't do that kind of -- things in TeX. @@ -4392,7 +4416,7 @@ local function spaceinitializer(tfmdata,value) -- attr if rules then -- not now: analyze (simple) rules elseif not coverage then - -- nothng to do + -- nothing to do elseif kind == "gpos_single" then -- makes no sense in TeX elseif kind == "gpos_pair" then @@ -4476,17 +4500,3 @@ registerotffeature { node = spaceinitializer, }, } - -local function markinitializer(tfmdata,value) - local properties = tfmdata.properties - properties.checkmarks = value -end - -registerotffeature { - name = "checkmarks", - description = "check mark widths", - default = true, - initializers = { - node = markinitializer, - }, -} diff --git a/Master/texmf-dist/tex/luatex/luaotfload/fontloader-l-file.lua b/Master/texmf-dist/tex/luatex/luaotfload/fontloader-l-file.lua index 1b039a43866..d0af94f09d4 100644 --- a/Master/texmf-dist/tex/luatex/luaotfload/fontloader-l-file.lua +++ b/Master/texmf-dist/tex/luatex/luaotfload/fontloader-l-file.lua @@ -76,17 +76,27 @@ local P, R, S, C, Cs, Cp, Cc, Ct = lpeg.P, lpeg.R, lpeg.S, lpeg.C, lpeg.Cs, lpeg local attributes = lfs.attributes function lfs.isdir(name) - return attributes(name,"mode") == "directory" + if name then + return attributes(name,"mode") == "directory" + end end function lfs.isfile(name) - local a = attributes(name,"mode") - return a == "file" or a == "link" or nil + if name then + local a = attributes(name,"mode") + return a == "file" or a == "link" or nil + end end function lfs.isfound(name) - local a = attributes(name,"mode") - return (a == "file" or a == "link") and name or nil + if name then + local a = attributes(name,"mode") + return (a == "file" or a == "link") and name or nil + end +end + +function lfs.modification(name) + return name and attributes(name,"modification") or nil end if sandbox then diff --git a/Master/texmf-dist/tex/luatex/luaotfload/fontloader-l-io.lua b/Master/texmf-dist/tex/luatex/luaotfload/fontloader-l-io.lua index fa3ad3c4cda..a955262a31e 100644 --- a/Master/texmf-dist/tex/luatex/luaotfload/fontloader-l-io.lua +++ b/Master/texmf-dist/tex/luatex/luaotfload/fontloader-l-io.lua @@ -13,7 +13,7 @@ local concat = table.concat ----- floor = math.floor local type = type -if string.find(os.getenv("PATH"),";",1,true) then +if string.find(os.getenv("PATH") or "",";",1,true) then io.fileseparator, io.pathseparator = "\\", ";" else io.fileseparator, io.pathseparator = "/" , ":" diff --git a/Master/texmf-dist/tex/luatex/luaotfload/fontloader-l-lua.lua b/Master/texmf-dist/tex/luatex/luaotfload/fontloader-l-lua.lua index 51399216ccf..f411230d4aa 100644 --- a/Master/texmf-dist/tex/luatex/luaotfload/fontloader-l-lua.lua +++ b/Master/texmf-dist/tex/luatex/luaotfload/fontloader-l-lua.lua @@ -37,9 +37,9 @@ end -- this is lmtx only: -if lua and lua.openfile then - io.open = lua.openfile -end +-- if lua and lua.openfile then +-- io.open = lua.openfile +-- end -- lpeg diff --git a/Master/texmf-dist/tex/luatex/luaotfload/fontloader-l-table.lua b/Master/texmf-dist/tex/luatex/luaotfload/fontloader-l-table.lua index e8282038674..98b377bdc1c 100644 --- a/Master/texmf-dist/tex/luatex/luaotfload/fontloader-l-table.lua +++ b/Master/texmf-dist/tex/luatex/luaotfload/fontloader-l-table.lua @@ -6,7 +6,7 @@ if not modules then modules = { } end modules ['l-table'] = { license = "see context related readme files" } -local type, next, tostring, tonumber, select = type, next, tostring, tonumber, select +local type, next, tostring, tonumber, select, rawget = type, next, tostring, tonumber, select, rawget local table, string = table, string local concat, sort = table.concat, table.sort local format, lower, dump = string.format, string.lower, string.dump diff --git a/Master/texmf-dist/tex/luatex/luaotfload/fontloader-reference.lua b/Master/texmf-dist/tex/luatex/luaotfload/fontloader-reference.lua index b8a21fc937b..ce2794cf366 100644 --- a/Master/texmf-dist/tex/luatex/luaotfload/fontloader-reference.lua +++ b/Master/texmf-dist/tex/luatex/luaotfload/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 : 10/29/19 15:00:00 +-- merge date : 01/26/20 18:34:44 do -- begin closure to overcome local limits and interference @@ -20,9 +20,6 @@ if LUAVERSION<5.2 and jit then MINORVERSION=2 LUAVERSION=5.2 end -if lua and lua.openfile then - io.open=lua.openfile -end if not lpeg then lpeg=require("lpeg") end @@ -1052,7 +1049,7 @@ if not modules then modules={} end modules ['l-table']={ copyright="PRAGMA ADE / ConTeXt Development Team", license="see context related readme files" } -local type,next,tostring,tonumber,select=type,next,tostring,tonumber,select +local type,next,tostring,tonumber,select,rawget=type,next,tostring,tonumber,select,rawget local table,string=table,string local concat,sort=table.concat,table.sort local format,lower,dump=string.format,string.lower,string.dump @@ -2177,7 +2174,7 @@ local open,flush,write,read=io.open,io.flush,io.write,io.read local byte,find,gsub,format=string.byte,string.find,string.gsub,string.format local concat=table.concat local type=type -if string.find(os.getenv("PATH"),";",1,true) then +if string.find(os.getenv("PATH") or "",";",1,true) then io.fileseparator,io.pathseparator="\\",";" else io.fileseparator,io.pathseparator="/",":" @@ -2532,15 +2529,24 @@ local checkedsplit=string.checkedsplit local P,R,S,C,Cs,Cp,Cc,Ct=lpeg.P,lpeg.R,lpeg.S,lpeg.C,lpeg.Cs,lpeg.Cp,lpeg.Cc,lpeg.Ct local attributes=lfs.attributes function lfs.isdir(name) - return attributes(name,"mode")=="directory" + if name then + return attributes(name,"mode")=="directory" + end end function lfs.isfile(name) - local a=attributes(name,"mode") - return a=="file" or a=="link" or nil + if name then + local a=attributes(name,"mode") + return a=="file" or a=="link" or nil + end end function lfs.isfound(name) - local a=attributes(name,"mode") - return (a=="file" or a=="link") and name or nil + if name then + local a=attributes(name,"mode") + return (a=="file" or a=="link") and name or nil + end +end +function lfs.modification(name) + return name and attributes(name,"modification") or nil end if sandbox then sandbox.redefine(lfs.isfile,"lfs.isfile") @@ -3649,7 +3655,7 @@ local format_N if environment.FORMAT then n=n+1 if not f or f=="" then return format("FORMAT(a%s,'%%.9f')",n) - elseif f==".6" then + elseif f==".6" or f=="0.6" then return format("FORMAT(a%s)",n) else return format("FORMAT(a%s,'%%%sf')",n,f) @@ -4705,6 +4711,7 @@ if not modules then modules={} end modules ['data-con']={ copyright="PRAGMA ADE / ConTeXt Development Team", license="see context related readme files" } +local setmetatable=setmetatable local format,lower,gsub=string.format,string.lower,string.gsub local trace_cache=false trackers.register("resolvers.cache",function(v) trace_cache=v end) local trace_containers=false trackers.register("resolvers.containers",function(v) trace_containers=v end) @@ -4712,16 +4719,21 @@ local trace_storage=false trackers.register("resolvers.storage",function(v) tra containers=containers or {} local containers=containers containers.usecache=true +local getwritablepath=caches.getwritablepath +local getreadablepaths=caches.getreadablepaths +local cacheiswritable=caches.is_writable +local loaddatafromcache=caches.loaddata +local savedataincache=caches.savedata local report_containers=logs.reporter("resolvers","containers") local allocated={} local mt={ __index=function(t,k) if k=="writable" then - local writable=caches.getwritablepath(t.category,t.subcategory) or { "." } + local writable=getwritablepath(t.category,t.subcategory) or { "." } t.writable=writable return writable elseif k=="readables" then - local readables=caches.getreadablepaths(t.category,t.subcategory) or { "." } + local readables=getreadablepaths(t.category,t.subcategory) or { "." } t.readables=readables return readables end @@ -4752,7 +4764,7 @@ function containers.define(category,subcategory,version,enabled) end end function containers.is_usable(container,name) - return container.enabled and caches and caches.is_writable(container.writable,name) + return container.enabled and caches and cacheiswritable(container.writable,name) end function containers.is_valid(container,name) if name and name~="" then @@ -4766,7 +4778,7 @@ function containers.read(container,name) local storage=container.storage local stored=storage[name] if not stored and container.enabled and caches and containers.usecache then - stored=caches.loaddata(container.readables,name,container.writable) + stored=loaddatafromcache(container.readables,name,container.writable) if stored and stored.cache_version==container.version then if trace_cache or trace_containers then report_containers("action %a, category %a, name %a","load",container.subcategory,name) @@ -4782,17 +4794,20 @@ function containers.read(container,name) end return stored end -function containers.write(container,name,data) +function containers.write(container,name,data,fast) if data then data.cache_version=container.version if container.enabled and caches then - local unique,shared=data.unique,data.shared - data.unique,data.shared=nil,nil - caches.savedata(container.writable,name,data) + local unique=data.unique + local shared=data.shared + data.unique=nil + data.shared=nil + savedataincache(container.writable,name,data,fast) if trace_cache or trace_containers then report_containers("action %a, category %a, name %a","save",container.subcategory,name) end - data.unique,data.shared=unique,shared + data.unique=unique + data.shared=shared end if trace_cache or trace_containers then report_containers("action %a, category %a, name %a","store",container.subcategory,name) @@ -5027,6 +5042,13 @@ if not nuts.setreplace then setfield(n,"replace",h) end end +do + local getsubtype=nuts.getsubtype + function nuts.start_of_par(n) + local s=getsubtype(n) + return s==0 or s==2 + end +end end -- closure @@ -8677,6 +8699,9 @@ fonts.privateoffsets={ mathbase=0xFF000, keepnames=false, } +if node and not tex.getfontoffamily then + tex.getfontoffamily=node.family_font +end end -- closure @@ -8743,13 +8768,13 @@ fonts.handlers=handlers local allocate=utilities.storage.allocate local setmetatableindex=table.setmetatableindex constructors.dontembed=allocate() -constructors.autocleanup=true constructors.namemode="fullpath" constructors.version=1.01 constructors.cache=containers.define("fonts","constructors",constructors.version,false) constructors.privateoffset=fonts.privateoffsets.textbase or 0xF0000 constructors.cacheintex=true constructors.addtounicode=true +constructors.fixprotrusion=true local designsizes=allocate() constructors.designsizes=designsizes local loadedfonts=allocate() @@ -8801,11 +8826,6 @@ function constructors.getmathparameter(tfmdata,name) end end function constructors.cleanuptable(tfmdata) - if constructors.autocleanup and tfmdata.properties.virtualized then - for k,v in next,tfmdata.characters do - if v.commands then v.commands=nil end - end - end end function constructors.calculatescale(tfmdata,scaledpoints) local parameters=tfmdata.parameters @@ -9032,6 +9052,7 @@ function constructors.scale(tfmdata,specification) properties.direction=direction target.size=scaledpoints target.encodingbytes=properties.encodingbytes or 1 + target.subfont=properties.subfont target.embedding=properties.embedding or "subset" target.tounicode=1 target.cidinfo=properties.cidinfo @@ -9141,7 +9162,7 @@ function constructors.scale(tfmdata,specification) targetparameters.descender=delta*descender end constructors.enhanceparameters(targetparameters) - local protrusionfactor=(targetquad~=0 and 1000/targetquad) or 0 + local protrusionfactor=constructors.fixprotrusion and ((targetquad~=0 and 1000/targetquad) or 1) or 1 local scaledwidth=defaultwidth*hdelta local scaledheight=defaultheight*vdelta local scaleddepth=defaultdepth*vdelta @@ -9524,6 +9545,7 @@ function constructors.finalize(tfmdata) properties.name=properties.name or tfmdata.name properties.psname=properties.psname or tfmdata.psname properties.encodingbytes=tfmdata.encodingbytes or 1 + properties.subfont=tfmdata.subfont or nil properties.embedding=tfmdata.embedding or "subset" properties.tounicode=tfmdata.tounicode or 1 properties.cidinfo=tfmdata.cidinfo or nil @@ -9549,6 +9571,7 @@ function constructors.finalize(tfmdata) tfmdata.name=nil tfmdata.psname=nil tfmdata.encodingbytes=nil + tfmdata.subfont=nil tfmdata.embedding=nil tfmdata.tounicode=nil tfmdata.cidinfo=nil @@ -10862,7 +10885,7 @@ if not modules then modules={} end modules ['font-otr']={ copyright="PRAGMA ADE / ConTeXt Development Team", license="see context related readme files" } -local next,type,tonumber=next,type,tonumber +local next,type,tonumber,rawget=next,type,tonumber,rawget local byte,lower,char,gsub=string.byte,string.lower,string.char,string.gsub local fullstrip=string.fullstrip local floor,round=math.floor,math.round @@ -13981,7 +14004,7 @@ if not modules then modules={} end modules ['font-cff']={ license="see context related readme files" } local next,type,tonumber,rawget=next,type,tonumber,rawget -local byte,char,gmatch=string.byte,string.char,string.gmatch +local byte,char,gmatch,sub=string.byte,string.char,string.gmatch,string.sub local concat,remove,unpack=table.concat,table.remove,table.unpack 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 @@ -14088,6 +14111,37 @@ local defaultstrings={ [0]= "Thornsmall","Ydieresissmall","001.000","001.001","001.002","001.003", "Black","Bold","Book","Light","Medium","Regular","Roman","Semibold", } +local standardnames={ [0]= + false,false,false,false,false,false,false,false,false,false,false, + false,false,false,false,false,false,false,false,false,false,false, + false,false,false,false,false,false,false,false,false,false, + "space","exclam","quotedbl","numbersign","dollar","percent", + "ampersand","quoteright","parenleft","parenright","asterisk","plus", + "comma","hyphen","period","slash","zero","one","two","three","four", + "five","six","seven","eight","nine","colon","semicolon","less", + "equal","greater","question","at","A","B","C","D","E","F","G","H", + "I","J","K","L","M","N","O","P","Q","R","S","T","U","V","W", + "X","Y","Z","bracketleft","backslash","bracketright","asciicircum", + "underscore","quoteleft","a","b","c","d","e","f","g","h","i","j", + "k","l","m","n","o","p","q","r","s","t","u","v","w","x","y", + "z","braceleft","bar","braceright","asciitilde",false,false,false, + false,false,false,false,false,false,false,false,false,false,false, + false,false,false,false,false,false,false,false,false,false,false, + false,false,false,false,false,false,false,false,false,"exclamdown", + "cent","sterling","fraction","yen","florin","section","currency", + "quotesingle","quotedblleft","guillemotleft","guilsinglleft", + "guilsinglright","fi","fl",false,"endash","dagger","daggerdbl", + "periodcentered",false,"paragraph","bullet","quotesinglbase", + "quotedblbase","quotedblright","guillemotright","ellipsis","perthousand", + false,"questiondown",false,"grave","acute","circumflex","tilde", + "macron","breve","dotaccent","dieresis",false,"ring","cedilla",false, + "hungarumlaut","ogonek","caron","emdash",false,false,false,false, + false,false,false,false,false,false,false,false,false,false,false, + false,"AE",false,"ordfeminine",false,false,false,false,"Lslash", + "Oslash","OE","ordmasculine",false,false,false,false,false,"ae", + false,false,false,"dotlessi",false,false,"lslash","oslash","oe", + "germandbls",false,false,false,false +} local cffreaders={ readbyte, readushort, @@ -14449,6 +14503,7 @@ do local x=0 local y=0 local width=false + local lsb=0 local r=0 local stems=0 local globalbias=0 @@ -14472,6 +14527,9 @@ do local factors=false local axis=false local vsindex=0 + local justpass=false + local seacs={} + local procidx=nil local function showstate(where) report("%w%-10s : [%s] n=%i",depth*2,where,concat(stack," ",1,top),top) end @@ -15011,14 +15069,14 @@ do top=0 end local function divide() - if version==1 then + if version=="cff" then local d=stack[top] top=top-1 stack[top]=stack[top]/d end end local function closepath() - if version==1 then + if version=="cff" then if trace_charstrings then showstate("closepath") end @@ -15026,54 +15084,73 @@ do top=0 end local function hsbw() - if version==1 then + if version=="cff" then if trace_charstrings then showstate("hsbw") end + lsb=stack[top-1] or 0 width=stack[top] end top=0 end - local function seac() - if version==1 then + local function sbw() + if version=="cff" then if trace_charstrings then - showstate("seac") + showstate("sbw") end + lsb=stack[top-3] + width=stack[top-1] end top=0 end - local function sbw() - if version==1 then + local function seac() + if version=="cff" then if trace_charstrings then - showstate("sbw") + showstate("seac") end - width=stack[top-1] end top=0 end + local popped=3 + local hints=3 local function callothersubr() - if version==1 then + if version=="cff" then if trace_charstrings then - showstate("callothersubr (unsupported)") + showstate("callothersubr") + end + if stack[top]==hints then + popped=stack[top-2] + else + popped=3 + end + local t=stack[top-1] + if t then + top=top-(t+2) + if top<0 then + top=0 + end + else + top=0 end + else + top=0 end - top=0 end local function pop() - if version==1 then + if version=="cff" then if trace_charstrings then - showstate("pop (unsupported)") + showstate("pop") end top=top+1 - stack[top]=0 + stack[top]=popped else top=0 end end local function setcurrentpoint() - if version==1 then + if version=="cff" then if trace_charstrings then - showstate("pop (unsupported)") + showstate("setcurrentpoint (unsupported)") end x=x+stack[top-1] y=y+stack[top] @@ -15199,6 +15276,39 @@ do vhcurveto, hvcurveto, } + local reverse={ [0]="unsupported", + "getstem", + "unsupported", + "getstem", + "vmoveto", + "rlineto", + "hlineto", + "vlineto", + "rrcurveto", + "unsupported", + "unsupported", + "unsupported", + "unsupported", + "hsbw", + "unsupported", + "setvsindex", + "blend", + "unsupported", + "getstem", + "getmask", + "getmask", + "rmoveto", + "hmoveto", + "getstem", + "rcurveline", + "rlinecurve", + "vvcurveto", + "hhcurveto", + "unsupported", + "unsupported", + "vhcurveto", + "hvcurveto", + } local subactions={ [000]=dotsection, [001]=getstem3, @@ -15312,7 +15422,7 @@ do local function call(scope,list,bias) depth=depth+1 if top==0 then - showstate(formatters["unknown %s call %s"](scope,"?")) + showstate(formatters["unknown %s call %s, case %s"](scope,"?",1)) top=0 else local index=stack[top]+bias @@ -15324,13 +15434,12 @@ do if tab then process(tab) else - showstate(formatters["unknown %s call %s"](scope,index)) + showstate(formatters["unknown %s call %s, case %s"](scope,index,2)) top=0 end end depth=depth-1 end - local justpass=false process=function(tab) local i=1 local n=#tab @@ -15401,6 +15510,17 @@ do r=r+1;result[r]=chars[12] r=r+1;result[r]=chars[t] top=0 + elseif t==6 then + seacs[procidx]={ + asb=stack[1], + adx=stack[2], + ady=stack[3], + base=stack[4], + accent=stack[5], + width=width, + lsb=lsb, + } + top=0 else local a=subactions[t] if a then @@ -15430,44 +15550,52 @@ do i=i+s+1 elseif t==1 or t==3 or t==18 or operation==23 then p_getstem() -if true then - if top>0 then - for i=1,top do - r=r+1;result[r]=encode[stack[i]] + if true then + if top>0 then + for i=1,top do + r=r+1;result[r]=encode[stack[i]] + end + top=0 end + r=r+1;result[r]=chars[t] + else top=0 end - r=r+1;result[r]=chars[t] -else - top=0 -end i=i+1 elseif t==19 or t==20 then local s=p_getmask() or 0 -if true then - if top>0 then - for i=1,top do - r=r+1;result[r]=encode[stack[i]] + if true then + if top>0 then + for i=1,top do + r=r+1;result[r]=encode[stack[i]] + end + top=0 end + r=r+1;result[r]=chars[t] + for j=1,s do + i=i+1 + r=r+1;result[r]=chars[tab[i]] + end + else + i=i+s top=0 end - r=r+1;result[r]=chars[t] - for j=1,s do - i=i+1 - r=r+1;result[r]=chars[tab[i]] - end -else - i=i+s - top=0 -end i=i+1 elseif t==9 then top=0 i=i+1 elseif t==13 then - local s=hsbw() or 0 - i=i+s+1 + hsbw() + if version=="cff" then + r=r+1;result[r]=encode[lsb] + r=r+1;result[r]=chars[22] + else + end + i=i+1 else + if trace_charstrings then + showstate(reverse[t] or "<action>") + end if top>0 then for i=1,top do r=r+1;result[r]=encode[stack[i]] @@ -15488,7 +15616,7 @@ end end else if trace_charstrings then - showvalue("<action>",t) + showstate(reverse[t] or "<action>") end top=0 i=i+1 @@ -15507,7 +15635,7 @@ end ((l<1240 and 107) or (l<33900 and 1131) or 32768)+1 end end - local function processshape(tab,index) + local function processshape(tab,index,hack) if not tab then glyphs[index]={ boundingbox={ 0,0,0,0 }, @@ -15520,10 +15648,13 @@ end x=0 y=0 width=false + lsb=0 r=0 top=0 stems=0 result={} + popped=3 + procidx=index xmin=0 xmax=0 ymin=0 @@ -15537,6 +15668,9 @@ end updateregions(vsindex) end process(tab) + if hack then + return x,y + end local boundingbox={ round(xmin), round(ymin), @@ -15591,6 +15725,8 @@ end axis=false regions=data.regions justpass=streams==true + popped=3 + seacs={} if regions then regions={ regions } axis=data.factors or false @@ -15604,6 +15740,8 @@ end locals=false globals=false strings=false + popped=3 + seacs={} end local function setwidths(private) if not private then @@ -15633,6 +15771,29 @@ end for index=1,#charstrings do processshape(charstrings[index],index-1) end + if justpass and next(seacs) then + local charset=data.dictionaries[1].charset + if charset then + local lookup=table.swapped(charset) + for index,v in next,seacs do + local bindex=lookup[standardnames[v.base]] + local aindex=lookup[standardnames[v.accent]] + local bglyph=bindex and glyphs[bindex] + local aglyph=aindex and glyphs[aindex] + if bglyph and aglyph then + local jp=justpass + justpass=false + local x,y=processshape(charstrings[bindex+1],bindex,true) + justpass=jp + local base=bglyph.stream + local accent=aglyph.stream + local moveto=encode[-x-v.asb+v.adx]..chars[22]..encode[-y+v.ady]..chars[ 4] + base=sub(base,1,#base-1) + glyphs[index].stream=base..moveto..accent + end + end + end + end stopparsing(fontdata,data) else report("no charstrings") @@ -15649,6 +15810,7 @@ end vsindex=dictionary.vsindex or 0 glyphs=glphs or {} justpass=streams==true + seacs={} globalbias,localbias=setbias(globals,locals,nobias) nominalwidth,defaultwidth=setwidths(dictionary.private) processshape(tab,index-1) @@ -23779,7 +23941,7 @@ if not modules then modules={} end modules ['font-oto']={ local concat,unpack=table.concat,table.unpack local insert,remove=table.insert,table.remove local format,gmatch,gsub,find,match,lower,strip=string.format,string.gmatch,string.gsub,string.find,string.match,string.lower,string.strip -local type,next,tonumber,tostring,rawget=type,next,tonumber,tostring,rawget +local type,next,tonumber,tostring=type,next,tonumber,tostring local trace_baseinit=false trackers.register("otf.baseinit",function(v) trace_baseinit=v end) local trace_singles=false trackers.register("otf.singles",function(v) trace_singles=v end) local trace_multiples=false trackers.register("otf.multiples",function(v) trace_multiples=v end) @@ -26150,6 +26312,7 @@ local find_node_tail=nuts.tail local flush_node_list=nuts.flush_list local flush_node=nuts.flush_node local end_of_math=nuts.end_of_math +local start_of_par=nuts.start_of_par local setmetatable=setmetatable local setmetatableindex=table.setmetatableindex local nextnode=nuts.traversers.node @@ -29120,7 +29283,7 @@ do checkstep(head) end local initialrl=0 - if getid(head)==localpar_code and getsubtype(head)==0 then + if getid(head)==localpar_code and start_of_par(head) then initialrl=pardirstate(head) elseif direction==1 or direction=="TRT" then initialrl=-1 @@ -29452,19 +29615,27 @@ registerotffeature { plug=otf.pluginprocessor, } } +local function markinitializer(tfmdata,value) + local properties=tfmdata.properties + properties.checkmarks=value +end +registerotffeature { + name="checkmarks", + description="check mark widths", + default=true, + initializers={ + node=markinitializer, + }, +} otf.handlers=handlers +if context then + +--removed + +else +end local setspacekerns=nodes.injections.setspacekerns if not setspacekerns then os.exit() end -local tag="kern" -if fontfeatures then - function handlers.trigger_space_kerns(head,dataset,sequence,initialrl,font,attr) - local features=fontfeatures[font] - local enabled=features and features.spacekern and features[tag] - if enabled then - setspacekerns(font,sequence) - end - return head,enabled - end -else +local tag="kern" function handlers.trigger_space_kerns(head,dataset,sequence,initialrl,font,attr) local shared=fontdata[font].shared local features=shared and shared.features @@ -29474,7 +29645,6 @@ else end return head,enabled end -end local function hasspacekerns(data) local resources=data.resources local sequences=resources.sequences @@ -29659,18 +29829,6 @@ registerotffeature { node=spaceinitializer, }, } -local function markinitializer(tfmdata,value) - local properties=tfmdata.properties - properties.checkmarks=value -end -registerotffeature { - name="checkmarks", - description="check mark widths", - default=true, - initializers={ - node=markinitializer, - }, -} end -- closure @@ -32380,7 +32538,6 @@ do local pdfshapes={} local inkscape=runner() if inkscape then - local indices=fonts.getindices(tfmdata) local descriptions=tfmdata.descriptions local nofshapes=#svgshapes local f_svgfile=formatters["temp-otf-svg-shape-%i.svg"] @@ -33355,7 +33512,7 @@ if not modules then modules={} end modules ['font-onr']={ license="see context related readme files" } local fonts,logs,trackers,resolvers=fonts,logs,trackers,resolvers -local next,type,tonumber,rawget,rawset=next,type,tonumber,rawget,rawset +local next,type,tonumber,rawset=next,type,tonumber,rawset local match,lower,gsub,strip,find=string.match,string.lower,string.gsub,string.strip,string.find local char,byte,sub=string.char,string.byte,string.sub local abs=math.abs @@ -35192,7 +35349,6 @@ local variants=allocate() specifiers.variants=variants definers.methods=definers.methods or {} local internalized=allocate() -local lastdefined=nil local loadedfonts=constructors.loadedfonts local designsizes=constructors.designsizes local resolvefile=fontgoodies and fontgoodies.filenames and fontgoodies.filenames.resolve or function(s) return s end @@ -35453,9 +35609,6 @@ function constructors.readanddefine(name,size) end return fontdata[id],id end -function definers.current() - return lastdefined -end function definers.registered(hash) local id=internalized[hash] return id,id and fontdata[id] @@ -35506,7 +35659,6 @@ function definers.read(specification,size,id) end end end - lastdefined=tfmdata or id if not tfmdata then report_defining("unknown font %a, loading aborted",specification.name) elseif trace_defining and type(tfmdata)=="table" then @@ -35522,7 +35674,9 @@ end function font.getfont(id) return fontdata[id] end -callbacks.register('define_font',definers.read,"definition of fonts (tfmdata preparation)") +if not context then + callbacks.register('define_font',definers.read,"definition of fonts (tfmdata preparation)") +end end -- closure diff --git a/Master/texmf-dist/tex/luatex/luaotfload/fontloader-util-str.lua b/Master/texmf-dist/tex/luatex/luaotfload/fontloader-util-str.lua index 432b39ec5ad..68c9be5860b 100644 --- a/Master/texmf-dist/tex/luatex/luaotfload/fontloader-util-str.lua +++ b/Master/texmf-dist/tex/luatex/luaotfload/fontloader-util-str.lua @@ -944,7 +944,7 @@ local format_N if environment.FORMAT then n = n + 1 if not f or f == "" then return format("FORMAT(a%s,'%%.9f')",n) - elseif f == ".6" then + elseif f == ".6" or f == "0.6" then return format("FORMAT(a%s)",n) else return format("FORMAT(a%s,'%%%sf')",n,f) diff --git a/Master/texmf-dist/tex/luatex/luaotfload/luaotfload-auxiliary.lua b/Master/texmf-dist/tex/luatex/luaotfload/luaotfload-auxiliary.lua index fd4291f67cc..f6539dca8d6 100644 --- a/Master/texmf-dist/tex/luatex/luaotfload/luaotfload-auxiliary.lua +++ b/Master/texmf-dist/tex/luatex/luaotfload/luaotfload-auxiliary.lua @@ -6,8 +6,8 @@ local ProvidesLuaModule = { name = "luaotfload-auxiliary", - version = "3.11", --TAGVERSION - date = "2019-11-10", --TAGDATE + version = "3.12", --TAGVERSION + date = "2020-02-02", --TAGDATE description = "luaotfload submodule / auxiliary functions", license = "GPL v2.0" } @@ -429,6 +429,19 @@ function aux.name_of_slot(codepoint) return false end +--[[doc-- + + Get the GID of the glyph associated with a given name. + +--doc]]-- +function aux.gid_of_name(font_id, glyphname) + local slot = aux.slot_of_name(font_id, glyphname) + if not slot then return end + local tfmdata = identifiers[font_id] or font.fonts[font_id] + -- assert(tfmdata) -- Otherwise slot_of_name would have failed already + return tfmdata.characters[slot].index or slot +end + ----------------------------------------------------------------------- --- features / scripts / languages ----------------------------------------------------------------------- @@ -638,7 +651,7 @@ function aux.provides_feature(font_id, asked_script, or asked_script) local language = harf.Tag.new(asked_language == "DFLT" and "dflt" or asked_language) - local feature = harf.Tag.new(feature) + local feature = harf.Tag.new(asked_feature) for _, tag in next, { GSUBtag, GPOStag } do local _, script_idx = hbface:ot_layout_find_script(tag, script) diff --git a/Master/texmf-dist/tex/luatex/luaotfload/luaotfload-colors.lua b/Master/texmf-dist/tex/luatex/luaotfload/luaotfload-colors.lua index ddc564b05bc..2569eb1b48e 100644 --- a/Master/texmf-dist/tex/luatex/luaotfload/luaotfload-colors.lua +++ b/Master/texmf-dist/tex/luatex/luaotfload/luaotfload-colors.lua @@ -5,8 +5,8 @@ local ProvidesLuaModule = { name = "luaotfload-colors", - version = "3.11", --TAGVERSION - date = "2019-11-10", --TAGDATE + version = "3.12", --TAGVERSION + date = "2020-02-02", --TAGDATE description = "luaotfload submodule / color", license = "GPL v2.0", author = "Khaled Hosny, Elie Roux, Philipp Gesang, Dohyun Kim, David Carlisle", @@ -40,9 +40,13 @@ local insert_node_after = nodedirect.insert_after local todirect = nodedirect.todirect local tonode = nodedirect.tonode local setfield = nodedirect.setfield +local setdisc = nodedirect.setdisc +local setreplace = nodedirect.setreplace local getid = nodedirect.getid local getfont = nodedirect.getfont +local getchar = nodedirect.getchar local getlist = nodedirect.getlist +local getdisc = nodedirect.getdisc local getsubtype = nodedirect.getsubtype local getnext = nodedirect.getnext local nodetail = nodedirect.tail @@ -198,9 +202,14 @@ color_whatsit = function (head, curr, color, push, tail) end -- number -> string | nil -local get_font_color = function (font_id) +local get_glyph_color = function (font_id, char) local tfmdata = identifiers[font_id] local font_color = tfmdata and tfmdata.properties and tfmdata.properties.color + if type(font_color) == "table" then + local char_tbl = tfmdata.characters[char] + char = char_tbl and (char_tbl.index or char) + return char and font_color[char] or font_color.default + end return font_color end @@ -231,25 +240,30 @@ node_colorize = function (head, toplevel, current_color) setfield(n, "head", n_list) end + elseif n_id == disc_t then + local n_pre, n_post, n_replace = getdisc(n) + n_replace, current_color = node_colorize(n_replace, false, current_color) + setdisc(n, n_pre, n_post, n_replace) + elseif n_id == glyph_t then --- colorization is restricted to those fonts --- that received the “color” property upon --- loading (see ``setcolor()`` above) - local font_color = get_font_color(getfont(n)) - if font_color ~= current_color then + local glyph_color = get_glyph_color(getfont(n), getchar(n)) + if glyph_color ~= current_color then if current_color then head, n, current_color = color_whatsit(head, n, current_color, false) end - if font_color then - head, n, current_color = color_whatsit(head, n, font_color, true) + if glyph_color then + head, n, current_color = color_whatsit(head, n, glyph_color, true) end end if current_color and color_callback == "pre_linebreak_filter" then local nn = getnext(n) while nn and getid(nn) == glyph_t do - local font_color = get_font_color(getfont(nn)) - if font_color == current_color then + local glyph_color = get_glyph_color(getfont(nn), getchar(nn)) + if glyph_color == current_color then n = nn else break @@ -381,8 +395,41 @@ end --- hexadecimal, with an optional fourth transparency --- value) --- -local setcolor = function (tfmdata, value) - local sanitized = sanitize_color_expression(value) +local glyph_color_tables = { } +-- Currently this either sets a common color for the whole font or +-- builds a GID lookup table. This might change later to replace the +-- lookup table with color information in the character hash. The +-- problem with that approach right now are differences between harf +-- and node and difficulties with getting the mapped unicode value for +-- a GID. +local function setcolor (tfmdata, value) + local sanitized + local color_table = glyph_color_tables[tonumber(value) or value] + if color_table then + sanitized = {} + local unicodes = tfmdata.resources.unicodes + local gid_mapping = {} + local descriptions = tfmdata.descriptions or tfmdata.characters + for color, glyphs in next, color_table do + for _, glyph in ipairs(glyphs) do + local gid = glyph == "default" and "default" or tonumber(glyph) + if not gid then + local unicode = unicodes[glyph] + local desc = unicode and descriptions[unicode] + gid = desc and (desc.index or unicode) + end + if gid then + sanitized[gid] = sanitize_color_expression(color) + else + -- TODO: ??? Error out, warn or just ignore? Ignore + -- makes sense because we have to ignore for GIDs + -- anyway. + end + end + end + else + sanitized = sanitize_color_expression(value) + end local properties = tfmdata.properties if sanitized then @@ -391,6 +438,17 @@ local setcolor = function (tfmdata, value) end end +function luaotfload.add_colorscheme(name, colortable) + if fonts == nil then + fonts = name + name = #glyph_color_tables + 1 + else + name = name:lower() + end + glyph_color_tables[name] = colortable + return name +end + return function () logreport = luaotfload.log.report if not fonts then diff --git a/Master/texmf-dist/tex/luatex/luaotfload/luaotfload-configuration.lua b/Master/texmf-dist/tex/luatex/luaotfload/luaotfload-configuration.lua index b9ee9a6c7ac..b6b214c249f 100644 --- a/Master/texmf-dist/tex/luatex/luaotfload/luaotfload-configuration.lua +++ b/Master/texmf-dist/tex/luatex/luaotfload/luaotfload-configuration.lua @@ -7,8 +7,8 @@ local ProvidesLuaModule = { name = "luaotfload-configuration", - version = "3.11", --TAGVERSION - date = "2019-11-10", --TAGDATE + version = "3.12", --TAGVERSION + date = "2020-02-02", --TAGDATE description = "luaotfload submodule / config file reader", license = "GPL v2.0" } diff --git a/Master/texmf-dist/tex/luatex/luaotfload/luaotfload-database.lua b/Master/texmf-dist/tex/luatex/luaotfload/luaotfload-database.lua index ad00bb26f72..f4bace8b44e 100644 --- a/Master/texmf-dist/tex/luatex/luaotfload/luaotfload-database.lua +++ b/Master/texmf-dist/tex/luatex/luaotfload/luaotfload-database.lua @@ -5,8 +5,8 @@ do -- block to avoid to many local variables error local ProvidesLuaModule = { name = "luaotfload-database", - version = "3.11", --TAGVERSION - date = "2019-11-10", --TAGDATE + version = "3.12", --TAGVERSION + date = "2020-02-02", --TAGDATE description = "luaotfload submodule / database", license = "GPL v2.0", author = "Khaled Hosny, Elie Roux, Philipp Gesang, Marcel Krüger", diff --git a/Master/texmf-dist/tex/luatex/luaotfload/luaotfload-diagnostics.lua b/Master/texmf-dist/tex/luatex/luaotfload/luaotfload-diagnostics.lua index 0df0be7ff52..c6bb5c93711 100644 --- a/Master/texmf-dist/tex/luatex/luaotfload/luaotfload-diagnostics.lua +++ b/Master/texmf-dist/tex/luatex/luaotfload/luaotfload-diagnostics.lua @@ -7,8 +7,8 @@ local ProvidesLuaModule = { name = "luaotfload-diagnostics", - version = "3.11", --TAGVERSION - date = "2019-11-10", --TAGDATE + version = "3.12", --TAGVERSION + date = "2020-02-02", --TAGDATE description = "luaotfload-tool submodule / diagnostics", license = "GPL v2.0" } diff --git a/Master/texmf-dist/tex/luatex/luaotfload/luaotfload-embolden.lua b/Master/texmf-dist/tex/luatex/luaotfload/luaotfload-embolden.lua index 4e16a992d05..eec5ffde158 100644 --- a/Master/texmf-dist/tex/luatex/luaotfload/luaotfload-embolden.lua +++ b/Master/texmf-dist/tex/luatex/luaotfload/luaotfload-embolden.lua @@ -5,8 +5,8 @@ local ProvidesLuaModule = { name = "luaotfload-embolden", - version = "3.11", --TAGVERSION - date = "2019-11-10", --TAGDATE + version = "3.12", --TAGVERSION + date = "2020-02-02", --TAGDATE description = "luaotfload submodule / color", license = "GPL v2.0", author = "Marcel Krüger" diff --git a/Master/texmf-dist/tex/luatex/luaotfload/luaotfload-fallback.lua b/Master/texmf-dist/tex/luatex/luaotfload/luaotfload-fallback.lua new file mode 100644 index 00000000000..e07b3c726ad --- /dev/null +++ b/Master/texmf-dist/tex/luatex/luaotfload/luaotfload-fallback.lua @@ -0,0 +1,134 @@ +----------------------------------------------------------------------- +-- FILE: luaotfload-fallback.lua +-- DESCRIPTION: part of luaotfload / fallback +----------------------------------------------------------------------- + +local ProvidesLuaModule = { + name = "luaotfload-fallback", + version = "3.12", --TAGVERSION + date = "2020-02-02", --TAGDATE + description = "luaotfload submodule / fallback", + license = "GPL v2.0", + author = "Marcel Krüger" +} + +if luatexbase and luatexbase.provides_module then + luatexbase.provides_module (ProvidesLuaModule) +end + +local nodenew = node.direct.new +local getfont = font.getfont +local setfont = node.direct.setfont +local getwhd = node.direct.getwhd +local insert_after = node.direct.insert_after +local traverse_char = node.direct.traverse_char +local protect_glyph = node.direct.protect_glyph +local otffeatures = fonts.constructors.newfeatures "otf" +-- local normalize = fonts.handlers.otf.features.normalize +local definers = fonts.definers +local define_font = luaotfload.define_font + +local fallback_table_fontnames = {} + +local fallback_table = setmetatable({}, { + __index = function(t, name) + local names = fallback_table_fontnames[name] + if not names then + t[name] = false + return false + end + local res = setmetatable({}, { + __index = function(tt, size) + local lookup = {} + for i=#names,1,-1 do + local f = define_font(names[i] .. ';-fallback', size) + local fid + if type(f) == 'table' then + fid = font.define(f) + definers.register(f, fid) + elseif f then + fid = f + f = font.getfont(fid) + end + lookup[-i] = f -- Needed for multiscript interactions + for uni, _ in next, f.characters do + rawset(lookup, uni, fid) + end + end + tt[size] = lookup + return lookup + end, + }) + t[name] = res + return res + end, +}) + +local fallback_lookups = setmetatable({}, { + __index = function(t, fid) + local f = font.getfont(fid) + -- table.tofile('myfont2', f) + local res = f and f.fallback_lookup or false + if res then + res = table.merged(res) + for uni in next, f.characters do + rawset(res, uni, nil) + end + end + t[fid] = res + return res + end, +}) + +local function makefallbackfont(tfmdata, _, fallback) + local t = fallback_table[fallback] + if not t then error(string.format("Unknown fallback table %s", fallback)) end + fallback = t[tfmdata.size] + local fallback_lookup = {} + tfmdata.fallback_lookup = fallback +end + +local glyph_id = node.id'glyph' +-- TODO: unset last_script, matching parentheses etc +function dofallback(head, _, _, _, direction) + head = node.direct.todirect(head) + local last_fid, last_fallbacks + for cur, cid, fid in traverse_char(head) do + if fid ~= last_fid then + last_fid, last_fallbacks = fid, fallback_lookups[fid] + end + if last_fallbacks then + local new_fid = last_fallbacks[cid] + if new_fid then + setfont(cur, new_fid) + end + end + end +end + +function luaotfload.add_fallback(name, fonts) + if fonts == nil then + fonts = name + name = #fallback_table_fontnames + 1 + else + name = name:lower() + end + fallback_table_fontnames[name] = fonts + fallback_table[name] = nil + return name +end + +otffeatures.register { + name = "fallback", + description = "Fill in missing glyphs from other fonts", + manipulators = { + node = makefallbackfont, + plug = makefallbackfont, + }, + -- processors = { -- processors would be nice, but they are applied + -- -- too late for our purposes + -- node = donotdef, + -- } +} + +--- vim:sw=2:ts=2:expandtab:tw=71 diff --git a/Master/texmf-dist/tex/luatex/luaotfload/luaotfload-features.lua b/Master/texmf-dist/tex/luatex/luaotfload/luaotfload-features.lua index de129891e3f..0fe8a281c66 100644 --- a/Master/texmf-dist/tex/luatex/luaotfload/luaotfload-features.lua +++ b/Master/texmf-dist/tex/luatex/luaotfload/luaotfload-features.lua @@ -5,8 +5,8 @@ local ProvidesLuaModule = { name = "luaotfload-features", - version = "3.11", --TAGVERSION - date = "2019-11-10", --TAGDATE + version = "3.12", --TAGVERSION + date = "2020-02-02", --TAGDATE description = "luaotfload submodule / features", license = "GPL v2.0", author = "Hans Hagen, Khaled Hosny, Elie Roux, Philipp Gesang, Marcel Krüger", @@ -29,6 +29,8 @@ local R = lpeg.R local S = lpeg.S local C = lpeg.C +local lower = string.lower + local table = table local tabletohash = table.tohash local tablesort = table.sort @@ -240,7 +242,14 @@ local support_incomplete = tabletohash({ --doc]]-- --- (string, string) dict -> (string, string) dict -local apply_default_features = function (speclist) +local apply_default_features = function (rawlist) + local speclist = {} + for k, v in pairs(rawlist) do + if type(v) == 'string' then + v = ({['true'] = true, ['false'] = false})[lower(v)] or v + end + speclist[k] = v + end local default_features = luaotfload.features speclist = speclist or { } @@ -248,8 +257,8 @@ local apply_default_features = function (speclist) --- handle language tag local language = speclist.language - if language then --- already lowercase at this point - language = stringgsub(language, "[^a-z0-9]", "") + if language then + language = stringgsub(lower(language), "[^a-z0-9]", "") language = rawget(verboselanguages, language) -- srsly, rawget? or (languages[language] and language) or "dflt" @@ -261,7 +270,7 @@ local apply_default_features = function (speclist) --- handle script tag local script = speclist.script if script then - script = stringgsub(script, "[^a-z0-9]","") + script = stringgsub(lower(script), "[^a-z0-9]","") script = rawget(verbosescripts, script) or (scripts[script] and script) or "dflt" @@ -392,15 +401,7 @@ local handle_request = function (specification) end features.raw = request.features or {} - request.features = {} - for k, v in pairs(features.raw) do - if type(v) == 'string' then - v = string.lower(v) - v = ({['true'] = true, ['false'] = false})[v] or v - end - request.features[k] = v - end - request.features = apply_default_features(request.features) + request.features = apply_default_features(features.raw) if name then specification.name = name @@ -430,9 +431,12 @@ local handle_request = function (specification) features.normal = normalize (request.features) specification.sub = request.sub or specification.sub or false - if request.features and request.features.mode - and fonts.readers[request.features.mode] then - specification.forced = request.features.mode + local forced_mode = request.features and request.features.mode + if forced_mode then + forced_mode = lower(forced_mode) + if fonts.readers[forced_mode] then + specification.forced = forced_mode + end end return specification @@ -576,6 +580,8 @@ local add_auto_features = function () end end +luaotfload.apply_default_features = apply_default_features + return function () if not fonts and fonts.handlers then report ("log", 0, "features", diff --git a/Master/texmf-dist/tex/luatex/luaotfload/luaotfload-filelist.lua b/Master/texmf-dist/tex/luatex/luaotfload/luaotfload-filelist.lua index 4a1348b5f06..11bc5255474 100644 --- a/Master/texmf-dist/tex/luatex/luaotfload/luaotfload-filelist.lua +++ b/Master/texmf-dist/tex/luatex/luaotfload/luaotfload-filelist.lua @@ -6,8 +6,8 @@ local ProvidesLuaModule = { name = "luaotfload-filelist", - version = "3.11", --TAGVERSION - date = "2019-11-10", --TAGDATE + version = "3.12", --TAGVERSION + date = "2020-02-02", --TAGDATE description = "luaotfload submodule / filelist", license = "GPL v2.0" } @@ -252,6 +252,7 @@ luaotfload.filelist.data = { name = "harf-plug" ,kind = kind_library, ext =".lua", gitdir=gitdirsrc, texdir=texdirtex, gitpref = "luaotfload-" }, { name = "loaders" ,kind = kind_library, ext =".lua", gitdir=gitdirsrc, texdir=texdirtex, gitpref = "luaotfload-" }, { name = "multiscript" ,kind = kind_library, ext =".lua", gitdir=gitdirsrc, texdir=texdirtex, gitpref = "luaotfload-" }, + { name = "fallback" ,kind = kind_library, ext =".lua", gitdir=gitdirsrc, texdir=texdirtex, gitpref = "luaotfload-" }, { name = "parsers" ,kind = kind_library, ext =".lua", gitdir=gitdirsrc, texdir=texdirtex, gitpref = "luaotfload-" }, { name = "resolvers" ,kind = kind_library, ext =".lua", gitdir=gitdirsrc, texdir=texdirtex, gitpref = "luaotfload-" }, { name = "unicode" ,kind = kind_library, ext =".lua", gitdir=gitdirsrc, texdir=texdirtex, gitpref = "luaotfload-" }, diff --git a/Master/texmf-dist/tex/luatex/luaotfload/luaotfload-glyphlist.lua b/Master/texmf-dist/tex/luatex/luaotfload/luaotfload-glyphlist.lua index 8e0a2dec5f2..50f1b4d5906 100644 --- a/Master/texmf-dist/tex/luatex/luaotfload/luaotfload-glyphlist.lua +++ b/Master/texmf-dist/tex/luatex/luaotfload/luaotfload-glyphlist.lua @@ -1,7 +1,7 @@ local ProvidesLuaModule = { name = "luaotfload-glyphlist", - version = "3.11", --TAGVERSION - date = "2019-11-10", --TAGDATE + version = "3.12", --TAGVERSION + date = "2020-02-02", --TAGDATE description = "luaotfload submodule / autogenerated glyphlist", copyright = "derived from https://raw.githubusercontent.com/adobe-type-tools/agl-aglfn/master/glyphlist.txt", original = "Adobe Glyph List, version 2.0, September 20, 2002", diff --git a/Master/texmf-dist/tex/luatex/luaotfload/luaotfload-harf-define.lua b/Master/texmf-dist/tex/luatex/luaotfload/luaotfload-harf-define.lua index ad02cdb99a0..555180435af 100644 --- a/Master/texmf-dist/tex/luatex/luaotfload/luaotfload-harf-define.lua +++ b/Master/texmf-dist/tex/luatex/luaotfload/luaotfload-harf-define.lua @@ -5,8 +5,8 @@ do -- block to avoid to many local variables error local ProvidesLuaModule = { name = "luaotfload-harf-define", - version = "3.11", --TAGVERSION - date = "2019-11-10", --TAGDATE + version = "3.12", --TAGVERSION + date = "2020-02-02", --TAGDATE description = "luaotfload submodule / database", license = "GPL v2.0", author = "Khaled Hosny, Marcel Krüger", @@ -46,6 +46,7 @@ local function loadfont(spec) local key = string.format("%s:%d", gsub(path, "[/\\]", ":"), sub) local attributes = lfs.attributes(path) + if not attributes then return end local size, date = attributes.size or 0, attributes.modification or 0 local cached = containers.read(facecache, key) @@ -193,6 +194,17 @@ local function loadfont(spec) end cached.face = hbface cached.font = hbfont + do + local nominals = cached.nominals + local gid_offset = cached.gid_offset + cached.name_to_char = setmetatable({}, {__index = function(t, name) + local gid = hbfont:get_glyph_from_name(name) + local char = gid and (nominals[gid] or gid_offset + gid) + t[name] = char -- ? Do we want this + return char + end}) + end + return cached end @@ -217,11 +229,11 @@ local tlig ={ } local function scalefont(data, spec) + if not data then return data, spec end local size = spec.size - local features = spec.features.normal + local features = fonts.constructors.checkedfeatures("otf", spec.features.normal) features.mode = 'plug' features.features = 'harf' - fonts.constructors.checkedfeatures("otf", features) local hbface = data.face local hbfont = data.font local upem = data.upem @@ -316,7 +328,7 @@ local function scalefont(data, spec) local tfmdata = { name = spec.specification, - filename = spec.resolved, + filename = 'harfloaded:' .. spec.resolved, subfont = spec.sub or 1, designsize = size, psname = sanitize(data.psname), @@ -356,8 +368,12 @@ local function scalefont(data, spec) specification = spec, shared = {}, properties = {}, + resources = { + unicodes = data.name_to_char, + }, } tfmdata.shared.processes = fonts.handlers.otf.setfeatures(tfmdata, features) + fonts.constructors.applymanipulators("otf", tfmdata, features, false) return tfmdata end @@ -404,3 +420,11 @@ fonts.readers.harf = function(spec) end return scalefont(loadfont(spec), spec) end + +luatexbase.add_to_callback('find_opentype_file', function(name) + return name:gsub('^harfloaded:', '') +end, 'luaotfload.harf.strip_prefix') + +luatexbase.add_to_callback('find_truetype_file', function(name) + return name:gsub('^harfloaded:', '') +end, 'luaotfload.harf.strip_prefix') diff --git a/Master/texmf-dist/tex/luatex/luaotfload/luaotfload-harf-plug.lua b/Master/texmf-dist/tex/luatex/luaotfload/luaotfload-harf-plug.lua index 528d8c1e60b..c1d87de3129 100644 --- a/Master/texmf-dist/tex/luatex/luaotfload/luaotfload-harf-plug.lua +++ b/Master/texmf-dist/tex/luatex/luaotfload/luaotfload-harf-plug.lua @@ -5,8 +5,8 @@ do -- block to avoid to many local variables error local ProvidesLuaModule = { name = "luaotfload-harf-plug", - version = "3.11", --TAGVERSION - date = "2019-11-10", --TAGDATE + version = "3.12", --TAGVERSION + date = "2020-02-02", --TAGDATE description = "luaotfload submodule / database", license = "GPL v2.0", author = "Khaled Hosny, Marcel Krüger", @@ -565,8 +565,17 @@ end local push_cmd = { "push" } local pop_cmd = { "pop" } local nop_cmd = { "nop" } -local save_cmd = { "pdf", "page", "q" } -local restore_cmd = { "pdf", "page", "Q" } +--[[ + In the following, "text" actually refers to "font" mode and not to "text" + mode. "font" mode is called "text" inside of virtual font commands (don't + ask me why, but the LuaTeX source does make it clear that this is intentional) + and behaves mostly like "page" (especially it does not enter a "BT" "ET" + block) except that it always resets the current position to the origin. + This is necessary to ensure that the q/Q pair does not interfere with TeX's + position tracking. + ]] +local save_cmd = { "pdf", "text", "q" } +local restore_cmd = { "pdf", "text", "Q" } -- Convert glyphs to nodes and collect font characters. local function tonodes(head, node, run, glyphs) diff --git a/Master/texmf-dist/tex/luatex/luaotfload/luaotfload-init.lua b/Master/texmf-dist/tex/luatex/luaotfload/luaotfload-init.lua index e136d6cf63c..0f8d7b3206f 100644 --- a/Master/texmf-dist/tex/luatex/luaotfload/luaotfload-init.lua +++ b/Master/texmf-dist/tex/luatex/luaotfload/luaotfload-init.lua @@ -7,8 +7,8 @@ local ProvidesLuaModule = { name = "luaotfload-init", - version = "3.11", --TAGVERSION - date = "2019-11-10", --TAGDATE + version = "3.12", --TAGVERSION + date = "2020-02-02", --TAGDATE description = "luaotfload submodule / initialization", license = "GPL v2.0" } @@ -192,6 +192,22 @@ local load_context_modules = function (pth) end +local function verify_context_dir (pth) + if lfsisdir(file.join(pth, ltx)) then + return true + end + for _, d in ipairs(ctx) do + if lfsisdir(file.join(pth, d)) then + return true + end + end + logreport("both", 0, "init", "A directory name has been passed as \z + fontloader name but this directory does not acutally seem to contain \z + a font loader. I will try to interpret your fontloader name in another \z + way for now, but please fix your settings.") + return false +end + local function init_main(early_hook) config = config or { } --- global config.luaotfload = config.luaotfload or { } @@ -374,7 +390,7 @@ local function init_main(early_hook) "Loading Context modules in lookup path.") load_context_modules () - elseif lfsisdir (fontloader) then + elseif lfsisdir (fontloader) and verify_context_dir (fontloader) then logreport ("log", 0, "init", "Loading Context files under prefix “%s”.", fontloader) @@ -439,6 +455,7 @@ local init_post_install_callbacks = function () direction = tex.get'textdir' end domultiscript(head, nil, nil, nil, direction) + dofallback(head, nil, nil, nil, direction) return handler(head, groupcode, nil, nil, direction) end luatexbase.add_to_callback("pre_linebreak_filter", diff --git a/Master/texmf-dist/tex/luatex/luaotfload/luaotfload-letterspace.lua b/Master/texmf-dist/tex/luatex/luaotfload/luaotfload-letterspace.lua index 905fc6acce8..ce7d6fcd565 100644 --- a/Master/texmf-dist/tex/luatex/luaotfload/luaotfload-letterspace.lua +++ b/Master/texmf-dist/tex/luatex/luaotfload/luaotfload-letterspace.lua @@ -5,8 +5,8 @@ local ProvidesLuaModule = { name = "luaotfload-letterspace", - version = "3.11", --TAGVERSION - date = "2019-11-10", --TAGDATE + version = "3.12", --TAGVERSION + date = "2020-02-02", --TAGDATE description = "luaotfload submodule / color", license = "GPL v2.0", copyright = "PRAGMA ADE / ConTeXt Development Team", @@ -82,6 +82,7 @@ local fonthashes = fonts.hashes local identifiers = fonthashes.identifiers local chardata = fonthashes.characters local otffeatures = fonts.constructors.newfeatures "otf" +local markdata local function getprevreal(n) repeat @@ -144,6 +145,21 @@ if not chardata then fonthashes.characters = chardata end +if not markdata then + markdata = setmetatable({}, {__index = function(t, k) + if k == true then + return t[currentfont()] + else + local tfmdata = font.getfont(k) or font.fonts[k] + if tfmdata then + local marks = tfmdata.resources.marks or {} + t[k] = marks + return marks + end + end + end}) +end + ---=================================================================--- --- character kerning functionality ---=================================================================--- @@ -334,7 +350,7 @@ kerncharacters = function (head) local kern = 0 local kerns = prevchardata.kerns if kerns then kern = kerns[lastchar] or kern end - krn = kern + krn -- here + krn = kern + (markdata[lastfont][lastchar] and 0 or krn) -- here insert_node_before(head,start,kern_injector(fillup,krn)) end end @@ -409,7 +425,7 @@ kerncharacters = function (head) if kerns then kern = kerns[lastchar] or kern end end end - krn = kern + krn -- here + krn = kern + (markdata[lastfont][lastchar] and 0 or krn) -- here end setfield(disc, "replace", kern_injector(false, krn)) end --[[if replace and prv and nxt]] diff --git a/Master/texmf-dist/tex/luatex/luaotfload/luaotfload-loaders.lua b/Master/texmf-dist/tex/luatex/luaotfload/luaotfload-loaders.lua index 2865bf55165..0f24e4542ec 100644 --- a/Master/texmf-dist/tex/luatex/luaotfload/luaotfload-loaders.lua +++ b/Master/texmf-dist/tex/luatex/luaotfload/luaotfload-loaders.lua @@ -8,8 +8,8 @@ local ProvidesLuaModule = { name = "luaotfload-loaders", - version = "3.11", --TAGVERSION - date = "2019-11-10", --TAGDATE + version = "3.12", --TAGVERSION + date = "2020-02-02", --TAGDATE description = "luaotfload submodule / callback handling", license = "GPL v2.0" } @@ -120,10 +120,20 @@ end local definers --- (string, spec -> size -> id -> tmfdata) hash_t do - local read = fonts.definers.read + local ctx_read = fonts.definers.read + local register = fonts.definers.register + local function read(specification, size, id) + local tfmdata = ctx_read(specification, size, id) + if not tfmdata or id or tonumber(tfmdata) then + return tfmdata + end + id = font.define(tfmdata) + register(tfmdata, id) + return id + end local patch = function (specification, size, id) - local fontdata = read (specification, size, id) + local fontdata = ctx_read (specification, size, id) ----if not fontdata then not_found_msg (specification, size, id) end if type (fontdata) == "table" and fontdata.encodingbytes == 2 then --- We need to test for `encodingbytes` to avoid passing @@ -133,7 +143,12 @@ do else luatexbase.call_callback ("luaotfload.patch_font_unsafe", fontdata, specification, id) end - return fontdata + if not fontdata or id or tonumber(fontdata) then + return fontdata + end + id = font.define(fontdata) + register(fontdata, id) + return id end local mk_info = function (name) @@ -209,9 +224,11 @@ local install_callbacks = function () create_callback ("luaotfload.patch_font", "simple", dummy_function) create_callback ("luaotfload.patch_font_unsafe", "simple", dummy_function) purge_define_font () - local definer = config.luaotfload.run.definer + local definer = config.luaotfload.run.definer or "patch" + local selected_definer = definers[definer] + luaotfload.define_font = selected_definer luatexbase.add_to_callback ("define_font", - definers[definer or "patch"], + selected_definer, "luaotfload.define_font", 1) return true diff --git a/Master/texmf-dist/tex/luatex/luaotfload/luaotfload-log.lua b/Master/texmf-dist/tex/luatex/luaotfload/luaotfload-log.lua index 95328771272..2cbacd597f3 100644 --- a/Master/texmf-dist/tex/luatex/luaotfload/luaotfload-log.lua +++ b/Master/texmf-dist/tex/luatex/luaotfload/luaotfload-log.lua @@ -6,8 +6,8 @@ local ProvidesLuaModule = { name = "luaotfload-log", - version = "3.11", --TAGVERSION - date = "2019-11-10", --TAGDATE + version = "3.12", --TAGVERSION + date = "2020-02-02", --TAGDATE description = "luaotfload submodule / logging", license = "GPL v2.0", author = "Khaled Hosny, Elie Roux, Philipp Gesang", diff --git a/Master/texmf-dist/tex/luatex/luaotfload/luaotfload-main.lua b/Master/texmf-dist/tex/luatex/luaotfload/luaotfload-main.lua index 65fdc9fc00b..35378d91cbc 100644 --- a/Master/texmf-dist/tex/luatex/luaotfload/luaotfload-main.lua +++ b/Master/texmf-dist/tex/luatex/luaotfload/luaotfload-main.lua @@ -20,8 +20,8 @@ local authors = "\z -- version number is used below! local ProvidesLuaModule = { name = "luaotfload-main", - version = "3.11", --TAGVERSION - date = "2019-11-10", --TAGDATE + version = "3.12", --TAGVERSION + date = "2020-02-02", --TAGDATE description = "luaotfload entry point", author = authors, copyright = authors, @@ -44,25 +44,35 @@ luaotfload.fontloader_package = "reference" --- default: from current Con if not tex or not tex.luatexversion then error "this program must be run in TeX mode" --- or call tex.initialize() =) -else - --- version check - local major = tex.luatexversion / 100 - local minor = tex.luatexversion % 100 - local revision = tex.luatexrevision --[[ : string ]] - local revno = tonumber (revision) - local minimum = luaotfload.min_luatex_version - local actual = { major, minor, revno or 0 } - if actual [1] < minimum [1] +end + +--- version check +local major = tex.luatexversion / 100 +local minor = tex.luatexversion % 100 +local revision = tex.luatexrevision --[[ : string ]] +local revno = tonumber (revision) +local minimum = luaotfload.min_luatex_version +local actual = { major, minor, revno or 0 } +if actual [1] < minimum [1] or actual == minimum and actual [2] < minimum [2] or actual == minimum and actual [2] == minimum [2] and actual [3] < minimum [3] - then - texio.write_nl ("term and log", - string.format ("\tFATAL ERROR\n\z - \tLuaotfload requires a Luatex version >= %d.%d.%d.\n\z - \tPlease update your TeX distribution!\n\n", - (unpack or table.unpack) (minimum))) - error "version check failed" - end +then + texio.write_nl ("term and log", + string.format ("\tFATAL ERROR\n\z + \tLuaotfload requires a Luatex version >= %d.%d.%d.\n\z + \tPlease update your TeX distribution!\n\n", + (unpack or table.unpack) (minimum))) + error "version check failed" +end + +if not utf8 then + texio.write_nl("term and log", string.format("\z + \tluaotfload: module utf8 is unavailable\n\z + \tutf8 is available in Lua 5.3+; engine\'s _VERSION is '%s'\n\z + \tThis probably means that the engine is not supported\n\z + \n", + _VERSION)) + error "module utf8 is unavailable" end if status.safer_option ~= 0 then @@ -316,12 +326,13 @@ luaotfload.main = function () loadmodule "harf-plug" end initialize "auxiliary" --- additional high-level functionality + loadmodule "fallback" --- ... loadmodule "multiscript" --- ... loadmodule "tounicode" luaotfload.aux.start_rewrite_fontname () --- to be migrated to fontspec - logreport ("both", 0, "main", + logreport ("log", 1, "main", "initialization completed in %0.3f seconds\n", osgettimeofday() - starttime) ----inspect (timing_info) diff --git a/Master/texmf-dist/tex/luatex/luaotfload/luaotfload-multiscript.lua b/Master/texmf-dist/tex/luatex/luaotfload/luaotfload-multiscript.lua index c2aa664fabc..f6a272ecabd 100644 --- a/Master/texmf-dist/tex/luatex/luaotfload/luaotfload-multiscript.lua +++ b/Master/texmf-dist/tex/luatex/luaotfload/luaotfload-multiscript.lua @@ -5,8 +5,8 @@ local ProvidesLuaModule = { name = "luaotfload-multiscript", - version = "3.11", --TAGVERSION - date = "2019-11-10", --TAGDATE + version = "3.12", --TAGVERSION + date = "2020-02-02", --TAGDATE description = "luaotfload submodule / multiscript", license = "GPL v2.0", author = "Marcel Krüger" @@ -24,6 +24,19 @@ local insert_after = node.direct.insert_after local traverse_char = node.direct.traverse_char local protect_glyph = node.direct.protect_glyph local otffeatures = fonts.constructors.newfeatures "otf" +-- local normalize = fonts.handlers.otf.features.normalize +local definers = fonts.definers +local define_font = luaotfload.define_font +local scripts_lib = require'luaotfload-scripts'.script +local script_to_iso = scripts_lib.to_iso +local script_to_ot = scripts_lib.to_ot + +local harf = luaotfload.harfbuzz +local GSUBtag, GPOStag +if harf then + GSUBtag = harf.Tag.new("GSUB") + GPOStag = harf.Tag.new("GPOS") +end local sep = lpeg.P' '^0 * ';' * lpeg.P' '^0 local codepoint = lpeg.S'0123456789ABCDEF'^4/function(c)return tonumber(c, 16)end @@ -35,7 +48,7 @@ local function multirawset(table, key1, key2, value) return table end local script_extensions do - local entry = lpeg.Cg(codepoint_range * sep * lpeg.Ct((lpeg.C(lpeg.R'AZ' * lpeg.R'az'^1))^1 * ' ') * '#')^-1 * (1-lpeg.P'\n')^0 * '\n' + local entry = lpeg.Cg(codepoint_range * sep * lpeg.Ct((lpeg.C(lpeg.R'AZ' * lpeg.R'az'^1)/string.lower)^1 * ' ') * '#')^-1 * (1-lpeg.P'\n')^0 * '\n' local file = lpeg.Cf( lpeg.Ct'' * entry^0 @@ -98,7 +111,7 @@ local script_mapping do Cuneiform = "Xsux", Yi = "Yiii", Zanabazar_Square = "Zanb", Inherited = "Zinh", Common = "Zyyy", Unknown = "Zzzz", } - local entry = lpeg.Cg(codepoint_range * sep * ((lpeg.R'AZ' + lpeg.R'az' + '_')^1/script_aliases))^-1 * (1-lpeg.P'\n')^0 * '\n' + local entry = lpeg.Cg(codepoint_range * sep * ((lpeg.R'AZ' + lpeg.R'az' + '_')^1/script_aliases/string.lower))^-1 * (1-lpeg.P'\n')^0 * '\n' -- local entry = lpeg.Cg(codepoint_range * sep * lpeg.Cc(true))^-1 * (1-lpeg.P'\n')^0 * '\n' local file = lpeg.Cf( lpeg.Ct'' @@ -110,6 +123,48 @@ local script_mapping do f:close() end +local function load_on_demand(specifications, size) + return setmetatable({}, { __index = function(t, k) + local specification = specifications[k] + if not specification then return end + local f = define_font(specification, size) + local fid + if type(f) == 'table' then + fid = font.define(f) + definers.register(f, fid) + elseif f then + fid = f + end + t[k] = fid + return fid + end}) +end + +local function collect_scripts(tfmdata) + local script_dict = {} + local hbdata = tfmdata.hb + if hbdata then + local face = hbdata.shared.face + for _, tag in next, { GSUBtag, GPOStag } do + local script_tags = face:ot_layout_get_script_tags(tag) or {} + for i = 1, #script_tags do + script_dict[tostring(script_tags[i]):gsub(" +$", "")] = true + end + end + else + local features = tfmdata.resources.features + for _, feature_table in next, features do + for _, scripts in next, feature_table do + for script in next, scripts do + script_dict[script] = true + end + end + end + script_dict["*"] = nil + end + return script_dict +end + local additional_scripts_tables = { } local additional_scripts_fonts = setmetatable({}, { @@ -122,27 +177,112 @@ local additional_scripts_fonts = setmetatable({}, { end, }) +local function is_dominant_script(scripts, script, first, ...) + if script == first then return true end + if scripts[first] or not first then return false end + return is_dominant_script(scripts, script, ...) +end + local function makecombifont(tfmdata, _, additional_scripts) - local basescript = tfmdata.properties.script - local scripts = {basescript = false} - additional_scripts = additional_scripts_tables[additional_scripts] - for script, fontname in pairs(additional_scripts) do - if script ~= basescript then - local f = fonts.definers.read(fontname, tfmdata.size) - local fid - if type(f) == 'table' then - fid = font.define(f) - else - error[[FIXME???]] + local has_auto + additional_scripts = tostring(additional_scripts) + if additional_scripts:sub(1, 5) == "auto+" then + additional_scripts = additional_scripts:sub(6) + has_auto = true + elseif additional_scripts == "auto" then + has_auto, additional_scripts = true, false + end + if additional_scripts then + local t = additional_scripts_tables[tonumber(additional_scripts) or additional_scripts] + if not t then error(string.format("Unknown multiscript table %s", additional_scripts)) end + local lower_t = {} + for k, v in next, t do if type(k) == "string" then + local l = string.lower(k) + if lower_t[l] ~= nil and lower_t[l] ~= v then + error(string.format("Inconsistant multiscript table %q for script %s", additional_scripts, l)) + end + lower_t[l] = v + end end + additional_scripts = lower_t + else + additional_scripts = {} + end + if has_auto then + local fallback = tfmdata.fallback_lookup + if fallback then -- FIXME: here be dragons + local fallbacks = {} + local current = tfmdata + local i = 0 + while current do + local collected = collect_scripts(current) + for script in next, collected do + local scr_fb = fallbacks[script] + if not scr_fb then + scr_fb = {} + fallbacks[script] = scr_fb + end + scr_fb[#scr_fb + 1] = current.specification.specification .. ';script=' .. script .. ';-multiscript' + end + i = i - 1 + current = fallback[i] + end + current = tfmdata + i = 0 + while current do + local collected = collect_scripts(current) + for script, scr_fb in next, fallbacks do + if not collected[script] then + scr_fb[#scr_fb + 1] = current.specification.specification .. ';-multiscript' + end + end + i = i - 1 + current = fallback[i] + end + for script, scr_fb in next, fallbacks do + local iso_script = script_to_iso(script) + if not additional_scripts[iso_script] and is_dominant_script(scr_fb, script, script_to_ot(iso_script)) then + local main = scr_fb[1] + table.remove(scr_fb, 1) + local fbid = luaotfload.add_fallback(scr_fb) + additional_scripts[iso_script] = main .. ';fallback=' .. fbid + end + end + else + local spec = tfmdata.specification + local collected = collect_scripts(tfmdata) + for script in next, collected do + local iso_script = script_to_iso(script) + if not additional_scripts[iso_script] and is_dominant_script(collected, script, script_to_ot(iso_script)) then + additional_scripts[iso_script] = spec.specification .. ';-multiscript;script=' .. script + ---- FIXME: IMHO the following which just modiefies the spec + -- would be nicer, but it breaks font patching callbacks + -- (except if we ignore them, but that would be inconsistant to + -- other fonts) + -- local new_raw_features = {} + -- local new_features = { raw = new_raw_features, normal = new_raw_features } + -- for f, v in next, spec.features.raw do + -- new_raw_features[f] = v + -- end + -- new_raw_features.multiscript = false + -- new_raw_features.script = script + -- local new_normal_features = luaotfload.apply_default_features(new_raw_features) + -- new_normal_features.sub = nil + -- new_normal_features.lookup = nil + -- new_features.normal = normalize(new_normal_features) + -- local new_spec = {} + -- for k, v in next, spec do + -- new_spec[k] = v + -- end + -- new_spec.hash = nil + -- new_spec.features = new_features + -- additional_scripts[script] = new_spec + end end - scripts[script] = { - fid = fid, - font = f, - characters = f.characters, - } end end - tfmdata.additional_scripts = scripts + local basescript = tfmdata.properties.script or "dflt" + tfmdata.additional_scripts = load_on_demand(additional_scripts, tfmdata.size) + tfmdata.additional_scripts[basescript] = false end local glyph_id = node.id'glyph' @@ -156,29 +296,30 @@ function domultiscript(head, _, _, _, direction) end if last_fonts then local mapped_scr = script_mapping[cid] - if mapped_scr == "Zinh" then + if mapped_scr == "zinh" then mapped_scr = last_script else - local additional_scr = script_extensions[cid] + local additional_scripts = script_extensions[cid] if additional_scripts then if additional_scripts[last_script] then mapped_scr = last_script - elseif not last_fonts[mapped_scr] then + elseif last_fonts[mapped_scr] == nil then for i = 1, #additional_scripts do - if last_fonts[additional_scripts[i]] then - mapped_scr = additional_scripts[i] + local script = additional_scripts[i] + if last_fonts[script] ~= nil then + mapped_scr = script break end end end - elseif mapped_scr == "Zyyy" then + elseif mapped_scr == "zyyy" then mapped_scr = last_script end end last_script = mapped_scr local mapped_font = last_fonts[mapped_scr] if mapped_font then - setfont(cur, mapped_font.fid) + setfont(cur, mapped_font) end end end @@ -188,6 +329,8 @@ function luaotfload.add_multiscript(name, fonts) if fonts == nil then fonts = name name = #additional_scripts_fonts + 1 + else + name = name:lower() end additional_scripts_tables[name] = fonts return name @@ -198,6 +341,7 @@ otffeatures.register { description = "Combine fonts for multiple scripts", manipulators = { node = makecombifont, + plug = makecombifont, }, -- processors = { -- processors would be nice, but they are applied -- -- too late for our purposes diff --git a/Master/texmf-dist/tex/luatex/luaotfload/luaotfload-notdef.lua b/Master/texmf-dist/tex/luatex/luaotfload/luaotfload-notdef.lua index 9c0634f90d7..3156882e866 100644 --- a/Master/texmf-dist/tex/luatex/luaotfload/luaotfload-notdef.lua +++ b/Master/texmf-dist/tex/luatex/luaotfload/luaotfload-notdef.lua @@ -5,8 +5,8 @@ local ProvidesLuaModule = { name = "luaotfload-notdef", - version = "3.11", --TAGVERSION - date = "2019-11-10", --TAGDATE + version = "3.12", --TAGVERSION + date = "2020-02-02", --TAGDATE description = "luaotfload submodule / color", license = "GPL v2.0", author = "Marcel Krüger" diff --git a/Master/texmf-dist/tex/luatex/luaotfload/luaotfload-parsers.lua b/Master/texmf-dist/tex/luatex/luaotfload/luaotfload-parsers.lua index 4cf46fe3293..2cdd0063783 100644 --- a/Master/texmf-dist/tex/luatex/luaotfload/luaotfload-parsers.lua +++ b/Master/texmf-dist/tex/luatex/luaotfload/luaotfload-parsers.lua @@ -7,8 +7,8 @@ local ProvidesLuaModule = { name = "luaotfload-parsers", - version = "3.11", --TAGVERSION - date = "2019-11-10", --TAGDATE + version = "3.12", --TAGVERSION + date = "2020-02-02", --TAGDATE description = "luaotfload submodule / filelist", license = "GPL v2.0" } diff --git a/Master/texmf-dist/tex/luatex/luaotfload/luaotfload-resolvers.lua b/Master/texmf-dist/tex/luatex/luaotfload/luaotfload-resolvers.lua index 61949621cb0..c49fa58fd97 100644 --- a/Master/texmf-dist/tex/luatex/luaotfload/luaotfload-resolvers.lua +++ b/Master/texmf-dist/tex/luatex/luaotfload/luaotfload-resolvers.lua @@ -11,8 +11,8 @@ local ProvidesLuaModule = { name = "luaotfload-resolvers", - version = "3.11", --TAGVERSION - date = "2019-11-10", --TAGDATE + version = "3.12", --TAGVERSION + date = "2020-02-02", --TAGDATE description = "luaotfload submodule / resolvers", license = "GPL v2.0" } diff --git a/Master/texmf-dist/tex/luatex/luaotfload/luaotfload-scripts.lua b/Master/texmf-dist/tex/luatex/luaotfload/luaotfload-scripts.lua index 48ececf8908..814223b5ed5 100644 --- a/Master/texmf-dist/tex/luatex/luaotfload/luaotfload-scripts.lua +++ b/Master/texmf-dist/tex/luatex/luaotfload/luaotfload-scripts.lua @@ -5,8 +5,8 @@ local ProvidesLuaModule = { name = "luaotfload-script", - version = "3.11", --TAGVERSION - date = "2019-11-10", --TAGDATE + version = "3.12", --TAGVERSION + date = "2020-02-02", --TAGDATE description = "luaotfload submodule / Script helpers", license = "CC0 1.0 Universal", author = "Marcel Krüger" diff --git a/Master/texmf-dist/tex/luatex/luaotfload/luaotfload-status.lua b/Master/texmf-dist/tex/luatex/luaotfload/luaotfload-status.lua index b4bad63474f..ed3324f304c 100644 --- a/Master/texmf-dist/tex/luatex/luaotfload/luaotfload-status.lua +++ b/Master/texmf-dist/tex/luatex/luaotfload/luaotfload-status.lua @@ -1,18 +1,18 @@ return { ["hashes"]={ - { "fontloader-2019-10-29.lua", "8b7d755e08cfef0826429ffa68271eb3" }, + { "fontloader-2020-01-26.lua", "010915906c0926fc7f5f4d064a879be4" }, { "fontloader-util-fil.lua", "4bb3e4dc72e308d8ed67cd7a80027fa7" }, - { "fontloader-util-str.lua", "fc15d89c4c35f7338d09fc7644fac181" }, + { "fontloader-util-str.lua", "2e4625b13a5f4be76b1d8664a32119ec" }, { "fontloader-l-unicode.lua", "9bc311ce08ce498f9caacb6164ea1d9f" }, { "fontloader-l-math.lua", "a373be3ed2db0d5f98588fa81abca48f" }, { "fontloader-l-boolean.lua", "18ed6c4b2c40dd87224ea33229548d20" }, - { "fontloader-l-file.lua", "3d6ea476061292a0da98c3f65cdabe46" }, - { "fontloader-l-io.lua", "42608ad95eb2822fdc370d1c11f08fb5" }, - { "fontloader-l-table.lua", "9844897b04a01bb197427d71de71de2b" }, + { "fontloader-l-file.lua", "60ddd3948d9de7bde8b4a0f5c51ff9f5" }, + { "fontloader-l-io.lua", "a4042e9d6bce71c61fdd94e6e17f2bf4" }, + { "fontloader-l-table.lua", "a495e837874aa3e4fa57fea4dd05a26c" }, { "fontloader-l-string.lua", "e1347bef0eeeff9f098df83b30b32df9" }, { "fontloader-l-function.lua", "f771cc91839ebcdfc094083434fbe00f" }, { "fontloader-l-lpeg.lua", "efe630e3a9a1d269120e59cfd8fba4ba" }, - { "fontloader-l-lua.lua", "dda8438a34886bb767dbad381f1ea70a" }, + { "fontloader-l-lua.lua", "4185c43dd58d217094ef91c0310d8772" }, { "fontloader-fonts-gbn.lua", "d25472d54c4841db43a745764a63533e" }, { "fontloader-fonts-lig.lua", "b9dbe77ce747d4c35bb2a20ffbe5aa51" }, { "fontloader-fonts-ext.lua", "01015ab3758cdc2af29394e6d502a91a" }, @@ -21,74 +21,74 @@ return { { "fontloader-fonts-enc.lua", "3e71a54297e8f85a1ac438bb0f20dd79" }, { "fontloader-fonts-mis.lua", "bc9eb43c27f63ce9d0fff67e104fe1c6" }, { "fontloader-basics-chr.lua", "58b7ef0c486e06090b362971b9f85e27" }, - { "fontloader-basics-nod.lua", "c05f47077c709bbf12a8758852dc4e06" }, + { "fontloader-basics-nod.lua", "4ce2f7c752fdc4c1d6d9f74e8cd50be8" }, { "fontloader-font-imp-effects.lua", "73a660359a0ec71e44cc2b7225a715ac" }, { "fontloader-font-imp-italics.lua", "fe1ca80fb5ea4a2f8d2d5c484e7ba913" }, { "fontloader-font-imp-ligatures.lua", "043daa4fcccf2560868da359d71d3a4a" }, { "fontloader-font-imp-tex.lua", "77c374b0ef00c2fb12188ec42beb4257" }, - { "fontloader-font-def.lua", "f66c365dae4499f982d8bf16e5d37de3" }, + { "fontloader-font-def.lua", "c525b9f55da1c736a1f6939c0a6f8f00" }, { "fontloader-font-lua.lua", "55b281fb98f7bd848fc19928f376f647" }, { "fontloader-font-afk.lua", "54d554530e75c57c56ee76234724e26d" }, { "fontloader-font-one.lua", "987c5c5ed3754ad2feab80985067d59e" }, - { "fontloader-font-onr.lua", "d4d2449b4084e6afb1837ae5835082cc" }, + { "fontloader-font-onr.lua", "22572ec0f86f53631e14b6d1ed43ee51" }, { "fontloader-font-otc.lua", "1204a2fdc436e644127c0aa38ab69607" }, - { "fontloader-font-ocl.lua", "ba40df1a92b9b42a5c70d20c28f44759" }, + { "fontloader-font-ocl.lua", "c1f4cbea3c4ec5002a04fc637b135711" }, { "fontloader-font-osd.lua", "39e92f6e575741646d75ea79e3be87f3" }, - { "fontloader-font-ots.lua", "d6a0ce4b40cd4ee1895e2248dcf87d37" }, + { "fontloader-font-ots.lua", "d0107799ec82da7f96dafe9626c5ee7f" }, { "fontloader-font-ota.lua", "d6dfb94563d6a52675e274b2e673e4a6" }, { "fontloader-font-otj.lua", "66c7a910d95d4a52b81061de776898e1" }, - { "fontloader-font-oto.lua", "52804afd96f4be005f513a012b874668" }, + { "fontloader-font-oto.lua", "24238a7c600d090a8ee88312321dd9b3" }, { "fontloader-font-otl.lua", "ec0241b7465a7713e53c246e8e9fb2a8" }, { "fontloader-font-oup.lua", "0cef35af01739f52fd09feb5401192ae" }, { "fontloader-font-dsp.lua", "5d3db0184c903829b2c5bddcb8cdb14c" }, { "fontloader-font-ttf.lua", "44e61cef50dab9b1aaf48130f9367c34" }, - { "fontloader-font-cff.lua", "98d5a660ea803b65cb883c009ecf3c0b" }, + { "fontloader-font-cff.lua", "c769020b41b39418f703347f3d328bc7" }, { "fontloader-font-ott.lua", "aba6d8335a5f38a5a62d3631492f3392" }, { "fontloader-font-oti.lua", "dbae7722baae24d917a17176553825cf" }, - { "fontloader-font-otr.lua", "b1c03925c949027c86f781785fa7a208" }, + { "fontloader-font-otr.lua", "d96724dcb40c673ac294df7044a39925" }, { "fontloader-font-vfc.lua", "94937140f2c909e9c831ba021f1ab303" }, { "fontloader-font-map.lua", "f486746e90fe972de4b73e208ac7cbb2" }, { "fontloader-font-cid.lua", "4d87988efa86020a14708ee03c23415f" }, - { "fontloader-font-con.lua", "8b35e7c2203d5b57c61942e07cee2c0a" }, - { "fontloader-font-ini.lua", "4299a02110bbd7c0d27e131235c5319d" }, - { "fontloader-data-con.lua", "7ce546725b1550f655c78ac9d69419ca" }, - { "fontloader-reference.lua", "5be3565068a1929b173bde862b48a30e" }, - { "fontloader-basics-gen.lua", "b21e91bbd534f77e368f0ec13f865aed" }, + { "fontloader-font-con.lua", "b436bf6880a56216445779ac68fee877" }, + { "fontloader-font-ini.lua", "4dee96e1e1474d324dd126bd5d375df8" }, + { "fontloader-data-con.lua", "de6ae0997b0e70a23bcc9afff5d8b072" }, + { "fontloader-reference.lua", "0c0e3262f5cc53d1142e459921526f69" }, + { "fontloader-basics-gen.lua", "b88f9848c3247e4222b7bb63b0ee3f35" }, { "mktests", "c7cff7025962922944376acc1ffa9c47" }, - { "mkstatus", "1a9f8bbf36426071b6970678975360a9" }, + { "mkstatus", "72f4b4ff15c9f4fd95b8ba942b541b20" }, { "mkcharacters", "92c24bb582fc84c0365634f29eb89863" }, { "mkglyphlist", "557836886d4f0e6d656eac3ded4456a2" }, { "mkimport", "60e0b11a1a68719033e86a3e0f4d5e86" }, - { "luaotfload-glyphlist.lua", "bb67952ea9fb1c3766402457bd477629" }, + { "luaotfload-glyphlist.lua", "0c2e6db4d2d944b5e4e6d83971edc166" }, { "luaotfload-characters.lua", "593ce9dccf6ddc4f7d4be0514f581102" }, - { "luaotfload-tounicode.lua", "f37eab5828b4aee392de359bf4d57027" }, - { "luaotfload-unicode.lua", "861eb4a6332e0b7d8e757cab4759a734" }, - { "luaotfload-resolvers.lua", "5d9e254413ba333a4f559be023355224" }, - { "luaotfload-parsers.lua", "e1f4a54c2f29550d3c8ff18e19841ee4" }, - { "luaotfload-multiscript.lua", "05d2f1c9a27afdbc4b9ad95f958cb6cb" }, - { "luaotfload-loaders.lua", "cc475c8b04368d3f8ef6e52495fb579a" }, - { "luaotfload-harf-plug.lua", "ec3ad02c41bd174aedc350dc4cabbc54" }, - { "luaotfload-harf-define.lua", "7e85627ae64b749f41de5863d7c5ca86" }, - { "luaotfload-notdef.lua", "23d514bea20fcb0343a8382537ab3924" }, - { "luaotfload-embolden.lua", "bd0cd6e3951dab2862ca2d2dc1c6bccb" }, - { "luaotfload-letterspace.lua", "352d83726eead3902323d451907aeb66" }, - { "luaotfload-features.lua", "c60d2fcaab63dc338d9abd82176f96ee" }, - { "luaotfload-database.lua", "3f126f3acdcf4b90f13d6c3c41b83147" }, - { "luaotfload-configuration.lua", "fdb8f0e3b826e91b8598d4b4a387aaa5" }, - { "luaotfload-colors.lua", "7f63ffde97bb798b63f2c94c5a7e474f" }, - { "luaotfload-auxiliary.lua", "5e027ad1dde5655eaa74204cdb709098" }, - { "luaotfload-filelist.lua", "3194c19d0618e4784711e87864e625ea" }, - { "luaotfload-tool.lua", "3f989f7646d8df2aea584d2333cfb894" }, - { "luaotfload-diagnostics.lua", "b31b30dd151cd2e6c359b56f4c9fd12c" }, - { "luaotfload-log.lua", "30d00c154254ce70fe7c1a33692110e2" }, - { "luaotfload-init.lua", "e22c43529440994d0c99734c736dbb65" }, - { "luaotfload-main.lua", "9fc20061c7af28ccfcfb95a69115c3e4" }, + { "luaotfload-tounicode.lua", "8c678ba2c2c809706a63a79a339d102b" }, + { "luaotfload-unicode.lua", "ec04cec91b4c7a73acace241f791a228" }, + { "luaotfload-resolvers.lua", "92c1c59341213f716a6eee355b847849" }, + { "luaotfload-parsers.lua", "ef73b50dee1935a1af4cd76ed303bba6" }, + { "luaotfload-multiscript.lua", "d5a1d602ecc4b4caad5f89772dd8affa" }, + { "luaotfload-loaders.lua", "084e6b89d85ccdc59d90102059d8020a" }, + { "luaotfload-harf-plug.lua", "09d1f0baf43fb6932d5619436d0ff950" }, + { "luaotfload-harf-define.lua", "e27975867cbe2eac101ea2ff366050dc" }, + { "luaotfload-notdef.lua", "1a4f3eeedfb374927fa0673849c5f95b" }, + { "luaotfload-embolden.lua", "8412b95b699231918ea78384ada0e3df" }, + { "luaotfload-letterspace.lua", "2ffa8128161281fa2ca7605fc056e13d" }, + { "luaotfload-features.lua", "2db4774ed71aa8ba4e859655e6076f1b" }, + { "luaotfload-database.lua", "c11b6638c72aa2216aaf0432278654cc" }, + { "luaotfload-configuration.lua", "d4c270b581eb22ded89bc2c6dffd7a78" }, + { "luaotfload-colors.lua", "693b527638ff44e88530bef81cff360c" }, + { "luaotfload-auxiliary.lua", "90307f9dc0fde714e7ade75ed8606de6" }, + { "luaotfload-filelist.lua", "629600766c33b11ebce09dd77dbd67c0" }, + { "luaotfload-tool.lua", "dfa990067c3f21fdebfcbd47b291fc9c" }, + { "luaotfload-diagnostics.lua", "7c13bd4abdd110073b6dd438c94d28ec" }, + { "luaotfload-log.lua", "c6e62cd69d185ea57605c21919ae103e" }, + { "luaotfload-init.lua", "0e156bb051ffa7c51dbdaca4afe0b5ae" }, + { "luaotfload-main.lua", "352cf2115d0b60e8537557baa9748f7a" }, }, ["notes"]={ ["committer"]="Ulrike Fischer <fischer@troubleshooting-tex.de>", - ["description"]="v3.11/2019-11-10", - ["loader"]="fontloader-2019-10-29.lua", - ["revision"]="d2ab135f432eadbc68f529447aa47b906ff961ab", - ["timestamp"]="2019-11-10 21:29:47 +0100", + ["description"]="v3.12/2020-02-02", + ["loader"]="fontloader-2020-01-26.lua", + ["revision"]="df675afec78546b857a89f1c416dc0f2600c8ff0", + ["timestamp"]="2020-02-02 22:36:36 +0100", }, }
\ No newline at end of file diff --git a/Master/texmf-dist/tex/luatex/luaotfload/luaotfload-tounicode.lua b/Master/texmf-dist/tex/luatex/luaotfload/luaotfload-tounicode.lua index 560f2c83aa0..509a0d782d7 100644 --- a/Master/texmf-dist/tex/luatex/luaotfload/luaotfload-tounicode.lua +++ b/Master/texmf-dist/tex/luatex/luaotfload/luaotfload-tounicode.lua @@ -5,8 +5,8 @@ local ProvidesLuaModule = { name = "luaotfload-tounicode", - version = "3.11", --TAGVERSION - date = "2019-11-10", --TAGDATE + version = "3.12", --TAGVERSION + date = "2020-02-02", --TAGDATE description = "luaotfload submodule / tounicode", license = "GPL v2.0", author = "Hans Hagen, Khaled Hosny, Elie Roux, Philipp Gesang, Marcel Krüger", diff --git a/Master/texmf-dist/tex/luatex/luaotfload/luaotfload-unicode.lua b/Master/texmf-dist/tex/luatex/luaotfload/luaotfload-unicode.lua index 659e92d9387..8c1f92cf318 100644 --- a/Master/texmf-dist/tex/luatex/luaotfload/luaotfload-unicode.lua +++ b/Master/texmf-dist/tex/luatex/luaotfload/luaotfload-unicode.lua @@ -5,8 +5,8 @@ local ProvidesLuaModule = { name = "luaotfload-unicode", - version = "3.11", --TAGVERSION - date = "2019-11-10", --TAGDATE + version = "3.12", --TAGVERSION + date = "2020-02-02", --TAGDATE description = "luaotfload submodule / Unicode helpers", license = "CC0 1.0 Universal", author = "Marcel Krüger" diff --git a/Master/texmf-dist/tex/luatex/luaotfload/luaotfload.sty b/Master/texmf-dist/tex/luatex/luaotfload/luaotfload.sty index 2c9582e4645..f779ecbf83a 100644 --- a/Master/texmf-dist/tex/luatex/luaotfload/luaotfload.sty +++ b/Master/texmf-dist/tex/luatex/luaotfload/luaotfload.sty @@ -40,7 +40,7 @@ \fi \ifdefined\ProvidesPackage \ProvidesPackage{luaotfload}% - [2019/11/10 v3.11 OpenType layout system] + [2020/02/02 v3.12 OpenType layout system] \fi \directlua{ if xpcall(function ()% |