diff options
author | Karl Berry <karl@freefriends.org> | 2019-11-05 21:35:11 +0000 |
---|---|---|
committer | Karl Berry <karl@freefriends.org> | 2019-11-05 21:35:11 +0000 |
commit | 34a198a074607c6eb90b0d82734630ca2bf439d9 (patch) | |
tree | ca4c5abc73c33da09c19716b13688a1b7ac53b9d /Master/texmf-dist/tex/luatex | |
parent | faac65e4c5efc26d958be7633783eecc9d0c0ddc (diff) |
luaotfload (5nov19)
git-svn-id: svn://tug.org/texlive/trunk@52645 c570f23f-e606-0410-a88d-b1316a301751
Diffstat (limited to 'Master/texmf-dist/tex/luatex')
40 files changed, 2667 insertions, 823 deletions
diff --git a/Master/texmf-dist/tex/luatex/luaotfload/fontloader-2019-08-11.lua b/Master/texmf-dist/tex/luatex/luaotfload/fontloader-2019-10-29.lua index b4d3f3ce126..dc98bd56969 100644 --- a/Master/texmf-dist/tex/luatex/luaotfload/fontloader-2019-08-11.lua +++ b/Master/texmf-dist/tex/luatex/luaotfload/fontloader-2019-10-29.lua @@ -1,6 +1,6 @@ --[[info----------------------------------------------------------------------- Luaotfload fontloader package - build 2019-08-13 18:34:34 + build 2019-10-29 22:02:47 ------------------------------------------------------------------------------- © 2019 PRAGMA ADE / ConTeXt Development Team @@ -62,7 +62,7 @@ --info]]----------------------------------------------------------------------- -do --- [luaotfload, fontloader-2019-08-13.lua scope for “data-con” 7ce546725b1550f655c78ac9d69419ca] --- +do --- [luaotfload, fontloader-2019-10-29.lua scope for “data-con” 7ce546725b1550f655c78ac9d69419ca] --- if not modules then modules={} end modules ['data-con']={ version=1.100, @@ -174,10 +174,10 @@ function containers.cleanname(name) return (gsub(lower(name),"[^%w\128-\255]+","-")) end -end --- [luaotfload, fontloader-2019-08-13.lua scope for “data-con”] --- +end --- [luaotfload, fontloader-2019-10-29.lua scope for “data-con”] --- -do --- [luaotfload, fontloader-2019-08-13.lua scope for “basics-nod” 65064d03c2650a1761ee13ebd9e1400a] --- +do --- [luaotfload, fontloader-2019-10-29.lua scope for “basics-nod” c05f47077c709bbf12a8758852dc4e06] --- if not modules then modules={} end modules ['luatex-fonts-nod']={ version=1.001, @@ -247,6 +247,7 @@ nuts.getchar=direct.getchar nuts.getcomponents=direct.getcomponents nuts.getdirection=direct.getdirection nuts.getdisc=direct.getdisc +nuts.getreplace=direct.getreplace nuts.getfield=direct.getfield nuts.getfont=direct.getfont nuts.getid=direct.getid @@ -263,6 +264,7 @@ nuts.setchar=direct.setchar nuts.setcomponents=direct.setcomponents nuts.setdirection=direct.setdirection nuts.setdisc=direct.setdisc +nuts.setreplace=direct.setreplace nuts.setfield=setfield nuts.setkern=direct.setkern nuts.setlink=direct.setlink @@ -380,11 +382,22 @@ do node=nuts.traverse(dummy), } end +if not nuts.setreplace then + local getdisc=nuts.getdisc + local setfield=nuts.setfield + function nuts.getreplace(n) + local _,_,h,_,_,t=getdisc(n,true) + return h,t + end + function nuts.setreplace(n,h) + setfield(n,"replace",h) + end +end -end --- [luaotfload, fontloader-2019-08-13.lua scope for “basics-nod”] --- +end --- [luaotfload, fontloader-2019-10-29.lua scope for “basics-nod”] --- -do --- [luaotfload, fontloader-2019-08-13.lua scope for “basics-chr” 58b7ef0c486e06090b362971b9f85e27] --- +do --- [luaotfload, fontloader-2019-10-29.lua scope for “basics-chr” 58b7ef0c486e06090b362971b9f85e27] --- characters=characters or {} @@ -3994,10 +4007,10 @@ characters.indicgroups={ }, } -end --- [luaotfload, fontloader-2019-08-13.lua scope for “basics-chr”] --- +end --- [luaotfload, fontloader-2019-10-29.lua scope for “basics-chr”] --- -do --- [luaotfload, fontloader-2019-08-13.lua scope for “font-ini” 4299a02110bbd7c0d27e131235c5319d] --- +do --- [luaotfload, fontloader-2019-10-29.lua scope for “font-ini” 4299a02110bbd7c0d27e131235c5319d] --- if not modules then modules={} end modules ['font-ini']={ version=1.001, @@ -4035,10 +4048,10 @@ fonts.privateoffsets={ keepnames=false, } -end --- [luaotfload, fontloader-2019-08-13.lua scope for “font-ini”] --- +end --- [luaotfload, fontloader-2019-10-29.lua scope for “font-ini”] --- -do --- [luaotfload, fontloader-2019-08-13.lua scope for “fonts-mis” bc9eb43c27f63ce9d0fff67e104fe1c6] --- +do --- [luaotfload, fontloader-2019-10-29.lua scope for “fonts-mis” bc9eb43c27f63ce9d0fff67e104fe1c6] --- if not modules then modules={} end modules ['luatex-font-mis']={ version=1.001, @@ -4070,10 +4083,10 @@ function font.each() return table.sortedhash(fonts.hashes.identifiers) end -end --- [luaotfload, fontloader-2019-08-13.lua scope for “fonts-mis”] --- +end --- [luaotfload, fontloader-2019-10-29.lua scope for “fonts-mis”] --- -do --- [luaotfload, fontloader-2019-08-13.lua scope for “font-con” ca733211a0555d9a93b1e2f7ebc937d3] --- +do --- [luaotfload, fontloader-2019-10-29.lua scope for “font-con” 8b35e7c2203d5b57c61942e07cee2c0a] --- if not modules then modules={} end modules ['font-con']={ version=1.001, @@ -4376,7 +4389,8 @@ function constructors.scale(tfmdata,specification) local units=parameters.units or 1000 targetproperties.language=properties.language or "dflt" targetproperties.script=properties.script or "dflt" - targetproperties.mode=properties.mode or "base" + targetproperties.mode=properties.mode or "base" + targetproperties.method=properties.method local askedscaledpoints=scaledpoints local scaledpoints,delta=constructors.calculatescale(tfmdata,scaledpoints,nil,specification) local hdelta=delta @@ -5416,10 +5430,10 @@ function constructors.addcoreunicodes(unicodes) return unicodes end -end --- [luaotfload, fontloader-2019-08-13.lua scope for “font-con”] --- +end --- [luaotfload, fontloader-2019-10-29.lua scope for “font-con”] --- -do --- [luaotfload, fontloader-2019-08-13.lua scope for “fonts-enc” 3e71a54297e8f85a1ac438bb0f20dd79] --- +do --- [luaotfload, fontloader-2019-10-29.lua scope for “fonts-enc” 3e71a54297e8f85a1ac438bb0f20dd79] --- if not modules then modules={} end modules ['luatex-font-enc']={ version=1.001, @@ -5488,10 +5502,10 @@ function encodings.load(filename) return containers.write(encodings.cache,name,data) end -end --- [luaotfload, fontloader-2019-08-13.lua scope for “fonts-enc”] --- +end --- [luaotfload, fontloader-2019-10-29.lua scope for “fonts-enc”] --- -do --- [luaotfload, fontloader-2019-08-13.lua scope for “font-cid” 4d87988efa86020a14708ee03c23415f] --- +do --- [luaotfload, fontloader-2019-10-29.lua scope for “font-cid” 4d87988efa86020a14708ee03c23415f] --- if not modules then modules={} end modules ['font-cid']={ version=1.001, @@ -5642,10 +5656,10 @@ function cid.getmap(specification) return found end -end --- [luaotfload, fontloader-2019-08-13.lua scope for “font-cid”] --- +end --- [luaotfload, fontloader-2019-10-29.lua scope for “font-cid”] --- -do --- [luaotfload, fontloader-2019-08-13.lua scope for “font-map” f486746e90fe972de4b73e208ac7cbb2] --- +do --- [luaotfload, fontloader-2019-10-29.lua scope for “font-map” f486746e90fe972de4b73e208ac7cbb2] --- if not modules then modules={} end modules ['font-map']={ version=1.001, @@ -6033,10 +6047,10 @@ function mappings.addtounicode(data,filename,checklookups,forceligatures) end end -end --- [luaotfload, fontloader-2019-08-13.lua scope for “font-map”] --- +end --- [luaotfload, fontloader-2019-10-29.lua scope for “font-map”] --- -do --- [luaotfload, fontloader-2019-08-13.lua scope for “font-vfc” 94937140f2c909e9c831ba021f1ab303] --- +do --- [luaotfload, fontloader-2019-10-29.lua scope for “font-vfc” 94937140f2c909e9c831ba021f1ab303] --- if not modules then modules={} end modules ['font-vfc']={ version=1.001, @@ -6134,10 +6148,10 @@ helpers.commands=utilities.storage.allocate { dummy=dummy, } -end --- [luaotfload, fontloader-2019-08-13.lua scope for “font-vfc”] --- +end --- [luaotfload, fontloader-2019-10-29.lua scope for “font-vfc”] --- -do --- [luaotfload, fontloader-2019-08-13.lua scope for “font-otr” b1c03925c949027c86f781785fa7a208] --- +do --- [luaotfload, fontloader-2019-10-29.lua scope for “font-otr” b1c03925c949027c86f781785fa7a208] --- if not modules then modules={} end modules ['font-otr']={ version=1.001, @@ -7987,10 +8001,10 @@ function readers.extend(fontdata) end end -end --- [luaotfload, fontloader-2019-08-13.lua scope for “font-otr”] --- +end --- [luaotfload, fontloader-2019-10-29.lua scope for “font-otr”] --- -do --- [luaotfload, fontloader-2019-08-13.lua scope for “font-oti” dbae7722baae24d917a17176553825cf] --- +do --- [luaotfload, fontloader-2019-10-29.lua scope for “font-oti” dbae7722baae24d917a17176553825cf] --- if not modules then modules={} end modules ['font-oti']={ version=1.001, @@ -8133,10 +8147,10 @@ function otffeatures.checkeddefaultlanguage(featuretype,autolanguage,languages) end end -end --- [luaotfload, fontloader-2019-08-13.lua scope for “font-oti”] --- +end --- [luaotfload, fontloader-2019-10-29.lua scope for “font-oti”] --- -do --- [luaotfload, fontloader-2019-08-13.lua scope for “font-ott” aba6d8335a5f38a5a62d3631492f3392] --- +do --- [luaotfload, fontloader-2019-10-29.lua scope for “font-ott” aba6d8335a5f38a5a62d3631492f3392] --- if not modules then modules={} end modules ["font-ott"]={ version=1.001, @@ -9255,10 +9269,10 @@ function otffeatures.normalize(features,wrap) end end -end --- [luaotfload, fontloader-2019-08-13.lua scope for “font-ott”] --- +end --- [luaotfload, fontloader-2019-10-29.lua scope for “font-ott”] --- -do --- [luaotfload, fontloader-2019-08-13.lua scope for “font-cff” 98d5a660ea803b65cb883c009ecf3c0b] --- +do --- [luaotfload, fontloader-2019-10-29.lua scope for “font-cff” 98d5a660ea803b65cb883c009ecf3c0b] --- if not modules then modules={} end modules ['font-cff']={ version=1.001, @@ -11282,10 +11296,10 @@ function readers.cffcheck(filename) end end -end --- [luaotfload, fontloader-2019-08-13.lua scope for “font-cff”] --- +end --- [luaotfload, fontloader-2019-10-29.lua scope for “font-cff”] --- -do --- [luaotfload, fontloader-2019-08-13.lua scope for “font-ttf” 44e61cef50dab9b1aaf48130f9367c34] --- +do --- [luaotfload, fontloader-2019-10-29.lua scope for “font-ttf” 44e61cef50dab9b1aaf48130f9367c34] --- if not modules then modules={} end modules ['font-ttf']={ version=1.001, @@ -12455,10 +12469,10 @@ function readers.gvar(f,fontdata,specification,glyphdata,shapedata) end end -end --- [luaotfload, fontloader-2019-08-13.lua scope for “font-ttf”] --- +end --- [luaotfload, fontloader-2019-10-29.lua scope for “font-ttf”] --- -do --- [luaotfload, fontloader-2019-08-13.lua scope for “font-dsp” b5bf2f1c198e027a0d4ededcdf3947b4] --- +do --- [luaotfload, fontloader-2019-10-29.lua scope for “font-dsp” 5d3db0184c903829b2c5bddcb8cdb14c] --- if not modules then modules={} end modules ['font-dsp']={ version=1.001, @@ -15092,6 +15106,8 @@ function readers.cpal(f,fontdata,specification) fontdata.colorpalettes=palettes end end +local compress=gzip and gzip.compress +local compressed=compress and gzip.compressed function readers.svg(f,fontdata,specification) local tableoffset=gotodatatable(f,fontdata,"svg",specification.glyphs) if tableoffset then @@ -15113,10 +15129,14 @@ function readers.svg(f,fontdata,specification) for i=1,nofentries do local entry=entries[i] setposition(f,entry.offset) + local data=readstring(f,entry.length) + if compressed and not compressed(data) then + data=compress(data) + end entries[i]={ first=entry.first, last=entry.last, - data=readstring(f,entry.length) + data=data } end fontdata.svgshapes=entries @@ -15699,10 +15719,10 @@ function readers.mvar(f,fontdata,specification) end end -end --- [luaotfload, fontloader-2019-08-13.lua scope for “font-dsp”] --- +end --- [luaotfload, fontloader-2019-10-29.lua scope for “font-dsp”] --- -do --- [luaotfload, fontloader-2019-08-13.lua scope for “font-oup” 669e479e716999edc626a1f045bd76fa] --- +do --- [luaotfload, fontloader-2019-10-29.lua scope for “font-oup” 0cef35af01739f52fd09feb5401192ae] --- if not modules then modules={} end modules ['font-oup']={ version=1.001, @@ -16379,6 +16399,9 @@ local function checklookups(fontdata,missing,nofmissing) end end end +local firstprivate=fonts.privateoffsets and fonts.privateoffsets.textbase or 0xF0000 +local puafirst=0xE000 +local pualast=0xF8FF local function unifymissing(fontdata) if not fonts.mappings then require("font-map") @@ -16389,18 +16412,19 @@ local function unifymissing(fontdata) resources.unicodes=unicodes for unicode,d in next,fontdata.descriptions do if unicode<privateoffset then - local name=d.name - if name then - unicodes[name]=unicode + if unicode>=puafirst and unicode<=pualast then + else + local name=d.name + if name then + unicodes[name]=unicode + end end + else end end fonts.mappings.addtounicode(fontdata,fontdata.filename,checklookups) resources.unicodes=nil end -local firstprivate=fonts.privateoffsets and fonts.privateoffsets.textbase or 0xF0000 -local puafirst=0xE000 -local pualast=0xF8FF local function unifyglyphs(fontdata,usenames) local private=fontdata.private or privateoffset local glyphs=fontdata.glyphs @@ -18339,10 +18363,10 @@ function readers.expand(data) expandlookups(sublookups) end -end --- [luaotfload, fontloader-2019-08-13.lua scope for “font-oup”] --- +end --- [luaotfload, fontloader-2019-10-29.lua scope for “font-oup”] --- -do --- [luaotfload, fontloader-2019-08-13.lua scope for “font-otl” 940f9c5ad84f4968a8488f4da2d15e2d] --- +do --- [luaotfload, fontloader-2019-10-29.lua scope for “font-otl” ec0241b7465a7713e53c246e8e9fb2a8] --- if not modules then modules={} end modules ['font-otl']={ version=1.001, @@ -18370,11 +18394,12 @@ local trace_defining=false registertracker("fonts.defining",function(v) trace_d local report_otf=logs.reporter("fonts","otf loading") local fonts=fonts local otf=fonts.handlers.otf -otf.version=3.109 +otf.version=3.110 otf.cache=containers.define("fonts","otl",otf.version,true) otf.svgcache=containers.define("fonts","svg",otf.version,true) otf.pngcache=containers.define("fonts","png",otf.version,true) otf.pdfcache=containers.define("fonts","pdf",otf.version,true) +otf.mpscache=containers.define("fonts","mps",otf.version,true) otf.svgenabled=false otf.pngenabled=false local otfreaders=otf.readers @@ -19045,10 +19070,10 @@ otf.coverup={ end } -end --- [luaotfload, fontloader-2019-08-13.lua scope for “font-otl”] --- +end --- [luaotfload, fontloader-2019-10-29.lua scope for “font-otl”] --- -do --- [luaotfload, fontloader-2019-08-13.lua scope for “font-oto” 52804afd96f4be005f513a012b874668] --- +do --- [luaotfload, fontloader-2019-10-29.lua scope for “font-oto” 52804afd96f4be005f513a012b874668] --- if not modules then modules={} end modules ['font-oto']={ version=1.001, @@ -19506,10 +19531,10 @@ registerotffeature { } otf.basemodeinitializer=featuresinitializer -end --- [luaotfload, fontloader-2019-08-13.lua scope for “font-oto”] --- +end --- [luaotfload, fontloader-2019-10-29.lua scope for “font-oto”] --- -do --- [luaotfload, fontloader-2019-08-13.lua scope for “font-otj” 66c7a910d95d4a52b81061de776898e1] --- +do --- [luaotfload, fontloader-2019-10-29.lua scope for “font-otj” 66c7a910d95d4a52b81061de776898e1] --- if not modules then modules={} end modules ['font-otj']={ version=1.001, @@ -20966,10 +20991,10 @@ function injections.handler(head,where) end end -end --- [luaotfload, fontloader-2019-08-13.lua scope for “font-otj”] --- +end --- [luaotfload, fontloader-2019-10-29.lua scope for “font-otj”] --- -do --- [luaotfload, fontloader-2019-08-13.lua scope for “font-ota” d6dfb94563d6a52675e274b2e673e4a6] --- +do --- [luaotfload, fontloader-2019-10-29.lua scope for “font-ota” d6dfb94563d6a52675e274b2e673e4a6] --- if not modules then modules={} end modules ['font-ota']={ version=1.001, @@ -21346,10 +21371,10 @@ directives.register("otf.analyze.useunicodemarks",function(v) analyzers.useunicodemarks=v end) -end --- [luaotfload, fontloader-2019-08-13.lua scope for “font-ota”] --- +end --- [luaotfload, fontloader-2019-10-29.lua scope for “font-ota”] --- -do --- [luaotfload, fontloader-2019-08-13.lua scope for “font-ots” d5504847a278385cd0d20ecf1b3d59cc] --- +do --- [luaotfload, fontloader-2019-10-29.lua scope for “font-ots” d6a0ce4b40cd4ee1895e2248dcf87d37] --- if not modules then modules={} end modules ['font-ots']={ version=1.001, @@ -21408,7 +21433,6 @@ registertracker("otf.actions","otf.substitutions","otf.positions") registertracker("otf.sample","otf.steps","otf.substitutions","otf.positions","otf.analyzing") registertracker("otf.sample.silent","otf.steps=silent","otf.substitutions","otf.positions","otf.analyzing") local nuts=nodes.nuts -local getfield=nuts.getfield local getnext=nuts.getnext local setnext=nuts.setnext local getprev=nuts.getprev @@ -21424,6 +21448,7 @@ local getchar=nuts.getchar local setchar=nuts.setchar local getdisc=nuts.getdisc local setdisc=nuts.setdisc +local getreplace=nuts.getreplace local setlink=nuts.setlink local getcomponents=nuts.getcomponents local setcomponents=nuts.setcomponents @@ -23002,7 +23027,7 @@ local function chaindisk(head,start,dataset,sequence,rlmode,skiphash,ck) if keepdisc then keepdisc=false lookaheaddisc=current - local replace=getfield(current,"replace") + local replace=getreplace(current) if not replace then sweepoverflow=true sweepnode=current @@ -23074,7 +23099,7 @@ local function chaindisk(head,start,dataset,sequence,rlmode,skiphash,ck) if notmatchpre[current]~=notmatchreplace[current] then lookaheaddisc=current end - local replace=getfield(current,"replace") + local replace=getreplace(current) while replace and i<s do if getid(replace)==glyph_code then i=i+1 @@ -23118,7 +23143,7 @@ local function chaindisk(head,start,dataset,sequence,rlmode,skiphash,ck) if notmatchpost[current]~=notmatchreplace[current] then backtrackdisc=current end - local replace=getfield(current,"replace") + local replace=getreplace(current) while replace and i>1 do if getid(replace)==glyph_code then i=i-1 @@ -24082,7 +24107,7 @@ local function t_run_single(start,stop,font,attr,lookupcache) end while getid(s)==disc_code do ss=getnext(s) - s=getfield(s,"replace") + s=getreplace(s) if not s then s=ss ss=nil @@ -24109,7 +24134,7 @@ local function t_run_single(start,stop,font,attr,lookupcache) end while getid(s)==disc_code do ss=getnext(s) - s=getfield(s,"replace") + s=getreplace(s) if not s then s=ss ss=nil @@ -24236,7 +24261,7 @@ local function t_run_multiple(start,stop,font,attr,steps,nofsteps) end while getid(s)==disc_code do ss=getnext(s) - s=getfield(s,"replace") + s=getreplace(s) if not s then s=ss ss=nil @@ -24263,7 +24288,7 @@ local function t_run_multiple(start,stop,font,attr,steps,nofsteps) end while getid(s)==disc_code do ss=getnext(s) - s=getfield(s,"replace") + s=getreplace(s) if not s then s=ss ss=nil @@ -24963,10 +24988,10 @@ registerotffeature { }, } -end --- [luaotfload, fontloader-2019-08-13.lua scope for “font-ots”] --- +end --- [luaotfload, fontloader-2019-10-29.lua scope for “font-ots”] --- -do --- [luaotfload, fontloader-2019-08-13.lua scope for “font-osd” 79eb2fc4a71364fd73c8b996a109f5df] --- +do --- [luaotfload, fontloader-2019-10-29.lua scope for “font-osd” 39e92f6e575741646d75ea79e3be87f3] --- if not modules then modules={} end modules ['font-osd']={ version=1.001, @@ -26046,7 +26071,7 @@ local function reorder_one(head,start,stop,font,attr,nbspaces) local cp=getprev(current) local cnsn=getnext(cns) setlink(cp,n) - setlink(cns,current) + setlink(cns,current) setlink(c,cnsn) if c==stop then stop=cp @@ -27398,10 +27423,10 @@ for i=1,nofscripts do methods[scripts_two[i]]=method_two end -end --- [luaotfload, fontloader-2019-08-13.lua scope for “font-osd”] --- +end --- [luaotfload, fontloader-2019-10-29.lua scope for “font-osd”] --- -do --- [luaotfload, fontloader-2019-08-13.lua scope for “font-ocl” b720867fb19a23f0b50377efd2a3c54a] --- +do --- [luaotfload, fontloader-2019-10-29.lua scope for “font-ocl” ba40df1a92b9b42a5c70d20c28f44759] --- if not modules then modules={} end modules ['font-ocl']={ version=1.001, @@ -27410,9 +27435,13 @@ if not modules then modules={} end modules ['font-ocl']={ copyright="PRAGMA ADE / ConTeXt Development Team", license="see context related readme files" } +if CONTEXTLMTXMODE and CONTEXTLMTXMODE>0 then + return +end local tostring,tonumber,next=tostring,tonumber,next local round,max=math.round,math.round -local sortedkeys,sortedhash=table.sortedkeys,table.sortedhash +local gsub,find=string.gsub,string.find +local sortedkeys,sortedhash,concat=table.sortedkeys,table.sortedhash,table.concat local setmetatableindex=table.setmetatableindex local formatters=string.formatters local tounicode=fonts.mappings.tounicode @@ -27422,6 +27451,7 @@ local rightcommand=helpers.commands.right local leftcommand=helpers.commands.left local downcommand=helpers.commands.down local otf=fonts.handlers.otf +local otfregister=otf.features.register local f_color=formatters["%.3f %.3f %.3f rg"] local f_gray=formatters["%.3f g"] if context then @@ -27515,7 +27545,7 @@ end local start={ "pdf","mode","font" } local push={ "pdf","page","q" } local pop={ "pdf","page","Q" } -local function initialize(tfmdata,kind,value) +local function initializeoverlay(tfmdata,kind,value) if value then local resources=tfmdata.resources local palettes=resources.colorpalettes @@ -27557,52 +27587,39 @@ local function initialize(tfmdata,kind,value) local s=#colorlist local goback=w~=0 and leftcommand[w] or nil local t={ - start, - not u and actualb or { "pdf","page",(getactualtext(tounicode(u))) } + not u and actualb or { "pdf","page",(getactualtext(tounicode(u))) }, + push, } local n=2 local l=nil - local f=false for i=1,s do local entry=colorlist[i] local v=colorvalues[entry.class] or default if v and l~=v then - if f then - n=n+1 t[n]=pop - end - n=n+1 t[n]=push - f=true n=n+1 t[n]=v l=v - else - if f then - n=n+1 t[n]=pop - end - f=false - l=nil end n=n+1 t[n]=charcommand[entry.slot] if s>1 and i<s and goback then n=n+1 t[n]=goback end end - if f then - n=n+1 t[n]=pop - end + n=n+1 t[n]=pop n=n+1 t[n]=actuale character.commands=t end end end + return true end end end -fonts.handlers.otf.features.register { +otfregister { name="colr", description="color glyphs", manipulators={ - base=initialize, - node=initialize, + base=initializeoverlay, + node=initializeoverlay, } } do @@ -27653,14 +27670,20 @@ local function pdftovirtual(tfmdata,pdfshapes,kind) local data=nil local dx=nil local dy=nil + local scale=1 if typ=="table" then data=pdf.data - dx=pdf.dx or 0 - dy=pdf.dy or 0 + dx=pdf.x or pdf.dx or 0 + dy=pdf.y or pdf.dy or 0 + scale=pdf.scale or 1 elseif typ=="string" then data=pdf dx=0 dy=0 + elseif typ=="number" then + data=pdf + dx=0 + dy=0 end if data then local bt=unicode and getactualtext(unicode) @@ -27669,9 +27692,9 @@ local function pdftovirtual(tfmdata,pdfshapes,kind) local dp=character.depth or 0 character.commands={ not unicode and actualb or { "pdf","page",(getactualtext(unicode)) }, - downcommand[dp+dy*hfactor], - rightcommand[dx*hfactor], - vfimage(wd,ht,dp,data,name), + downcommand [dp+dy*hfactor], + rightcommand[ dx*hfactor], + vfimage(scale*wd,ht,dp,data,pdfshapes.filename or ""), actuale, } character[kind]=true @@ -27705,24 +27728,27 @@ do name="otfsvg", program="inkscape", method="pipeto", - template="--shell > temp-otf-svg-shape.log", + template="--export-area-drawing --shell > temp-otf-svg-shape.log", reporter=report_svg, } if not runner then runner=function() - return io.open("inkscape --shell > temp-otf-svg-shape.log","w") + return io.popen("inkscape --export-area-drawing --shell > temp-otf-svg-shape.log","w") end end - function otfsvg.topdf(svgshapes) + function otfsvg.topdf(svgshapes,tfmdata) 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"] local f_pdffile=formatters["temp-otf-svg-shape-%i.pdf"] local f_convert=formatters["%s --export-pdf=%s\n"] local filterglyph=otfsvg.filterglyph local nofdone=0 + local processed={} report_svg("processing %i svg containers",nofshapes) statistics.starttiming() for i=1,nofshapes do @@ -27734,24 +27760,51 @@ do local pdffile=f_pdffile(index) savedata(svgfile,data) inkscape:write(f_convert(svgfile,pdffile)) - pdfshapes[index]=true + processed[index]=true nofdone=nofdone+1 - if nofdone%100==0 then - report_svg("%i shapes processed",nofdone) + if nofdone%25==0 then + report_svg("%i shapes submitted",nofdone) end end end end + if nofdone%25~=0 then + report_svg("%i shapes submitted",nofdone) + end + report_svg("processing can be going on for a while") inkscape:write("quit\n") inkscape:close() report_svg("processing %i pdf results",nofshapes) - for index in next,pdfshapes do + for index in next,processed do local svgfile=f_svgfile(index) local pdffile=f_pdffile(index) - pdfshapes[index]=loaddata(pdffile) + local pdfdata=loaddata(pdffile) + if pdfdata and pdfdata~="" then + pdfshapes[index]={ + data=pdfdata, + } + end remove(svgfile) remove(pdffile) end + local characters=tfmdata.characters + for k,v in next,characters do + local d=descriptions[k] + local i=d.index + if i then + local p=pdfshapes[i] + if p then + local w=d.width + local l=d.boundingbox[1] + local r=d.boundingbox[3] + p.scale=(r-l)/w + p.x=l + end + end + end + if not next(pdfshapes) then + report_svg("there are no converted shapes, fix your setup") + end statistics.stoptiming() if statistics.elapsedseconds then report_svg("svg conversion time %s",statistics.elapsedseconds() or "-") @@ -27770,19 +27823,20 @@ local function initializesvg(tfmdata,kind,value) end local pdffile=containers.read(otf.pdfcache,hash) local pdfshapes=pdffile and pdffile.pdfshapes - if not pdfshapes or pdffile.timestamp~=timestamp then + if not pdfshapes or pdffile.timestamp~=timestamp or not next(pdfshapes) then local svgfile=containers.read(otf.svgcache,hash) local svgshapes=svgfile and svgfile.svgshapes - pdfshapes=svgshapes and otfsvg.topdf(svgshapes) or {} + pdfshapes=svgshapes and otfsvg.topdf(svgshapes,tfmdata,otf.pdfcache.writable,hash) or {} containers.write(otf.pdfcache,hash,{ pdfshapes=pdfshapes, timestamp=timestamp, }) end pdftovirtual(tfmdata,pdfshapes,"svg") + return true end end -fonts.handlers.otf.features.register { +otfregister { name="svg", description="svg glyphs", manipulators={ @@ -27865,9 +27919,10 @@ local function initializepng(tfmdata,kind,value) }) end pdftovirtual(tfmdata,pdfshapes,"png") + return true end end -fonts.handlers.otf.features.register { +otfregister { name="sbix", description="sbix glyphs", manipulators={ @@ -27875,7 +27930,7 @@ fonts.handlers.otf.features.register { node=initializepng, } } -fonts.handlers.otf.features.register { +otfregister { name="cblc", description="cblc glyphs", manipulators={ @@ -27883,11 +27938,36 @@ fonts.handlers.otf.features.register { node=initializepng, } } +if context then + local function initializecolor(tfmdata,kind,value) + if value=="auto" then + return + initializeoverlay(tfmdata,kind,value) or + initializesvg(tfmdata,kind,value) or + initializepng(tfmdata,kind,value) + elseif value=="overlay" then + return initializeoverlay(tfmdata,kind,value) + elseif value=="svg" then + return initializesvg(tfmdata,kind,value) + elseif value=="png" or value=="bitmap" then + return initializepng(tfmdata,kind,value) + else + end + end + otfregister { + name="color", + description="color glyphs", + manipulators={ + base=initializecolor, + node=initializecolor, + } + } +end -end --- [luaotfload, fontloader-2019-08-13.lua scope for “font-ocl”] --- +end --- [luaotfload, fontloader-2019-10-29.lua scope for “font-ocl”] --- -do --- [luaotfload, fontloader-2019-08-13.lua scope for “font-otc” 95a4ff28ba4afb55a978a4aecfd688bf] --- +do --- [luaotfload, fontloader-2019-10-29.lua scope for “font-otc” 1204a2fdc436e644127c0aa38ab69607] --- if not modules then modules={} end modules ['font-otc']={ version=1.001, @@ -27907,9 +27987,10 @@ local fonts=fonts local otf=fonts.handlers.otf local registerotffeature=otf.features.register local setmetatableindex=table.setmetatableindex -local checkmerge=fonts.helpers.checkmerge -local checkflags=fonts.helpers.checkflags -local checksteps=fonts.helpers.checksteps +local fonthelpers=fonts.helpers +local checkmerge=fonthelpers.checkmerge +local checkflags=fonthelpers.checkflags +local checksteps=fonthelpers.checksteps local normalized={ substitution="substitution", single="substitution", @@ -28031,6 +28112,7 @@ local function addfeature(data,feature,specifications) local done=0 local skip=0 local aglunicodes=false + local privateslot=fonthelpers.privateslot local specifications=validspecification(specifications,feature) if not specifications then return @@ -28053,6 +28135,12 @@ local function addfeature(data,feature,specifications) return u end end + if privateslot then + u=privateslot(code) + if u then + return u + end + end local u=lpegmatch(p,code) if u then return u @@ -28082,7 +28170,7 @@ local function addfeature(data,feature,specifications) replacement=replacement[1] end replacement=tounicode(replacement) - if replacement and descriptions[replacement] then + if replacement and (nocheck or descriptions[replacement]) then cover(coverage,unicode,replacement) done=done+1 else @@ -28452,7 +28540,6 @@ local function addfeature(data,feature,specifications) local featuretype=normalized[specification.type or "substitution"] or "substitution" local featureflags=specification.flags or noflags local nocheck=specification.nocheck - local futuresteps=specification.futuresteps local featureorder=specification.order or { feature } local featurechain=(featuretype=="chainsubstitution" or featuretype=="chainposition") and 1 or 0 local nofsteps=0 @@ -28637,10 +28724,10 @@ end otf.enhancers.enhance=enhance otf.enhancers.register("check extra features",enhance) -end --- [luaotfload, fontloader-2019-08-13.lua scope for “font-otc”] --- +end --- [luaotfload, fontloader-2019-10-29.lua scope for “font-otc”] --- -do --- [luaotfload, fontloader-2019-08-13.lua scope for “font-onr” d4d2449b4084e6afb1837ae5835082cc] --- +do --- [luaotfload, fontloader-2019-10-29.lua scope for “font-onr” d4d2449b4084e6afb1837ae5835082cc] --- if not modules then modules={} end modules ['font-onr']={ version=1.001, @@ -29012,10 +29099,10 @@ function readers.getinfo(filename) end end -end --- [luaotfload, fontloader-2019-08-13.lua scope for “font-onr”] --- +end --- [luaotfload, fontloader-2019-10-29.lua scope for “font-onr”] --- -do --- [luaotfload, fontloader-2019-08-13.lua scope for “font-one” 987c5c5ed3754ad2feab80985067d59e] --- +do --- [luaotfload, fontloader-2019-10-29.lua scope for “font-one” 987c5c5ed3754ad2feab80985067d59e] --- if not modules then modules={} end modules ['font-one']={ version=1.001, @@ -29726,10 +29813,10 @@ registerafmenhancer("normalize features",enhance_normalize_features) registerafmenhancer("check extra features",otfenhancers.enhance) registerafmenhancer("fix names",enhance_fix_names) -end --- [luaotfload, fontloader-2019-08-13.lua scope for “font-one”] --- +end --- [luaotfload, fontloader-2019-10-29.lua scope for “font-one”] --- -do --- [luaotfload, fontloader-2019-08-13.lua scope for “font-afk” 54d554530e75c57c56ee76234724e26d] --- +do --- [luaotfload, fontloader-2019-10-29.lua scope for “font-afk” 54d554530e75c57c56ee76234724e26d] --- if not modules then modules={} end modules ['font-afk']={ version=1.001, @@ -29896,10 +29983,10 @@ fonts.handlers.afm.helpdata={ } } -end --- [luaotfload, fontloader-2019-08-13.lua scope for “font-afk”] --- +end --- [luaotfload, fontloader-2019-10-29.lua scope for “font-afk”] --- -do --- [luaotfload, fontloader-2019-08-13.lua scope for “fonts-tfm” 3bbba3214fd0b8c6f35ad85592fc2917] --- +do --- [luaotfload, fontloader-2019-10-29.lua scope for “fonts-tfm” 3bbba3214fd0b8c6f35ad85592fc2917] --- if not modules then modules={} end modules ['luatex-fonts-tfm']={ version=1.001, @@ -30414,10 +30501,10 @@ registertfmfeature { } } -end --- [luaotfload, fontloader-2019-08-13.lua scope for “fonts-tfm”] --- +end --- [luaotfload, fontloader-2019-10-29.lua scope for “fonts-tfm”] --- -do --- [luaotfload, fontloader-2019-08-13.lua scope for “font-lua” 55b281fb98f7bd848fc19928f376f647] --- +do --- [luaotfload, fontloader-2019-10-29.lua scope for “font-lua” 55b281fb98f7bd848fc19928f376f647] --- if not modules then modules={} end modules ['font-lua']={ version=1.001, @@ -30457,10 +30544,10 @@ function readers.lua(specification) return check_lua(specification,fullname) end -end --- [luaotfload, fontloader-2019-08-13.lua scope for “font-lua”] --- +end --- [luaotfload, fontloader-2019-10-29.lua scope for “font-lua”] --- -do --- [luaotfload, fontloader-2019-08-13.lua scope for “font-def” f66c365dae4499f982d8bf16e5d37de3] --- +do --- [luaotfload, fontloader-2019-10-29.lua scope for “font-def” f66c365dae4499f982d8bf16e5d37de3] --- if not modules then modules={} end modules ['font-def']={ version=1.001, @@ -30862,10 +30949,10 @@ function font.getfont(id) end callbacks.register('define_font',definers.read,"definition of fonts (tfmdata preparation)") -end --- [luaotfload, fontloader-2019-08-13.lua scope for “font-def”] --- +end --- [luaotfload, fontloader-2019-10-29.lua scope for “font-def”] --- -do --- [luaotfload, fontloader-2019-08-13.lua scope for “fonts-def” 5ad79120ebc5e60f4d322fb3ee13bffe] --- +do --- [luaotfload, fontloader-2019-10-29.lua scope for “fonts-def” 5ad79120ebc5e60f4d322fb3ee13bffe] --- if not modules then modules={} end modules ['luatex-fonts-def']={ version=1.001, @@ -30946,10 +31033,10 @@ function fonts.definers.applypostprocessors(tfmdata) return tfmdata end -end --- [luaotfload, fontloader-2019-08-13.lua scope for “fonts-def”] --- +end --- [luaotfload, fontloader-2019-10-29.lua scope for “fonts-def”] --- -do --- [luaotfload, fontloader-2019-08-13.lua scope for “fonts-ext” 01015ab3758cdc2af29394e6d502a91a] --- +do --- [luaotfload, fontloader-2019-10-29.lua scope for “fonts-ext” 01015ab3758cdc2af29394e6d502a91a] --- if not modules then modules={} end modules ['luatex-fonts-ext']={ version=1.001, @@ -31135,10 +31222,10 @@ registerotffeature { } } -end --- [luaotfload, fontloader-2019-08-13.lua scope for “fonts-ext”] --- +end --- [luaotfload, fontloader-2019-10-29.lua scope for “fonts-ext”] --- -do --- [luaotfload, fontloader-2019-08-13.lua scope for “font-imp-tex” 77c374b0ef00c2fb12188ec42beb4257] --- +do --- [luaotfload, fontloader-2019-10-29.lua scope for “font-imp-tex” 77c374b0ef00c2fb12188ec42beb4257] --- if not modules then modules={} end modules ['font-imp-tex']={ version=1.001, @@ -31237,10 +31324,10 @@ registerotffeature { description="arabic digits", } -end --- [luaotfload, fontloader-2019-08-13.lua scope for “font-imp-tex”] --- +end --- [luaotfload, fontloader-2019-10-29.lua scope for “font-imp-tex”] --- -do --- [luaotfload, fontloader-2019-08-13.lua scope for “font-imp-ligatures” 043daa4fcccf2560868da359d71d3a4a] --- +do --- [luaotfload, fontloader-2019-10-29.lua scope for “font-imp-ligatures” 043daa4fcccf2560868da359d71d3a4a] --- if not modules then modules={} end modules ['font-imp-ligatures']={ version=1.001, @@ -31354,10 +31441,10 @@ if context then } end -end --- [luaotfload, fontloader-2019-08-13.lua scope for “font-imp-ligatures”] --- +end --- [luaotfload, fontloader-2019-10-29.lua scope for “font-imp-ligatures”] --- -do --- [luaotfload, fontloader-2019-08-13.lua scope for “font-imp-italics” fe1ca80fb5ea4a2f8d2d5c484e7ba913] --- +do --- [luaotfload, fontloader-2019-10-29.lua scope for “font-imp-italics” fe1ca80fb5ea4a2f8d2d5c484e7ba913] --- if not modules then modules={} end modules ['font-imp-italics']={ version=1.001, @@ -31463,10 +31550,10 @@ if context then registerafmfeature(dimensions_specification) end -end --- [luaotfload, fontloader-2019-08-13.lua scope for “font-imp-italics”] --- +end --- [luaotfload, fontloader-2019-10-29.lua scope for “font-imp-italics”] --- -do --- [luaotfload, fontloader-2019-08-13.lua scope for “font-imp-effects” 73a660359a0ec71e44cc2b7225a715ac] --- +do --- [luaotfload, fontloader-2019-10-29.lua scope for “font-imp-effects” 73a660359a0ec71e44cc2b7225a715ac] --- if not modules then modules={} end modules ['font-imp-effects']={ version=1.001, @@ -31823,10 +31910,10 @@ local specification={ registerotffeature(specification) registerafmfeature(specification) -end --- [luaotfload, fontloader-2019-08-13.lua scope for “font-imp-effects”] --- +end --- [luaotfload, fontloader-2019-10-29.lua scope for “font-imp-effects”] --- -do --- [luaotfload, fontloader-2019-08-13.lua scope for “fonts-lig” b9dbe77ce747d4c35bb2a20ffbe5aa51] --- +do --- [luaotfload, fontloader-2019-10-29.lua scope for “fonts-lig” b9dbe77ce747d4c35bb2a20ffbe5aa51] --- fonts.handlers.otf.addfeature { @@ -33895,10 +33982,10 @@ fonts.handlers.otf.addfeature { ["type"]="ligature", } -end --- [luaotfload, fontloader-2019-08-13.lua scope for “fonts-lig”] --- +end --- [luaotfload, fontloader-2019-10-29.lua scope for “fonts-lig”] --- -do --- [luaotfload, fontloader-2019-08-13.lua scope for “fonts-gbn” d25472d54c4841db43a745764a63533e] --- +do --- [luaotfload, fontloader-2019-10-29.lua scope for “fonts-gbn” d25472d54c4841db43a745764a63533e] --- if not modules then modules={} end modules ['luatex-fonts-gbn']={ version=1.001, @@ -34163,7 +34250,7 @@ function nodes.simple_font_handler(head,groupcode,size,packtype,direction) return head end -end --- [luaotfload, fontloader-2019-08-13.lua scope for “fonts-gbn”] --- +end --- [luaotfload, fontloader-2019-10-29.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-nod.lua b/Master/texmf-dist/tex/luatex/luaotfload/fontloader-basics-nod.lua index 418b9d69d42..172fcc7f7ed 100644 --- a/Master/texmf-dist/tex/luatex/luaotfload/fontloader-basics-nod.lua +++ b/Master/texmf-dist/tex/luatex/luaotfload/fontloader-basics-nod.lua @@ -99,6 +99,7 @@ nuts.getchar = direct.getchar nuts.getcomponents = direct.getcomponents nuts.getdirection = direct.getdirection nuts.getdisc = direct.getdisc +nuts.getreplace = direct.getreplace nuts.getfield = direct.getfield nuts.getfont = direct.getfont nuts.getid = direct.getid @@ -115,6 +116,7 @@ nuts.setchar = direct.setchar nuts.setcomponents = direct.setcomponents nuts.setdirection = direct.setdirection nuts.setdisc = direct.setdisc +nuts.setreplace = direct.setreplace nuts.setfield = setfield nuts.setkern = direct.setkern nuts.setlink = direct.setlink @@ -261,3 +263,19 @@ do } end + +if not nuts.setreplace then + + local getdisc = nuts.getdisc + local setfield = nuts.setfield + + function nuts.getreplace(n) + local _, _, h, _, _, t = getdisc(n,true) + return h, t + end + + function nuts.setreplace(n,h) + setfield(n,"replace",h) + end + +end 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 9c1e825fa2e..652794142b5 100644 --- a/Master/texmf-dist/tex/luatex/luaotfload/fontloader-font-con.lua +++ b/Master/texmf-dist/tex/luatex/luaotfload/fontloader-font-con.lua @@ -444,9 +444,10 @@ function constructors.scale(tfmdata,specification) -- boundarychar = 65536, -- there is now a string 'right_boundary' -- false_boundarychar = 65536, -- produces invalid tfm in luatex -- - targetproperties.language = properties.language or "dflt" -- inherited - targetproperties.script = properties.script or "dflt" -- inherited - targetproperties.mode = properties.mode or "base" -- inherited + targetproperties.language = properties.language or "dflt" -- inherited + targetproperties.script = properties.script or "dflt" -- inherited + targetproperties.mode = properties.mode or "base" -- inherited + targetproperties.method = properties.method -- local askedscaledpoints = scaledpoints local scaledpoints, delta = constructors.calculatescale(tfmdata,scaledpoints,nil,specification) -- no shortcut, dan be redefined diff --git a/Master/texmf-dist/tex/luatex/luaotfload/fontloader-font-dsp.lua b/Master/texmf-dist/tex/luatex/luaotfload/fontloader-font-dsp.lua index 79749741c34..7777f9c6ad4 100644 --- a/Master/texmf-dist/tex/luatex/luaotfload/fontloader-font-dsp.lua +++ b/Master/texmf-dist/tex/luatex/luaotfload/fontloader-font-dsp.lua @@ -3159,6 +3159,14 @@ function readers.cpal(f,fontdata,specification) end end +local compress = gzip and gzip.compress +local compressed = compress and gzip.compressed + +-- At some point I will delay loading and only store the offsets (in context lmtx +-- only). + +-- compressed = false + function readers.svg(f,fontdata,specification) local tableoffset = gotodatatable(f,fontdata,"svg",specification.glyphs) if tableoffset then @@ -3184,10 +3192,14 @@ function readers.svg(f,fontdata,specification) for i=1,nofentries do local entry = entries[i] setposition(f,entry.offset) + local data = readstring(f,entry.length) + if compressed and not compressed(data) then + data = compress(data) + end entries[i] = { first = entry.first, last = entry.last, - data = readstring(f,entry.length) + data = data } end fontdata.svgshapes = entries 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 d79ed657e02..3752203fa22 100644 --- a/Master/texmf-dist/tex/luatex/luaotfload/fontloader-font-ocl.lua +++ b/Master/texmf-dist/tex/luatex/luaotfload/fontloader-font-ocl.lua @@ -8,9 +8,14 @@ if not modules then modules = { } end modules ['font-ocl'] = { -- todo : user list of colors +if CONTEXTLMTXMODE and CONTEXTLMTXMODE > 0 then + return +end + local tostring, tonumber, next = tostring, tonumber, next local round, max = math.round, math.round -local sortedkeys, sortedhash = table.sortedkeys, table.sortedhash +local gsub, find = string.gsub, string.find +local sortedkeys, sortedhash, concat = table.sortedkeys, table.sortedhash, table.concat local setmetatableindex = table.setmetatableindex local formatters = string.formatters @@ -24,6 +29,7 @@ local leftcommand = helpers.commands.left local downcommand = helpers.commands.down local otf = fonts.handlers.otf +local otfregister = otf.features.register local f_color = formatters["%.3f %.3f %.3f rg"] local f_gray = formatters["%.3f g"] @@ -150,7 +156,7 @@ local pop = { "pdf", "page", "Q" } -- -- only shows the first glyph in acrobat and nothing more. No problem with other -- -- renderers. -- --- local function initialize(tfmdata,kind,value) -- hm, always value +-- local function initializeoverlay(tfmdata,kind,value) -- hm, always value -- if value then -- local resources = tfmdata.resources -- local palettes = resources.colorpalettes @@ -193,11 +199,11 @@ local pop = { "pdf", "page", "Q" } -- local goback = w ~= 0 and leftcommand[w] or nil -- needs checking: are widths the same -- local t = { -- start, --- not u and actualb or { "pdf", "page", (getactualtext(tounicode(u))) } +-- not u and actualb or { "pdf", "page", (getactualtext(tounicode(u))) }, +-- push, -- } --- local n = 2 +-- local n = 3 -- local l = nil --- n = n + 1 t[n] = push -- for i=1,s do -- local entry = colorlist[i] -- local v = colorvalues[entry.class] or default @@ -220,11 +226,8 @@ local pop = { "pdf", "page", "Q" } -- end -- end -- end --- --- -- Here we have no color change in BT .. ET and more q Q pairs but even then acrobat --- -- fails displaying the overlays correctly. Other renderers do it right. -local function initialize(tfmdata,kind,value) +local function initializeoverlay(tfmdata,kind,value) if value then local resources = tfmdata.resources local palettes = resources.colorpalettes @@ -271,54 +274,40 @@ local function initialize(tfmdata,kind,value) local s = #colorlist local goback = w ~= 0 and leftcommand[w] or nil -- needs checking: are widths the same local t = { - start, -- really needed - not u and actualb or { "pdf", "page", (getactualtext(tounicode(u))) } + not u and actualb or { "pdf", "page", (getactualtext(tounicode(u))) }, + push, } local n = 2 local l = nil - local f = false for i=1,s do local entry = colorlist[i] local v = colorvalues[entry.class] or default if v and l ~= v then - if f then - n = n + 1 t[n] = pop - end - n = n + 1 t[n] = push - f = true n = n + 1 t[n] = v l = v - else - if f then - n = n + 1 t[n] = pop - end - f = false - l = nil end n = n + 1 t[n] = charcommand[entry.slot] if s > 1 and i < s and goback then n = n + 1 t[n] = goback end end - if f then - n = n + 1 t[n] = pop - end + n = n + 1 t[n] = pop n = n + 1 t[n] = actuale - -- n = n + 1 t[n] = stop -- not needed character.commands = t end end end + return true end end end -fonts.handlers.otf.features.register { +otfregister { name = "colr", description = "color glyphs", manipulators = { - base = initialize, - node = initialize, + base = initializeoverlay, + node = initializeoverlay, } } @@ -382,19 +371,25 @@ local function pdftovirtual(tfmdata,pdfshapes,kind) -- kind = png|svg for unicode, character in sortedhash(characters) do -- sort is nicer for svg local index = character.index if index then - local pdf = pdfshapes[index] - local typ = type(pdf) - local data = nil - local dx = nil - local dy = nil + local pdf = pdfshapes[index] + local typ = type(pdf) + local data = nil + local dx = nil + local dy = nil + local scale = 1 if typ == "table" then - data = pdf.data - dx = pdf.dx or 0 - dy = pdf.dy or 0 + data = pdf.data + dx = pdf.x or pdf.dx or 0 + dy = pdf.y or pdf.dy or 0 + scale = pdf.scale or 1 elseif typ == "string" then data = pdf dx = 0 dy = 0 + elseif typ == "number" then + data = pdf + dx = 0 + dy = 0 end if data then -- We can delay storage by a lua function in commands: but then we need to @@ -404,12 +399,20 @@ local function pdftovirtual(tfmdata,pdfshapes,kind) -- kind = png|svg local wd = character.width or 0 local ht = character.height or 0 local dp = character.depth or 0 - -- The down and right will change too (we can move that elsewhere). + -- The down and right will change too (we can move that elsewhere). We have + -- a different treatment in lmtx but the next kind of works. These images are + -- a mess anyway as in svg the bbox can be messed up absent). A png image + -- needs the x/y. I might normalize this once we moev to lmtx exlusively. character.commands = { not unicode and actualb or { "pdf", "page", (getactualtext(unicode)) }, - downcommand[dp + dy * hfactor], - rightcommand[dx * hfactor], - vfimage(wd,ht,dp,data,name), + -- lmtx (when we deal with depth in vfimage, currently disabled): + -- downcommand [dy * hfactor], + -- rightcommand[dx * hfactor], + -- vfimage(wd,ht,dp,data,name), + -- mkiv + downcommand [dp + dy * hfactor], + rightcommand[ dx * hfactor], + vfimage(scale*wd,ht,dp,data,pdfshapes.filename or ""), actuale, } character[kind] = true @@ -455,7 +458,7 @@ do name = "otfsvg", program = "inkscape", method = "pipeto", - template = "--shell > temp-otf-svg-shape.log", + template = "--export-area-drawing --shell > temp-otf-svg-shape.log", reporter = report_svg, } @@ -464,20 +467,31 @@ do -- poor mans variant for generic: -- runner = function() - return io.open("inkscape --shell > temp-otf-svg-shape.log","w") + return io.popen("inkscape --export-area-drawing --shell > temp-otf-svg-shape.log","w") end end - function otfsvg.topdf(svgshapes) + -- There are svg out there with bad viewBox specifications where shapes lay outside that area, + -- but trying to correct that didn't work out well enough so I discarded that code. BTW, we + -- decouple the inskape run and the loading run because inkscape is working in the background + -- in the files so we need to have unique files. + -- + -- Because a generic setup can be flawed we need to catch bad inkscape runs which add a bit of + -- ugly overhead. Bah. + + function otfsvg.topdf(svgshapes,tfmdata) local pdfshapes = { } local inkscape = runner() if inkscape then - local nofshapes = #svgshapes - local f_svgfile = formatters["temp-otf-svg-shape-%i.svg"] - local f_pdffile = formatters["temp-otf-svg-shape-%i.pdf"] - local f_convert = formatters["%s --export-pdf=%s\n"] - local filterglyph = otfsvg.filterglyph - local nofdone = 0 + local indices = fonts.getindices(tfmdata) + local descriptions = tfmdata.descriptions + local nofshapes = #svgshapes + local f_svgfile = formatters["temp-otf-svg-shape-%i.svg"] + local f_pdffile = formatters["temp-otf-svg-shape-%i.pdf"] + local f_convert = formatters["%s --export-pdf=%s\n"] + local filterglyph = otfsvg.filterglyph + local nofdone = 0 + local processed = { } report_svg("processing %i svg containers",nofshapes) statistics.starttiming() for i=1,nofshapes do @@ -489,24 +503,55 @@ do local pdffile = f_pdffile(index) savedata(svgfile,data) inkscape:write(f_convert(svgfile,pdffile)) - pdfshapes[index] = true + processed[index] = true nofdone = nofdone + 1 - if nofdone % 100 == 0 then - report_svg("%i shapes processed",nofdone) + if nofdone % 25 == 0 then + report_svg("%i shapes submitted",nofdone) end end end end + if nofdone % 25 ~= 0 then + report_svg("%i shapes submitted",nofdone) + end + report_svg("processing can be going on for a while") inkscape:write("quit\n") inkscape:close() report_svg("processing %i pdf results",nofshapes) - for index in next, pdfshapes do + for index in next, processed do local svgfile = f_svgfile(index) local pdffile = f_pdffile(index) - pdfshapes[index] = loaddata(pdffile) + -- local fntdata = descriptions[indices[index]] + -- local bounds = fntdata and fntdata.boundingbox + local pdfdata = loaddata(pdffile) + if pdfdata and pdfdata ~= "" then + pdfshapes[index] = { + data = pdfdata, + -- x = bounds and bounds[1] or 0, + -- y = bounds and bounds[2] or 0, + } + end remove(svgfile) remove(pdffile) end + local characters = tfmdata.characters + for k, v in next, characters do + local d = descriptions[k] + local i = d.index + if i then + local p = pdfshapes[i] + if p then + local w = d.width + local l = d.boundingbox[1] + local r = d.boundingbox[3] + p.scale = (r - l) / w + p.x = l + end + end + end + if not next(pdfshapes) then + report_svg("there are no converted shapes, fix your setup") + end statistics.stoptiming() if statistics.elapsedseconds then report_svg("svg conversion time %s",statistics.elapsedseconds() or "-") @@ -527,20 +572,23 @@ local function initializesvg(tfmdata,kind,value) -- hm, always value end local pdffile = containers.read(otf.pdfcache,hash) local pdfshapes = pdffile and pdffile.pdfshapes - if not pdfshapes or pdffile.timestamp ~= timestamp then + if not pdfshapes or pdffile.timestamp ~= timestamp or not next(pdfshapes) then + -- the next test tries to catch errors in generic usage but of course can result + -- in running again and again local svgfile = containers.read(otf.svgcache,hash) local svgshapes = svgfile and svgfile.svgshapes - pdfshapes = svgshapes and otfsvg.topdf(svgshapes) or { } + pdfshapes = svgshapes and otfsvg.topdf(svgshapes,tfmdata,otf.pdfcache.writable,hash) or { } containers.write(otf.pdfcache, hash, { pdfshapes = pdfshapes, timestamp = timestamp, }) end pdftovirtual(tfmdata,pdfshapes,"svg") + return true end end -fonts.handlers.otf.features.register { +otfregister { name = "svg", description = "svg glyphs", manipulators = { @@ -648,10 +696,11 @@ local function initializepng(tfmdata,kind,value) -- hm, always value end -- pdftovirtual(tfmdata,pdfshapes,"png") + return true end end -fonts.handlers.otf.features.register { +otfregister { name = "sbix", description = "sbix glyphs", manipulators = { @@ -660,7 +709,7 @@ fonts.handlers.otf.features.register { } } -fonts.handlers.otf.features.register { +otfregister { name = "cblc", description = "cblc glyphs", manipulators = { @@ -668,3 +717,36 @@ fonts.handlers.otf.features.register { node = initializepng, } } + +if context then + + -- untested in generic and might clash with other color trickery + -- anyway so let's stick to context only + + local function initializecolor(tfmdata,kind,value) + if value == "auto" then + return + initializeoverlay(tfmdata,kind,value) or + initializesvg(tfmdata,kind,value) or + initializepng(tfmdata,kind,value) + elseif value == "overlay" then + return initializeoverlay(tfmdata,kind,value) + elseif value == "svg" then + return initializesvg(tfmdata,kind,value) + elseif value == "png" or value == "bitmap" then + return initializepng(tfmdata,kind,value) + else + -- forget about it + end + end + + otfregister { + name = "color", + description = "color glyphs", + manipulators = { + base = initializecolor, + node = initializecolor, + } + } + +end diff --git a/Master/texmf-dist/tex/luatex/luaotfload/fontloader-font-osd.lua b/Master/texmf-dist/tex/luatex/luaotfload/fontloader-font-osd.lua index 203c1d79d40..b97ac9c6f57 100644 --- a/Master/texmf-dist/tex/luatex/luaotfload/fontloader-font-osd.lua +++ b/Master/texmf-dist/tex/luatex/luaotfload/fontloader-font-osd.lua @@ -1285,7 +1285,7 @@ local function reorder_one(head,start,stop,font,attr,nbspaces) local cp = getprev(current) local cnsn = getnext(cns) setlink(cp,n) - setlink(cns,current) + setlink(cns,current) -- cns ? setlink(c,cnsn) if c == stop then stop = cp diff --git a/Master/texmf-dist/tex/luatex/luaotfload/fontloader-font-otc.lua b/Master/texmf-dist/tex/luatex/luaotfload/fontloader-font-otc.lua index a774a81c2c9..2643d022a57 100644 --- a/Master/texmf-dist/tex/luatex/luaotfload/fontloader-font-otc.lua +++ b/Master/texmf-dist/tex/luatex/luaotfload/fontloader-font-otc.lua @@ -22,9 +22,10 @@ local otf = fonts.handlers.otf local registerotffeature = otf.features.register local setmetatableindex = table.setmetatableindex -local checkmerge = fonts.helpers.checkmerge -local checkflags = fonts.helpers.checkflags -local checksteps = fonts.helpers.checksteps +local fonthelpers = fonts.helpers +local checkmerge = fonthelpers.checkmerge +local checkflags = fonthelpers.checkflags +local checksteps = fonthelpers.checksteps local normalized = { substitution = "substitution", @@ -167,6 +168,7 @@ local function addfeature(data,feature,specifications) local done = 0 local skip = 0 local aglunicodes = false + local privateslot = fonthelpers.privateslot local specifications = validspecification(specifications,feature) if not specifications then @@ -196,6 +198,13 @@ local function addfeature(data,feature,specifications) return u end end + if privateslot then + u = privateslot(code) -- no creation ! + if u then + -- unicodes[code] = u + return u + end + end local u = lpegmatch(p,code) if u then -- unicodes[code] = u @@ -229,7 +238,7 @@ local function addfeature(data,feature,specifications) replacement = replacement[1] end replacement = tounicode(replacement) - if replacement and descriptions[replacement] then + if replacement and (nocheck or descriptions[replacement]) then cover(coverage,unicode,replacement) done = done + 1 else @@ -620,7 +629,6 @@ local function addfeature(data,feature,specifications) local featuretype = normalized[specification.type or "substitution"] or "substitution" local featureflags = specification.flags or noflags local nocheck = specification.nocheck - local futuresteps = specification.futuresteps local featureorder = specification.order or { feature } local featurechain = (featuretype == "chainsubstitution" or featuretype == "chainposition") and 1 or 0 local nofsteps = 0 diff --git a/Master/texmf-dist/tex/luatex/luaotfload/fontloader-font-otl.lua b/Master/texmf-dist/tex/luatex/luaotfload/fontloader-font-otl.lua index f8cd8217cd7..5d3bd4230cb 100644 --- a/Master/texmf-dist/tex/luatex/luaotfload/fontloader-font-otl.lua +++ b/Master/texmf-dist/tex/luatex/luaotfload/fontloader-font-otl.lua @@ -52,11 +52,12 @@ local report_otf = logs.reporter("fonts","otf loading") local fonts = fonts local otf = fonts.handlers.otf -otf.version = 3.109 -- beware: also sync font-mis.lua and in mtx-fonts +otf.version = 3.110 -- beware: also sync font-mis.lua and in mtx-fonts otf.cache = containers.define("fonts", "otl", otf.version, true) otf.svgcache = containers.define("fonts", "svg", otf.version, true) otf.pngcache = containers.define("fonts", "png", otf.version, true) otf.pdfcache = containers.define("fonts", "pdf", otf.version, true) +otf.mpscache = containers.define("fonts", "mps", otf.version, true) otf.svgenabled = false otf.pngenabled = false 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 63130220069..5091fd76570 100644 --- a/Master/texmf-dist/tex/luatex/luaotfload/fontloader-font-ots.lua +++ b/Master/texmf-dist/tex/luatex/luaotfload/fontloader-font-ots.lua @@ -177,7 +177,6 @@ registertracker("otf.sample.silent", "otf.steps=silent","otf.substitutions","otf local nuts = nodes.nuts -local getfield = nuts.getfield local getnext = nuts.getnext local setnext = nuts.setnext local getprev = nuts.getprev @@ -193,6 +192,7 @@ local getchar = nuts.getchar local setchar = nuts.setchar local getdisc = nuts.getdisc local setdisc = nuts.setdisc +local getreplace = nuts.getreplace local setlink = nuts.setlink local getcomponents = nuts.getcomponents -- the original one, not yet node-aux local setcomponents = nuts.setcomponents -- the original one, not yet node-aux @@ -2090,7 +2090,7 @@ local function chaindisk(head,start,dataset,sequence,rlmode,skiphash,ck) if keepdisc then keepdisc = false lookaheaddisc = current - local replace = getfield(current,"replace") + local replace = getreplace(current) if not replace then sweepoverflow = true sweepnode = current @@ -2167,7 +2167,7 @@ local function chaindisk(head,start,dataset,sequence,rlmode,skiphash,ck) lookaheaddisc = current end -- we assume a simple text only replace (we could use nuts.count) - local replace = getfield(current,"replace") + local replace = getreplace(current) while replace and i < s do if getid(replace) == glyph_code then i = i + 1 @@ -2213,7 +2213,7 @@ local function chaindisk(head,start,dataset,sequence,rlmode,skiphash,ck) backtrackdisc = current end -- we assume a simple text only replace (we could use nuts.count) - local replace = getfield(current,"replace") + local replace = getreplace(current) while replace and i > 1 do if getid(replace) == glyph_code then i = i - 1 @@ -3386,7 +3386,7 @@ local function t_run_single(start,stop,font,attr,lookupcache) -- how about post ... we can probably merge this into the while while getid(s) == disc_code do ss = getnext(s) - s = getfield(s,"replace") + s = getreplace(s) if not s then s = ss ss = nil @@ -3413,7 +3413,7 @@ local function t_run_single(start,stop,font,attr,lookupcache) end while getid(s) == disc_code do ss = getnext(s) - s = getfield(s,"replace") + s = getreplace(s) if not s then s = ss ss = nil @@ -3556,7 +3556,7 @@ local function t_run_multiple(start,stop,font,attr,steps,nofsteps) end while getid(s) == disc_code do ss = getnext(s) - s = getfield(s,"replace") + s = getreplace(s) if not s then s = ss ss = nil @@ -3583,7 +3583,7 @@ local function t_run_multiple(start,stop,font,attr,steps,nofsteps) end while getid(s) == disc_code do ss = getnext(s) - s = getfield(s,"replace") + s = getreplace(s) if not s then s = ss ss = nil diff --git a/Master/texmf-dist/tex/luatex/luaotfload/fontloader-font-oup.lua b/Master/texmf-dist/tex/luatex/luaotfload/fontloader-font-oup.lua index 51b1c248f87..0e7e25808ca 100644 --- a/Master/texmf-dist/tex/luatex/luaotfload/fontloader-font-oup.lua +++ b/Master/texmf-dist/tex/luatex/luaotfload/fontloader-font-oup.lua @@ -720,6 +720,10 @@ local function checklookups(fontdata,missing,nofmissing) end end +local firstprivate = fonts.privateoffsets and fonts.privateoffsets.textbase or 0xF0000 +local puafirst = 0xE000 +local pualast = 0xF8FF + local function unifymissing(fontdata) if not fonts.mappings then require("font-map") @@ -730,20 +734,22 @@ local function unifymissing(fontdata) resources.unicodes = unicodes for unicode, d in next, fontdata.descriptions do if unicode < privateoffset then - local name = d.name - if name then - unicodes[name] = unicode + if unicode >= puafirst and unicode <= pualast then + -- report_unicodes("resolving private unicode %U",unicode) + else + local name = d.name + if name then + unicodes[name] = unicode + end end + else + -- report_unicodes("resolving private unicode %U",unicode) end end fonts.mappings.addtounicode(fontdata,fontdata.filename,checklookups) resources.unicodes = nil end -local firstprivate = fonts.privateoffsets and fonts.privateoffsets.textbase or 0xF0000 -local puafirst = 0xE000 -local pualast = 0xF8FF - local function unifyglyphs(fontdata,usenames) local private = fontdata.private or privateoffset local glyphs = fontdata.glyphs diff --git a/Master/texmf-dist/tex/luatex/luaotfload/fontloader-l-lpeg.lua b/Master/texmf-dist/tex/luatex/luaotfload/fontloader-l-lpeg.lua index 51bc1d3df30..7979a40fb94 100644 --- a/Master/texmf-dist/tex/luatex/luaotfload/fontloader-l-lpeg.lua +++ b/Master/texmf-dist/tex/luatex/luaotfload/fontloader-l-lpeg.lua @@ -295,7 +295,7 @@ patterns.longtostring = Cs(whitespace^0/"" * ((patterns.quoted + nonwhitespace^ -- return P { P(pattern) + 1 * V(1) } -- end -function anywhere(pattern) -- faster +local function anywhere(pattern) -- faster return (1-P(pattern))^0 * P(pattern) end 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 6e9606e849f..51399216ccf 100644 --- a/Master/texmf-dist/tex/luatex/luaotfload/fontloader-l-lua.lua +++ b/Master/texmf-dist/tex/luatex/luaotfload/fontloader-l-lua.lua @@ -35,6 +35,12 @@ if LUAVERSION < 5.2 and jit then LUAVERSION = 5.2 end +-- this is lmtx only: + +if lua and lua.openfile then + io.open = lua.openfile +end + -- lpeg if not lpeg then 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 cffdcc23e20..e8282038674 100644 --- a/Master/texmf-dist/tex/luatex/luaotfload/fontloader-l-table.lua +++ b/Master/texmf-dist/tex/luatex/luaotfload/fontloader-l-table.lua @@ -287,6 +287,37 @@ local function sortedhash(t,cmp) return nothing end +-- local function iterate(t,i) +-- local i = i + 1 +-- if i <= t.n then +-- local k = t[i] +-- return i, k, t.t[k] +-- end +-- end +-- +-- local function indexedhash(t,cmp) +-- if t then +-- local s +-- if cmp then +-- -- it would be nice if the sort function would accept a third argument (or nicer, an optional first) +-- s = sortedhashkeys(t,function(a,b) return cmp(t,a,b) end) +-- else +-- s = sortedkeys(t) -- the robust one +-- end +-- local m = #s +-- if m == 1 then +-- return next, t +-- elseif m > 0 then +-- s.n = m +-- s.t = t +-- return iterate, s, 0 +-- end +-- end +-- return nothing +-- end +-- +-- -- for i, k, v in indexedhash(t) do print(k,v,s) end + table.sortedhash = sortedhash table.sortedpairs = sortedhash -- obsolete diff --git a/Master/texmf-dist/tex/luatex/luaotfload/fontloader-l-unicode.lua b/Master/texmf-dist/tex/luatex/luaotfload/fontloader-l-unicode.lua index 13e0a3fa1c1..c57aaf33ebc 100644 --- a/Master/texmf-dist/tex/luatex/luaotfload/fontloader-l-unicode.lua +++ b/Master/texmf-dist/tex/luatex/luaotfload/fontloader-l-unicode.lua @@ -1081,56 +1081,62 @@ function utf.utf32_to_utf8_t(t,endian) return endian and utf32_to_utf8_be_t(t) or utf32_to_utf8_le_t(t) or t end -local function little(b) - if b < 0x10000 then - return char(b%256,rshift(b,8)) - else - b = b - 0x10000 - local b1 = rshift(b,10) + 0xD800 - local b2 = b%1024 + 0xDC00 - return char(b1%256,rshift(b1,8),b2%256,rshift(b2,8)) +if bit32 then + + local rshift = bit32.rshift + + local function little(b) + if b < 0x10000 then + return char(b%256,rshift(b,8)) + else + b = b - 0x10000 + local b1 = rshift(b,10) + 0xD800 + local b2 = b%1024 + 0xDC00 + return char(b1%256,rshift(b1,8),b2%256,rshift(b2,8)) + end end -end -local function big(b) - if b < 0x10000 then - return char(rshift(b,8),b%256) - else - b = b - 0x10000 - local b1 = rshift(b,10) + 0xD800 - local b2 = b%1024 + 0xDC00 - return char(rshift(b1,8),b1%256,rshift(b2,8),b2%256) + local function big(b) + if b < 0x10000 then + return char(rshift(b,8),b%256) + else + b = b - 0x10000 + local b1 = rshift(b,10) + 0xD800 + local b2 = b%1024 + 0xDC00 + return char(rshift(b1,8),b1%256,rshift(b2,8),b2%256) + end end -end -local l_remap = Cs((p_utf8byte/little+P(1)/"")^0) -local b_remap = Cs((p_utf8byte/big +P(1)/"")^0) + local l_remap = Cs((p_utf8byte/little+P(1)/"")^0) + local b_remap = Cs((p_utf8byte/big +P(1)/"")^0) -local function utf8_to_utf16_be(str,nobom) - if nobom then - return lpegmatch(b_remap,str) - else - return char(254,255) .. lpegmatch(b_remap,str) + local function utf8_to_utf16_be(str,nobom) + if nobom then + return lpegmatch(b_remap,str) + else + return char(254,255) .. lpegmatch(b_remap,str) + end end -end -local function utf8_to_utf16_le(str,nobom) - if nobom then - return lpegmatch(l_remap,str) - else - return char(255,254) .. lpegmatch(l_remap,str) + local function utf8_to_utf16_le(str,nobom) + if nobom then + return lpegmatch(l_remap,str) + else + return char(255,254) .. lpegmatch(l_remap,str) + end end -end -utf.utf8_to_utf16_be = utf8_to_utf16_be -utf.utf8_to_utf16_le = utf8_to_utf16_le + utf.utf8_to_utf16_be = utf8_to_utf16_be + utf.utf8_to_utf16_le = utf8_to_utf16_le -function utf.utf8_to_utf16(str,littleendian,nobom) - if littleendian then - return utf8_to_utf16_le(str,nobom) - else - return utf8_to_utf16_be(str,nobom) + function utf.utf8_to_utf16(str,littleendian,nobom) + if littleendian then + return utf8_to_utf16_le(str,nobom) + else + return utf8_to_utf16_be(str,nobom) + end end + end local pattern = Cs ( diff --git a/Master/texmf-dist/tex/luatex/luaotfload/fontloader-reference.lua b/Master/texmf-dist/tex/luatex/luaotfload/fontloader-reference.lua index 3120f45135b..b8a21fc937b 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 : 08/11/19 20:03:46 +-- merge date : 10/29/19 15:00:00 do -- begin closure to overcome local limits and interference @@ -20,6 +20,9 @@ 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 @@ -296,7 +299,7 @@ patterns.propername=(uppercase+lowercase+underscore)*(uppercase+lowercase+unders patterns.somecontent=(anything-newline-space)^1 patterns.beginline=#(1-newline) patterns.longtostring=Cs(whitespace^0/""*((patterns.quoted+nonwhitespace^1+whitespace^1/""*(endofstring+Cc(" ")))^0)) -function anywhere(pattern) +local function anywhere(pattern) return (1-P(pattern))^0*P(pattern) end lpeg.anywhere=anywhere @@ -3433,7 +3436,7 @@ local environment={ stripzero=patterns.stripzero, stripzeros=patterns.stripzeros, escapedquotes=string.escapedquotes, - FORMAT=string.f9, + FORMAT=string.f6, } local arguments={ "a1" } setmetatable(arguments,{ __index=function(t,k) @@ -3641,12 +3644,25 @@ local format_n=function() n=n+1 return format("((a%s %% 1 == 0) and format('%%i',a%s) or tostring(a%s))",n,n,n) end -local format_N=function(f) - n=n+1 - if not f or f=="" then - f=".9" - end - return format("(((a%s %% 1 == 0) and format('%%i',a%s)) or lpegmatch(stripzero,format('%%%sf',a%s)))",n,n,f,n) +local format_N if environment.FORMAT then + format_N=function(f) + n=n+1 + if not f or f=="" then + return format("FORMAT(a%s,'%%.9f')",n) + elseif f==".6" then + return format("FORMAT(a%s)",n) + else + return format("FORMAT(a%s,'%%%sf')",n,f) + end + end +else + format_N=function(f) + n=n+1 + if not f or f=="" then + f=".9" + end + return format("(((a%s %% 1 == 0) and format('%%i',a%s)) or lpegmatch(stripzero,format('%%%sf',a%s)))",n,n,f,n) + end end local format_a=function(f) n=n+1 @@ -4865,6 +4881,7 @@ nuts.getchar=direct.getchar nuts.getcomponents=direct.getcomponents nuts.getdirection=direct.getdirection nuts.getdisc=direct.getdisc +nuts.getreplace=direct.getreplace nuts.getfield=direct.getfield nuts.getfont=direct.getfont nuts.getid=direct.getid @@ -4881,6 +4898,7 @@ nuts.setchar=direct.setchar nuts.setcomponents=direct.setcomponents nuts.setdirection=direct.setdirection nuts.setdisc=direct.setdisc +nuts.setreplace=direct.setreplace nuts.setfield=setfield nuts.setkern=direct.setkern nuts.setlink=direct.setlink @@ -4998,6 +5016,17 @@ do node=nuts.traverse(dummy), } end +if not nuts.setreplace then + local getdisc=nuts.getdisc + local setfield=nuts.setfield + function nuts.getreplace(n) + local _,_,h,_,_,t=getdisc(n,true) + return h,t + end + function nuts.setreplace(n,h) + setfield(n,"replace",h) + end +end end -- closure @@ -8989,7 +9018,8 @@ function constructors.scale(tfmdata,specification) local units=parameters.units or 1000 targetproperties.language=properties.language or "dflt" targetproperties.script=properties.script or "dflt" - targetproperties.mode=properties.mode or "base" + targetproperties.mode=properties.mode or "base" + targetproperties.method=properties.method local askedscaledpoints=scaledpoints local scaledpoints,delta=constructors.calculatescale(tfmdata,scaledpoints,nil,specification) local hdelta=delta @@ -19773,6 +19803,8 @@ function readers.cpal(f,fontdata,specification) fontdata.colorpalettes=palettes end end +local compress=gzip and gzip.compress +local compressed=compress and gzip.compressed function readers.svg(f,fontdata,specification) local tableoffset=gotodatatable(f,fontdata,"svg",specification.glyphs) if tableoffset then @@ -19794,10 +19826,14 @@ function readers.svg(f,fontdata,specification) for i=1,nofentries do local entry=entries[i] setposition(f,entry.offset) + local data=readstring(f,entry.length) + if compressed and not compressed(data) then + data=compress(data) + end entries[i]={ first=entry.first, last=entry.last, - data=readstring(f,entry.length) + data=data } end fontdata.svgshapes=entries @@ -21059,6 +21095,9 @@ local function checklookups(fontdata,missing,nofmissing) end end end +local firstprivate=fonts.privateoffsets and fonts.privateoffsets.textbase or 0xF0000 +local puafirst=0xE000 +local pualast=0xF8FF local function unifymissing(fontdata) if not fonts.mappings then require("font-map") @@ -21069,18 +21108,19 @@ local function unifymissing(fontdata) resources.unicodes=unicodes for unicode,d in next,fontdata.descriptions do if unicode<privateoffset then - local name=d.name - if name then - unicodes[name]=unicode + if unicode>=puafirst and unicode<=pualast then + else + local name=d.name + if name then + unicodes[name]=unicode + end end + else end end fonts.mappings.addtounicode(fontdata,fontdata.filename,checklookups) resources.unicodes=nil end -local firstprivate=fonts.privateoffsets and fonts.privateoffsets.textbase or 0xF0000 -local puafirst=0xE000 -local pualast=0xF8FF local function unifyglyphs(fontdata,usenames) local private=fontdata.private or privateoffset local glyphs=fontdata.glyphs @@ -23049,11 +23089,12 @@ local trace_defining=false registertracker("fonts.defining",function(v) trace_d local report_otf=logs.reporter("fonts","otf loading") local fonts=fonts local otf=fonts.handlers.otf -otf.version=3.109 +otf.version=3.110 otf.cache=containers.define("fonts","otl",otf.version,true) otf.svgcache=containers.define("fonts","svg",otf.version,true) otf.pngcache=containers.define("fonts","png",otf.version,true) otf.pdfcache=containers.define("fonts","pdf",otf.version,true) +otf.mpscache=containers.define("fonts","mps",otf.version,true) otf.svgenabled=false otf.pngenabled=false local otfreaders=otf.readers @@ -26076,7 +26117,6 @@ registertracker("otf.actions","otf.substitutions","otf.positions") registertracker("otf.sample","otf.steps","otf.substitutions","otf.positions","otf.analyzing") registertracker("otf.sample.silent","otf.steps=silent","otf.substitutions","otf.positions","otf.analyzing") local nuts=nodes.nuts -local getfield=nuts.getfield local getnext=nuts.getnext local setnext=nuts.setnext local getprev=nuts.getprev @@ -26092,6 +26132,7 @@ local getchar=nuts.getchar local setchar=nuts.setchar local getdisc=nuts.getdisc local setdisc=nuts.setdisc +local getreplace=nuts.getreplace local setlink=nuts.setlink local getcomponents=nuts.getcomponents local setcomponents=nuts.setcomponents @@ -27670,7 +27711,7 @@ local function chaindisk(head,start,dataset,sequence,rlmode,skiphash,ck) if keepdisc then keepdisc=false lookaheaddisc=current - local replace=getfield(current,"replace") + local replace=getreplace(current) if not replace then sweepoverflow=true sweepnode=current @@ -27742,7 +27783,7 @@ local function chaindisk(head,start,dataset,sequence,rlmode,skiphash,ck) if notmatchpre[current]~=notmatchreplace[current] then lookaheaddisc=current end - local replace=getfield(current,"replace") + local replace=getreplace(current) while replace and i<s do if getid(replace)==glyph_code then i=i+1 @@ -27786,7 +27827,7 @@ local function chaindisk(head,start,dataset,sequence,rlmode,skiphash,ck) if notmatchpost[current]~=notmatchreplace[current] then backtrackdisc=current end - local replace=getfield(current,"replace") + local replace=getreplace(current) while replace and i>1 do if getid(replace)==glyph_code then i=i-1 @@ -28750,7 +28791,7 @@ local function t_run_single(start,stop,font,attr,lookupcache) end while getid(s)==disc_code do ss=getnext(s) - s=getfield(s,"replace") + s=getreplace(s) if not s then s=ss ss=nil @@ -28777,7 +28818,7 @@ local function t_run_single(start,stop,font,attr,lookupcache) end while getid(s)==disc_code do ss=getnext(s) - s=getfield(s,"replace") + s=getreplace(s) if not s then s=ss ss=nil @@ -28904,7 +28945,7 @@ local function t_run_multiple(start,stop,font,attr,steps,nofsteps) end while getid(s)==disc_code do ss=getnext(s) - s=getfield(s,"replace") + s=getreplace(s) if not s then s=ss ss=nil @@ -28931,7 +28972,7 @@ local function t_run_multiple(start,stop,font,attr,steps,nofsteps) end while getid(s)==disc_code do ss=getnext(s) - s=getfield(s,"replace") + s=getreplace(s) if not s then s=ss ss=nil @@ -30708,7 +30749,7 @@ local function reorder_one(head,start,stop,font,attr,nbspaces) local cp=getprev(current) local cnsn=getnext(cns) setlink(cp,n) - setlink(cns,current) + setlink(cns,current) setlink(c,cnsn) if c==stop then stop=cp @@ -32071,9 +32112,13 @@ if not modules then modules={} end modules ['font-ocl']={ copyright="PRAGMA ADE / ConTeXt Development Team", license="see context related readme files" } +if CONTEXTLMTXMODE and CONTEXTLMTXMODE>0 then + return +end local tostring,tonumber,next=tostring,tonumber,next local round,max=math.round,math.round -local sortedkeys,sortedhash=table.sortedkeys,table.sortedhash +local gsub,find=string.gsub,string.find +local sortedkeys,sortedhash,concat=table.sortedkeys,table.sortedhash,table.concat local setmetatableindex=table.setmetatableindex local formatters=string.formatters local tounicode=fonts.mappings.tounicode @@ -32083,6 +32128,7 @@ local rightcommand=helpers.commands.right local leftcommand=helpers.commands.left local downcommand=helpers.commands.down local otf=fonts.handlers.otf +local otfregister=otf.features.register local f_color=formatters["%.3f %.3f %.3f rg"] local f_gray=formatters["%.3f g"] if context then @@ -32139,7 +32185,7 @@ end local start={ "pdf","mode","font" } local push={ "pdf","page","q" } local pop={ "pdf","page","Q" } -local function initialize(tfmdata,kind,value) +local function initializeoverlay(tfmdata,kind,value) if value then local resources=tfmdata.resources local palettes=resources.colorpalettes @@ -32181,52 +32227,39 @@ local function initialize(tfmdata,kind,value) local s=#colorlist local goback=w~=0 and leftcommand[w] or nil local t={ - start, - not u and actualb or { "pdf","page",(getactualtext(tounicode(u))) } + not u and actualb or { "pdf","page",(getactualtext(tounicode(u))) }, + push, } local n=2 local l=nil - local f=false for i=1,s do local entry=colorlist[i] local v=colorvalues[entry.class] or default if v and l~=v then - if f then - n=n+1 t[n]=pop - end - n=n+1 t[n]=push - f=true n=n+1 t[n]=v l=v - else - if f then - n=n+1 t[n]=pop - end - f=false - l=nil end n=n+1 t[n]=charcommand[entry.slot] if s>1 and i<s and goback then n=n+1 t[n]=goback end end - if f then - n=n+1 t[n]=pop - end + n=n+1 t[n]=pop n=n+1 t[n]=actuale character.commands=t end end end + return true end end end -fonts.handlers.otf.features.register { +otfregister { name="colr", description="color glyphs", manipulators={ - base=initialize, - node=initialize, + base=initializeoverlay, + node=initializeoverlay, } } do @@ -32277,14 +32310,20 @@ local function pdftovirtual(tfmdata,pdfshapes,kind) local data=nil local dx=nil local dy=nil + local scale=1 if typ=="table" then data=pdf.data - dx=pdf.dx or 0 - dy=pdf.dy or 0 + dx=pdf.x or pdf.dx or 0 + dy=pdf.y or pdf.dy or 0 + scale=pdf.scale or 1 elseif typ=="string" then data=pdf dx=0 dy=0 + elseif typ=="number" then + data=pdf + dx=0 + dy=0 end if data then local bt=unicode and getactualtext(unicode) @@ -32293,9 +32332,9 @@ local function pdftovirtual(tfmdata,pdfshapes,kind) local dp=character.depth or 0 character.commands={ not unicode and actualb or { "pdf","page",(getactualtext(unicode)) }, - downcommand[dp+dy*hfactor], - rightcommand[dx*hfactor], - vfimage(wd,ht,dp,data,name), + downcommand [dp+dy*hfactor], + rightcommand[ dx*hfactor], + vfimage(scale*wd,ht,dp,data,pdfshapes.filename or ""), actuale, } character[kind]=true @@ -32329,24 +32368,27 @@ do name="otfsvg", program="inkscape", method="pipeto", - template="--shell > temp-otf-svg-shape.log", + template="--export-area-drawing --shell > temp-otf-svg-shape.log", reporter=report_svg, } if not runner then runner=function() - return io.open("inkscape --shell > temp-otf-svg-shape.log","w") + return io.popen("inkscape --export-area-drawing --shell > temp-otf-svg-shape.log","w") end end - function otfsvg.topdf(svgshapes) + function otfsvg.topdf(svgshapes,tfmdata) 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"] local f_pdffile=formatters["temp-otf-svg-shape-%i.pdf"] local f_convert=formatters["%s --export-pdf=%s\n"] local filterglyph=otfsvg.filterglyph local nofdone=0 + local processed={} report_svg("processing %i svg containers",nofshapes) statistics.starttiming() for i=1,nofshapes do @@ -32358,24 +32400,51 @@ do local pdffile=f_pdffile(index) savedata(svgfile,data) inkscape:write(f_convert(svgfile,pdffile)) - pdfshapes[index]=true + processed[index]=true nofdone=nofdone+1 - if nofdone%100==0 then - report_svg("%i shapes processed",nofdone) + if nofdone%25==0 then + report_svg("%i shapes submitted",nofdone) end end end end + if nofdone%25~=0 then + report_svg("%i shapes submitted",nofdone) + end + report_svg("processing can be going on for a while") inkscape:write("quit\n") inkscape:close() report_svg("processing %i pdf results",nofshapes) - for index in next,pdfshapes do + for index in next,processed do local svgfile=f_svgfile(index) local pdffile=f_pdffile(index) - pdfshapes[index]=loaddata(pdffile) + local pdfdata=loaddata(pdffile) + if pdfdata and pdfdata~="" then + pdfshapes[index]={ + data=pdfdata, + } + end remove(svgfile) remove(pdffile) end + local characters=tfmdata.characters + for k,v in next,characters do + local d=descriptions[k] + local i=d.index + if i then + local p=pdfshapes[i] + if p then + local w=d.width + local l=d.boundingbox[1] + local r=d.boundingbox[3] + p.scale=(r-l)/w + p.x=l + end + end + end + if not next(pdfshapes) then + report_svg("there are no converted shapes, fix your setup") + end statistics.stoptiming() if statistics.elapsedseconds then report_svg("svg conversion time %s",statistics.elapsedseconds() or "-") @@ -32394,19 +32463,20 @@ local function initializesvg(tfmdata,kind,value) end local pdffile=containers.read(otf.pdfcache,hash) local pdfshapes=pdffile and pdffile.pdfshapes - if not pdfshapes or pdffile.timestamp~=timestamp then + if not pdfshapes or pdffile.timestamp~=timestamp or not next(pdfshapes) then local svgfile=containers.read(otf.svgcache,hash) local svgshapes=svgfile and svgfile.svgshapes - pdfshapes=svgshapes and otfsvg.topdf(svgshapes) or {} + pdfshapes=svgshapes and otfsvg.topdf(svgshapes,tfmdata,otf.pdfcache.writable,hash) or {} containers.write(otf.pdfcache,hash,{ pdfshapes=pdfshapes, timestamp=timestamp, }) end pdftovirtual(tfmdata,pdfshapes,"svg") + return true end end -fonts.handlers.otf.features.register { +otfregister { name="svg", description="svg glyphs", manipulators={ @@ -32489,9 +32559,10 @@ local function initializepng(tfmdata,kind,value) }) end pdftovirtual(tfmdata,pdfshapes,"png") + return true end end -fonts.handlers.otf.features.register { +otfregister { name="sbix", description="sbix glyphs", manipulators={ @@ -32499,7 +32570,7 @@ fonts.handlers.otf.features.register { node=initializepng, } } -fonts.handlers.otf.features.register { +otfregister { name="cblc", description="cblc glyphs", manipulators={ @@ -32507,6 +32578,11 @@ fonts.handlers.otf.features.register { node=initializepng, } } +if context then + +--removed + +end end -- closure @@ -32530,9 +32606,10 @@ local fonts=fonts local otf=fonts.handlers.otf local registerotffeature=otf.features.register local setmetatableindex=table.setmetatableindex -local checkmerge=fonts.helpers.checkmerge -local checkflags=fonts.helpers.checkflags -local checksteps=fonts.helpers.checksteps +local fonthelpers=fonts.helpers +local checkmerge=fonthelpers.checkmerge +local checkflags=fonthelpers.checkflags +local checksteps=fonthelpers.checksteps local normalized={ substitution="substitution", single="substitution", @@ -32654,6 +32731,7 @@ local function addfeature(data,feature,specifications) local done=0 local skip=0 local aglunicodes=false + local privateslot=fonthelpers.privateslot local specifications=validspecification(specifications,feature) if not specifications then return @@ -32676,6 +32754,12 @@ local function addfeature(data,feature,specifications) return u end end + if privateslot then + u=privateslot(code) + if u then + return u + end + end local u=lpegmatch(p,code) if u then return u @@ -32705,7 +32789,7 @@ local function addfeature(data,feature,specifications) replacement=replacement[1] end replacement=tounicode(replacement) - if replacement and descriptions[replacement] then + if replacement and (nocheck or descriptions[replacement]) then cover(coverage,unicode,replacement) done=done+1 else @@ -33075,7 +33159,6 @@ local function addfeature(data,feature,specifications) local featuretype=normalized[specification.type or "substitution"] or "substitution" local featureflags=specification.flags or noflags local nocheck=specification.nocheck - local futuresteps=specification.futuresteps local featureorder=specification.order or { feature } local featurechain=(featuretype=="chainsubstitution" or featuretype=="chainposition") and 1 or 0 local nofsteps=0 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 ad22302df0c..432b39ec5ad 100644 --- a/Master/texmf-dist/tex/luatex/luaotfload/fontloader-util-str.lua +++ b/Master/texmf-dist/tex/luatex/luaotfload/fontloader-util-str.lua @@ -633,7 +633,7 @@ local environment = { stripzeros = patterns.stripzeros, escapedquotes = string.escapedquotes, - FORMAT = string.f9, + FORMAT = string.f6, } -- -- -- @@ -908,7 +908,7 @@ local format_L = function() return format("(a%s and 'TRUE' or 'FALSE')",n) end -local format_n = function() -- strips leading and trailing zeros and removes .0 +local format_n = function() -- strips leading and trailing zeros and removes .0, beware: can produce e notation n = n + 1 return format("((a%s %% 1 == 0) and format('%%i',a%s) or tostring(a%s))",n,n,n) end @@ -938,13 +938,30 @@ end -- end -- end -local format_N = function(f) -- strips leading and trailing zeros - n = n + 1 - -- stripzero (singular) as we only have a number - if not f or f == "" then - f = ".9" - end -- always a leading number ! - return format("(((a%s %% 1 == 0) and format('%%i',a%s)) or lpegmatch(stripzero,format('%%%sf',a%s)))",n,n,f,n) +local format_N if environment.FORMAT then + + format_N = function(f) + n = n + 1 + if not f or f == "" then + return format("FORMAT(a%s,'%%.9f')",n) + elseif f == ".6" then + return format("FORMAT(a%s)",n) + else + return format("FORMAT(a%s,'%%%sf')",n,f) + end + end + +else + + format_N = function(f) -- strips leading and trailing zeros + n = n + 1 + -- stripzero (singular) as we only have a number + if not f or f == "" then + f = ".9" + end -- always a leading number ! + return format("(((a%s %% 1 == 0) and format('%%i',a%s)) or lpegmatch(stripzero,format('%%%sf',a%s)))",n,n,f,n) + end + end local format_a = function(f) diff --git a/Master/texmf-dist/tex/luatex/luaotfload/luaotfload-auxiliary.lua b/Master/texmf-dist/tex/luatex/luaotfload/luaotfload-auxiliary.lua index d3b5c734183..9538a15bb01 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.00", --TAGVERSION - date = "2019-09-13", --TAGDATE + version = "3.1", --TAGVERSION + date = "2019-11-04", --TAGDATE description = "luaotfload submodule / auxiliary functions", license = "GPL v2.0" } @@ -39,6 +39,13 @@ local stringbyte = string.byte local stringfind = string.find local tablecopy = table.copy +local harf = luaotfload.harfbuzz +local GSUBtag, GPOStag +if harf then + GSUBtag = harf.Tag.new("GSUB") + GPOStag = harf.Tag.new("GPOS") +end + local aux = { } local luaotfload_callbacks = { } @@ -101,6 +108,14 @@ luaotfload_callbacks [#luaotfload_callbacks + 1] = { "patch_font", set_sscale_dimens, "set_sscale_dimens", } +-- Starting with LuaTeX 1.11.2, this is a more reliable way of selecting the +-- right font than relying on psnames +luaotfload_callbacks [#luaotfload_callbacks + 1] = { + "patch_font", function(fontdata) + fontdata.subfont = fontdata.specification.sub or 1 + end, "set_font_index", +} + local default_units = 1000 --- fontobj -> int @@ -349,15 +364,27 @@ function aux.slot_of_name(font_id, glyphname, unsafe) local tfmdata = identifiers [font_id] if not tfmdata then return raw_slot_of_name (font_id, glyphname) end - local resources = tfmdata.resources if not resources then return false end - local unicodes = resources.unicodes if not unicodes then return false end - - local unicode = unicodes [glyphname] - if unicode then - if type (unicode) == "number" then - return unicode - else - return unicode [1] --- for multiple components + local hbdata = tfmdata.hb + if hbdata then + local hbshared = hbdata.shared + local nominals = hbshared.nominals + local hbfont = hbshared.font + + local gid = hbfont:get_glyph_from_name(glyphname) + if gid ~= nil then + return nominals[gid] or gid + hbshared.gid_offset + end + else + local resources = tfmdata.resources if not resources then return false end + local unicodes = resources.unicodes if not unicodes then return false end + + local unicode = unicodes [glyphname] + if unicode then + if type (unicode) == "number" then + return unicode + else + return unicode [1] --- for multiple components + end end end return false @@ -412,6 +439,11 @@ local function get_features(tfmdata) return features end +local function get_hbface(tfmdata) + if not tfmdata.hb then return end + return tfmdata.hbshared.face +end + --[[doc-- This function, modeled after “check_script()” from fontspec, returns true if in the given font, the script “asked_script” is accounted for in at @@ -429,9 +461,22 @@ function aux.provides_script(font_id, asked_script) return false end asked_script = stringlower(asked_script) - if font_id and font_id > 0 then - local tfmdata = identifiers[font_id] - if not tfmdata then return false end + local tfmdata = identifiers[font_id] + if not tfmdata then + logreport ("log", 0, "aux", "no font with id %d", font_id) + return false + end + local hbface = get_hbface(tfmdata) + if hbface then + local script = harf.Tag.new(asked_script == "dflt" and "DFLT" + or asked_script) + for _, tag in next, { GSUBtag, GPOStag } do + if hbface:ot_layout_find_script(tag, script) then + return true + end + end + return false + else local features = get_features (tfmdata) if features == false then logreport ("log", 1, "aux", "font no %d lacks a features table", font_id) @@ -452,7 +497,6 @@ function aux.provides_script(font_id, asked_script) "font no %d (%s) defines no feature for script %s", font_id, fontname, asked_script) end - logreport ("log", 0, "aux", "no font with id %d", font_id) return false end @@ -477,8 +521,30 @@ function aux.provides_language(font_id, asked_script, asked_language) return false end asked_script = stringlower(asked_script) - asked_language = stringlower(asked_language) - if font_id and font_id > 0 then + local tfmdata = identifiers[font_id] + if not tfmdata then + logreport ("log", 0, "aux", "no font with id %d", font_id) + return false + end + local hbface = get_hbface(tfmdata) + if hbface then + asked_language = stringupper(asked_language) + if asked_language == "DFLT" then + return aux.provides_script(font_id, asked_script) + end + local script = harf.Tag.new(asked_script == "dflt" and "DFLT" + or asked_script) + local language = harf.Tag.new(asked_language == "DFLT" and "dflt" + or asked_language) + for _, tag in next, { GSUBtag, GPOStag } do + local _, script_idx = hbface:ot_layout_find_script(tag, script) + if hbface:ot_layout_find_language(tag, script_idx, language) then + return true + end + end + return false + else + asked_language = stringlower(asked_language) local tfmdata = identifiers[font_id] if not tfmdata then return false end local features = get_features (tfmdata) @@ -504,9 +570,8 @@ function aux.provides_language(font_id, asked_script, asked_language) "font no %d (%s) defines no feature " .. "for script %s with language %s", font_id, fontname, asked_script, asked_language) + return false end - logreport ("log", 0, "aux", "no font with id %d", font_id) - return false end --[[doc-- @@ -558,12 +623,32 @@ function aux.provides_feature(font_id, asked_script, return false end asked_script = stringlower(asked_script) - asked_language = stringlower(asked_language) asked_feature = lpegmatch(strip_garbage, asked_feature) - if font_id > 0 then - local tfmdata = identifiers[font_id] - if not tfmdata then return false end + local tfmdata = identifiers[font_id] + if not tfmdata then + logreport ("log", 0, "aux", "no font with id %d", font_id) + return false + end + local hbface = get_hbface(tfmdata) + if hbface then + asked_language = stringupper(asked_language) + local script = harf.Tag.new(asked_script == "dflt" and "DFLT" + or asked_script) + local language = harf.Tag.new(asked_language == "DFLT" and "dflt" + or asked_language) + local feature = harf.Tag.new(feature) + + for _, tag in next, { GSUBtag, GPOStag } do + local _, script_idx = hbface:ot_layout_find_script(tag, script) + local _, language_idx = hbface:ot_layout_find_language(tag, script_idx, language) + if hbface:ot_layout_find_feature(tag, script_idx, language_idx, feature) then + return true + end + end + return false + else + asked_language = stringlower(asked_language) local features = get_features (tfmdata) if features == false then logreport ("log", 1, "aux", "font no %d lacks a features table", font_id) @@ -588,8 +673,6 @@ function aux.provides_feature(font_id, asked_script, "font no %d (%s) does not define feature %s for script %s with language %s", font_id, fontname, asked_feature, asked_script, asked_language) end - logreport ("log", 0, "aux", "no font with id %d", font_id) - return false end ----------------------------------------------------------------------- diff --git a/Master/texmf-dist/tex/luatex/luaotfload/luaotfload-colors.lua b/Master/texmf-dist/tex/luatex/luaotfload/luaotfload-colors.lua index fdae0c4450c..ae78130b4f8 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.00", --TAGVERSION - date = "2019-09-13", --TAGDATE + version = "3.1", --TAGVERSION + date = "2019-11-04", --TAGDATE description = "luaotfload submodule / color", license = "GPL v2.0", author = "Khaled Hosny, Elie Roux, Philipp Gesang, Dohyun Kim, David Carlisle", @@ -405,6 +405,7 @@ return function () initializers = { base = setcolor, node = setcolor, + plug = setcolor, } } return true diff --git a/Master/texmf-dist/tex/luatex/luaotfload/luaotfload-configuration.lua b/Master/texmf-dist/tex/luatex/luaotfload/luaotfload-configuration.lua index fc30cc8343a..e9b818df2d8 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.00", --TAGVERSION - date = "2019-09-13", --TAGDATE + version = "3.1", --TAGVERSION + date = "2019-11-04", --TAGDATE description = "luaotfload submodule / config file reader", license = "GPL v2.0" } @@ -62,7 +62,7 @@ local filejoin = file.join local filereplacesuffix = file.replacesuffix local logreport = print -- overloaded later -local getwritablepath = caches.getwritablepath +local getwritablepath = luaotfload.fontloader.caches.getwritablepath local config_parser -- set later during init @@ -382,7 +382,7 @@ local set_default_features = function () global = { }, defaults = { }, } - current_features = luaotfload.features + local current_features = luaotfload.features for var, val in next, default_features do if var == "global" then current_features.global = val diff --git a/Master/texmf-dist/tex/luatex/luaotfload/luaotfload-database.lua b/Master/texmf-dist/tex/luatex/luaotfload/luaotfload-database.lua index 06106189056..10a0853c890 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.00", --TAGVERSION - date = "2019-09-13", --TAGDATE + version = "3.1", --TAGVERSION + date = "2019-11-04", --TAGDATE description = "luaotfload submodule / database", license = "GPL v2.0", author = "Khaled Hosny, Elie Roux, Philipp Gesang, Marcel Krüger", @@ -148,7 +148,6 @@ local gzipload = gzip.load local gzipsave = gzip.save local iolines = io.lines local ioopen = io.open -local iopopen = io.popen local kpseexpand_path = kpse.expand_path local kpsefind_file = kpse.find_file local kpselookup = kpse.lookup @@ -168,13 +167,14 @@ local stringgmatch = string.gmatch local stringgsub = string.gsub local stringlower = string.lower local stringsub = string.sub -local stringupper = string.upper local tableconcat = table.concat local tablesort = table.sort local utf8len = utf8.len local utf8offset = utf8.offset --- these come from Lualibs/Context +local context_environment = luaotfload.fontloader +local caches = context_environment.caches local filebasename = file.basename local filecollapsepath = file.collapsepath or file.collapse_path local filedirname = file.dirname @@ -198,9 +198,9 @@ local tablecontains = table.contains local tablecopy = table.copy local tablefastcopy = table.fastcopy local tabletofile = table.tofile -local tabletohash = table.tohash local tableserialize = table.serialize local names = fonts and fonts.names or { } +local resolversfindfile = context_environment.resolvers.findfile --- some of our own local unicode = require'luaotfload-unicode' @@ -736,7 +736,7 @@ lookup_font_file = function (filename) if not found then local type = file.suffix(filename) if type ~= "" then - found = resolvers.findfile(filename, type) + found = resolversfindfile(filename, type) end end @@ -746,7 +746,7 @@ lookup_font_file = function (filename) for i=1, #type1_metrics do local format = type1_metrics[i] - if resolvers.findfile(filename, format) then + if resolversfindfile(filename, format) then return file.addsuffix(filename, format), format, true end end @@ -785,7 +785,7 @@ local get_font_file = function (index) end local basename = entry.basename if entry.location == "texmf" then - local fullname = resolvers.findfile(basename, entry.format) + local fullname = resolversfindfile(basename, entry.format) if fullname then return true, fullname, entry.subfont end @@ -809,7 +809,7 @@ local verify_font_file = function (basename) if path and lfsisfile(path) then return true end - if resolvers.findfile(basename) then + if resolversfindfile(basename) then return true end return false @@ -2125,9 +2125,8 @@ do return end - if splitcomma == nil then - splitcomma = luaotfload.parsers and luaotfload.parsers.splitcomma - end + local splitcomma = luaotfload.parsers and luaotfload.parsers.splitcomma + if stringsub (formats, 1, 1) == "+" then -- add formats = lpegmatch (splitcomma, stringsub (formats, 2)) if formats then @@ -2281,7 +2280,14 @@ local truncate_string = function (str, restrict) local tw = config.luaotfload.misc.termwidth local wd = tw - restrict local len = utf8len (str) - if wd - len < 0 then + if not len then + -- str is not valid UTF-8... We will assume a 8-bit + -- encoding and forward it verbatim to the output. + len = #str + if wd - len < 0 then + str = ".." .. stringsub(str, len - wd + 2) + end + elseif wd - len < 0 then --- combined length exceeds terminal, str = ".." .. stringsub(str, utf8offset(str, - wd + 2)) end @@ -3098,6 +3104,39 @@ end --[[doc-- + Get the subfont index corresponding to a given psname in a + font collection + +--doc]]-- + +local function lookup_subfont_index(filepath, psname) + assert(name_index) + -- if not name_index then name_index = load_names () end + local filestatus = name_index.status[filepath] + local mappings = name_index.mappings + if filestatus then + for subfont, idx in next, filestatus.index do + if mappings[idx].psname == psname then + return subfont or 1 + end + end + end + + -- If that didn't work, we do a manual search + psname = sanitize_fontname(psname) + local err, info = read_font_file (filepath) + if #info == 0 then return 1 end + for i = 1, #info do + for _, names in next, info[i].platformnames do + if psname == sanitize_fontname(names.postscriptname) then + return i + end + end + end +end + +--[[doc-- + collect_font_filenames -- Scan the three search path categories for font files. This constitutes the first pass of the update mode. @@ -3707,8 +3746,6 @@ end --- PHG: we need to investigate these, maybe they’re useful as early --- hooks -local ignoredfile = function () return false end - local reportmissingbase = function () logreport ("info", 0, "db", --> bug‽ "Font name database not found but expected by fontloader.") @@ -3737,7 +3774,7 @@ local resolve = function (name, subfont) end local api = { - ignoredfile = ignoredfile, + ignoredfile = function() return false end, reportmissingbase = reportmissingbase, reportmissingname = reportmissingname, getfilename = getfilename, @@ -3770,6 +3807,7 @@ local export = { count_font_files = count_font_files, nth_font_filename = nth_font_filename, font_slice = font_slice, + lookup_subfont_index = lookup_subfont_index, --- font cache purge_cache = purge_cache, erase_cache = erase_cache, diff --git a/Master/texmf-dist/tex/luatex/luaotfload/luaotfload-diagnostics.lua b/Master/texmf-dist/tex/luatex/luaotfload/luaotfload-diagnostics.lua index b38c1add0d2..1dc24ba6ee7 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.00", --TAGVERSION - date = "2019-09-13", --TAGDATE + version = "3.1", --TAGVERSION + date = "2019-11-04", --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 bd2237f0869..8d512499764 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.00", --TAGVERSION - date = "2019-09-13", --TAGDATE + version = "3.1", --TAGVERSION + date = "2019-11-04", --TAGDATE description = "luaotfload submodule / color", license = "GPL v2.0", author = "Marcel Krüger" diff --git a/Master/texmf-dist/tex/luatex/luaotfload/luaotfload-features.lua b/Master/texmf-dist/tex/luatex/luaotfload/luaotfload-features.lua index 3901d940dd8..bf56c4e3d14 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.00", --TAGVERSION - date = "2019-09-13", --TAGDATE + version = "3.1", --TAGVERSION + date = "2019-11-04", --TAGDATE description = "luaotfload submodule / features", license = "GPL v2.0", author = "Hans Hagen, Khaled Hosny, Elie Roux, Philipp Gesang, Marcel Krüger", @@ -26,6 +26,7 @@ local lpeg = require "lpeg" local lpegmatch = lpeg.match local P = lpeg.P local R = lpeg.R +local S = lpeg.S local C = lpeg.C local table = table @@ -338,10 +339,9 @@ end local extract_subfont do local eof = P(-1) - local digit = R"09" --- Theoretically a valid subfont address can be up to ten - --- digits long. - local sub_expr = P"(" * C(digit^1) * P")" * eof + --- digits long. Additionally we allow names + local sub_expr = P"(" * C((1 - S"()")^1) * P")" * eof local full_path = C(P(1 - sub_expr)^1) extract_subfont = full_path * sub_expr end @@ -371,7 +371,7 @@ local handle_request = function (specification) local fullpath, sub = lpegmatch(extract_subfont, specification.specification) if fullpath and sub then - specification.sub = tonumber(sub) + specification.sub = tonumber(sub) or sub specification.name = fullpath else specification.name = specification.specification @@ -428,12 +428,7 @@ local handle_request = function (specification) --- investigated it any further (luatex-fonts-ext), so it will --- just stay here. features.normal = normalize (request.features) - local subfont = tonumber (request.sub) - if subfont and subfont >= 0 then - specification.sub = subfont + 1 - else - specification.sub = false - end + specification.sub = request.sub or specification.sub or false if request.features and request.features.mode and fonts.readers[request.features.mode] then @@ -572,8 +567,8 @@ local autofeatures = { local add_auto_features = function () local nfeats = #autofeatures - logreport ("both", 5, "features", - "auto-installing %d feature definitions", nfeats) + report ("both", 5, "features", + "auto-installing %d feature definitions", nfeats) for i = 1, nfeats do local name, spec, desc = unpack (autofeatures [i]) spec.description = desc @@ -582,12 +577,10 @@ local add_auto_features = function () end return function () - logreport = luaotfload.log.report - if not fonts and fonts.handlers then - logreport ("log", 0, "features", - "OTF mechanisms missing -- did you forget to \z - load a font loader?") + report ("log", 0, "features", + "OTF mechanisms missing -- did you forget to \z + load a font loader?") return false end add_auto_features () diff --git a/Master/texmf-dist/tex/luatex/luaotfload/luaotfload-filelist.lua b/Master/texmf-dist/tex/luatex/luaotfload/luaotfload-filelist.lua index ade50b43166..24868eb3154 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.00", --TAGVERSION - date = "2019-09-13", --TAGDATE + version = "3.1", --TAGVERSION + date = "2019-11-04", --TAGDATE description = "luaotfload submodule / filelist", license = "GPL v2.0" } @@ -248,11 +248,14 @@ luaotfload.filelist.data = { name = "letterspace" ,kind = kind_library, ext =".lua", gitdir=gitdirsrc, texdir=texdirtex, gitpref = "luaotfload-" }, { name = "embolden" ,kind = kind_library, ext =".lua", gitdir=gitdirsrc, texdir=texdirtex, gitpref = "luaotfload-" }, { name = "notdef" ,kind = kind_library, ext =".lua", gitdir=gitdirsrc, texdir=texdirtex, gitpref = "luaotfload-" }, + { name = "harf-define" ,kind = kind_library, ext =".lua", gitdir=gitdirsrc, texdir=texdirtex, gitpref = "luaotfload-" }, + { 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 = "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-" }, + { name = "tounicode" ,kind = kind_library, ext =".lua", gitdir=gitdirsrc, texdir=texdirtex, gitpref = "luaotfload-" }, { name = "characters" ,kind = kind_generated, ext =".lua", gitdir=gitdirgen, texdir=texdirtex, gitpref = "luaotfload-", script="mkcharacter" }, { name = "glyphlist" ,kind = kind_generated, ext =".lua", gitdir=gitdirgen, texdir=texdirtex, gitpref = "luaotfload-", script="mkglyphlist" }, diff --git a/Master/texmf-dist/tex/luatex/luaotfload/luaotfload-glyphlist.lua b/Master/texmf-dist/tex/luatex/luaotfload/luaotfload-glyphlist.lua index 1ba46ab0d76..fe655149ada 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.00", --TAGVERSION - date = "2019-09-13", --TAGDATE + version = "3.1", --TAGVERSION + date = "2019-11-04", --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 new file mode 100644 index 00000000000..e8154cb719d --- /dev/null +++ b/Master/texmf-dist/tex/luatex/luaotfload/luaotfload-harf-define.lua @@ -0,0 +1,394 @@ +----------------------------------------------------------------------- +-- FILE: luaotfload-harf-define.lua +-- DESCRIPTION: part of luaotfload / HarfBuzz / font definition +----------------------------------------------------------------------- +do -- block to avoid to many local variables error + local ProvidesLuaModule = { + name = "luaotfload-harf-define", + version = "3.1", --TAGVERSION + date = "2019-11-04", --TAGDATE + description = "luaotfload submodule / database", + license = "GPL v2.0", + author = "Khaled Hosny, Marcel Krüger", + copyright = "Luaotfload Development Team", + } + + if luatexbase and luatexbase.provides_module then + luatexbase.provides_module (ProvidesLuaModule) + end +end + +local stringlower = string.lower +local stringupper = string.upper +local gsub = string.gsub + +local hb = luaotfload.harfbuzz + +local hbfonts = {} + +local cfftag = hb.Tag.new("CFF ") +local cff2tag = hb.Tag.new("CFF2") +local os2tag = hb.Tag.new("OS/2") +local posttag = hb.Tag.new("post") +local glyftag = hb.Tag.new("glyf") + +local containers = luaotfload.fontloader.containers +local hbcacheversion = 1.0 +local facecache = containers.define("fonts", "hb", hbcacheversion, true) + +local function loadfont(spec) + local path, sub = spec.resolved, spec.sub or 1 + + local key = string.format("%s:%d", gsub(path, "[/\\]", ":"), sub) + + local attributes = lfs.attributes(path) + local size, date = attributes.size or 0, attributes.modification or 0 + + local cached = containers.read(facecache, key) + local iscached = cached and cached.date == date and cached.size == size + + local hbface = iscached and cached.face or hb.Face.new(path, sub - 1) + local tags = hbface and hbface:get_table_tags() + -- If the face has no table tags then it isn’t a valid SFNT font that + -- HarfBuzz can handle. + if not tags then return end + local hbfont = iscached and cached.font or hb.Font.new(hbface) + + if not iscached then + local upem = hbface:get_upem() + + -- The engine seems to use the font type to tell whether there is a CFF + -- table or not, so we check for that here. + local fonttype = nil + local hasos2 = false + local haspost = false + for i = 1, #tags do + local tag = tags[i] + if tag == cfftag or tag == cff2tag then + fonttype = "opentype" + elseif tag == glyftag then + fonttype = "truetype" + elseif tag == os2tag then + hasos2 = true + elseif tag == posttag then + haspost = true + end + end + + local fontextents = hbfont:get_h_extents() + local ascender = fontextents and fontextents.ascender or upem * .8 + local descender = fontextents and fontextents.descender or upem * .2 + + local gid = hbfont:get_nominal_glyph(0x0020) + local space = gid and hbfont:get_glyph_h_advance(gid) or upem / 2 + + local slant = 0 + if haspost then + local post = hbface:get_table(posttag) + local length = post:get_length() + local data = post:get_data() + if length >= 32 and string.unpack(">i4", data) <= 0x00030000 then + local italicangle = string.unpack(">i4", data, 5) / 2^16 + if italicangle ~= 0 then + slant = -math.tan(italicangle * math.pi / 180) * 65536.0 + end + end + end + + -- Load glyph metrics for all glyphs in the font. We used to do this on + -- demand to make loading fonts faster, but hit many limitations inside + -- the engine (mainly with shared backend fonts, where the engine would + -- assume all fonts it decides to share load the same set of glyphs). + -- + -- Getting glyph advances is fast enough, but glyph extents are slower + -- especially in CFF fonts. We might want to have an option to ignore exact + -- glyph extents and use font ascender and descender if this proved to be + -- too slow. + local glyphcount = hbface:get_glyph_count() + local glyphs = {} + for gid = 0, glyphcount - 1 do + local width = hbfont:get_glyph_h_advance(gid) + local height, depth, italic = nil, nil, nil + local extents = hbfont:get_glyph_extents(gid) + if extents then + height = extents.y_bearing + depth = extents.y_bearing + extents.height + if extents.x_bearing < 0 then + italic = -extents.x_bearing + end + end + glyphs[gid] = { + width = width, + height = height or ascender, + depth = -(depth or descender), + italic = italic or 0, + } + end + + local unicodes = hbface:collect_unicodes() + local characters = {} + local nominals = {} + for _, uni in next, unicodes do + local glyph = hbfont:get_nominal_glyph(uni) + if glyph then + characters[uni] = glyph + nominals[glyph] = uni + end + end + + local xheight, capheight = 0, 0 + if hasos2 then + local os2 = hbface:get_table(os2tag) + local length = os2:get_length() + local data = os2:get_data() + if length >= 96 and string.unpack(">H", data) > 1 then + -- We don’t need much of the table, so we read from hard-coded offsets. + xheight = string.unpack(">H", data, 87) + capheight = string.unpack(">H", data, 89) + end + end + + if xheight == 0 then + local gid = characters[120] -- x + if gid then + xheight = glyphs[gid].height + else + xheight = ascender / 2 + end + end + + if capheight == 0 then + local gid = characters[88] -- X + if gid then + capheight = glyphs[gid].height + else + capheight = ascender + end + end + + cached = { + date = date, + size = size, + gid_offset = 0x120000, + upem = upem, + fonttype = fonttype, + space = space, + xheight = xheight, + capheight = capheight, + slant = slant, + glyphs = glyphs, + nominals = nominals, + unicodes = characters, + psname = hbface:get_name(hb.ot.NAME_ID_POSTSCRIPT_NAME), + fullname = hbface:get_name(hb.ot.NAME_ID_FULL_NAME), + haspng = hbface:ot_color_has_png(), + loaded = {}, -- Cached loaded glyph data. + } + + containers.write(facecache, key, cached) + end + cached.face = hbface + cached.font = hbfont + return cached +end + +-- Drop illegal characters from PS Name, per the spec +-- https://docs.microsoft.com/en-us/typography/opentype/spec/name#nid6 +local function sanitize(psname) + return psname:gsub('[][\0-\32\127-\255(){}<>/%%]', '-') +end + +-- Ligatures. The value is a character "ligature" table as described in the +-- manual. +local tlig ={ + [0x2013] = { [0x002D] = { char = 0x2014 } }, -- [---] + [0x002D] = { [0x002D] = { char = 0x2013 } }, -- [--] + [0x0060] = { [0x0060] = { char = 0x201C } }, -- [``] + [0x0027] = { [0x0027] = { char = 0x201D } }, -- [''] + [0x0021] = { [0x0060] = { char = 0x00A1 } }, -- [!`] + [0x003F] = { [0x0060] = { char = 0x00BF } }, -- [?`] + [0x002C] = { [0x002C] = { char = 0x201E } }, -- [,,] + [0x003C] = { [0x003C] = { char = 0x00AB } }, -- [<<] + [0x003E] = { [0x003E] = { char = 0x00BB } }, -- [>>] +} + +local function scalefont(data, spec) + local size = spec.size + local features = 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 + local space = data.space + local gid_offset = data.gid_offset + + if size < 0 then + size = -655.36 * size + end + + -- We shape in font units (at UPEM) and then scale output with the desired + -- sfont size. + local scale = size / upem + hbfont:set_scale(upem, upem) + + -- Populate font’s characters table. + local glyphs = data.glyphs + local characters = {} + for gid, glyph in next, glyphs do + characters[gid_offset + gid] = { + index = gid, + width = glyph.width * scale, + height = glyph.height * scale, + depth = glyph.depth * scale, + italic = glyph.italic * scale, + } + end + + local unicodes = data.unicodes + for uni, gid in next, unicodes do + characters[uni] = characters[gid_offset + gid] + end + + -- Select font palette, we support `palette=index` option, and load the first + -- one otherwise. + local paletteidx = tonumber(features.palette or features.colr) or 1 + + -- Load CPAL palette from the font. + local palette = nil + if hbface:ot_color_has_palettes() and hbface:ot_color_has_layers() then + local count = hbface:ot_color_palette_get_count() + if paletteidx <= count then + palette = hbface:ot_color_palette_get_colors(paletteidx) + end + end + + local letterspace = 0 + if features.letterspace then + letterspace = tonumber(features.letterspace) / 100 * upem + elseif features.kernfactor then + letterspace = tonumber(features.kernfactor) * upem + end + space = space + letterspace + + local slantfactor = nil + if features.slant then + slantfactor = tonumber(features.slant) * 1000 + end + + local mode = nil + local width = nil + if features.embolden then + mode = 2 + -- The multiplication by 7200.0/7227 is to undo the opposite conversion + -- the engine is doing and make the final number written in the PDF file + -- match XeTeX’s. + width = (size * tonumber(features.embolden) / 6553.6) * (7200.0/7227) + end + + local hscale = upem + local extendfactor = nil + if features.extend then + extendfactor = tonumber(features.extend) * 1000 + hscale = hscale * tonumber(features.extend) + end + + local vscale = upem + local squeezefactor = nil + if features.squeeze then + squeezefactor = tonumber(features.squeeze) * 1000 + vscale = vscale * tonumber(features.squeeze) + end + + if features.tlig then + for char in next, characters do + local ligatures = tlig[char] + if ligatures then + characters[char].ligatures = ligatures + end + end + end + + local tfmdata = { + name = spec.specification, + filename = spec.resolved, + subfont = spec.sub or 1, + designsize = size, + psname = sanitize(data.psname), + fullname = data.fullname, + index = spec.index, + size = size, + units_per_em = upem, + embedding = "subset", + tounicode = 1, + nomath = true, + format = data.fonttype, + slant = slantfactor, + mode = mode, + width = width, + extend = extendfactor, + squeeze = squeezefactor, + characters = characters, + parameters = { + slant = data.slant, + space = space * scale, + space_stretch = space * scale / 2, + space_shrink = space * scale / 3, + x_height = data.xheight * scale, + quad = size, + extra_space = space * scale / 3, + [8] = data.capheight * scale, -- for XeTeX compatibility. + }, + hb = { + scale = scale, + spec = spec, + palette = palette, + shared = data, + letterspace = letterspace, + hscale = hscale, + vscale = vscale, + }, + specification = spec, + shared = {}, + properties = {}, + } + tfmdata.shared.processes = fonts.handlers.otf.setfeatures(tfmdata, features) + return tfmdata +end + +-- Register a reader for `harf` mode (`mode=harf` font option) so that we only +-- load fonts when explicitly requested. Fonts we load will be shaped by the +-- harf plugin in luaotfload-harf-plug. +fonts.readers.harf = function(spec) + if not spec.resolved then return end + local rawfeatures = spec.features.raw + local hb_features = {} + spec.hb_features = hb_features + + if rawfeatures.language then + local language = stringupper(rawfeatures.language) + spec.language = hb.Language.new(language == "DFLT" and "dflt" + or language) + end + if rawfeatures.script then + local script = stringlower(rawfeatures.script) + spec.script = hb.Script.new(script == "dflt" and "DFLT" + or script) + end + for key, val in next, rawfeatures do + if key:len() == 4 then + -- 4-letter options are likely font features, but not always, so we do + -- some checks below. Other options will be queried + -- from spec.features.normal. + if val == true or val == false then + val = (val and '+' or '-')..key + hb_features[#hb_features + 1] = hb.Feature.new(val) + elseif tonumber(val) then + val = '+'..key..'='..tonumber(val) - 1 + hb_features[#hb_features + 1] = hb.Feature.new(val) + end + end + end + return scalefont(loadfont(spec), spec) +end diff --git a/Master/texmf-dist/tex/luatex/luaotfload/luaotfload-harf-plug.lua b/Master/texmf-dist/tex/luatex/luaotfload/luaotfload-harf-plug.lua new file mode 100644 index 00000000000..123a1c4563e --- /dev/null +++ b/Master/texmf-dist/tex/luatex/luaotfload/luaotfload-harf-plug.lua @@ -0,0 +1,983 @@ +----------------------------------------------------------------------- +-- FILE: luaotfload-harf-plug.lua +-- DESCRIPTION: part of luaotfload / HarfBuzz / fontloader plugin +----------------------------------------------------------------------- +do -- block to avoid to many local variables error + local ProvidesLuaModule = { + name = "luaotfload-harf-plug", + version = "3.1", --TAGVERSION + date = "2019-11-04", --TAGDATE + description = "luaotfload submodule / database", + license = "GPL v2.0", + author = "Khaled Hosny, Marcel Krüger", + copyright = "Luaotfload Development Team", + } + + if luatexbase and luatexbase.provides_module then + luatexbase.provides_module (ProvidesLuaModule) + end +end + +local hb = luaotfload.harfbuzz + +local assert = assert +local next = next +local tonumber = tonumber +local type = type +local format = string.format +local open = io.open +local tableinsert = table.insert +local tableremove = table.remove +local ostmpname = os.tmpname +local osremove = os.remove + +local direct = node.direct +local tonode = direct.tonode +local todirect = direct.todirect +local traverse = direct.traverse +local insertbefore = direct.insert_before +local insertafter = direct.insert_after +local protectglyph = direct.protect_glyph +local newnode = direct.new +local freenode = direct.free +local copynode = direct.copy +local removenode = direct.remove +local copynodelist = direct.copy_list +local ischar = direct.is_char +local uses_font = direct.uses_font + +local getattrs = direct.getattributelist +local setattrs = direct.setattributelist +local getchar = direct.getchar +local setchar = direct.setchar +local getdir = direct.getdir +local setdir = direct.setdir +local getdisc = direct.getdisc +local setdisc = direct.setdisc +local getfont = direct.getfont +local getdata = direct.getdata +local setdata = direct.setdata +local getfont = direct.getfont +local setfont = direct.setfont +local getfield = direct.getfield +local setfield = direct.setfield +local getid = direct.getid +local getkern = direct.getkern +local setkern = direct.setkern +local getnext = direct.getnext +local setnext = direct.setnext +local getoffsets = direct.getoffsets +local setoffsets = direct.setoffsets +local getproperty = direct.getproperty +local setproperty = direct.setproperty +local getprev = direct.getprev +local setprev = direct.setprev +local getsubtype = direct.getsubtype +local setsubtype = direct.setsubtype +local getwidth = direct.getwidth +local setwidth = direct.setwidth +local is_char = direct.is_char +local tail = direct.tail + +local properties = direct.get_properties_table() + +local imgnode = img.node + +local disc_t = node.id("disc") +local glue_t = node.id("glue") +local glyph_t = node.id("glyph") +local dir_t = node.id("dir") +local kern_t = node.id("kern") +local localpar_t = node.id("local_par") +local whatsit_t = node.id("whatsit") +local pdfliteral_t = node.subtype("pdf_literal") + +local explicitdisc_t = 1 +local fontkern_t = 0 +local italiccorr_t = 3 +local regulardisc_t = 3 +local spaceskip_t = 13 + +local invalid_l = hb.Language.new() +local invalid_s = hb.Script.new() + +local dir_ltr = hb.Direction.new("ltr") +local dir_rtl = hb.Direction.new("rtl") +local fl_unsafe = hb.Buffer.GLYPH_FLAG_UNSAFE_TO_BREAK + +local startactual_p = "luaotfload_startactualtext" +local endactual_p = "luaotfload_endactualtext" + +-- "Copy" properties as done by LuaTeX: Make old properties metatable +local function copytable(old) + local new = {} + for k, v in next, old do + if type(v) == "table" then v = copytable(v) end + new[k] = v + end + setmetatable(new, getmetatable(old)) + return new +end + +-- Set and get properties. +local function setprop(n, prop, value) + local props = properties[n] + if not props then + props = {} + properties[n] = props + end + props[prop] = value +end + +local function inherit(t, base, properties) + local n = newnode(t) + setattrs(n, getattrs(base)) + if properties then + setproperty(n, setmetatable({}, {__index = properties})) + end + return n +end +-- New kern node of amount `v`, inheriting the properties/attributes of `n`. +local function newkern(v, n) + local kern = inherit(kern_t, n, getproperty(n)) + setkern(kern, v) + return kern +end + +local function insertkern(head, current, kern, rtl) + if rtl then + head = insertbefore(head, current, kern) + else + head, current = insertafter(head, current, kern) + end + return head, current +end + +-- Convert list of integers to UTF-16 hex string used in PDF. +local function to_utf16_hex(uni) + if uni < 0x10000 then + return format("%04X", uni) + else + uni = uni - 0x10000 + local hi = 0xD800 + (uni // 0x400) + local lo = 0xDC00 + (uni % 0x400) + return format("%04X%04X", hi, lo) + end +end + +local process + +-- Legacy TeX Input Method Disguised as Font Ligatures hack. +-- +-- Single replacements, keyed by character to replace. Handled separately +-- because TeX ligaturing mechanism does not support one-to-one replacements. +local trep = { + [0x0022] = 0x201D, -- ["] + [0x0027] = 0x2019, -- ['] + [0x0060] = 0x2018, -- [`] +} + +local function itemize(head, fontid, direction) + local fontdata = font.getfont(fontid) + local hbdata = fontdata and fontdata.hb + local spec = fontdata and fontdata.specification + local options = spec and spec.features.raw + local texlig = options and options.tlig + + local runs, codes = {}, {} + local dirstack = {} + local currdir = direction or "TLT" + local lastskip, lastdir = true + local lastrun = {} + + for n, id, subtype in direct.traverse(head) do + local code = 0xFFFC -- OBJECT REPLACEMENT CHARACTER + local skip = false + + if id == glyph_t then + if is_char(n) and getfont(n) == fontid then + code = getchar(n) + else + skip = true + end + elseif id == glue_t and subtype == spaceskip_t then + code = 0x0020 -- SPACE + skip = lastskip + elseif id == disc_t then + if uses_font(n, fontid) then + code = 0x00AD -- SOFT HYPHEN + else + skip = true + end + elseif id == dir_t then + local dir = getdir(n) + if dir:sub(1, 1) == "+" then + -- Push the current direction to the stack. + tableinsert(dirstack, currdir) + currdir = dir:sub(2) + else + assert(currdir == dir:sub(2)) + -- Pop the last direction from the stack. + currdir = tableremove(dirstack) + end + skip = lastskip + elseif id == localpar_t then + currdir = getdir(n) + skip = lastskip + end + + if not skip and texlig then + local replacement = trep[code] + if replacement then + code = replacement + end + end + + codes[#codes + 1] = code + + if lastdir ~= currdir or lastskip ~= skip then + lastrun.after = n + lastrun = { + start = #codes, + len = 1, + font = fontid, + dir = currdir == "TRT" and dir_rtl or dir_ltr, + skip = skip, + codes = codes, + } + runs[#runs + 1] = lastrun + lastdir, lastskip = currdir, skip + else + lastrun.len = lastrun.len + 1 + end + end + + return runs +end + + +-- Check if it is not safe to break before this glyph. +local function unsafetobreak(glyph) + return glyph + and glyph.flags + and glyph.flags & fl_unsafe +end + +local shape + +-- Make s a sub run, used by discretionary nodes. +local function makesub(run, codes, nodelist) + local subrun = { + start = 1, + len = #codes, + font = run.font, + dir = run.dir, + fordisc = true, + node = nodelist, + codes = codes, + } + local glyphs + if nodelist == 0 then -- FIXME: This shouldn't happen + nodelist = nil + end + nodelist, glyphs = shape(nodelist, nodelist, subrun) + return { glyphs = glyphs, run = subrun, head = nodelist } +end + +local function printnodes(label, head, after) + after = tonode(after) + for n in node.traverse(tonode(head)) do + if n == after then return end + print(label, n, n.font or '', n.char or '') + local pre, post, rep = getdisc(todirect(n)) + if pre then + printnodes(label .. '<', pre) + end + if post then + printnodes(label .. '>', post) + end + if rep then + printnodes(label .. '=', rep) + end + end +end +-- Main shaping function that calls HarfBuzz, and does some post-processing of +-- the output. +function shape(head, node, run) + local codes = run.codes + local offset = run.start + local nodeindex = offset + run.start = offset + local len = run.len + local fontid = run.font + local dir = run.dir + local fordisc = run.fordisc + local cluster = offset - 2 + + local fontdata = font.getfont(fontid) + local hbdata = fontdata.hb + local spec = hbdata.spec + local features = spec.hb_features + local options = spec.features.raw + local hbshared = hbdata.shared + local hbfont = hbshared.font + + local lang = spec.language or invalid_l + local script = spec.script or invalid_s + local shapers = options.shaper and { options.shaper } or {} + + local buf = hb.Buffer.new() + buf:set_direction(dir) + buf:set_script(script) + buf:set_language(lang) + buf:set_cluster_level(buf.CLUSTER_LEVEL_MONOTONE_CHARACTERS) + buf:add_codepoints(codes, offset - 1, len) + + local hscale = hbdata.hscale + local vscale = hbdata.vscale + hbfont:set_scale(hscale, vscale) + + if hb.shape_full(hbfont, buf, features, shapers) then + -- The engine wants the glyphs in logical order, but HarfBuzz outputs them + -- in visual order, so we reverse RTL buffers. + if dir:is_backward() then buf:reverse() end + + local glyphs = buf:get_glyphs() + + local i = 0 + while i < #glyphs do + i = i + 1 + local glyph = glyphs[i] + + -- Calculate the Unicode code points of this glyph. If cluster did not + -- change then this is a glyph inside a complex cluster and will be + -- handled with the start of its cluster. + if cluster ~= glyph.cluster then + cluster = glyph.cluster + for i = nodeindex, cluster do node = getnext(node) end + nodeindex = cluster + 1 + local hex = "" + local str = "" + local nextcluster + for j = i+1, #glyphs do + nextcluster = glyphs[j].cluster + if cluster ~= nextcluster then + glyph.nglyphs = j - i + goto NEXTCLUSTERFOUND -- break + end + end -- else -- only executed if the loop reached the end without + -- finding another cluster + nextcluster = offset + len - 1 + glyph.nglyphs = #glyphs + 1 - i + ::NEXTCLUSTERFOUND:: -- end + glyph.nextcluster = nextcluster + do + local node = node + for j = cluster,nextcluster-1 do + local id = getid(node) + if id == glyph_t or id == glue_t then + local code = codes[j + 1] + hex = hex..to_utf16_hex(code) + str = str..utf8.char(code) + end + end + glyph.tounicode = hex + glyph.string = str + end + if not fordisc then + local discindex = nil + local disc = node + for j = cluster + 1, nextcluster do + if codes[j] == 0x00AD then + discindex = j + break + end + disc = getnext(disc) + end + if discindex then + -- Discretionary found. + local startindex, stopindex = nil, nil + local startglyph, stopglyph = nil, nil + + -- Find the previous glyph that is safe to break at. + local startglyph = i + while startglyph > 1 + and codes[glyphs[startglyph - 1].cluster + 1] ~= 0x20 + and codes[glyphs[startglyph - 1].cluster + 1] ~= 0xFFFC + and unsafetobreak(glyphs[startglyph]) do + startglyph = startglyph - 1 + end + -- Get the corresponding character index. + startindex = glyphs[startglyph].cluster + 1 + + -- Find the next glyph that is safe to break at. + stopglyph = i + 1 + local lastcluster = glyphs[i].cluster + while stopglyph <= #glyphs + and codes[glyphs[stopglyph].cluster + 1] ~= 0x20 + and codes[glyphs[stopglyph].cluster + 1] ~= 0xFFFC + and (unsafetobreak(glyphs[stopglyph]) + or lastcluster == glyphs[stopglyph].cluster) do + lastcluster = glyphs[stopglyph].cluster + stopglyph = stopglyph + 1 + end + + stopindex = stopglyph <= #glyphs and glyphs[stopglyph].cluster + 1 + or offset + len + + local startnode, stopnode = node, node + for j=nodeindex - 1, startindex, -1 do + startnode = getprev(startnode) + end + for j=nodeindex + 1, stopindex do + stopnode = getnext(stopnode) + end + + glyphs[startglyph] = glyph + glyph.cluster = startindex - 1 + glyph.nextcluster = startindex + for j = stopglyph, #glyphs do + local glyph = glyphs[j] + glyph.cluster = glyph.cluster - (stopindex - startindex) + 1 + end + len = len - (stopindex - startindex) + 1 + table.move(glyphs, stopglyph, #glyphs + stopglyph - startglyph - 1, startglyph + 1) + + local subcodes, subindex = {} + do + local node = startnode + while node ~= stopnode do + if node == disc then + subindex = #subcodes + startindex = startindex + 1 + node = getnext(node) + elseif getid(node) == disc_t then + local oldnode = node + startnode, node = removenode(startnode, node) + freenode(oldnode) + tableremove(codes, startindex) + else + subcodes[#subcodes + 1] = tableremove(codes, startindex) + node = getnext(node) + end + end + end + + local pre, post, rep, lastpre, lastpost, lastrep = getdisc(disc, true) + local precodes, postcodes, repcodes = {}, {}, {} + table.move(subcodes, 1, subindex, 1, repcodes) + for n, id, subtype in traverse(rep) do + repcodes[#repcodes + 1] = getfont(n) == fontid and getchar(n) or 0xFFFC + end + table.move(subcodes, subindex + 1, #subcodes, #repcodes + 1, repcodes) + table.move(subcodes, 1, subindex, 1, precodes) + for n, id, subtype in traverse(pre) do + precodes[#precodes + 1] = getfont(n) == fontid and getchar(n) or 0xFFFC + end + for n, id, subtype in traverse(post) do + postcodes[#postcodes + 1] = getfont(n) == fontid and getchar(n) or 0xFFFC + end + table.move(subcodes, subindex + 1, #subcodes, #postcodes + 1, postcodes) + if startnode ~= disc then + local newpre = copynodelist(startnode, disc) + setnext(tail(newpre), pre) + pre = newpre + end + if post then + setnext(lastpost, copynodelist(getnext(disc), stopnode)) + else + post = copynodelist(getnext(disc), stopnode) + end + if startnode ~= disc then + local predisc = getprev(disc) + setnext(predisc, rep) + setprev(rep, predisc) + if startnode == head then + head = disc + else + local before = getprev(startnode) + setnext(before, disc) + setprev(disc, before) + end + setprev(startnode, nil) + rep = startnode + lastrep = lastrep or predisc + end + if getnext(disc) ~= stopnode then + setnext(getprev(stopnode), nil) + setprev(stopnode, disc) + setprev(getnext(disc), lastrep) + setnext(lastrep, getnext(disc)) + rep = rep or getnext(disc) + setnext(disc, stopnode) + end + glyph.replace = makesub(run, repcodes, rep) + glyph.pre = makesub(run, precodes, pre) + glyph.post = makesub(run, postcodes, post) + i = startglyph + node = disc + cluster = glyph.cluster + nodeindex = cluster + 1 + end + end + end + end + return head, glyphs, run.len - len + end + + return head, {}, 0 +end + +local function color_to_rgba(color) + local r = color.red / 255 + local g = color.green / 255 + local b = color.blue / 255 + local a = color.alpha / 255 + if a ~= 1 then + -- XXX: alpha + return format('%s %s %s rg', r, g, b) + else + return format('%s %s %s rg', r, g, b) + end +end + +-- Cache of color glyph PNG data for bookkeeping, only because I couldn’t +-- figure how to make the engine load the image from the binary data directly. +local pngcache = {} +local pngcachefiles = {} +local function cachedpng(data) + local hash = md5.sumhexa(data) + local i = pngcache[hash] + if not i then + local path = ostmpname() + pngcachefiles[#pngcachefiles + 1] = path + open(path, "wb"):write(data):close() + -- local file = open(path, "wb"):write():close() + -- file:write(data) + -- file:close() + i = img.scan{filename = path} + pngcache[hash] = i + end + return i +end + +local function get_png_glyph(gid, fontid, characters, haspng) + return gid +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" } + +-- Convert glyphs to nodes and collect font characters. +local function tonodes(head, node, run, glyphs) + local nodeindex = run.start + local dir = run.dir + local fontid = run.font + local fontdata = font.getfont(fontid) + local characters = fontdata.characters + local hbdata = fontdata.hb + local palette = hbdata.palette + local hbshared = hbdata.shared + local hbface = hbshared.face + local nominals = hbshared.nominals + local hbfont = hbshared.font + local fontglyphs = hbshared.glyphs + local gid_offset = hbshared.gid_offset + local rtl = dir:is_backward() + local lastprops + + local scale = hbdata.scale + local letterspace = hbdata.letterspace + + local haspng = hbshared.haspng + local fonttype = hbshared.fonttype + + local nextcluster + + for i, glyph in ipairs(glyphs) do + if glyph.cluster + 1 >= nodeindex then -- Reached a new cluster + nextcluster = glyph.nextcluster + assert(nextcluster) + for j = nodeindex, glyph.cluster do + local oldnode = node + head, node = removenode(head, node) + freenode(oldnode) + end + lastprops = getproperty(node) + nodeindex = glyph.cluster + 1 + elseif nextcluster + 1 == nodeindex then -- Oops, we went too far + nodeindex = nodeindex - 1 + local new = inherit(glyph_t, getprev(node), lastprops) + setfont(new, fontid) + head, node = insertbefore(head, node, new) + end + local gid = glyph.codepoint + local char = nominals[gid] or gid_offset + gid + local id = getid(node) + + if glyph.replace then + -- For discretionary the glyph itself is skipped and a discretionary node + -- is output in place of it. + local rep, pre, post = glyph.replace, glyph.pre, glyph.post + + setdisc(node, tonodes(pre.head, pre.head, pre.run, pre.glyphs), + tonodes(post.head, post.head, post.run, post.glyphs), + tonodes(rep.head, rep.head, rep.run, rep.glyphs)) + node = getnext(node) + nodeindex = nodeindex + 1 + elseif glyph.skip then + local oldnode = node + head, node = removenode(head, node) + freenode(oldnode) + nodeindex = nodeindex + 1 + else + if id == glyph_t then + local done + local fontglyph = fontglyphs[gid] + local character = characters[char] + + if not character.commands then + if palette then + local layers = fontglyph.layers + if layers == nil then + layers = hbface:ot_color_glyph_get_layers(gid) or false + fontglyph.layers = layers + end + if layers then + local cmds = {} -- Every layer will add 5 cmds + local prev_color = nil + for j = 1, #layers do + local layer = layers[j] + local layerchar = characters[gid_offset + layer.glyph] + if layerchar.height > character.height then + character.height = layerchar.height + end + if layerchar.depth > character.depth then + character.depth = layerchar.depth + end + -- color_index has a special value, 0x10000, that mean use text + -- color, we don’t check for it here explicitly since we will + -- get nil anyway. + local color = palette[layer.color_index] + cmds[5*j - 4] = (color and not prev_color) and save_cmd or nop_cmd + cmds[5*j - 3] = prev_color == color and nop_cmd or (color and {"pdf", "page", color_to_rgba(color)} or restore_cmd) + cmds[5*j - 2] = push_cmd + cmds[5*j - 1] = {"char", layer.glyph + gid_offset} + cmds[5*j] = pop_cmd + fontglyphs[layer.glyph].used = true + prev_color = color + end + cmds[#cmds + 1] = prev_color and restore_cmd + if not character.colored then + local coloredcharacter = {} + for k,v in next, character do + coloredcharacter[k] = v + end + coloredcharacter.commands = cmds + local newcharacters = {[gid + 0x130000] = coloredcharacter} + characters[gid + 0x130000] = coloredcharacter + if char ~= gid + gid_offset then + newcharacters[char] = coloredcharacter + characters[char] = coloredcharacter + character.colored = char + else + character.colored = gid + 0x130000 + end + font.addcharacters(fontid, {characters = newcharacters}) + end + char = character.colored + character = characters[char] + end + end + + if haspng then + local pngglyph = character.pngglyph + if pngglyph == nil then + local pngblob = hbfont:ot_color_glyph_get_png(gid) + if pngblob then + local glyphimg = cachedpng(pngblob:get_data()) + local pngchar = { } + for k,v in next, character do + pngchar[k] = v + end + local i = img.copy(glyphimg) + i.width = character.width + i.depth = 0 + i.height = character.height + character.depth + pngchar.commands = fonttype and { + {"push"}, {"char", gid_offset + gid}, {"pop"}, + {"down", character.depth}, {"image", i} + } or { {"down", character.depth}, {"image", i} } + if not nominals[gid] then + char = 0x130000 + gid + end + characters[char] = pngchar + pngglyph = char + font.addcharacters(fontid, {characters = {[char] = pngchar}}) + end + character.pngglyph = pngglyph + end + if pngglyph then + char = pngglyph + elseif not fonttype then + -- Color bitmap font with no glyph outlines (like Noto + -- Color Emoji) but has no bitmap for current glyph (most likely + -- `.notdef` glyph). The engine does not know how to embed such + -- fonts, so we don’t want them to reach the backend as it will cause + -- a fatal error. We use `nullfont` instead. That is a hack, but I + -- think it is good enough for now. We could make the glyph virtual + -- with empty commands suh that LuaTeX ignores it, but we still want + -- a missing glyph warning. + -- We insert the glyph node and move on, no further work is needed. + setfont(node, 0) + done = true + end + end + end + if not done then + local oldcharacter = characters[getchar(node)] + -- If the glyph index of current font character is the same as shaped + -- glyph, keep the node char unchanged. Helps with primitives that + -- take characters as input but actually work on glyphs, like + -- `\rpcode`. + if character.commands or not oldcharacter + or character.index ~= oldcharacter.index then + setchar(node, char) + end + local xoffset = (rtl and -glyph.x_offset or glyph.x_offset) * scale + local yoffset = glyph.y_offset * scale + setoffsets(node, xoffset, yoffset) + + fontglyph.used = fonttype and true + + -- The engine will use this string when printing a glyph node e.g. in + -- overfull messages, otherwise it will be trying to print our + -- invalid pseudo Unicode code points. + -- If the string is empty it means this glyph is part of a larger + -- cluster and we don’t to print anything for it as the first glyph + -- in the cluster will have the string of the whole cluster. + local props = properties[node] + if not props then + props = {} + properties[node] = props + end + props.glyph_info = glyph.string or "" + + -- Handle PDF text extraction: + -- * Find how many characters in this cluster and how many glyphs, + -- * If there is more than 0 characters + -- * One glyph: one to one or one to many mapping, can be + -- represented by font’s /ToUnicode + -- * More than one: many to one or many to many mapping, can be + -- represented by /ActualText spans. + -- * If there are zero characters, then this glyph is part of complex + -- cluster that will be covered by an /ActualText span. + local tounicode = glyph.tounicode + if tounicode then + if glyph.nglyphs == 1 + and not character.commands + and not fontglyph.tounicode then + fontglyph.tounicode = tounicode + elseif character.commands or tounicode ~= fontglyph.tounicode then + setprop(node, startactual_p, tounicode) + glyphs[i + glyph.nglyphs - 1].endactual = true + end + end + if glyph.endactual then + setprop(node, endactual_p, true) + end + local x_advance = glyph.x_advance + letterspace + local width = fontglyph.width + if width ~= x_advance then + -- The engine always uses the glyph width from the font, so we need + -- to insert a kern node if the x advance is different. + local kern = newkern((x_advance - width) * scale, node) + head, node = insertkern(head, node, kern, rtl) + end + end + elseif id == glue_t and getsubtype(node) == spaceskip_t then + -- If the glyph advance is different from the font space, then a + -- substitution or positioning was applied to the space glyph changing + -- it from the default, so reset the glue using the new advance. + -- We are intentionally not comparing with the existing glue width as + -- spacing after the period is larger by default in TeX. + local width = (glyph.x_advance + letterspace) * scale + if fontdata.parameters.space ~= width then + setwidth(node, width) + setfield(node, "stretch", width / 2) + setfield(node, "shrink", width / 3) + end + elseif id == kern_t and getsubtype(node) == italiccorr_t then + -- If this is an italic correction node and the previous node is a + -- glyph, update its kern value with the glyph’s italic correction. + local prevchar, prevfontid = ischar(getprev(node)) + if prevfontid == fontid and prevchar and prevchar > 0 then + local italic = characters[prevchar].italic + if italic then + setkern(node, italic) + end + end + end + node = getnext(node) + nodeindex = nodeindex + 1 + end + end + while node ~= run.after do + local oldnode = node + head, node = removenode(head, node) + freenode(oldnode) + end + + return head, node +end + +local function shape_run(head, current, run) + if not run.skip then + -- Font loaded with our loader and an HarfBuzz face is present, do our + -- shaping. + local fontid = run.font + local fontdata = font.getfont(fontid) + local options = fontdata.specification.features.raw + + local glyphs, offset + head, glyphs, offset = shape(head, current, run) + return offset, tonodes(head, current, run, glyphs) + else + return 0, head, run.after + end +end + +function process(head, font, direction) + local newhead, current = head, head + local runs = itemize(head, font, direction) + + local offset = 0 + for i = 1,#runs do + local run = runs[i] + run.start = run.start - offset + local new_offset + new_offset, newhead, current = shape_run(newhead, current, run) + offset = offset + new_offset + end + + return newhead or head +end + +local function pageliteral(data) + local n = newnode(whatsit_t, pdfliteral_t) + setfield(n, "mode", 1) -- page + setdata(n, data) + return n +end + +local function post_process(head) + for n in traverse(head) do + local props = properties[n] + + local startactual, endactual + if props then + startactual = rawget(props, startactual_p) + endactual = rawget(props, endactual_p) + end + + if startactual then + local actualtext = "/Span<</ActualText<FEFF"..startactual..">>>BDC" + head = insertbefore(head, n, pageliteral(actualtext)) + end + + if endactual then + head = insertafter(head, n, pageliteral("EMC")) + end + + local replace = getfield(n, "replace") + if replace then + setfield(n, "replace", post_process(replace)) + end + + local subhead = getfield(n, "head") + if subhead then + setfield(n, "head", post_process(subhead)) + end + end + return head +end + +local function post_process_nodes(head, groupcode) + return tonode(post_process(todirect(head))) +end + +local function run_cleanup() + -- Remove temporary PNG files that we created, if any. + -- FIXME: It would be nice if we wouldn't need this + for _, path in next, pngcachefiles do + osremove(path) + end +end + +local function set_tounicode() + for fontid, fontdata in font.each() do + local hbdata = fontdata.hb + if hbdata and fontid == pdf.getfontname(fontid) then + local characters = fontdata.characters + local newcharacters = {} + local hbshared = hbdata.shared + local glyphs = hbshared.glyphs + local nominals = hbshared.nominals + local gid_offset = hbshared.gid_offset + for gid = 0, #glyphs do + local glyph = glyphs[gid] + if glyph.used then + local character = characters[gid + gid_offset] + newcharacters[gid + gid_offset] = character + local unicode = nominals[gid] + if unicode then + newcharacters[unicode] = character + end + character.tounicode = glyph.tounicode or "FFFD" + character.used = true + end + end + font.addcharacters(fontid, { characters = newcharacters }) + end + end +end + +-- FIXME: Move this into generic parts of luaotfload +local utfchar = utf8.char +local function get_glyph_info(n) + n = todirect(n) + local props = properties[n] + return props and props.glyph_info or utfchar(getchar(n)):gsub('\0', '^^@') +end + +fonts.handlers.otf.registerplugin('harf', process) + +-- luatexbase does not know how to handle `wrapup_run` callback, teach it. +-- TODO: Move these into ltluatex +luatexbase.callbacktypes.wrapup_run = 1 -- simple +luatexbase.callbacktypes.glyph_info = 1 -- simple + +local base_callback_descriptions = luatexbase.callback_descriptions +local base_add_to_callback = luatexbase.add_to_callback +local base_remove_from_callback = luatexbase.remove_from_callback + +-- Remove all existing functions from given callback, insert ours, then +-- reinsert the removed ones, so ours takes a priority. +local function add_to_callback(name, func) + local saved_callbacks = {}, ff, dd + for k, v in next, base_callback_descriptions(name) do + saved_callbacks[k] = { base_remove_from_callback(name, v) } + end + base_add_to_callback(name, func, "Harf "..name.." callback") + for _, v in next, saved_callbacks do + base_add_to_callback(name, v[1], v[2]) + end +end + +add_to_callback('pre_output_filter', post_process_nodes) -- FIXME: Wrong callback, but I want to get rid of the whole function anyway +add_to_callback('wrapup_run', run_cleanup) +add_to_callback('finish_pdffile', set_tounicode) +add_to_callback('glyph_info', get_glyph_info) diff --git a/Master/texmf-dist/tex/luatex/luaotfload/luaotfload-init.lua b/Master/texmf-dist/tex/luatex/luaotfload/luaotfload-init.lua index 6a80546d436..5f7b710d9b1 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.00", --TAGVERSION - date = "2019-09-13", --TAGDATE + version = "3.1", --TAGVERSION + date = "2019-11-04", --TAGDATE description = "luaotfload submodule / initialization", license = "GPL v2.0" } @@ -78,122 +78,6 @@ local logreport --- filled in after loading the log module --doc]]-- -local init_early = function () - - local store = { } - config = config or { } --- global - config.luaotfload = config.luaotfload or { } - config.lualibs = config.lualibs or { } - config.lualibs.verbose = false - config.lualibs.prefer_merged = true - config.lualibs.load_extended = true - fonts = fonts or { } - - require "lualibs" - - if not lualibs then error "this module requires Luaotfload" end - if not luaotfload then error "this module requires Luaotfload" end - - --[[doc-- - - The logger needs to be in place prior to loading the fontloader due - to order of initialization being crucial for the logger functions - that are swapped. - - --doc]]-- - - luaotfload.loaders.luaotfload "log" - log = luaotfload.log - logreport = log.report - log.set_loglevel (default_log_level) - - logreport ("log", 4, "init", "Concealing callback.register().") - store.trapped_register = callback.register - - callback.register = function (id) - logreport ("log", 4, "init", - "Dummy callback.register() invoked on %s.", - id) - end - - --[[doc-- - - By default, the fontloader requires a number of \emphasis{private - attributes} for internal use. - These must be kept consistent with the attribute handling methods - as provided by \identifier{luatexbase}. - Our strategy is to override the function that allocates new - attributes before we initialize the font loader, making it a - wrapper around \luafunction{luatexbase.new_attribute}.\footnote{% - Many thanks, again, to Hans Hagen for making this part - configurable! - } - The attribute identifiers are prefixed “\fileent{luaotfload@}” to - avoid name clashes. - - --doc]]-- - - local new_attribute = luatexbase.new_attribute - local the_attributes = luatexbase.attributes - - attributes = attributes or { } --- this writes a global, sorry - - attributes.private = function (name) - local attr = "luaotfload@" .. name --- used to be: “otfl@” - local number = the_attributes[attr] - if not number then number = new_attribute(attr) end - return number - end - - luaotfload.loaders.fontloader "basics-gen" - - return store -end --- [init_early] - ---[[doc-- - - These next lines replicate the behavior of - \fileent{luatex-fonts.lua}. - ---doc]]-- - -local push_namespaces = function () - logreport ("log", 4, "init", "push namespace for font loader") - local normalglobal = { } - for k, v in next, _G do - normalglobal[k] = v - end - return normalglobal -end - -local pop_namespaces = function (normalglobal, - isolate, - context_environment) - if normalglobal then - local _G = _G - local mode = "non-destructive" - if isolate then mode = "destructive" end - logreport ("log", 4, "init", "pop namespace from font loader -- " .. mode) - for k, v in next, _G do - if not normalglobal[k] then - context_environment[k] = v - if isolate then - _G[k] = nil - end - end - end - for k, v in next, normalglobal do - _G[k] = v - end - -- just to be sure: - setmetatable(context_environment, _G) - else - logreport ("both", 0, "init", - "irrecoverable error during pop_namespace: no globals to restore") - os.exit () - end -end - --- below paths are relative to the texmf-context local ltx = "tex/generic/context/luatex" local ctx = { "tex/context/base/mkiv", "tex/context/base" } @@ -308,159 +192,71 @@ local load_context_modules = function (pth) end -local init_adapt = function () +local function init_main(early_hook) + config = config or { } --- global + config.luaotfload = config.luaotfload or { } + config.lualibs = config.lualibs or { } + config.lualibs.verbose = false + config.lualibs.prefer_merged = true + config.lualibs.load_extended = true + fonts = fonts or { } + + require "lualibs" - local context_environment = { } - local our_environment = push_namespaces () + if not lualibs then error "this module requires Luaotfload" end + if not luaotfload then error "this module requires Luaotfload" end --[[doc-- - The font loader requires that the attribute with index zero be - zero. We happily oblige. - (Cf. \fileent{luatex-fonts-nod.lua}.) + The logger needs to be in place prior to loading the fontloader due + to order of initialization being crucial for the logger functions + that are swapped. --doc]]-- - tex.attribute[0] = 0 - - return our_environment, context_environment - -end --- [init_adapt] - ---[[doc-- + luaotfload.loaders.luaotfload "log" + log = luaotfload.log + logreport = log.report + log.set_loglevel (default_log_level) - In Context, characters.data is where the data from char-def.lua - resides. The file is huge (>4.4 MB as of 2016) and only a stripped - down version is part of the isolated font loader. Nevertheless, we - include an excerpt generated by the mkcharacters script that contains - a subset of the fields of each character defined and some extra - metadata. + logreport ("log", 4, "init", "Concealing callback.register().") + local trapped_register = callback.register - Currently, these are (compare the mkcharacters script!) + callback.register = function (id) + logreport ("log", 4, "init", + "Dummy callback.register() invoked on %s.", + id) + end - · "direction" - · "mirror" - · "category" - · "textclass" + --[[doc-- - The directional information is required for packages like Simurgh [0] - to work correctly. In an early stage [1] it was necessary to load - further files from Context directly, including the full blown version - of char-def. Since we have no use for most of the so imported - functionality, the required parts have been isolated and are now - instated along with luaotfload-characters.lua. We can extend the set - of imported features easily should it not be enough. + By default, the fontloader requires a number of \emphasis{private + attributes} for internal use. + These must be kept consistent with the attribute handling methods + as provided by \identifier{luatexbase}. + Our strategy is to override the function that allocates new + attributes before we initialize the font loader, making it a + wrapper around \luafunction{luatexbase.new_attribute}.\footnote{% + Many thanks, again, to Hans Hagen for making this part + configurable! + } + The attribute identifiers are prefixed “\fileent{luaotfload@}” to + avoid name clashes. - [0] https://github.com/persian-tex/simurgh - [1] http://tex.stackexchange.com/a/132301/14066 + --doc]]-- ---doc]]-- + local new_attribute = luatexbase.new_attribute + local the_attributes = luatexbase.attributes ---[[--14.12.2018disable characters ---characters = characters or { } --- should be created in basics-gen ---characters.data = nil ---local chardef = "luaotfload-characters" --- ---do --- local setmetatableindex = function (t, f) --- local mt = getmetatable (t) --- if mt then --- mt.__index = f --- else --- setmetatable (t, { __index = f }) --- end --- end --- --- --- there are some special tables for each field that provide access --- --- to fields of the character table by means of a metatable --- --- local mkcharspecial = function (characters, tablename, field) --- --- local chardata = characters.data --- --- if chardata then --- local newspecial = { } --- characters [tablename] = newspecial --> e.g. “characters.data.mirrors” --- --- local idx = function (t, char) --- local c = chardata [char] --- if c then --- local m = c [field] --> e.g. “mirror” --- if m then --- t [char] = m --- return m --- end --- end --- newspecial [char] = false --- return char --- end --- --- setmetatableindex (newspecial, idx) --- end --- --- end --- --- local mkcategories = function (characters) -- different from the others --- --- local chardata = characters.data --- local categories = characters.categories or { } --- characters.categories = categories --- --- setmetatable (categories, { __index = function (t, char) --- if char then --- local c = chardata [char] --- c = c.category or char --- t [char] = c --- return c --- end --- end}) --- --- end --- --- local load_failed = false --- local chardata --> characters.data; loaded on demand --- --- local load_chardef = function () --- --- logreport ("both", 1, "aux", "Loading character metadata from %s.", chardef) --- chardata = dofile (kpse.find_file (chardef, "lua")) --- --- if chardata == nil then --- logreport ("both", 0, "aux", --- "Could not load %s; continuing with empty character table.", --- chardef) --- chardata = { } --- load_failed = true --- end --- --- characters = { } --- nuke metatable --- characters.data = chardata --- characters.classifiers = chardata.classifiers --- chardata.classifiers = nil --- --- --- institute some of the functionality from char-ini.lua --- --- mkcharspecial (characters, "mirrors", "mirror") --- mkcharspecial (characters, "directions", "direction") --- mkcharspecial (characters, "textclasses", "textclass") --- mkcategories (characters) --- --- end --- --- local charindex = function (t, k) --- if chardata == nil and load_failed ~= true then --- load_chardef () --- end --- --- return rawget (characters, k) --- end --- --- setmetatableindex (characters, charindex) --- ---end ---]] --14.12.2018disable characters - -local init_main = function () + local context_environment = luaotfload.fontloader + context_environment.attributes = { + private = function (name) + local attr = "luaotfload@" .. name --- used to be: “otfl@” + local number = the_attributes[attr] + if not number then number = new_attribute(attr) end + return number + end + } --[[doc-- @@ -473,6 +269,20 @@ local init_main = function () local load_fontloader_module = luaotfload.loaders.fontloader local ignore_module = luaotfload.loaders.ignore + load_fontloader_module "basics-gen" + + if early_hook then early_hook() end + + --[[doc-- + + The font loader requires that the attribute with index zero be + zero. We happily oblige. + (Cf. \fileent{luatex-fonts-nod.lua}.) + + --doc]]-- + + tex.attribute[0] = 0 + --[[doc-- Now that things are sorted out we can finally load the @@ -574,14 +384,14 @@ local init_main = function () logreport ("log", 0, "init", "Loading fontloader from absolute path “%s”.", fontloader) - local _void = require (fontloader) + local _void = assert (loadfile (fontloader, nil, context_environment)) () elseif kpsefind_file (fontloader) then local path = kpsefind_file (fontloader) logreport ("log", 0, "init", "Loading fontloader “%s” from kpse-resolved path “%s”.", fontloader, path) - local _void = require (path) + local _void = assert (loadfile (path, nil, context_environment)) () elseif kpsefind_file (("fontloader-%s.lua"):format(fontloader)) then logreport ("log", 0, "init", @@ -605,43 +415,12 @@ local init_main = function () logreport ("log", 0, "init", "Context OpenType loader version “%s”", fonts.handlers.otf.version) + callback.register = trapped_register + nodes = context_environment.nodes + -- setmetatable(context_environment, nil) -- Would be nice, might break the + -- fontloader end --- [init_main] -local init_cleanup = function (store) - --- reinstate all the stuff we had to move out of the way to - --- accomodate the loader - - --[[doc-- - - Here we adjust the globals created during font loader - initialization. If the second argument to - \luafunction{pop_namespaces()} is \verb|true| this will restore the - state of \luafunction{_G}, eliminating every global generated since - the last call to \luafunction{push_namespaces()}. At the moment we - see no reason to do this, and since the font loader is considered - an essential part of \identifier{luatex} as well as a very well - organized piece of code, we happily concede it the right to add to - \luafunction{_G} if needed. - - --doc]]-- - - pop_namespaces (store.our_environment, - false, - store.context_environment) - - --[[doc-- - - \subsection{Callbacks} - After the fontloader is ready we can restore the callback trap - from \identifier{luatexbase}. - - --doc]]-- - - logreport ("log", 4, "init", - "Restoring original callback.register().") - callback.register = store.trapped_register -end --- [init_cleanup] - local init_post_install_callbacks = function () --[[doc-- @@ -654,7 +433,7 @@ local init_post_install_callbacks = function () --doc]]-- -- MK Pass current text direction to simple_font_handler - local handler = nodes.simple_font_handler + local handler = luaotfload.fontloader.nodes.simple_font_handler local callback = function(head, groupcode, _, _, direction) if not direction then direction = tex.get'textdir' @@ -774,20 +553,14 @@ local init_post = function () return n end --- [init_post] -return { - early = init_early, - main = function (store) - local starttime = os.gettimeofday () - store.our_environment, store.context_environment = init_adapt () - init_main () - init_cleanup (store) - logreport ("both", 1, "init", - "fontloader loaded in %0.3f seconds", - os.gettimeofday() - starttime) - local n = init_post () - logreport ("both", 5, "init", "post hook terminated, %d actions performed", n) - return true - end -} - +return function (early_hook) + local starttime = os.gettimeofday () + init_main (early_hook) + logreport ("both", 1, "init", + "fontloader loaded in %0.3f seconds", + os.gettimeofday() - starttime) + local n = init_post () + logreport ("both", 5, "init", "post hook terminated, %d actions performed", n) + return true +end -- vim:tw=79:sw=2:ts=2:expandtab diff --git a/Master/texmf-dist/tex/luatex/luaotfload/luaotfload-letterspace.lua b/Master/texmf-dist/tex/luatex/luaotfload/luaotfload-letterspace.lua index bbd045e4f8c..a58d59ba1a5 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.00", --TAGVERSION - date = "2019-09-13", --TAGDATE + version = "3.1", --TAGVERSION + date = "2019-11-04", --TAGDATE description = "luaotfload submodule / color", license = "GPL v2.0", copyright = "PRAGMA ADE / ConTeXt Development Team", diff --git a/Master/texmf-dist/tex/luatex/luaotfload/luaotfload-loaders.lua b/Master/texmf-dist/tex/luatex/luaotfload/luaotfload-loaders.lua index 11e63c571aa..c2c2320ff8b 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.00", --TAGVERSION - date = "2019-09-13", --TAGDATE + version = "3.1", --TAGVERSION + date = "2019-11-04", --TAGDATE description = "luaotfload submodule / callback handling", license = "GPL v2.0" } @@ -27,17 +27,8 @@ if not luaotfload then error "this module requires Luaotfload" end local logreport = luaotfload.log and luaotfload.log.report or print local lua_reader = function (specification) - local fullname = specification.filename or "" - if fullname == "" then - local forced = specification.forced or "" - if forced ~= "" then - fullname = specification.name .. "." .. forced - else - fullname = specification.name - end - end - local fullname = resolvers.findfile (fullname) or "" - if fullname ~= "" then + local fullname = specification.resolved + if fullname then local loader = loadfile (fullname) loader = loader and loader () return loader and loader (specification) diff --git a/Master/texmf-dist/tex/luatex/luaotfload/luaotfload-log.lua b/Master/texmf-dist/tex/luatex/luaotfload/luaotfload-log.lua index 04012632fa6..e6bb042b4f5 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.00", --TAGVERSION - date = "2019-09-13", --TAGDATE + version = "3.1", --TAGVERSION + date = "2019-11-04", --TAGDATE description = "luaotfload submodule / logging", license = "GPL v2.0", author = "Khaled Hosny, Elie Roux, Philipp Gesang", @@ -220,16 +220,16 @@ else end end -stdout = function (writer, category, ...) +local stdout = function (writer, category, ...) local res = { module_name, "|", category, ":" } local nargs = select("#", ...) if nargs == 0 then --writeln tableconcat(res, " ") --return elseif nargs == 1 then - res[#res+1] = select(1, ...) -- around 30% faster than unpack() + res[5] = ... -- around 30% faster than unpack() else - res[#res+1] = stringformat(...) + res[5] = stringformat(...) end writer (tableconcat(res, " ")) end diff --git a/Master/texmf-dist/tex/luatex/luaotfload/luaotfload-main.lua b/Master/texmf-dist/tex/luatex/luaotfload/luaotfload-main.lua index 26bbfab5066..d17a1d9b264 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.00", --TAGVERSION - date = "2019-09-13", --TAGDATE + version = "3.1", --TAGVERSION + date = "2019-11-04", --TAGDATE description = "luaotfload entry point", author = authors, copyright = authors, @@ -142,12 +142,12 @@ local timing_info = { t_init = { }, } -local make_loader = function (prefix) +local make_loader = function (prefix, load_helper) return function (name) local t_0 = osgettimeofday () local modname = make_loader_name (prefix, name) --- We don’t want the stack info from inside, so just pcall(). - local ok, data = pcall (require, modname) + local ok, data = pcall (load_helper or require, modname) local t_end = osgettimeofday () timing_info.t_load [name] = t_end - t_0 if not ok then @@ -190,6 +190,16 @@ local dummy_loader = function (name) name) end +local context_environment = setmetatable({}, {__index = _G}) +luaotfload.fontloader = context_environment +local function context_isolated_load(name) + local fullname = kpse.find_file(name, 'lua') + if not fullname then + error(string.format('Fontloader module "%s" could not be found.', name)) + end + return assert(loadfile(fullname, nil, context_environment))(name) +end + local context_loader = function (name, path) luaotfload.log.report ("log", 3, "load", "Loading module “%s” from Context.", @@ -209,7 +219,7 @@ local context_loader = function (name, path) path) end end - local ret = require (modpath) + local ret = context_isolated_load (modpath) local t_end = osgettimeofday () timing_info.t_load [name] = t_end - t_0 @@ -228,7 +238,7 @@ local install_loaders = function () local loaders = { } local loadmodule = make_loader "luaotfload" loaders.luaotfload = loadmodule - loaders.fontloader = make_loader "fontloader" + loaders.fontloader = make_loader ("fontloader", context_isolated_load) loaders.context = context_loader loaders.ignore = dummy_loader ----loaders.plaintex = make_loader "luatex" --=> for Luatex-Plain @@ -275,15 +285,13 @@ luaotfload.main = function () local starttime = osgettimeofday () local init = loadmodule "init" --- fontloader initialization - local store = init.early () --- injects the log module too - local logreport = luaotfload.log.report + init (function () - initialize "parsers" --- fonts.conf and syntax - initialize "configuration" --- configuration options + initialize "parsers" --- fonts.conf and syntax + initialize "configuration" --- configuration options + end) - if not init.main (store) then - logreport ("log", 0, "load", "Main fontloader initialization failed.") - end + local logreport = luaotfload.log.report initialize "loaders" --- Font loading; callbacks initialize "database" --- Font management. @@ -297,11 +305,19 @@ luaotfload.main = function () end initialize "features" --- font request and feature handling + loadmodule "letterspace" --- extra character kerning loadmodule "embolden" --- fake bold loadmodule "notdef" --- missing glyph handling + local harfstatus, harfbuzz = pcall(require, 'luaharfbuzz') + if harfstatus then + luaotfload.harfbuzz = harfbuzz + loadmodule "harf-define" + loadmodule "harf-plug" + end initialize "auxiliary" --- additional high-level functionality loadmodule "multiscript" --- ... + loadmodule "tounicode" luaotfload.aux.start_rewrite_fontname () --- to be migrated to fontspec diff --git a/Master/texmf-dist/tex/luatex/luaotfload/luaotfload-multiscript.lua b/Master/texmf-dist/tex/luatex/luaotfload/luaotfload-multiscript.lua index ed3aef05c36..56d381a9118 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.00", --TAGVERSION - date = "2019-09-13", --TAGDATE + version = "3.1", --TAGVERSION + date = "2019-11-04", --TAGDATE description = "luaotfload submodule / multiscript", license = "GPL v2.0", author = "Marcel Krüger" diff --git a/Master/texmf-dist/tex/luatex/luaotfload/luaotfload-notdef.lua b/Master/texmf-dist/tex/luatex/luaotfload/luaotfload-notdef.lua index 0cc972a0e3e..53f4af8e3ae 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.00", --TAGVERSION - date = "2019-09-13", --TAGDATE + version = "3.1", --TAGVERSION + date = "2019-11-04", --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 f9fd5c919e4..4a2d6305e1c 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.00", --TAGVERSION - date = "2019-09-13", --TAGDATE + version = "3.1", --TAGVERSION + date = "2019-11-04", --TAGDATE description = "luaotfload submodule / filelist", license = "GPL v2.0" } @@ -603,7 +603,9 @@ local combolist = Ct(combodef1 * (comborowsep * combodef)^1) --- Note to self: subfonts apparently start at index 0. Tested with --- Cambria.ttc that includes “Cambria Math” at 0 and “Cambria” at 1. --- Other values cause luatex to segfault. -local subfont = P"(" * Cg((1 - S"()")^1, "sub") * P")" +local subfont = P"(" * Cg(R'09'^1 / function (s) + return tonumber(s) + 1 + end + (1 - S"()")^1, "sub") * P")" --- lookups ----------------------------------------------------------- local fontname = C((1-S":(/")^1) --- like luatex-fonts diff --git a/Master/texmf-dist/tex/luatex/luaotfload/luaotfload-resolvers.lua b/Master/texmf-dist/tex/luatex/luaotfload/luaotfload-resolvers.lua index 5146f1d20e6..97e85f0a41e 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.00", --TAGVERSION - date = "2019-09-13", --TAGDATE + version = "3.1", --TAGVERSION + date = "2019-11-04", --TAGDATE description = "luaotfload submodule / resolvers", license = "GPL v2.0" } @@ -148,11 +148,12 @@ end local tex_formats = { "tfm", "ofm" } +local resolvers_findfile = luaotfload.fontloader.resolvers.findfile local resolve_tex_format = function (specification) local name = specification.name for i=1, #tex_formats do local format = tex_formats [i] - local resolved = resolvers.findfile(name, format) + local resolved = resolvers_findfile(name, format) if resolved then return resolved, format end @@ -241,6 +242,7 @@ local function resolve_kpse (specification) end end +local lookup_subfont_index = fonts.names.lookup_subfont_index local function wrap_resolver(resolver) return function (specification) local filename, sub, forced = resolver(specification) @@ -253,6 +255,10 @@ local function wrap_resolver(resolver) specification.filename = filename specification.name = filename specification.sub = sub or specification.sub + if type(specification.sub) == "string" then + specification.sub = + lookup_subfont_index(filename, specification.sub) + end specification.forced = specification.forced or forced if not specification.forced then local suffix = stringlower (filesuffix (filename)) diff --git a/Master/texmf-dist/tex/luatex/luaotfload/luaotfload-status.lua b/Master/texmf-dist/tex/luatex/luaotfload/luaotfload-status.lua index 69948c43caa..3221986ca78 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-08-11.lua", "9ad89bd01fccf2f98b8777ad42851c58" }, + { "fontloader-2019-10-29.lua", "8b7d755e08cfef0826429ffa68271eb3" }, { "fontloader-util-fil.lua", "4bb3e4dc72e308d8ed67cd7a80027fa7" }, - { "fontloader-util-str.lua", "3c829af0b336703e62cb5a1cb7a6e503" }, - { "fontloader-l-unicode.lua", "d46cc6cf18fb3f368ef1e404dc9fcb5c" }, + { "fontloader-util-str.lua", "fc15d89c4c35f7338d09fc7644fac181" }, + { "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", "63b13279139d2f94d29238b0d6242330" }, + { "fontloader-l-table.lua", "9844897b04a01bb197427d71de71de2b" }, { "fontloader-l-string.lua", "e1347bef0eeeff9f098df83b30b32df9" }, { "fontloader-l-function.lua", "f771cc91839ebcdfc094083434fbe00f" }, - { "fontloader-l-lpeg.lua", "a5364ddabb490408da9276ea7f7a7ba1" }, - { "fontloader-l-lua.lua", "9e5e9d4f3b8f9e337f28aa2322192b94" }, + { "fontloader-l-lpeg.lua", "efe630e3a9a1d269120e59cfd8fba4ba" }, + { "fontloader-l-lua.lua", "dda8438a34886bb767dbad381f1ea70a" }, { "fontloader-fonts-gbn.lua", "d25472d54c4841db43a745764a63533e" }, { "fontloader-fonts-lig.lua", "b9dbe77ce747d4c35bb2a20ffbe5aa51" }, { "fontloader-fonts-ext.lua", "01015ab3758cdc2af29394e6d502a91a" }, @@ -21,7 +21,7 @@ return { { "fontloader-fonts-enc.lua", "3e71a54297e8f85a1ac438bb0f20dd79" }, { "fontloader-fonts-mis.lua", "bc9eb43c27f63ce9d0fff67e104fe1c6" }, { "fontloader-basics-chr.lua", "58b7ef0c486e06090b362971b9f85e27" }, - { "fontloader-basics-nod.lua", "65064d03c2650a1761ee13ebd9e1400a" }, + { "fontloader-basics-nod.lua", "c05f47077c709bbf12a8758852dc4e06" }, { "fontloader-font-imp-effects.lua", "73a660359a0ec71e44cc2b7225a715ac" }, { "fontloader-font-imp-italics.lua", "fe1ca80fb5ea4a2f8d2d5c484e7ba913" }, { "fontloader-font-imp-ligatures.lua", "043daa4fcccf2560868da359d71d3a4a" }, @@ -31,16 +31,16 @@ return { { "fontloader-font-afk.lua", "54d554530e75c57c56ee76234724e26d" }, { "fontloader-font-one.lua", "987c5c5ed3754ad2feab80985067d59e" }, { "fontloader-font-onr.lua", "d4d2449b4084e6afb1837ae5835082cc" }, - { "fontloader-font-otc.lua", "95a4ff28ba4afb55a978a4aecfd688bf" }, - { "fontloader-font-ocl.lua", "b720867fb19a23f0b50377efd2a3c54a" }, - { "fontloader-font-osd.lua", "79eb2fc4a71364fd73c8b996a109f5df" }, - { "fontloader-font-ots.lua", "d5504847a278385cd0d20ecf1b3d59cc" }, + { "fontloader-font-otc.lua", "1204a2fdc436e644127c0aa38ab69607" }, + { "fontloader-font-ocl.lua", "ba40df1a92b9b42a5c70d20c28f44759" }, + { "fontloader-font-osd.lua", "39e92f6e575741646d75ea79e3be87f3" }, + { "fontloader-font-ots.lua", "d6a0ce4b40cd4ee1895e2248dcf87d37" }, { "fontloader-font-ota.lua", "d6dfb94563d6a52675e274b2e673e4a6" }, { "fontloader-font-otj.lua", "66c7a910d95d4a52b81061de776898e1" }, { "fontloader-font-oto.lua", "52804afd96f4be005f513a012b874668" }, - { "fontloader-font-otl.lua", "940f9c5ad84f4968a8488f4da2d15e2d" }, - { "fontloader-font-oup.lua", "669e479e716999edc626a1f045bd76fa" }, - { "fontloader-font-dsp.lua", "b5bf2f1c198e027a0d4ededcdf3947b4" }, + { "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-ott.lua", "aba6d8335a5f38a5a62d3631492f3392" }, @@ -49,43 +49,46 @@ return { { "fontloader-font-vfc.lua", "94937140f2c909e9c831ba021f1ab303" }, { "fontloader-font-map.lua", "f486746e90fe972de4b73e208ac7cbb2" }, { "fontloader-font-cid.lua", "4d87988efa86020a14708ee03c23415f" }, - { "fontloader-font-con.lua", "ca733211a0555d9a93b1e2f7ebc937d3" }, + { "fontloader-font-con.lua", "8b35e7c2203d5b57c61942e07cee2c0a" }, { "fontloader-font-ini.lua", "4299a02110bbd7c0d27e131235c5319d" }, { "fontloader-data-con.lua", "7ce546725b1550f655c78ac9d69419ca" }, - { "fontloader-reference.lua", "759787e7ee75437382c0a2c4f8fe3b81" }, + { "fontloader-reference.lua", "5be3565068a1929b173bde862b48a30e" }, { "fontloader-basics-gen.lua", "b21e91bbd534f77e368f0ec13f865aed" }, { "mktests", "c7cff7025962922944376acc1ffa9c47" }, - { "mkstatus", "64b9a6b302168fced414830a53fdcce1" }, + { "mkstatus", "32b8eee5316ca3100e4434db79d08230" }, { "mkcharacters", "92c24bb582fc84c0365634f29eb89863" }, { "mkglyphlist", "557836886d4f0e6d656eac3ded4456a2" }, { "mkimport", "60e0b11a1a68719033e86a3e0f4d5e86" }, - { "luaotfload-glyphlist.lua", "df822678061548ce6b510a0c1c7fc103" }, + { "luaotfload-glyphlist.lua", "6dc41351ebdb122e044bed6d3fc2ca4b" }, { "luaotfload-characters.lua", "593ce9dccf6ddc4f7d4be0514f581102" }, - { "luaotfload-unicode.lua", "d9ce2f2a07e951be6310e85fdfcc785d" }, - { "luaotfload-resolvers.lua", "0b0d407501e68537971484ac2256af20" }, - { "luaotfload-parsers.lua", "9b199d5157d9972c415aee7f9350df5b" }, - { "luaotfload-multiscript.lua", "3a4cfa1687c9d1694cbf728183bb066e" }, - { "luaotfload-loaders.lua", "007be1e29cf23779f4d9d0097b56cc4a" }, - { "luaotfload-notdef.lua", "982810e9197d2261ffdc3acd5d8dcecf" }, - { "luaotfload-embolden.lua", "92dfba7dbf10484c85f7e3c971691f8e" }, - { "luaotfload-letterspace.lua", "bb123f78712cc0342419f3c2a5f6a940" }, - { "luaotfload-features.lua", "45ab2c6405c678f8834339fe0d9fb47a" }, - { "luaotfload-database.lua", "da3c5b55a086a2213ee825ecc2bf7e0f" }, - { "luaotfload-configuration.lua", "015022f5b9597254afafff26f9f0f98c" }, - { "luaotfload-colors.lua", "81a23496c5f5c855674b05180869b8cf" }, - { "luaotfload-auxiliary.lua", "81432ebaebfce3df73b5949e1001d13c" }, - { "luaotfload-filelist.lua", "aa3c9fa695042573d6f6c2e5d0c23558" }, - { "luaotfload-tool.lua", "1833a47868c3e5958d492bb947d39dec" }, - { "luaotfload-diagnostics.lua", "53dbf51623658f1e325d2e6279a2ee15" }, - { "luaotfload-log.lua", "30491ef5890898d5ae3af44f72e82b1f" }, - { "luaotfload-init.lua", "479854a620629b1934d16723aa4cae0c" }, - { "luaotfload-main.lua", "95c7d3ce348ac83e0659f7332e98eacc" }, + { "luaotfload-tounicode.lua", "b87cab857631c47f5c2bbfa4dc1b5598" }, + { "luaotfload-unicode.lua", "eaf637834d735afce54cf81721b89626" }, + { "luaotfload-resolvers.lua", "7bcd23bf0c4079174679f61c315f54ed" }, + { "luaotfload-parsers.lua", "23b0550fcc6bf872714d882b8d15f465" }, + { "luaotfload-multiscript.lua", "bd0b25f9b9b21ad1e1a24fb88dc5cdbf" }, + { "luaotfload-loaders.lua", "34d130aa4e365639baecfa0481e34d13" }, + { "luaotfload-harf-plug.lua", "59429664d9bebfbf0e0bfa8a8bdd85e3" }, + { "luaotfload-harf-define.lua", "f0aafaecaddbc43f665a076195ed9205" }, + { "luaotfload-notdef.lua", "ce00644d5801c6fac2e274626a52ecf2" }, + { "luaotfload-embolden.lua", "7ff4b7e2970f2748a4d881b23085495d" }, + { "luaotfload-letterspace.lua", "2b24d57529363de4a004510da84bafd9" }, + { "luaotfload-features.lua", "b8c279955bcc473f02ad77b46942eb29" }, + { "luaotfload-database.lua", "131587572dcf49769bec7e085ab61281" }, + { "luaotfload-configuration.lua", "a59a94e07e20998144c91d5eb44b9302" }, + { "luaotfload-colors.lua", "c13f4c88058e2c4869205ad015765070" }, + { "luaotfload-auxiliary.lua", "77bcb55f9d215ad8a61701dc64e9a07e" }, + { "luaotfload-filelist.lua", "96967c2f4ad091f2a8c74a50294c25d5" }, + { "luaotfload-tool.lua", "9a53d4aedf71012530be90303aabe0d9" }, + { "luaotfload-diagnostics.lua", "f521a2b70b24bd23fb23d3d08d7845bf" }, + { "luaotfload-log.lua", "28c5c63d7af789ab7ca5757870dfc595" }, + { "luaotfload-init.lua", "ebb2e936d4c95cab76649897f6af0e25" }, + { "luaotfload-main.lua", "e4208f459c12b57a6996b4c7e9adbb8b" }, }, ["notes"]={ - ["committer"]="Marcel Fabian Krüger <tex@2krueger.de>", - ["description"]="v3.00/2019-09-13", - ["loader"]="fontloader-2019-08-11.lua", - ["revision"]="e758f5d39e3d416e4bc1e2a23918abed744563ae", - ["timestamp"]="2019-09-13 00:43:25 +0200", + ["committer"]="Ulrike Fischer <fischer@troubleshooting-tex.de>", + ["description"]="v3.1/2019-11-04", + ["loader"]="fontloader-2019-10-29.lua", + ["revision"]="cdc212ae76bc0f839d116c8f66af98445ba9f307", + ["timestamp"]="2019-11-03 15:29:57 +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 new file mode 100644 index 00000000000..3636f79220d --- /dev/null +++ b/Master/texmf-dist/tex/luatex/luaotfload/luaotfload-tounicode.lua @@ -0,0 +1,200 @@ +----------------------------------------------------------------------- +-- FILE: luaotfload-tounicode.lua +-- DESCRIPTION: part of luaotfload / tounicode overwrites +----------------------------------------------------------------------- + +local ProvidesLuaModule = { + name = "luaotfload-tounicode", + version = "3.1", --TAGVERSION + date = "2019-11-04", --TAGDATE + description = "luaotfload submodule / tounicode", + license = "GPL v2.0", + author = "Hans Hagen, Khaled Hosny, Elie Roux, Philipp Gesang, Marcel Krüger", + copyright = "PRAGMA ADE / ConTeXt Development Team", +} + +if luatexbase and luatexbase.provides_module then + luatexbase.provides_module (ProvidesLuaModule) +end + +local overloads = { + -- rougly based on texglyphlist-g2u.txt + + -- ff = { unicode = {0x0066, 0x0066} }, + -- ffi = { unicode = {0x0066, 0x0066, 0x0069} }, + -- ffl = { unicode = {0x0066, 0x0066, 0x006C} }, + -- fi = { unicode = {0x0066, 0x0069} }, + -- fl = { unicode = {0x0066, 0x006C} }, + longst = { unicode = {0x017F, 0x0074} }, + st = { unicode = {0x0073, 0x0074} }, + AEsmall = { unicode = 0x00E6 }, + Aacutesmall = { unicode = 0x00E1 }, + Acircumflexsmall = { unicode = 0x00E2 }, + Acute = { unicode = 0x00B4 }, + Acutesmall = { unicode = 0x00B4 }, + Adieresissmall = { unicode = 0x00E4 }, + Agravesmall = { unicode = 0x00E0 }, + Aringsmall = { unicode = 0x00E5 }, + Asmall = { unicode = 0x0061 }, + Atildesmall = { unicode = 0x00E3 }, + Brevesmall = { unicode = 0x02D8 }, + Bsmall = { unicode = 0x0062 }, + Caron = { unicode = 0x02C7 }, + Caronsmall = { unicode = 0x02C7 }, + Ccedillasmall = { unicode = 0x00E7 }, + Cedillasmall = { unicode = 0x00B8 }, + Circumflexsmall = { unicode = 0x02C6 }, + Csmall = { unicode = 0x0063 }, + Dieresis = { unicode = 0x00A8 }, + DieresisAcute = { unicode = 0xF6CC }, + DieresisGrave = { unicode = 0xF6CD }, + Dieresissmall = { unicode = 0x00A8 }, + Dotaccentsmall = { unicode = 0x02D9 }, + Dsmall = { unicode = 0x0064 }, + Eacutesmall = { unicode = 0x00E9 }, + Ecircumflexsmall = { unicode = 0x00EA }, + Edieresissmall = { unicode = 0x00EB }, + Egravesmall = { unicode = 0x00E8 }, + Esmall = { unicode = 0x0065 }, + Ethsmall = { unicode = 0x00F0 }, + Fsmall = { unicode = 0x0066 }, + Grave = { unicode = 0x0060 }, + Gravesmall = { unicode = 0x0060 }, + Gsmall = { unicode = 0x0067 }, + Hsmall = { unicode = 0x0068 }, + Hungarumlaut = { unicode = 0x02DD }, + Hungarumlautsmall = { unicode = 0x02DD }, + Iacutesmall = { unicode = 0x00ED }, + Icircumflexsmall = { unicode = 0x00EE }, + Idieresissmall = { unicode = 0x00EF }, + Igravesmall = { unicode = 0x00EC }, + Ismall = { unicode = 0x0069 }, + Jsmall = { unicode = 0x006A }, + Ksmall = { unicode = 0x006B }, + LL = { unicode = {0x004C, 0x004C} }, + Lslashsmall = { unicode = 0x0142 }, + Lsmall = { unicode = 0x006C }, + Macron = { unicode = 0x00AF }, + Macronsmall = { unicode = 0x00AF }, + Msmall = { unicode = 0x006D }, + Nsmall = { unicode = 0x006E }, + Ntildesmall = { unicode = 0x00F1 }, + OEsmall = { unicode = 0x0153 }, + Oacutesmall = { unicode = 0x00F3 }, + Ocircumflexsmall = { unicode = 0x00F4 }, + Odieresissmall = { unicode = 0x00F6 }, + Ogoneksmall = { unicode = 0x02DB }, + Ogravesmall = { unicode = 0x00F2 }, + Oslashsmall = { unicode = 0x00F8 }, + Osmall = { unicode = 0x006F }, + Otildesmall = { unicode = 0x00F5 }, + Psmall = { unicode = 0x0070 }, + Qsmall = { unicode = 0x0071 }, + Ringsmall = { unicode = 0x02DA }, + Rsmall = { unicode = 0x0072 }, + Scaronsmall = { unicode = 0x0161 }, + Ssmall = { unicode = 0x0073 }, + Thornsmall = { unicode = 0x00FE }, + Tildesmall = { unicode = 0x02DC }, + Tsmall = { unicode = 0x0074 }, + Uacutesmall = { unicode = 0x00FA }, + Ucircumflexsmall = { unicode = 0x00FB }, + Udieresissmall = { unicode = 0x00FC }, + Ugravesmall = { unicode = 0x00F9 }, + Usmall = { unicode = 0x0075 }, + Vsmall = { unicode = 0x0076 }, + Wsmall = { unicode = 0x0077 }, + Xsmall = { unicode = 0x0078 }, + Yacutesmall = { unicode = 0x00FD }, + Ydieresissmall = { unicode = 0x00FF }, + Ysmall = { unicode = 0x0079 }, + Zcaronsmall = { unicode = 0x017E }, + Zsmall = { unicode = 0x007A }, + ampersandsmall = { unicode = 0x0026 }, + asuperior = { unicode = 0x0061 }, + bsuperior = { unicode = 0x0062 }, + centinferior = { unicode = 0x00A2 }, + centoldstyle = { unicode = 0x00A2 }, + centsuperior = { unicode = 0x00A2 }, + commainferior = { unicode = 0x002C }, + commasuperior = { unicode = 0x002C }, + copyrightsans = { unicode = 0x00A9 }, + copyrightserif = { unicode = 0x00A9 }, + cyrBreve = { unicode = 0x02D8 }, + cyrFlex = { unicode = {0x00A0, 0x0311} }, + cyrbreve = { unicode = 0x02D8 }, + cyrflex = { unicode = {0x00A0, 0x0311} }, + dblGrave = { unicode = {0x00A0, 0x030F} }, + dblgrave = { unicode = {0x00A0, 0x030F} }, + dieresisacute = { unicode = {0x00A0, 0x0308, 0x0301} }, + dieresisgrave = { unicode = {0x00A0, 0x0308, 0x0300} }, + dollarinferior = { unicode = 0x0024 }, + dollaroldstyle = { unicode = 0x0024 }, + dollarsuperior = { unicode = 0x0024 }, + dotlessj = { unicode = 0x0237 }, + dsuperior = { unicode = 0x0064 }, + eightoldstyle = { unicode = 0x0038 }, + esuperior = { unicode = 0x0065 }, + exclamdownsmall = { unicode = 0x00A1 }, + exclamsmall = { unicode = 0x0021 }, + fiveoldstyle = { unicode = 0x0035 }, + fouroldstyle = { unicode = 0x0034 }, + hypheninferior = { unicode = 0x002D }, + hyphensuperior = { unicode = 0x002D }, + isuperior = { unicode = 0x0069 }, + ll = { unicode = {0x006C, 0x006C} }, + lsuperior = { unicode = 0x006C }, + msuperior = { unicode = 0x006D }, + nineoldstyle = { unicode = 0x0039 }, + onefitted = { unicode = 0x0031 }, + oneoldstyle = { unicode = 0x0031 }, + osuperior = { unicode = 0x006F }, + periodinferior = { unicode = 0x002E }, + periodsuperior = { unicode = 0x002E }, + questiondownsmall = { unicode = 0x00BF }, + questionsmall = { unicode = 0x003F }, + registersans = { unicode = 0x00AE }, + registerserif = { unicode = 0x00AE }, + rsuperior = { unicode = 0x0072 }, + rupiah = { unicode = 0x20A8 }, + sevenoldstyle = { unicode = 0x0037 }, + sixoldstyle = { unicode = 0x0036 }, + ssuperior = { unicode = 0x0073 }, + threeoldstyle = { unicode = 0x0033 }, + trademarksans = { unicode = 0x2122 }, + trademarkserif = { unicode = 0x2122 }, + tsuperior = { unicode = 0x0074 }, + twooldstyle = { unicode = 0x0032 }, + zerooldstyle = { unicode = 0x0030 }, + FFsmall = { unicode = {0x0066, 0x0066} }, + FFIsmall = { unicode = {0x0066, 0x0066, 0x0069} }, + FFLsmall = { unicode = {0x0066, 0x0066, 0x006C} }, + FIsmall = { unicode = {0x0066, 0x0069} }, + FLsmall = { unicode = {0x0066, 0x006C} }, + Germandblssmall = { unicode = {0x0073, 0x0073} }, + SSsmall = { unicode = {0x0073, 0x0073} }, +} +-- For values that are used multiple times +local function registeroverload(mapped) + mapped = {unicode = mapped} + local function multiset(first, ...) + if first then + rawset(overloads, first, mapped) + return multiset(...) + end + end + return multiset +end + +-- These come from ConTeXt +registeroverload { 0x49, 0x4A } ("IJ", "I_J", 0x0132) +registeroverload { 0x69, 0x6A } ("ij", "i_j", 0x0133) +registeroverload { 0x66, 0x66 } ("ff", "f_f", 0xFB00) +registeroverload { 0x66, 0x69 } ("fi", "f_i", 0xFB01) +registeroverload { 0x66, 0x6C } ("fl", "f_l", 0xFB02) +registeroverload { 0x66, 0x66, 0x69 } ("ffi", "f_f_i", 0xFB03) +registeroverload { 0x66, 0x66, 0x6C } ("ffl", "f_f_l", 0xFB04) +registeroverload { 0x66, 0x6A } ("fj", "f_j") +registeroverload { 0x66, 0x6B } ("fk", "f_k") + +fonts.mappings.overloads = overloads diff --git a/Master/texmf-dist/tex/luatex/luaotfload/luaotfload-unicode.lua b/Master/texmf-dist/tex/luatex/luaotfload/luaotfload-unicode.lua index d7cb98a3387..c1bdf3cbd26 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.00", --TAGVERSION - date = "2019-09-13", --TAGDATE + version = "3.1", --TAGVERSION + date = "2019-11-04", --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 1dede25f2fd..4dc2553d334 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/09/13 v3.00 OpenType layout system] + [2019/11/04 v3.1 OpenType layout system] \fi \directlua{ if xpcall(function ()% |