diff options
Diffstat (limited to 'Master/texmf-dist/tex/luatex')
41 files changed, 2214 insertions, 1511 deletions
diff --git a/Master/texmf-dist/tex/luatex/luaotfload/fontloader-2020-08-31.lua b/Master/texmf-dist/tex/luatex/luaotfload/fontloader-2020-12-30.lua index 01e1f8300cd..835eca6695c 100644 --- a/Master/texmf-dist/tex/luatex/luaotfload/fontloader-2020-08-31.lua +++ b/Master/texmf-dist/tex/luatex/luaotfload/fontloader-2020-12-30.lua @@ -1,6 +1,6 @@ --[[info----------------------------------------------------------------------- Luaotfload fontloader package - build 2020-08-31 23:33:48 + build 2020-12-30 17:29:34 ------------------------------------------------------------------------------- © 2020 PRAGMA ADE / ConTeXt Development Team @@ -63,7 +63,7 @@ --info]]----------------------------------------------------------------------- -do --- [luaotfload, fontloader-2020-08-31.lua scope for “data-con” de6ae0997b0e70a23bcc9afff5d8b072] --- +do --- [luaotfload, fontloader-2020-12-30.lua scope for “data-con” 23a0f5386d46a1c157ae82a373e35fa0] --- if not modules then modules={} end modules ['data-con']={ version=1.100, @@ -184,10 +184,10 @@ function containers.cleanname(name) return (gsub(lower(name),"[^%w\128-\255]+","-")) end -end --- [luaotfload, fontloader-2020-08-31.lua scope for “data-con”] --- +end --- [luaotfload, fontloader-2020-12-30.lua scope for “data-con”] --- -do --- [luaotfload, fontloader-2020-08-31.lua scope for “basics-nod” e296bfb03d5654a596b43612348c4191] --- +do --- [luaotfload, fontloader-2020-12-30.lua scope for “basics-nod” 4b5c3c63e19df1b3f37fae7f87c25bda] --- if not modules then modules={} end modules ['luatex-fonts-nod']={ version=1.001, @@ -265,6 +265,7 @@ nuts.getkern=direct.getkern nuts.getlist=direct.getlist nuts.getnext=direct.getnext nuts.getoffsets=direct.getoffsets +nuts.getoptions=direct.getoptions or function() return 0 end nuts.getprev=direct.getprev nuts.getsubtype=direct.getsubtype nuts.getwidth=direct.getwidth @@ -348,6 +349,15 @@ local traverse_id=nuts.traverse_id local copy_node=nuts.copy_node local glyph_code=nodes.nodecodes.glyph local ligature_code=nodes.glyphcodes.ligature +do + local p=nodecodes.localpar or nodecodes.local_par + if p then + nodecodes.par=p + nodecodes[p]="par" + nodecodes.localpar=p + nodecodes.local_par=p + end +end do local get_components=node.direct.getcomponents local set_components=node.direct.setcomponents @@ -400,11 +410,14 @@ do end return 0 end + local function flush_components() + end nuts.set_components=set_components nuts.get_components=get_components nuts.copy_only_glyphs=copy_only_glyphs nuts.copy_no_components=copy_no_components nuts.count_components=count_components + nuts.flush_components=flush_components end nuts.uses_font=direct.uses_font do @@ -437,10 +450,10 @@ do end end -end --- [luaotfload, fontloader-2020-08-31.lua scope for “basics-nod”] --- +end --- [luaotfload, fontloader-2020-12-30.lua scope for “basics-nod”] --- -do --- [luaotfload, fontloader-2020-08-31.lua scope for “basics-chr” 58b7ef0c486e06090b362971b9f85e27] --- +do --- [luaotfload, fontloader-2020-12-30.lua scope for “basics-chr” 64fafe4eaf55d64aead6513c1e74a024] --- characters=characters or {} @@ -4050,10 +4063,10 @@ characters.indicgroups={ }, } -end --- [luaotfload, fontloader-2020-08-31.lua scope for “basics-chr”] --- +end --- [luaotfload, fontloader-2020-12-30.lua scope for “basics-chr”] --- -do --- [luaotfload, fontloader-2020-08-31.lua scope for “font-ini” 4dee96e1e1474d324dd126bd5d375df8] --- +do --- [luaotfload, fontloader-2020-12-30.lua scope for “font-ini” 5343de60613adb24cdd7a8d2ee1d153c] --- if not modules then modules={} end modules ['font-ini']={ version=1.001, @@ -4094,10 +4107,10 @@ if node and not tex.getfontoffamily then tex.getfontoffamily=node.family_font end -end --- [luaotfload, fontloader-2020-08-31.lua scope for “font-ini”] --- +end --- [luaotfload, fontloader-2020-12-30.lua scope for “font-ini”] --- -do --- [luaotfload, fontloader-2020-08-31.lua scope for “fonts-mis” bc9eb43c27f63ce9d0fff67e104fe1c6] --- +do --- [luaotfload, fontloader-2020-12-30.lua scope for “fonts-mis” 17e967c9ec4d001deefd43ddf25e98f7] --- if not modules then modules={} end modules ['luatex-font-mis']={ version=1.001, @@ -4129,10 +4142,10 @@ function font.each() return table.sortedhash(fonts.hashes.identifiers) end -end --- [luaotfload, fontloader-2020-08-31.lua scope for “fonts-mis”] --- +end --- [luaotfload, fontloader-2020-12-30.lua scope for “fonts-mis”] --- -do --- [luaotfload, fontloader-2020-08-31.lua scope for “font-con” cbccccc4a5016196d62332a365aa8b72] --- +do --- [luaotfload, fontloader-2020-12-30.lua scope for “font-con” a3eb543fa5946fa1faf0e1e50d5b3b91] --- if not modules then modules={} end modules ['font-con']={ version=1.001, @@ -5497,10 +5510,10 @@ function constructors.addcoreunicodes(unicodes) return unicodes end -end --- [luaotfload, fontloader-2020-08-31.lua scope for “font-con”] --- +end --- [luaotfload, fontloader-2020-12-30.lua scope for “font-con”] --- -do --- [luaotfload, fontloader-2020-08-31.lua scope for “fonts-enc” 3e71a54297e8f85a1ac438bb0f20dd79] --- +do --- [luaotfload, fontloader-2020-12-30.lua scope for “fonts-enc” 5ff4ca50493d7c4ecea0e15c203099f0] --- if not modules then modules={} end modules ['luatex-font-enc']={ version=1.001, @@ -5569,10 +5582,10 @@ function encodings.load(filename) return containers.write(encodings.cache,name,data) end -end --- [luaotfload, fontloader-2020-08-31.lua scope for “fonts-enc”] --- +end --- [luaotfload, fontloader-2020-12-30.lua scope for “fonts-enc”] --- -do --- [luaotfload, fontloader-2020-08-31.lua scope for “font-cid” 4d87988efa86020a14708ee03c23415f] --- +do --- [luaotfload, fontloader-2020-12-30.lua scope for “font-cid” 22b0367742fb253deef84ef7ccf5e8de] --- if not modules then modules={} end modules ['font-cid']={ version=1.001, @@ -5723,10 +5736,10 @@ function cid.getmap(specification) return found end -end --- [luaotfload, fontloader-2020-08-31.lua scope for “font-cid”] --- +end --- [luaotfload, fontloader-2020-12-30.lua scope for “font-cid”] --- -do --- [luaotfload, fontloader-2020-08-31.lua scope for “font-map” a03653ea3c5f042b457d54ed678d6df3] --- +do --- [luaotfload, fontloader-2020-12-30.lua scope for “font-map” c4a39db5ad822b348aa61bca5f4a599a] --- if not modules then modules={} end modules ['font-map']={ version=1.001, @@ -6134,10 +6147,10 @@ function mappings.addtounicode(data,filename,checklookups,forceligatures) end end -end --- [luaotfload, fontloader-2020-08-31.lua scope for “font-map”] --- +end --- [luaotfload, fontloader-2020-12-30.lua scope for “font-map”] --- -do --- [luaotfload, fontloader-2020-08-31.lua scope for “font-vfc” 04fa0ffad5c51198c7c19462949f54ed] --- +do --- [luaotfload, fontloader-2020-12-30.lua scope for “font-vfc” a81c29eda98cd62cbebdb6c93544b50d] --- if not modules then modules={} end modules ['font-vfc']={ version=1.001, @@ -6234,10 +6247,10 @@ helpers.commands=utilities.storage.allocate { dummy=dummy, } -end --- [luaotfload, fontloader-2020-08-31.lua scope for “font-vfc”] --- +end --- [luaotfload, fontloader-2020-12-30.lua scope for “font-vfc”] --- -do --- [luaotfload, fontloader-2020-08-31.lua scope for “font-otr” 7a2f7a9e9627b29158e1822ea3c650ab] --- +do --- [luaotfload, fontloader-2020-12-30.lua scope for “font-otr” 64dcbbc7107538723990e1119a80a9f8] --- if not modules then modules={} end modules ['font-otr']={ version=1.001, @@ -8081,10 +8094,10 @@ function readers.extend(fontdata) end end -end --- [luaotfload, fontloader-2020-08-31.lua scope for “font-otr”] --- +end --- [luaotfload, fontloader-2020-12-30.lua scope for “font-otr”] --- -do --- [luaotfload, fontloader-2020-08-31.lua scope for “font-oti” dbae7722baae24d917a17176553825cf] --- +do --- [luaotfload, fontloader-2020-12-30.lua scope for “font-oti” 309a75f9c14b77d87e94eba827dc4e71] --- if not modules then modules={} end modules ['font-oti']={ version=1.001, @@ -8227,10 +8240,10 @@ function otffeatures.checkeddefaultlanguage(featuretype,autolanguage,languages) end end -end --- [luaotfload, fontloader-2020-08-31.lua scope for “font-oti”] --- +end --- [luaotfload, fontloader-2020-12-30.lua scope for “font-oti”] --- -do --- [luaotfload, fontloader-2020-08-31.lua scope for “font-ott” 1249b7018dba80e080fc478a38aa6756] --- +do --- [luaotfload, fontloader-2020-12-30.lua scope for “font-ott” 673ed11e1d159997f535bfec5fa73808] --- if not modules then modules={} end modules ["font-ott"]={ version=1.001, @@ -9346,10 +9359,10 @@ function otffeatures.normalize(features,wrap) end end -end --- [luaotfload, fontloader-2020-08-31.lua scope for “font-ott”] --- +end --- [luaotfload, fontloader-2020-12-30.lua scope for “font-ott”] --- -do --- [luaotfload, fontloader-2020-08-31.lua scope for “font-cff” aa9038651d9fedd2b76cacd1f69fd742] --- +do --- [luaotfload, fontloader-2020-12-30.lua scope for “font-cff” 802a10ad12ac32329f540881f940e3f2] --- if not modules then modules={} end modules ['font-cff']={ version=1.001, @@ -11544,10 +11557,10 @@ function readers.cffcheck(filename) end end -end --- [luaotfload, fontloader-2020-08-31.lua scope for “font-cff”] --- +end --- [luaotfload, fontloader-2020-12-30.lua scope for “font-cff”] --- -do --- [luaotfload, fontloader-2020-08-31.lua scope for “font-ttf” 807599f6d56c775d53cf6f358d741f34] --- +do --- [luaotfload, fontloader-2020-12-30.lua scope for “font-ttf” ffffc827e1bcddc33a2b615340ecff7f] --- if not modules then modules={} end modules ['font-ttf']={ version=1.001, @@ -11672,7 +11685,7 @@ local function mergecomposites(glyphs,shapes) shape.components=nil return contours,points end - for index=0,#glyphs-1 do + for index=0,#glyphs do local shape=shapes[index] if shape then local components=shape.components @@ -12102,7 +12115,7 @@ local function repackpoints(glyphs,shapes) local result={} local xpoints={} local ypoints={} - for index=0,#glyphs-1 do + for index=0,#glyphs do local shape=shapes[index] if shape then local r=0 @@ -12718,10 +12731,10 @@ function readers.gvar(f,fontdata,specification,glyphdata,shapedata) end end -end --- [luaotfload, fontloader-2020-08-31.lua scope for “font-ttf”] --- +end --- [luaotfload, fontloader-2020-12-30.lua scope for “font-ttf”] --- -do --- [luaotfload, fontloader-2020-08-31.lua scope for “font-dsp” e1c275ded4770aa6cbe0b1afbdfd0dde] --- +do --- [luaotfload, fontloader-2020-12-30.lua scope for “font-dsp” 18c85a4857f45c31a3555bf1faac434a] --- if not modules then modules={} end modules ['font-dsp']={ version=1.001, @@ -13366,7 +13379,7 @@ local function readfirst(f,offset) end return { readushort(f) } end -function readarray(f,offset) +local function readarray(f,offset) if offset then setposition(f,offset) end @@ -15999,10 +16012,10 @@ function readers.mvar(f,fontdata,specification) end end -end --- [luaotfload, fontloader-2020-08-31.lua scope for “font-dsp”] --- +end --- [luaotfload, fontloader-2020-12-30.lua scope for “font-dsp”] --- -do --- [luaotfload, fontloader-2020-08-31.lua scope for “font-oup” 1700a2dac4f8b105c187d4e5b84cecdf] --- +do --- [luaotfload, fontloader-2020-12-30.lua scope for “font-oup” 6f46aa00ae1c20c43f8ffaf329dc8695] --- if not modules then modules={} end modules ['font-oup']={ version=1.001, @@ -18643,10 +18656,10 @@ function readers.expand(data) expandlookups(sublookups) end -end --- [luaotfload, fontloader-2020-08-31.lua scope for “font-oup”] --- +end --- [luaotfload, fontloader-2020-12-30.lua scope for “font-oup”] --- -do --- [luaotfload, fontloader-2020-08-31.lua scope for “font-otl” f111f9ac18d24049fadeb8883e4e8da5] --- +do --- [luaotfload, fontloader-2020-12-30.lua scope for “font-otl” 6c4b718ceacfb0cbeb2c03c423f97aec] --- if not modules then modules={} end modules ['font-otl']={ version=1.001, @@ -18674,7 +18687,7 @@ 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.111 +otf.version=3.112 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) @@ -19039,7 +19052,6 @@ local function copytotfm(data,cache_id) parameters.units=units parameters.vheight=metadata.defaultvheight properties.space=spacer - properties.encodingbytes=2 properties.format=data.format or formats.otf properties.filename=filename properties.fontname=fontname @@ -19047,6 +19059,9 @@ local function copytotfm(data,cache_id) properties.psname=psname properties.name=filename or fullname properties.subfont=subfont +if not CONTEXTLMTXMODE or CONTEXTLMTXMODE==0 then + properties.encodingbytes=2 +end properties.private=properties.private or data.private or privateoffset return { characters=characters, @@ -19350,10 +19365,10 @@ otf.coverup={ end } -end --- [luaotfload, fontloader-2020-08-31.lua scope for “font-otl”] --- +end --- [luaotfload, fontloader-2020-12-30.lua scope for “font-otl”] --- -do --- [luaotfload, fontloader-2020-08-31.lua scope for “font-oto” 24238a7c600d090a8ee88312321dd9b3] --- +do --- [luaotfload, fontloader-2020-12-30.lua scope for “font-oto” 2b1d6bc63b2ebf8f2655a15e1cda6541] --- if not modules then modules={} end modules ['font-oto']={ version=1.001, @@ -19811,10 +19826,10 @@ registerotffeature { } otf.basemodeinitializer=featuresinitializer -end --- [luaotfload, fontloader-2020-08-31.lua scope for “font-oto”] --- +end --- [luaotfload, fontloader-2020-12-30.lua scope for “font-oto”] --- -do --- [luaotfload, fontloader-2020-08-31.lua scope for “font-otj” a37a1007b8a92c9e7d24064180c2a772] --- +do --- [luaotfload, fontloader-2020-12-30.lua scope for “font-otj” 8de59cb9b043e5f73c6b9f7cc8f6978e] --- if not modules then modules={} end modules ['font-otj']={ version=1.001, @@ -21309,10 +21324,10 @@ function injections.handler(head,where) end end -end --- [luaotfload, fontloader-2020-08-31.lua scope for “font-otj”] --- +end --- [luaotfload, fontloader-2020-12-30.lua scope for “font-otj”] --- -do --- [luaotfload, fontloader-2020-08-31.lua scope for “font-ota” f31232af3a694ae3d50380a5a92f88d3] --- +do --- [luaotfload, fontloader-2020-12-30.lua scope for “font-ota” ad1d5de06400f88829509e1f3ff2b473] --- if not modules then modules={} end modules ['font-ota']={ version=1.001, @@ -21806,10 +21821,10 @@ directives.register("otf.analyze.useunicodemarks",function(v) analyzers.useunicodemarks=v end) -end --- [luaotfload, fontloader-2020-08-31.lua scope for “font-ota”] --- +end --- [luaotfload, fontloader-2020-12-30.lua scope for “font-ota”] --- -do --- [luaotfload, fontloader-2020-08-31.lua scope for “font-ots” c507280651dcbc549f1d8a5622da8667] --- +do --- [luaotfload, fontloader-2020-12-30.lua scope for “font-ots” 91c79619c386e4a96954f3115f398b94] --- if not modules then modules={} end modules ['font-ots']={ version=1.001, @@ -21893,6 +21908,7 @@ local copy_only_glyphs=nuts.copy_only_glyphs local count_components=nuts.count_components local set_components=nuts.set_components local get_components=nuts.get_components +local flush_components=nuts.flush_components local ischar=nuts.ischar local usesfont=nuts.uses_font local insert_node_after=nuts.insert_after @@ -21915,7 +21931,7 @@ local glue_code=nodecodes.glue local disc_code=nodecodes.disc local math_code=nodecodes.math local dir_code=nodecodes.dir -local localpar_code=nodecodes.localpar +local par_code=nodecodes.par local lefttoright_code=nodes.dirvalues.lefttoright local righttoleft_code=nodes.dirvalues.righttoleft local discretionarydisc_code=disccodes.discretionary @@ -22097,11 +22113,23 @@ local function markstoligature(head,start,stop,char) setsubtype(base,ligatureglyph_code) set_components(base,start) setlink(prev,base,next) + flush_components(start) return head,base end end +local no_left_ligature_code=1 +local no_right_ligature_code=2 +local no_left_kern_code=4 +local no_right_kern_code=8 +local has_glyph_option=node.direct.has_glyph_option or function(n,c) + if c==no_left_ligature_code or c==no_right_ligature_code then + return getattr(n,a_noligature)==1 + else + return false + end +end local function toligature(head,start,stop,char,dataset,sequence,skiphash,discfound,hasmarks) - if getattr(start,a_noligature)==1 then + if has_glyph_option(start,no_right_ligature_code) then return head,start end if start==stop and getchar(start)==char then @@ -22165,6 +22193,7 @@ local function toligature(head,start,stop,char,dataset,sequence,skiphash,discfou break end end + flush_components(components) else local discprev,discnext=getboth(discfound) if discprev and discnext then @@ -22451,78 +22480,86 @@ function handlers.gsub_ligature(head,start,dataset,sequence,ligature,rlmode,skip return head,start,false,false end function handlers.gpos_single(head,start,dataset,sequence,kerns,rlmode,skiphash,step,injection) - local startchar=getchar(start) - local format=step.format - if format=="single" or type(kerns)=="table" then - local dx,dy,w,h=setposition(0,start,factor,rlmode,kerns,injection) - if trace_kerns then - logprocess("%s: shifting single %s by %s xy (%p,%p) and wh (%p,%p)",pref(dataset,sequence),gref(startchar),format,dx,dy,w,h) - end + if has_glyph_option(start,no_right_kern_code) then + return head,start,false else - local k=(format=="move" and setmove or setkern)(start,factor,rlmode,kerns,injection) - if trace_kerns then - logprocess("%s: shifting single %s by %s %p",pref(dataset,sequence),gref(startchar),format,k) + local startchar=getchar(start) + local format=step.format + if format=="single" or type(kerns)=="table" then + local dx,dy,w,h=setposition(0,start,factor,rlmode,kerns,injection) + if trace_kerns then + logprocess("%s: shifting single %s by %s xy (%p,%p) and wh (%p,%p)",pref(dataset,sequence),gref(startchar),format,dx,dy,w,h) + end + else + local k=(format=="move" and setmove or setkern)(start,factor,rlmode,kerns,injection) + if trace_kerns then + logprocess("%s: shifting single %s by %s %p",pref(dataset,sequence),gref(startchar),format,k) + end end + return head,start,true end - return head,start,true end function handlers.gpos_pair(head,start,dataset,sequence,kerns,rlmode,skiphash,step,injection) - local snext=getnext(start) - if not snext then + if has_glyph_option(start,no_right_kern_code) then return head,start,false else - local prev=start - while snext do - local nextchar=ischar(snext,currentfont) - if nextchar then - if skiphash and skiphash[nextchar] then - prev=snext - snext=getnext(snext) - else - local krn=kerns[nextchar] - if not krn then - break - end - local format=step.format - if format=="pair" then - local a=krn[1] - local b=krn[2] - if a==true then - elseif a then - local x,y,w,h=setposition(1,start,factor,rlmode,a,injection) - if trace_kerns then - local startchar=getchar(start) - logprocess("%s: shifting first of pair %s and %s by xy (%p,%p) and wh (%p,%p) as %s",pref(dataset,sequence),gref(startchar),gref(nextchar),x,y,w,h,injection or "injections") - end + local snext=getnext(start) + if not snext then + return head,start,false + else + local prev=start + while snext do + local nextchar=ischar(snext,currentfont) + if nextchar then + if skiphash and skiphash[nextchar] then + prev=snext + snext=getnext(snext) + else + local krn=kerns[nextchar] + if not krn then + break end - if b==true then - start=snext - elseif b then - local x,y,w,h=setposition(2,snext,factor,rlmode,b,injection) + local format=step.format + if format=="pair" then + local a=krn[1] + local b=krn[2] + if a==true then + elseif a then + local x,y,w,h=setposition(1,start,factor,rlmode,a,injection) + if trace_kerns then + local startchar=getchar(start) + logprocess("%s: shifting first of pair %s and %s by xy (%p,%p) and wh (%p,%p) as %s",pref(dataset,sequence),gref(startchar),gref(nextchar),x,y,w,h,injection or "injections") + end + end + if b==true then + start=snext + elseif b then + local x,y,w,h=setposition(2,snext,factor,rlmode,b,injection) + if trace_kerns then + local startchar=getchar(start) + logprocess("%s: shifting second of pair %s and %s by xy (%p,%p) and wh (%p,%p) as %s",pref(dataset,sequence),gref(startchar),gref(nextchar),x,y,w,h,injection or "injections") + end + start=snext + elseif forcepairadvance then + start=snext + end + return head,start,true + elseif krn~=0 then + local k=(format=="move" and setmove or setkern)(snext,factor,rlmode,krn,injection) if trace_kerns then - local startchar=getchar(start) - logprocess("%s: shifting second of pair %s and %s by xy (%p,%p) and wh (%p,%p) as %s",pref(dataset,sequence),gref(startchar),gref(nextchar),x,y,w,h,injection or "injections") + logprocess("%s: inserting %s %p between %s and %s as %s",pref(dataset,sequence),format,k,gref(getchar(prev)),gref(nextchar),injection or "injections") end - start=snext - elseif forcepairadvance then - start=snext - end - return head,start,true - elseif krn~=0 then - local k=(format=="move" and setmove or setkern)(snext,factor,rlmode,krn,injection) - if trace_kerns then - logprocess("%s: inserting %s %p between %s and %s as %s",pref(dataset,sequence),format,k,gref(getchar(prev)),gref(nextchar),injection or "injections") + return head,start,true + else + break end - return head,start,true - else - break end + else + break end - else - break end + return head,start,false end - return head,start,false end end function handlers.gpos_mark2base(head,start,dataset,sequence,markanchors,rlmode,skiphash) @@ -22952,89 +22989,93 @@ function chainprocs.gsub_ligature(head,start,stop,dataset,sequence,currentlookup return head,start,false,0,false end function chainprocs.gpos_single(head,start,stop,dataset,sequence,currentlookup,rlmode,skiphash,chainindex) - local mapping=currentlookup.mapping - if mapping==nil then - mapping=getmapping(dataset,sequence,currentlookup) - end - if mapping then - local startchar=getchar(start) - local kerns=mapping[startchar] - if kerns then - local format=currentlookup.format - if format=="single" then - local dx,dy,w,h=setposition(0,start,factor,rlmode,kerns) - if trace_kerns then - logprocess("%s: shifting single %s by %s (%p,%p) and correction (%p,%p)",cref(dataset,sequence),gref(startchar),format,dx,dy,w,h) - end - else - local k=(format=="move" and setmove or setkern)(start,factor,rlmode,kerns,injection) - if trace_kerns then - logprocess("%s: shifting single %s by %s %p",cref(dataset,sequence),gref(startchar),format,k) + if not has_glyph_option(start,no_right_kern_code) then + local mapping=currentlookup.mapping + if mapping==nil then + mapping=getmapping(dataset,sequence,currentlookup) + end + if mapping then + local startchar=getchar(start) + local kerns=mapping[startchar] + if kerns then + local format=currentlookup.format + if format=="single" then + local dx,dy,w,h=setposition(0,start,factor,rlmode,kerns) + if trace_kerns then + logprocess("%s: shifting single %s by %s (%p,%p) and correction (%p,%p)",cref(dataset,sequence),gref(startchar),format,dx,dy,w,h) + end + else + local k=(format=="move" and setmove or setkern)(start,factor,rlmode,kerns,injection) + if trace_kerns then + logprocess("%s: shifting single %s by %s %p",cref(dataset,sequence),gref(startchar),format,k) + end end + return head,start,true end - return head,start,true end end return head,start,false end -function chainprocs.gpos_pair(head,start,stop,dataset,sequence,currentlookup,rlmode,skiphash,chainindex) - local mapping=currentlookup.mapping - if mapping==nil then - mapping=getmapping(dataset,sequence,currentlookup) - end - if mapping then - local snext=getnext(start) - if snext then - local startchar=getchar(start) - local kerns=mapping[startchar] - if kerns then - local prev=start - while snext do - local nextchar=ischar(snext,currentfont) - if not nextchar then - break - end - if skiphash and skiphash[nextchar] then - prev=snext - snext=getnext(snext) - else - local krn=kerns[nextchar] - if not krn then +function chainprocs.gpos_pair(head,start,stop,dataset,sequence,currentlookup,rlmode,skiphash,chainindex) + if not has_glyph_option(start,no_right_kern_code) then + local mapping=currentlookup.mapping + if mapping==nil then + mapping=getmapping(dataset,sequence,currentlookup) + end + if mapping then + local snext=getnext(start) + if snext then + local startchar=getchar(start) + local kerns=mapping[startchar] + if kerns then + local prev=start + while snext do + local nextchar=ischar(snext,currentfont) + if not nextchar then break end - local format=currentlookup.format - if format=="pair" then - local a=krn[1] - local b=krn[2] - if a==true then - elseif a then - local x,y,w,h=setposition(1,start,factor,rlmode,a,"injections") - if trace_kerns then - local startchar=getchar(start) - logprocess("%s: shifting first of pair %s and %s by (%p,%p) and correction (%p,%p)",cref(dataset,sequence),gref(startchar),gref(nextchar),x,y,w,h) - end + if skiphash and skiphash[nextchar] then + prev=snext + snext=getnext(snext) + else + local krn=kerns[nextchar] + if not krn then + break end - if b==true then - start=snext - elseif b then - local x,y,w,h=setposition(2,snext,factor,rlmode,b,"injections") + local format=currentlookup.format + if format=="pair" then + local a=krn[1] + local b=krn[2] + if a==true then + elseif a then + local x,y,w,h=setposition(1,start,factor,rlmode,a,"injections") + if trace_kerns then + local startchar=getchar(start) + logprocess("%s: shifting first of pair %s and %s by (%p,%p) and correction (%p,%p)",cref(dataset,sequence),gref(startchar),gref(nextchar),x,y,w,h) + end + end + if b==true then + start=snext + elseif b then + local x,y,w,h=setposition(2,snext,factor,rlmode,b,"injections") + if trace_kerns then + local startchar=getchar(start) + logprocess("%s: shifting second of pair %s and %s by (%p,%p) and correction (%p,%p)",cref(dataset,sequence),gref(startchar),gref(nextchar),x,y,w,h) + end + start=snext + elseif forcepairadvance then + start=snext + end + return head,start,true + elseif krn~=0 then + local k=(format=="move" and setmove or setkern)(snext,factor,rlmode,krn) if trace_kerns then - local startchar=getchar(start) - logprocess("%s: shifting second of pair %s and %s by (%p,%p) and correction (%p,%p)",cref(dataset,sequence),gref(startchar),gref(nextchar),x,y,w,h) + logprocess("%s: inserting %s %p between %s and %s",cref(dataset,sequence),format,k,gref(getchar(prev)),gref(nextchar)) end - start=snext - elseif forcepairadvance then - start=snext - end - return head,start,true - elseif krn~=0 then - local k=(format=="move" and setmove or setkern)(snext,factor,rlmode,krn) - if trace_kerns then - logprocess("%s: inserting %s %p between %s and %s",cref(dataset,sequence),format,k,gref(getchar(prev)),gref(nextchar)) + return head,start,true + else + break end - return head,start,true - else - break end end end @@ -24856,7 +24897,7 @@ do checkstep(head) end local initialrl=0 - if getid(head)==localpar_code and start_of_par(head) then + if getid(head)==par_code and start_of_par(head) then initialrl=pardirstate(head) elseif direction==righttoleft_code then initialrl=-1 @@ -25401,10 +25442,10 @@ registerotffeature { }, } -end --- [luaotfload, fontloader-2020-08-31.lua scope for “font-ots”] --- +end --- [luaotfload, fontloader-2020-12-30.lua scope for “font-ots”] --- -do --- [luaotfload, fontloader-2020-08-31.lua scope for “font-osd” 61f05fcf91add1aa5dac9bc8b235adc9] --- +do --- [luaotfload, fontloader-2020-12-30.lua scope for “font-osd” 73c9531c79df5ada320cb20777f7ed49] --- if not modules then modules={} end modules ['font-osd']={ version=1.001, @@ -27837,10 +27878,10 @@ for i=1,nofscripts do methods[scripts_two[i]]=method_two end -end --- [luaotfload, fontloader-2020-08-31.lua scope for “font-osd”] --- +end --- [luaotfload, fontloader-2020-12-30.lua scope for “font-osd”] --- -do --- [luaotfload, fontloader-2020-08-31.lua scope for “font-ocl” ab81576f20e2d37bc8707e1dbd3decf2] --- +do --- [luaotfload, fontloader-2020-12-30.lua scope for “font-ocl” 797b5c71bf819c5f4fb314a4d646e9a7] --- if not modules then modules={} end modules ['font-ocl']={ version=1.001, @@ -28383,10 +28424,10 @@ if context then } end -end --- [luaotfload, fontloader-2020-08-31.lua scope for “font-ocl”] --- +end --- [luaotfload, fontloader-2020-12-30.lua scope for “font-ocl”] --- -do --- [luaotfload, fontloader-2020-08-31.lua scope for “font-otc” 1204a2fdc436e644127c0aa38ab69607] --- +do --- [luaotfload, fontloader-2020-12-30.lua scope for “font-otc” 0f12230ea07b5151f75d52726977e91f] --- if not modules then modules={} end modules ['font-otc']={ version=1.001, @@ -29143,10 +29184,10 @@ end otf.enhancers.enhance=enhance otf.enhancers.register("check extra features",enhance) -end --- [luaotfload, fontloader-2020-08-31.lua scope for “font-otc”] --- +end --- [luaotfload, fontloader-2020-12-30.lua scope for “font-otc”] --- -do --- [luaotfload, fontloader-2020-08-31.lua scope for “font-onr” 7a9ece7bf3e36b5f0adf295a9a2a2989] --- +do --- [luaotfload, fontloader-2020-12-30.lua scope for “font-onr” 6d161533f3437435e12a0ad64866df44] --- if not modules then modules={} end modules ['font-onr']={ version=1.001, @@ -29519,10 +29560,10 @@ function readers.getinfo(filename) end end -end --- [luaotfload, fontloader-2020-08-31.lua scope for “font-onr”] --- +end --- [luaotfload, fontloader-2020-12-30.lua scope for “font-onr”] --- -do --- [luaotfload, fontloader-2020-08-31.lua scope for “font-one” 1402ae8e4e96186c848fa2742388fb24] --- +do --- [luaotfload, fontloader-2020-12-30.lua scope for “font-one” 53cd565030e919da984b50471cc3be37] --- if not modules then modules={} end modules ['font-one']={ version=1.001, @@ -30021,7 +30062,6 @@ local function copytotfm(data) parameters.descender=abs(metadata.descender or 0) parameters.units=1000 properties.spacer=spacer - properties.encodingbytes=2 properties.format=fonts.formats[filename] or "type1" properties.filename=filename properties.fontname=fontname @@ -30029,6 +30069,9 @@ local function copytotfm(data) properties.psname=fullname properties.name=filename or fullname or fontname properties.private=properties.private or data.private or privateoffset +if not CONTEXTLMTXMODE or CONTEXTLMTXMODE==0 then + properties.encodingbytes=2 +end if next(characters) then return { characters=characters, @@ -30234,10 +30277,10 @@ registerafmenhancer("normalize features",enhance_normalize_features) registerafmenhancer("check extra features",otfenhancers.enhance) registerafmenhancer("fix names",enhance_fix_names) -end --- [luaotfload, fontloader-2020-08-31.lua scope for “font-one”] --- +end --- [luaotfload, fontloader-2020-12-30.lua scope for “font-one”] --- -do --- [luaotfload, fontloader-2020-08-31.lua scope for “font-afk” 54d554530e75c57c56ee76234724e26d] --- +do --- [luaotfload, fontloader-2020-12-30.lua scope for “font-afk” 9da14e0fb22129c053acc599d1312544] --- if not modules then modules={} end modules ['font-afk']={ version=1.001, @@ -30404,10 +30447,10 @@ fonts.handlers.afm.helpdata={ } } -end --- [luaotfload, fontloader-2020-08-31.lua scope for “font-afk”] --- +end --- [luaotfload, fontloader-2020-12-30.lua scope for “font-afk”] --- -do --- [luaotfload, fontloader-2020-08-31.lua scope for “fonts-tfm” 3bbba3214fd0b8c6f35ad85592fc2917] --- +do --- [luaotfload, fontloader-2020-12-30.lua scope for “fonts-tfm” f0eb5e2a8068b17ad401bb7efdba1630] --- if not modules then modules={} end modules ['luatex-fonts-tfm']={ version=1.001, @@ -30922,10 +30965,10 @@ registertfmfeature { } } -end --- [luaotfload, fontloader-2020-08-31.lua scope for “fonts-tfm”] --- +end --- [luaotfload, fontloader-2020-12-30.lua scope for “fonts-tfm”] --- -do --- [luaotfload, fontloader-2020-08-31.lua scope for “font-lua” 55b281fb98f7bd848fc19928f376f647] --- +do --- [luaotfload, fontloader-2020-12-30.lua scope for “font-lua” 1fbfdf7b689b2bdfd0e3bb9bf74ce136] --- if not modules then modules={} end modules ['font-lua']={ version=1.001, @@ -30965,10 +31008,10 @@ function readers.lua(specification) return check_lua(specification,fullname) end -end --- [luaotfload, fontloader-2020-08-31.lua scope for “font-lua”] --- +end --- [luaotfload, fontloader-2020-12-30.lua scope for “font-lua”] --- -do --- [luaotfload, fontloader-2020-08-31.lua scope for “font-def” 226b4d26ede7fa7be8e45b7f0d93e781] --- +do --- [luaotfload, fontloader-2020-12-30.lua scope for “font-def” b9d908c2338b7dc443ce9d1e9fcb7139] --- if not modules then modules={} end modules ['font-def']={ version=1.001, @@ -31368,10 +31411,10 @@ if not context then callbacks.register('define_font',definers.read,"definition of fonts (tfmdata preparation)") end -end --- [luaotfload, fontloader-2020-08-31.lua scope for “font-def”] --- +end --- [luaotfload, fontloader-2020-12-30.lua scope for “font-def”] --- -do --- [luaotfload, fontloader-2020-08-31.lua scope for “font-shp” c4a8c14513597ce3579d3ad4c580fe51] --- +do --- [luaotfload, fontloader-2020-12-30.lua scope for “font-shp” 5ff497c993112d4fef4c148348d964eb] --- if not modules then modules={} end modules ['font-shp']={ version=1.001, @@ -31382,7 +31425,7 @@ if not modules then modules={} end modules ['font-shp']={ } local tonumber,next=tonumber,next local concat=table.concat -local formatters=string.formatters +local formatters,lower=string.formatters,string.lower local otf=fonts.handlers.otf local afm=fonts.handlers.afm local pfb=fonts.handlers.pfb @@ -31575,7 +31618,7 @@ end local function loadstreams(cache,filename,sub,instance) local base=file.basename(filename) local name=file.removesuffix(base) - local kind=file.suffix(filename) + local kind=lower(file.suffix(filename)) local attr=lfs.attributes(filename) local size=attr and attr.size or 0 local time=attr and attr.modification or 0 @@ -31736,10 +31779,10 @@ callback.register("glyph_stream_provider",function(id,index,mode) return "" end) -end --- [luaotfload, fontloader-2020-08-31.lua scope for “font-shp”] --- +end --- [luaotfload, fontloader-2020-12-30.lua scope for “font-shp”] --- -do --- [luaotfload, fontloader-2020-08-31.lua scope for “fonts-def” 5ad79120ebc5e60f4d322fb3ee13bffe] --- +do --- [luaotfload, fontloader-2020-12-30.lua scope for “fonts-def” f435e0875f203f343157baeff876ec9c] --- if not modules then modules={} end modules ['luatex-fonts-def']={ version=1.001, @@ -31820,10 +31863,10 @@ function fonts.definers.applypostprocessors(tfmdata) return tfmdata end -end --- [luaotfload, fontloader-2020-08-31.lua scope for “fonts-def”] --- +end --- [luaotfload, fontloader-2020-12-30.lua scope for “fonts-def”] --- -do --- [luaotfload, fontloader-2020-08-31.lua scope for “fonts-ext” 01015ab3758cdc2af29394e6d502a91a] --- +do --- [luaotfload, fontloader-2020-12-30.lua scope for “fonts-ext” 32013cbc5d5d336be8b1d1e5879d86c4] --- if not modules then modules={} end modules ['luatex-fonts-ext']={ version=1.001, @@ -32009,10 +32052,10 @@ registerotffeature { } } -end --- [luaotfload, fontloader-2020-08-31.lua scope for “fonts-ext”] --- +end --- [luaotfload, fontloader-2020-12-30.lua scope for “fonts-ext”] --- -do --- [luaotfload, fontloader-2020-08-31.lua scope for “font-imp-tex” 77c374b0ef00c2fb12188ec42beb4257] --- +do --- [luaotfload, fontloader-2020-12-30.lua scope for “font-imp-tex” ceb087ef6fa2f89aed7179f60ddf8f35] --- if not modules then modules={} end modules ['font-imp-tex']={ version=1.001, @@ -32111,10 +32154,10 @@ registerotffeature { description="arabic digits", } -end --- [luaotfload, fontloader-2020-08-31.lua scope for “font-imp-tex”] --- +end --- [luaotfload, fontloader-2020-12-30.lua scope for “font-imp-tex”] --- -do --- [luaotfload, fontloader-2020-08-31.lua scope for “font-imp-ligatures” 043daa4fcccf2560868da359d71d3a4a] --- +do --- [luaotfload, fontloader-2020-12-30.lua scope for “font-imp-ligatures” 26ffcf089391445f7af59536c8814364] --- if not modules then modules={} end modules ['font-imp-ligatures']={ version=1.001, @@ -32228,10 +32271,10 @@ if context then } end -end --- [luaotfload, fontloader-2020-08-31.lua scope for “font-imp-ligatures”] --- +end --- [luaotfload, fontloader-2020-12-30.lua scope for “font-imp-ligatures”] --- -do --- [luaotfload, fontloader-2020-08-31.lua scope for “font-imp-italics” 058fb834c11c6ac30c280b29e496966e] --- +do --- [luaotfload, fontloader-2020-12-30.lua scope for “font-imp-italics” ae563638fa29a4ff3e8e4d1e81fd35ae] --- if not modules then modules={} end modules ['font-imp-italics']={ version=1.001, @@ -32335,10 +32378,10 @@ if context then registerafmfeature(dimensions_specification) end -end --- [luaotfload, fontloader-2020-08-31.lua scope for “font-imp-italics”] --- +end --- [luaotfload, fontloader-2020-12-30.lua scope for “font-imp-italics”] --- -do --- [luaotfload, fontloader-2020-08-31.lua scope for “font-imp-effects” 582f9dd5031e9d67fff389efd16a874f] --- +do --- [luaotfload, fontloader-2020-12-30.lua scope for “font-imp-effects” a2dde5e071fcb3fc7b90f2bcd5aa4f22] --- if not modules then modules={} end modules ['font-imp-effects']={ version=1.001, @@ -32522,56 +32565,74 @@ local rules={ "FractionRuleThickness", "UnderbarRuleThickness", } -local function setmathparameters(tfmdata,characters,mathparameters,dx,dy,squeeze) - if delta~=0 then - for i=1,#rules do - local name=rules[i] - local value=mathparameters[name] - if value then - mathparameters[name]=(squeeze or 1)*(value+dx) +local setmathparameters +local setmathcharacters +if CONTEXTLMTXMODE and CONTEXTLMTXMODE>0 then + setmathparameters=function(tfmdata,characters,mathparameters,dx,dy,squeeze,multiplier) + if delta~=0 then + for i=1,#rules do + local name=rules[i] + local value=mathparameters[name] + if value then + mathparameters[name]=(squeeze or 1)*(value+dy) + end end end end -end -local function setmathcharacters(tfmdata,characters,mathparameters,dx,dy,squeeze,wdelta,hdelta,ddelta) - local function wdpatch(char) - if wsnap~=0 then - char.width=char.width+wdelta/2 - end + setmathcharacters=function() end - local function htpatch(char) - if hsnap~=0 then - local height=char.height - if height then - char.height=char.height+2*dy +else + setmathparameters=function(tfmdata,characters,mathparameters,dx,dy,squeeze,multiplier) + if delta~=0 then + for i=1,#rules do + local name=rules[i] + local value=mathparameters[name] + if value then + mathparameters[name]=(squeeze or 1)*(value+dy) + end end end end - local character=characters[0x221A] - if character and character.next then - local char=character - local next=character.next - wdpatch(char) - htpatch(char) - while next do - char=characters[next] + setmathcharacters=function(tfmdata,characters,mathparameters,dx,dy,squeeze,wdelta,hdelta,ddelta) + local function wdpatch(char) + if wsnap~=0 then + char.width=char.width+wdelta/2 + end + end + local function htpatch(char) + if hsnap~=0 then + local height=char.height + if height then + char.height=char.height+2*dy + end + end + end + local character=characters[0x221A] + if character and character.next then + local char=character + local next=character.next wdpatch(char) htpatch(char) - next=char.next - end - if char then - local v=char.vert_variants - if v then - local top=v[#v] - if top then - local char=characters[top.glyph] - htpatch(char) + while next do + char=characters[next] + wdpatch(char) + htpatch(char) + next=char.next + end + if char then + local v=char.vert_variants + if v then + local top=v[#v] + if top then + local char=characters[top.glyph] + htpatch(char) + end end end end end end -local shiftmode=CONTEXTLMTXMODE>0 +local shiftmode=CONTEXTLMTXMODE and CONTEXTLMTXMODE>0 local function manipulateeffect(tfmdata) local effect=tfmdata.properties.effect if effect then @@ -32643,7 +32704,7 @@ local function manipulateeffect(tfmdata) end end if mathparameters then - setmathparameters(tfmdata,characters,mathparameters,dx,dy,squeeze) + setmathparameters(tfmdata,characters,mathparameters,dx,dy,squeeze,multiplier) setmathcharacters(tfmdata,characters,mathparameters,dx,dy,squeeze,wdelta,hdelta,ddelta) end parameters.factor=factor @@ -32703,10 +32764,10 @@ local specification={ registerotffeature(specification) registerafmfeature(specification) -end --- [luaotfload, fontloader-2020-08-31.lua scope for “font-imp-effects”] --- +end --- [luaotfload, fontloader-2020-12-30.lua scope for “font-imp-effects”] --- -do --- [luaotfload, fontloader-2020-08-31.lua scope for “fonts-lig” b9dbe77ce747d4c35bb2a20ffbe5aa51] --- +do --- [luaotfload, fontloader-2020-12-30.lua scope for “fonts-lig” fbd251eea3810a43a8d5542319361d68] --- fonts.handlers.otf.addfeature { @@ -34775,10 +34836,10 @@ fonts.handlers.otf.addfeature { ["type"]="ligature", } -end --- [luaotfload, fontloader-2020-08-31.lua scope for “fonts-lig”] --- +end --- [luaotfload, fontloader-2020-12-30.lua scope for “fonts-lig”] --- -do --- [luaotfload, fontloader-2020-08-31.lua scope for “fonts-gbn” d25472d54c4841db43a745764a63533e] --- +do --- [luaotfload, fontloader-2020-12-30.lua scope for “fonts-gbn” 10ecdf01e7c926e5128ad8a9dff4d677] --- if not modules then modules={} end modules ['luatex-fonts-gbn']={ version=1.001, @@ -35043,7 +35104,7 @@ function nodes.simple_font_handler(head,groupcode,size,packtype,direction) return head end -end --- [luaotfload, fontloader-2020-08-31.lua scope for “fonts-gbn”] --- +end --- [luaotfload, fontloader-2020-12-30.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 67abf707b17..25f5473a5a3 100644 --- a/Master/texmf-dist/tex/luatex/luaotfload/fontloader-basics-nod.lua +++ b/Master/texmf-dist/tex/luatex/luaotfload/fontloader-basics-nod.lua @@ -107,6 +107,7 @@ nuts.getkern = direct.getkern nuts.getlist = direct.getlist nuts.getnext = direct.getnext nuts.getoffsets = direct.getoffsets +nuts.getoptions = direct.getoptions or function() return 0 end nuts.getprev = direct.getprev nuts.getsubtype = direct.getsubtype nuts.getwidth = direct.getwidth @@ -206,6 +207,19 @@ local copy_node = nuts.copy_node local glyph_code = nodes.nodecodes.glyph local ligature_code = nodes.glyphcodes.ligature +do -- this is consistent with the rest of context, not that we need it + + local p = nodecodes.localpar or nodecodes.local_par + + if p then + nodecodes.par = p + nodecodes[p] = "par" + nodecodes.localpar = p -- for old times sake + nodecodes.local_par = p -- for old times sake + end + +end + do local get_components = node.direct.getcomponents @@ -264,11 +278,16 @@ do return 0 end + local function flush_components() + -- this is a no-op in mkiv / generic + end + nuts.set_components = set_components nuts.get_components = get_components nuts.copy_only_glyphs = copy_only_glyphs nuts.copy_no_components = copy_no_components nuts.count_components = count_components + nuts.flush_components = flush_components end 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 0cff896e8d9..91ee83b19b2 100644 --- a/Master/texmf-dist/tex/luatex/luaotfload/fontloader-font-dsp.lua +++ b/Master/texmf-dist/tex/luatex/luaotfload/fontloader-font-dsp.lua @@ -823,7 +823,7 @@ end -- quite often 0, 1, 2 -function readarray(f,offset) +local function readarray(f,offset) if offset then setposition(f,offset) end diff --git a/Master/texmf-dist/tex/luatex/luaotfload/fontloader-font-imp-effects.lua b/Master/texmf-dist/tex/luatex/luaotfload/fontloader-font-imp-effects.lua index bd6cce87952..43ce82b71a6 100644 --- a/Master/texmf-dist/tex/luatex/luaotfload/fontloader-font-imp-effects.lua +++ b/Master/texmf-dist/tex/luatex/luaotfload/fontloader-font-imp-effects.lua @@ -215,62 +215,88 @@ local rules = { -- end -- end -local function setmathparameters(tfmdata,characters,mathparameters,dx,dy,squeeze) - if delta ~= 0 then - for i=1,#rules do - local name = rules[i] - local value = mathparameters[name] - if value then - mathparameters[name] = (squeeze or 1) * (value + dx) +-- radicals are not yet ok + +local setmathparameters +local setmathcharacters + +if CONTEXTLMTXMODE and CONTEXTLMTXMODE > 0 then + + setmathparameters = function(tfmdata,characters,mathparameters,dx,dy,squeeze,multiplier) + if delta ~= 0 then + for i=1,#rules do + local name = rules[i] + local value = mathparameters[name] + if value then + mathparameters[name] = (squeeze or 1) * (value + dy) + end end end end -end -local function setmathcharacters(tfmdata,characters,mathparameters,dx,dy,squeeze,wdelta,hdelta,ddelta) + setmathcharacters = function() + end - local function wdpatch(char) - if wsnap ~= 0 then - char.width = char.width + wdelta/2 +else + + setmathparameters = function(tfmdata,characters,mathparameters,dx,dy,squeeze,multiplier) + if delta ~= 0 then + for i=1,#rules do + local name = rules[i] + local value = mathparameters[name] + if value then + mathparameters[name] = (squeeze or 1) * (value + dy) + end + end end end - local function htpatch(char) - if hsnap ~= 0 then - local height = char.height - if height then - char.height = char.height + 2 * dy + setmathcharacters = function(tfmdata,characters,mathparameters,dx,dy,squeeze,wdelta,hdelta,ddelta) + + -- still not the perfect rule + + local function wdpatch(char) + if wsnap ~= 0 then + char.width = char.width + wdelta/2 + end + end + + local function htpatch(char) + if hsnap ~= 0 then + local height = char.height + if height then + char.height = char.height + 2 * dy + end end end - end - local character = characters[0x221A] + local character = characters[0x221A] - if character and character.next then --- print("base char",0x221A,table.sequenced(character)) - local char = character - local next = character.next - wdpatch(char) - htpatch(char) - while next do - char = characters[next] + if character and character.next then + local char = character + local next = character.next wdpatch(char) htpatch(char) --- print("next char",next,table.sequenced(char)) - next = char.next - end - if char then - local v = char.vert_variants - if v then - local top = v[#v] - if top then - local char = characters[top.glyph] --- print("top char",top.glyph,table.sequenced(char)) - htpatch(char) + while next do + char = characters[next] + wdpatch(char) + htpatch(char) + next = char.next + end + if char then + local v = char.vert_variants + if v then + local top = v[#v] + if top then + local char = characters[top.glyph] + htpatch(char) + end end end end + end + end -- local show_effect = { "lua", function(f,c) @@ -278,10 +304,7 @@ end -- inspect(fonts.hashes.characters[f][c]) -- end } --- local show_effect = { "lua", "print('!')" } - ------ shiftmode = false -- test in mkiv and lmtx -local shiftmode = CONTEXTLMTXMODE > 0 +local shiftmode = CONTEXTLMTXMODE and CONTEXTLMTXMODE > 0 local function manipulateeffect(tfmdata) local effect = tfmdata.properties.effect @@ -358,7 +381,7 @@ local function manipulateeffect(tfmdata) end end if mathparameters then - setmathparameters(tfmdata,characters,mathparameters,dx,dy,squeeze) + setmathparameters(tfmdata,characters,mathparameters,dx,dy,squeeze,multiplier) setmathcharacters(tfmdata,characters,mathparameters,dx,dy,squeeze,wdelta,hdelta,ddelta) end parameters.factor = factor diff --git a/Master/texmf-dist/tex/luatex/luaotfload/fontloader-font-one.lua b/Master/texmf-dist/tex/luatex/luaotfload/fontloader-font-one.lua index a76c9298599..5ef6e47497a 100644 --- a/Master/texmf-dist/tex/luatex/luaotfload/fontloader-font-one.lua +++ b/Master/texmf-dist/tex/luatex/luaotfload/fontloader-font-one.lua @@ -592,15 +592,18 @@ local function copytotfm(data) parameters.descender = abs(metadata.descender or 0) parameters.units = 1000 -- - properties.spacer = spacer + properties.spacer = spacer + properties.format = fonts.formats[filename] or "type1" + properties.filename = filename + properties.fontname = fontname + properties.fullname = fullname + properties.psname = fullname + properties.name = filename or fullname or fontname + properties.private = properties.private or data.private or privateoffset + -- +if not CONTEXTLMTXMODE or CONTEXTLMTXMODE == 0 then properties.encodingbytes = 2 - properties.format = fonts.formats[filename] or "type1" - properties.filename = filename - properties.fontname = fontname - properties.fullname = fullname - properties.psname = fullname - properties.name = filename or fullname or fontname - properties.private = properties.private or data.private or privateoffset +end -- if next(characters) then return { 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 aff4cc8c8d9..b8e13f1070b 100644 --- a/Master/texmf-dist/tex/luatex/luaotfload/fontloader-font-otl.lua +++ b/Master/texmf-dist/tex/luatex/luaotfload/fontloader-font-otl.lua @@ -52,7 +52,7 @@ local report_otf = logs.reporter("fonts","otf loading") local fonts = fonts local otf = fonts.handlers.otf -otf.version = 3.111 -- beware: also sync font-mis.lua and in mtx-fonts +otf.version = 3.112 -- 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) @@ -486,23 +486,26 @@ local function copytotfm(data,cache_id) end end -- - parameters.designsize = (designsize/10)*65536 - parameters.minsize = (minsize /10)*65536 - parameters.maxsize = (maxsize /10)*65536 - parameters.ascender = abs(metadata.ascender or 0) - parameters.descender = abs(metadata.descender or 0) - parameters.units = units - parameters.vheight = metadata.defaultvheight + parameters.designsize = (designsize/10)*65536 + parameters.minsize = (minsize /10)*65536 + parameters.maxsize = (maxsize /10)*65536 + parameters.ascender = abs(metadata.ascender or 0) + parameters.descender = abs(metadata.descender or 0) + parameters.units = units + parameters.vheight = metadata.defaultvheight -- - properties.space = spacer + properties.space = spacer + properties.format = data.format or formats.otf + properties.filename = filename + properties.fontname = fontname + properties.fullname = fullname + properties.psname = psname + properties.name = filename or fullname + properties.subfont = subfont + -- +if not CONTEXTLMTXMODE or CONTEXTLMTXMODE == 0 then properties.encodingbytes = 2 - properties.format = data.format or formats.otf - properties.filename = filename - properties.fontname = fontname - properties.fullname = fullname - properties.psname = psname - properties.name = filename or fullname - properties.subfont = subfont +end -- -- properties.name = specification.name -- properties.sub = specification.sub 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 490f28de699..1f4806ee257 100644 --- a/Master/texmf-dist/tex/luatex/luaotfload/fontloader-font-ots.lua +++ b/Master/texmf-dist/tex/luatex/luaotfload/fontloader-font-ots.lua @@ -13,7 +13,7 @@ with plain <l n='tex'/> it has to be so. This module is part of <l n='context'/> and discussion about improvements and functionality mostly happens on the <l n='context'/> mailing list.</p> -<p>The specification of OpenType is (or at least a decade ago was) kind of vague. +<p>The specification of OpenType is (or at least decades ago was) kind of vague. Apart from a lack of a proper free specifications there's also the problem that Microsoft and Adobe may have their own interpretation of how and in what order to apply features. In general the Microsoft website has more detailed specifications @@ -218,6 +218,7 @@ local copy_only_glyphs = nuts.copy_only_glyphs local count_components = nuts.count_components local set_components = nuts.set_components local get_components = nuts.get_components +local flush_components = nuts.flush_components --------------------------------------------------------------------------------------- @@ -251,7 +252,7 @@ local glue_code = nodecodes.glue local disc_code = nodecodes.disc local math_code = nodecodes.math local dir_code = nodecodes.dir -local localpar_code = nodecodes.localpar +local par_code = nodecodes.par local lefttoright_code = nodes.dirvalues.lefttoright local righttoleft_code = nodes.dirvalues.righttoleft @@ -488,6 +489,7 @@ local function markstoligature(head,start,stop,char) setsubtype(base,ligatureglyph_code) set_components(base,start) setlink(prev,base,next) + flush_components(start) return head, base end end @@ -500,9 +502,25 @@ end -- in the not discfound branch then. We now have skiphash too so we can be more -- selective if needed (todo). +-- we can have more granularity here but for now we only do a simple check + +local no_left_ligature_code = 1 +local no_right_ligature_code = 2 +local no_left_kern_code = 4 +local no_right_kern_code = 8 + +local has_glyph_option = node.direct.has_glyph_option or function(n,c) + if c == no_left_ligature_code or c == no_right_ligature_code then + return getattr(n,a_noligature) == 1 + else + return false + end +end + +-- in lmtx we need to check the components and can be slightly more clever + local function toligature(head,start,stop,char,dataset,sequence,skiphash,discfound,hasmarks) -- brr head - if getattr(start,a_noligature) == 1 then - -- so we can do: e\noligature{ff}e e\noligature{f}fie (we only look at the first) + if has_glyph_option(start,no_right_ligature_code) then return head, start end if start == stop and getchar(start) == char then @@ -572,6 +590,7 @@ local function toligature(head,start,stop,char,dataset,sequence,skiphash,discfou break end end + flush_components(components) else -- discfound ... forget about marks .. probably no scripts that hyphenate and have marks local discprev, discnext = getboth(discfound) @@ -902,81 +921,89 @@ function handlers.gsub_ligature(head,start,dataset,sequence,ligature,rlmode,skip end function handlers.gpos_single(head,start,dataset,sequence,kerns,rlmode,skiphash,step,injection) - local startchar = getchar(start) - local format = step.format - if format == "single" or type(kerns) == "table" then -- the table check can go - local dx, dy, w, h = setposition(0,start,factor,rlmode,kerns,injection) - if trace_kerns then - logprocess("%s: shifting single %s by %s xy (%p,%p) and wh (%p,%p)",pref(dataset,sequence),gref(startchar),format,dx,dy,w,h) - end + if has_glyph_option(start,no_right_kern_code) then + return head, start, false else - local k = (format == "move" and setmove or setkern)(start,factor,rlmode,kerns,injection) - if trace_kerns then - logprocess("%s: shifting single %s by %s %p",pref(dataset,sequence),gref(startchar),format,k) + local startchar = getchar(start) + local format = step.format + if format == "single" or type(kerns) == "table" then -- the table check can go + local dx, dy, w, h = setposition(0,start,factor,rlmode,kerns,injection) + if trace_kerns then + logprocess("%s: shifting single %s by %s xy (%p,%p) and wh (%p,%p)",pref(dataset,sequence),gref(startchar),format,dx,dy,w,h) + end + else + local k = (format == "move" and setmove or setkern)(start,factor,rlmode,kerns,injection) + if trace_kerns then + logprocess("%s: shifting single %s by %s %p",pref(dataset,sequence),gref(startchar),format,k) + end end + return head, start, true end - return head, start, true end function handlers.gpos_pair(head,start,dataset,sequence,kerns,rlmode,skiphash,step,injection) - local snext = getnext(start) - if not snext then + if has_glyph_option(start,no_right_kern_code) then return head, start, false else - local prev = start - while snext do - local nextchar = ischar(snext,currentfont) - if nextchar then - if skiphash and skiphash[nextchar] then -- includes marks too when flag - prev = snext - snext = getnext(snext) - else - local krn = kerns[nextchar] - if not krn then - break - end - local format = step.format - if format == "pair" then - local a = krn[1] - local b = krn[2] - if a == true then - -- zero - elseif a then -- #a > 0 - local x, y, w, h = setposition(1,start,factor,rlmode,a,injection) - if trace_kerns then - local startchar = getchar(start) - logprocess("%s: shifting first of pair %s and %s by xy (%p,%p) and wh (%p,%p) as %s",pref(dataset,sequence),gref(startchar),gref(nextchar),x,y,w,h,injection or "injections") - end + local snext = getnext(start) + if not snext then + return head, start, false + else + local prev = start + while snext do + local nextchar = ischar(snext,currentfont) + if nextchar then + if skiphash and skiphash[nextchar] then -- includes marks too when flag + prev = snext + snext = getnext(snext) + else + local krn = kerns[nextchar] + if not krn then + break end - if b == true then - -- zero - start = snext -- cf spec - elseif b then -- #b > 0 - local x, y, w, h = setposition(2,snext,factor,rlmode,b,injection) + local format = step.format + if format == "pair" then + local a = krn[1] + local b = krn[2] + if a == true then + -- zero + elseif a then -- #a > 0 + local x, y, w, h = setposition(1,start,factor,rlmode,a,injection) + if trace_kerns then + local startchar = getchar(start) + logprocess("%s: shifting first of pair %s and %s by xy (%p,%p) and wh (%p,%p) as %s",pref(dataset,sequence),gref(startchar),gref(nextchar),x,y,w,h,injection or "injections") + end + end + if b == true then + -- zero + start = snext -- cf spec + elseif b then -- #b > 0 + local x, y, w, h = setposition(2,snext,factor,rlmode,b,injection) + if trace_kerns then + local startchar = getchar(start) + logprocess("%s: shifting second of pair %s and %s by xy (%p,%p) and wh (%p,%p) as %s",pref(dataset,sequence),gref(startchar),gref(nextchar),x,y,w,h,injection or "injections") + end + start = snext -- cf spec + elseif forcepairadvance then + start = snext -- for testing, not cf spec + end + return head, start, true + elseif krn ~= 0 then + local k = (format == "move" and setmove or setkern)(snext,factor,rlmode,krn,injection) if trace_kerns then - local startchar = getchar(start) - logprocess("%s: shifting second of pair %s and %s by xy (%p,%p) and wh (%p,%p) as %s",pref(dataset,sequence),gref(startchar),gref(nextchar),x,y,w,h,injection or "injections") + logprocess("%s: inserting %s %p between %s and %s as %s",pref(dataset,sequence),format,k,gref(getchar(prev)),gref(nextchar),injection or "injections") end - start = snext -- cf spec - elseif forcepairadvance then - start = snext -- for testing, not cf spec - end - return head, start, true - elseif krn ~= 0 then - local k = (format == "move" and setmove or setkern)(snext,factor,rlmode,krn,injection) - if trace_kerns then - logprocess("%s: inserting %s %p between %s and %s as %s",pref(dataset,sequence),format,k,gref(getchar(prev)),gref(nextchar),injection or "injections") + return head, start, true + else -- can't happen + break end - return head, start, true - else -- can't happen - break end + else + break end - else - break end + return head, start, false end - return head, start, false end end @@ -1505,92 +1532,98 @@ function chainprocs.gsub_ligature(head,start,stop,dataset,sequence,currentlookup end function chainprocs.gpos_single(head,start,stop,dataset,sequence,currentlookup,rlmode,skiphash,chainindex) - local mapping = currentlookup.mapping - if mapping == nil then - mapping = getmapping(dataset,sequence,currentlookup) - end - if mapping then - local startchar = getchar(start) - local kerns = mapping[startchar] - if kerns then - local format = currentlookup.format - if format == "single" then - local dx, dy, w, h = setposition(0,start,factor,rlmode,kerns) -- currentlookup.flags ? - if trace_kerns then - logprocess("%s: shifting single %s by %s (%p,%p) and correction (%p,%p)",cref(dataset,sequence),gref(startchar),format,dx,dy,w,h) - end - else -- needs checking .. maybe no kerns format for single - local k = (format == "move" and setmove or setkern)(start,factor,rlmode,kerns,injection) - if trace_kerns then - logprocess("%s: shifting single %s by %s %p",cref(dataset,sequence),gref(startchar),format,k) + -- we actually should check no_left_kern_code with next + if not has_glyph_option(start,no_right_kern_code) then + local mapping = currentlookup.mapping + if mapping == nil then + mapping = getmapping(dataset,sequence,currentlookup) + end + if mapping then + local startchar = getchar(start) + local kerns = mapping[startchar] + if kerns then + local format = currentlookup.format + if format == "single" then + local dx, dy, w, h = setposition(0,start,factor,rlmode,kerns) -- currentlookup.flags ? + if trace_kerns then + logprocess("%s: shifting single %s by %s (%p,%p) and correction (%p,%p)",cref(dataset,sequence),gref(startchar),format,dx,dy,w,h) + end + else -- needs checking .. maybe no kerns format for single + local k = (format == "move" and setmove or setkern)(start,factor,rlmode,kerns,injection) + if trace_kerns then + logprocess("%s: shifting single %s by %s %p",cref(dataset,sequence),gref(startchar),format,k) + end end + return head, start, true end - return head, start, true end end return head, start, false end function chainprocs.gpos_pair(head,start,stop,dataset,sequence,currentlookup,rlmode,skiphash,chainindex) -- todo: injections ? - local mapping = currentlookup.mapping - if mapping == nil then - mapping = getmapping(dataset,sequence,currentlookup) - end - if mapping then - local snext = getnext(start) - if snext then - local startchar = getchar(start) - local kerns = mapping[startchar] -- always 1 step - if kerns then - local prev = start - while snext do - local nextchar = ischar(snext,currentfont) - if not nextchar then - break - end - if skiphash and skiphash[nextchar] then - prev = snext - snext = getnext(snext) - else - local krn = kerns[nextchar] - if not krn then + -- we actually should check no_left_kern_code with next + if not has_glyph_option(start,no_right_kern_code) then + local mapping = currentlookup.mapping + if mapping == nil then + mapping = getmapping(dataset,sequence,currentlookup) + end + if mapping then + local snext = getnext(start) + if snext then + local startchar = getchar(start) + local kerns = mapping[startchar] -- always 1 step + if kerns then + local prev = start + while snext do + local nextchar = ischar(snext,currentfont) + if not nextchar then break end - local format = currentlookup.format - if format == "pair" then - local a = krn[1] - local b = krn[2] - if a == true then - -- zero - elseif a then - local x, y, w, h = setposition(1,start,factor,rlmode,a,"injections") -- currentlookups flags? - if trace_kerns then - local startchar = getchar(start) - logprocess("%s: shifting first of pair %s and %s by (%p,%p) and correction (%p,%p)",cref(dataset,sequence),gref(startchar),gref(nextchar),x,y,w,h) - end + if skiphash and skiphash[nextchar] then + prev = snext + snext = getnext(snext) + else + local krn = kerns[nextchar] + if not krn then + break end - if b == true then - -- zero - start = snext -- cf spec - elseif b then -- #b > 0 - local x, y, w, h = setposition(2,snext,factor,rlmode,b,"injections") + local format = currentlookup.format + if format == "pair" then + local a = krn[1] + local b = krn[2] + if a == true then + -- zero + elseif a then + local x, y, w, h = setposition(1,start,factor,rlmode,a,"injections") -- currentlookups flags? + if trace_kerns then + local startchar = getchar(start) + logprocess("%s: shifting first of pair %s and %s by (%p,%p) and correction (%p,%p)",cref(dataset,sequence),gref(startchar),gref(nextchar),x,y,w,h) + end + end + if b == true then + -- zero + start = snext -- cf spec + elseif b then -- #b > 0 + local x, y, w, h = setposition(2,snext,factor,rlmode,b,"injections") + if trace_kerns then + local startchar = getchar(start) + logprocess("%s: shifting second of pair %s and %s by (%p,%p) and correction (%p,%p)",cref(dataset,sequence),gref(startchar),gref(nextchar),x,y,w,h) + end + start = snext -- cf spec + elseif forcepairadvance then + start = snext -- for testing, not cf spec + end + return head, start, true + elseif krn ~= 0 then + local k = (format == "move" and setmove or setkern)(snext,factor,rlmode,krn) if trace_kerns then - local startchar = getchar(start) - logprocess("%s: shifting second of pair %s and %s by (%p,%p) and correction (%p,%p)",cref(dataset,sequence),gref(startchar),gref(nextchar),x,y,w,h) + logprocess("%s: inserting %s %p between %s and %s",cref(dataset,sequence),format,k,gref(getchar(prev)),gref(nextchar)) end - start = snext -- cf spec - elseif forcepairadvance then - start = snext -- for testing, not cf spec - end - return head, start, true - elseif krn ~= 0 then - local k = (format == "move" and setmove or setkern)(snext,factor,rlmode,krn) - if trace_kerns then - logprocess("%s: inserting %s %p between %s and %s",cref(dataset,sequence),format,k,gref(getchar(prev)),gref(nextchar)) + return head, start, true + else + break end - return head, start, true - else - break end end end @@ -3759,7 +3792,7 @@ do local initialrl = 0 - if getid(head) == localpar_code and start_of_par(head) then + if getid(head) == par_code and start_of_par(head) then initialrl = pardirstate(head) elseif direction == righttoleft_code then initialrl = -1 @@ -3913,7 +3946,7 @@ do elseif id == dir_code then topstack, rlmode = txtdirstate(start,dirstack,topstack,rlparmode) start = getnext(start) - -- elseif id == localpar_code and start_of_par(start) then + -- elseif id == par_code and start_of_par(start) then -- rlparmode, rlmode = pardirstate(start) -- start = getnext(start) else @@ -3997,7 +4030,7 @@ do elseif id == dir_code then topstack, rlmode = txtdirstate(start,dirstack,topstack,rlparmode) start = getnext(start) - -- elseif id == localpar_code and start_of_par(start) then + -- elseif id == par_code and start_of_par(start) then -- rlparmode, rlmode = pardirstate(start) -- start = getnext(start) else @@ -4108,7 +4141,7 @@ do elseif id == dir_code then topstack, rlmode = txtdirstate(start,dirstack,topstack,rlparmode) start = getnext(start) - -- elseif id == localpar_code and start_of_par(start) then + -- elseif id == par_code and start_of_par(start) then -- rlparmode, rlmode = pardirstate(start) -- start = getnext(start) else diff --git a/Master/texmf-dist/tex/luatex/luaotfload/fontloader-font-shp.lua b/Master/texmf-dist/tex/luatex/luaotfload/fontloader-font-shp.lua index c3fea6d4601..78e8597b937 100644 --- a/Master/texmf-dist/tex/luatex/luaotfload/fontloader-font-shp.lua +++ b/Master/texmf-dist/tex/luatex/luaotfload/fontloader-font-shp.lua @@ -8,7 +8,7 @@ if not modules then modules = { } end modules ['font-shp'] = { local tonumber, next = tonumber, next local concat = table.concat -local formatters = string.formatters +local formatters, lower = string.formatters, string.lower local otf = fonts.handlers.otf local afm = fonts.handlers.afm @@ -221,7 +221,7 @@ end local function loadstreams(cache,filename,sub,instance) local base = file.basename(filename) local name = file.removesuffix(base) - local kind = file.suffix(filename) + local kind = lower(file.suffix(filename)) local attr = lfs.attributes(filename) local size = attr and attr.size or 0 local time = attr and attr.modification or 0 diff --git a/Master/texmf-dist/tex/luatex/luaotfload/fontloader-font-ttf.lua b/Master/texmf-dist/tex/luatex/luaotfload/fontloader-font-ttf.lua index 865f8e6e30b..a2732aa5f2e 100644 --- a/Master/texmf-dist/tex/luatex/luaotfload/fontloader-font-ttf.lua +++ b/Master/texmf-dist/tex/luatex/luaotfload/fontloader-font-ttf.lua @@ -163,8 +163,7 @@ local function mergecomposites(glyphs,shapes) return contours, points end --- for index=1,#glyphs do - for index=0,#glyphs-1 do + for index=0,#glyphs do local shape = shapes[index] if shape then local components = shape.components @@ -659,7 +658,7 @@ local function repackpoints(glyphs,shapes) local result = { } -- reused local xpoints = { } -- reused local ypoints = { } -- reused - for index=0,#glyphs-1 do + for index=0,#glyphs do local shape = shapes[index] if shape then local r = 0 diff --git a/Master/texmf-dist/tex/luatex/luaotfload/fontloader-reference.lua b/Master/texmf-dist/tex/luatex/luaotfload/fontloader-reference.lua index df4f3593c20..0b220327c35 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 : 2020-08-31 22:01 +-- merge date : 2020-12-30 16:42 do -- begin closure to overcome local limits and interference @@ -4939,6 +4939,7 @@ nuts.getkern=direct.getkern nuts.getlist=direct.getlist nuts.getnext=direct.getnext nuts.getoffsets=direct.getoffsets +nuts.getoptions=direct.getoptions or function() return 0 end nuts.getprev=direct.getprev nuts.getsubtype=direct.getsubtype nuts.getwidth=direct.getwidth @@ -5022,6 +5023,15 @@ local traverse_id=nuts.traverse_id local copy_node=nuts.copy_node local glyph_code=nodes.nodecodes.glyph local ligature_code=nodes.glyphcodes.ligature +do + local p=nodecodes.localpar or nodecodes.local_par + if p then + nodecodes.par=p + nodecodes[p]="par" + nodecodes.localpar=p + nodecodes.local_par=p + end +end do local get_components=node.direct.getcomponents local set_components=node.direct.setcomponents @@ -5074,11 +5084,14 @@ do end return 0 end + local function flush_components() + end nuts.set_components=set_components nuts.get_components=get_components nuts.copy_only_glyphs=copy_only_glyphs nuts.copy_no_components=copy_no_components nuts.count_components=count_components + nuts.flush_components=flush_components end nuts.uses_font=direct.uses_font do @@ -15147,7 +15160,7 @@ local function mergecomposites(glyphs,shapes) shape.components=nil return contours,points end - for index=0,#glyphs-1 do + for index=0,#glyphs do local shape=shapes[index] if shape then local components=shape.components @@ -15577,7 +15590,7 @@ local function repackpoints(glyphs,shapes) local result={} local xpoints={} local ypoints={} - for index=0,#glyphs-1 do + for index=0,#glyphs do local shape=shapes[index] if shape then local r=0 @@ -16840,7 +16853,7 @@ local function readfirst(f,offset) end return { readushort(f) } end -function readarray(f,offset) +local function readarray(f,offset) if offset then setposition(f,offset) end @@ -20766,7 +20779,7 @@ 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.111 +otf.version=3.112 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) @@ -21131,7 +21144,6 @@ local function copytotfm(data,cache_id) parameters.units=units parameters.vheight=metadata.defaultvheight properties.space=spacer - properties.encodingbytes=2 properties.format=data.format or formats.otf properties.filename=filename properties.fontname=fontname @@ -21139,6 +21151,9 @@ local function copytotfm(data,cache_id) properties.psname=psname properties.name=filename or fullname properties.subfont=subfont +if not CONTEXTLMTXMODE or CONTEXTLMTXMODE==0 then + properties.encodingbytes=2 +end properties.private=properties.private or data.private or privateoffset return { characters=characters, @@ -26617,6 +26632,7 @@ local copy_only_glyphs=nuts.copy_only_glyphs local count_components=nuts.count_components local set_components=nuts.set_components local get_components=nuts.get_components +local flush_components=nuts.flush_components local ischar=nuts.ischar local usesfont=nuts.uses_font local insert_node_after=nuts.insert_after @@ -26639,7 +26655,7 @@ local glue_code=nodecodes.glue local disc_code=nodecodes.disc local math_code=nodecodes.math local dir_code=nodecodes.dir -local localpar_code=nodecodes.localpar +local par_code=nodecodes.par local lefttoright_code=nodes.dirvalues.lefttoright local righttoleft_code=nodes.dirvalues.righttoleft local discretionarydisc_code=disccodes.discretionary @@ -26821,11 +26837,23 @@ local function markstoligature(head,start,stop,char) setsubtype(base,ligatureglyph_code) set_components(base,start) setlink(prev,base,next) + flush_components(start) return head,base end end +local no_left_ligature_code=1 +local no_right_ligature_code=2 +local no_left_kern_code=4 +local no_right_kern_code=8 +local has_glyph_option=node.direct.has_glyph_option or function(n,c) + if c==no_left_ligature_code or c==no_right_ligature_code then + return getattr(n,a_noligature)==1 + else + return false + end +end local function toligature(head,start,stop,char,dataset,sequence,skiphash,discfound,hasmarks) - if getattr(start,a_noligature)==1 then + if has_glyph_option(start,no_right_ligature_code) then return head,start end if start==stop and getchar(start)==char then @@ -26889,6 +26917,7 @@ local function toligature(head,start,stop,char,dataset,sequence,skiphash,discfou break end end + flush_components(components) else local discprev,discnext=getboth(discfound) if discprev and discnext then @@ -27175,78 +27204,86 @@ function handlers.gsub_ligature(head,start,dataset,sequence,ligature,rlmode,skip return head,start,false,false end function handlers.gpos_single(head,start,dataset,sequence,kerns,rlmode,skiphash,step,injection) - local startchar=getchar(start) - local format=step.format - if format=="single" or type(kerns)=="table" then - local dx,dy,w,h=setposition(0,start,factor,rlmode,kerns,injection) - if trace_kerns then - logprocess("%s: shifting single %s by %s xy (%p,%p) and wh (%p,%p)",pref(dataset,sequence),gref(startchar),format,dx,dy,w,h) - end + if has_glyph_option(start,no_right_kern_code) then + return head,start,false else - local k=(format=="move" and setmove or setkern)(start,factor,rlmode,kerns,injection) - if trace_kerns then - logprocess("%s: shifting single %s by %s %p",pref(dataset,sequence),gref(startchar),format,k) + local startchar=getchar(start) + local format=step.format + if format=="single" or type(kerns)=="table" then + local dx,dy,w,h=setposition(0,start,factor,rlmode,kerns,injection) + if trace_kerns then + logprocess("%s: shifting single %s by %s xy (%p,%p) and wh (%p,%p)",pref(dataset,sequence),gref(startchar),format,dx,dy,w,h) + end + else + local k=(format=="move" and setmove or setkern)(start,factor,rlmode,kerns,injection) + if trace_kerns then + logprocess("%s: shifting single %s by %s %p",pref(dataset,sequence),gref(startchar),format,k) + end end + return head,start,true end - return head,start,true end function handlers.gpos_pair(head,start,dataset,sequence,kerns,rlmode,skiphash,step,injection) - local snext=getnext(start) - if not snext then + if has_glyph_option(start,no_right_kern_code) then return head,start,false else - local prev=start - while snext do - local nextchar=ischar(snext,currentfont) - if nextchar then - if skiphash and skiphash[nextchar] then - prev=snext - snext=getnext(snext) - else - local krn=kerns[nextchar] - if not krn then - break - end - local format=step.format - if format=="pair" then - local a=krn[1] - local b=krn[2] - if a==true then - elseif a then - local x,y,w,h=setposition(1,start,factor,rlmode,a,injection) - if trace_kerns then - local startchar=getchar(start) - logprocess("%s: shifting first of pair %s and %s by xy (%p,%p) and wh (%p,%p) as %s",pref(dataset,sequence),gref(startchar),gref(nextchar),x,y,w,h,injection or "injections") - end + local snext=getnext(start) + if not snext then + return head,start,false + else + local prev=start + while snext do + local nextchar=ischar(snext,currentfont) + if nextchar then + if skiphash and skiphash[nextchar] then + prev=snext + snext=getnext(snext) + else + local krn=kerns[nextchar] + if not krn then + break end - if b==true then - start=snext - elseif b then - local x,y,w,h=setposition(2,snext,factor,rlmode,b,injection) + local format=step.format + if format=="pair" then + local a=krn[1] + local b=krn[2] + if a==true then + elseif a then + local x,y,w,h=setposition(1,start,factor,rlmode,a,injection) + if trace_kerns then + local startchar=getchar(start) + logprocess("%s: shifting first of pair %s and %s by xy (%p,%p) and wh (%p,%p) as %s",pref(dataset,sequence),gref(startchar),gref(nextchar),x,y,w,h,injection or "injections") + end + end + if b==true then + start=snext + elseif b then + local x,y,w,h=setposition(2,snext,factor,rlmode,b,injection) + if trace_kerns then + local startchar=getchar(start) + logprocess("%s: shifting second of pair %s and %s by xy (%p,%p) and wh (%p,%p) as %s",pref(dataset,sequence),gref(startchar),gref(nextchar),x,y,w,h,injection or "injections") + end + start=snext + elseif forcepairadvance then + start=snext + end + return head,start,true + elseif krn~=0 then + local k=(format=="move" and setmove or setkern)(snext,factor,rlmode,krn,injection) if trace_kerns then - local startchar=getchar(start) - logprocess("%s: shifting second of pair %s and %s by xy (%p,%p) and wh (%p,%p) as %s",pref(dataset,sequence),gref(startchar),gref(nextchar),x,y,w,h,injection or "injections") + logprocess("%s: inserting %s %p between %s and %s as %s",pref(dataset,sequence),format,k,gref(getchar(prev)),gref(nextchar),injection or "injections") end - start=snext - elseif forcepairadvance then - start=snext - end - return head,start,true - elseif krn~=0 then - local k=(format=="move" and setmove or setkern)(snext,factor,rlmode,krn,injection) - if trace_kerns then - logprocess("%s: inserting %s %p between %s and %s as %s",pref(dataset,sequence),format,k,gref(getchar(prev)),gref(nextchar),injection or "injections") + return head,start,true + else + break end - return head,start,true - else - break end + else + break end - else - break end + return head,start,false end - return head,start,false end end function handlers.gpos_mark2base(head,start,dataset,sequence,markanchors,rlmode,skiphash) @@ -27676,89 +27713,93 @@ function chainprocs.gsub_ligature(head,start,stop,dataset,sequence,currentlookup return head,start,false,0,false end function chainprocs.gpos_single(head,start,stop,dataset,sequence,currentlookup,rlmode,skiphash,chainindex) - local mapping=currentlookup.mapping - if mapping==nil then - mapping=getmapping(dataset,sequence,currentlookup) - end - if mapping then - local startchar=getchar(start) - local kerns=mapping[startchar] - if kerns then - local format=currentlookup.format - if format=="single" then - local dx,dy,w,h=setposition(0,start,factor,rlmode,kerns) - if trace_kerns then - logprocess("%s: shifting single %s by %s (%p,%p) and correction (%p,%p)",cref(dataset,sequence),gref(startchar),format,dx,dy,w,h) - end - else - local k=(format=="move" and setmove or setkern)(start,factor,rlmode,kerns,injection) - if trace_kerns then - logprocess("%s: shifting single %s by %s %p",cref(dataset,sequence),gref(startchar),format,k) + if not has_glyph_option(start,no_right_kern_code) then + local mapping=currentlookup.mapping + if mapping==nil then + mapping=getmapping(dataset,sequence,currentlookup) + end + if mapping then + local startchar=getchar(start) + local kerns=mapping[startchar] + if kerns then + local format=currentlookup.format + if format=="single" then + local dx,dy,w,h=setposition(0,start,factor,rlmode,kerns) + if trace_kerns then + logprocess("%s: shifting single %s by %s (%p,%p) and correction (%p,%p)",cref(dataset,sequence),gref(startchar),format,dx,dy,w,h) + end + else + local k=(format=="move" and setmove or setkern)(start,factor,rlmode,kerns,injection) + if trace_kerns then + logprocess("%s: shifting single %s by %s %p",cref(dataset,sequence),gref(startchar),format,k) + end end + return head,start,true end - return head,start,true end end return head,start,false end -function chainprocs.gpos_pair(head,start,stop,dataset,sequence,currentlookup,rlmode,skiphash,chainindex) - local mapping=currentlookup.mapping - if mapping==nil then - mapping=getmapping(dataset,sequence,currentlookup) - end - if mapping then - local snext=getnext(start) - if snext then - local startchar=getchar(start) - local kerns=mapping[startchar] - if kerns then - local prev=start - while snext do - local nextchar=ischar(snext,currentfont) - if not nextchar then - break - end - if skiphash and skiphash[nextchar] then - prev=snext - snext=getnext(snext) - else - local krn=kerns[nextchar] - if not krn then +function chainprocs.gpos_pair(head,start,stop,dataset,sequence,currentlookup,rlmode,skiphash,chainindex) + if not has_glyph_option(start,no_right_kern_code) then + local mapping=currentlookup.mapping + if mapping==nil then + mapping=getmapping(dataset,sequence,currentlookup) + end + if mapping then + local snext=getnext(start) + if snext then + local startchar=getchar(start) + local kerns=mapping[startchar] + if kerns then + local prev=start + while snext do + local nextchar=ischar(snext,currentfont) + if not nextchar then break end - local format=currentlookup.format - if format=="pair" then - local a=krn[1] - local b=krn[2] - if a==true then - elseif a then - local x,y,w,h=setposition(1,start,factor,rlmode,a,"injections") - if trace_kerns then - local startchar=getchar(start) - logprocess("%s: shifting first of pair %s and %s by (%p,%p) and correction (%p,%p)",cref(dataset,sequence),gref(startchar),gref(nextchar),x,y,w,h) - end + if skiphash and skiphash[nextchar] then + prev=snext + snext=getnext(snext) + else + local krn=kerns[nextchar] + if not krn then + break end - if b==true then - start=snext - elseif b then - local x,y,w,h=setposition(2,snext,factor,rlmode,b,"injections") + local format=currentlookup.format + if format=="pair" then + local a=krn[1] + local b=krn[2] + if a==true then + elseif a then + local x,y,w,h=setposition(1,start,factor,rlmode,a,"injections") + if trace_kerns then + local startchar=getchar(start) + logprocess("%s: shifting first of pair %s and %s by (%p,%p) and correction (%p,%p)",cref(dataset,sequence),gref(startchar),gref(nextchar),x,y,w,h) + end + end + if b==true then + start=snext + elseif b then + local x,y,w,h=setposition(2,snext,factor,rlmode,b,"injections") + if trace_kerns then + local startchar=getchar(start) + logprocess("%s: shifting second of pair %s and %s by (%p,%p) and correction (%p,%p)",cref(dataset,sequence),gref(startchar),gref(nextchar),x,y,w,h) + end + start=snext + elseif forcepairadvance then + start=snext + end + return head,start,true + elseif krn~=0 then + local k=(format=="move" and setmove or setkern)(snext,factor,rlmode,krn) if trace_kerns then - local startchar=getchar(start) - logprocess("%s: shifting second of pair %s and %s by (%p,%p) and correction (%p,%p)",cref(dataset,sequence),gref(startchar),gref(nextchar),x,y,w,h) + logprocess("%s: inserting %s %p between %s and %s",cref(dataset,sequence),format,k,gref(getchar(prev)),gref(nextchar)) end - start=snext - elseif forcepairadvance then - start=snext - end - return head,start,true - elseif krn~=0 then - local k=(format=="move" and setmove or setkern)(snext,factor,rlmode,krn) - if trace_kerns then - logprocess("%s: inserting %s %p between %s and %s",cref(dataset,sequence),format,k,gref(getchar(prev)),gref(nextchar)) + return head,start,true + else + break end - return head,start,true - else - break end end end @@ -29580,7 +29621,7 @@ do checkstep(head) end local initialrl=0 - if getid(head)==localpar_code and start_of_par(head) then + if getid(head)==par_code and start_of_par(head) then initialrl=pardirstate(head) elseif direction==righttoleft_code then initialrl=-1 @@ -34675,7 +34716,6 @@ local function copytotfm(data) parameters.descender=abs(metadata.descender or 0) parameters.units=1000 properties.spacer=spacer - properties.encodingbytes=2 properties.format=fonts.formats[filename] or "type1" properties.filename=filename properties.fontname=fontname @@ -34683,6 +34723,9 @@ local function copytotfm(data) properties.psname=fullname properties.name=filename or fullname or fontname properties.private=properties.private or data.private or privateoffset +if not CONTEXTLMTXMODE or CONTEXTLMTXMODE==0 then + properties.encodingbytes=2 +end if next(characters) then return { characters=characters, @@ -35993,7 +36036,7 @@ if not modules then modules={} end modules ['font-shp']={ } local tonumber,next=tonumber,next local concat=table.concat -local formatters=string.formatters +local formatters,lower=string.formatters,string.lower local otf=fonts.handlers.otf local afm=fonts.handlers.afm local pfb=fonts.handlers.pfb @@ -36186,7 +36229,7 @@ end local function loadstreams(cache,filename,sub,instance) local base=file.basename(filename) local name=file.removesuffix(base) - local kind=file.suffix(filename) + local kind=lower(file.suffix(filename)) local attr=lfs.attributes(filename) local size=attr and attr.size or 0 local time=attr and attr.modification or 0 @@ -37084,56 +37127,74 @@ local rules={ "FractionRuleThickness", "UnderbarRuleThickness", } -local function setmathparameters(tfmdata,characters,mathparameters,dx,dy,squeeze) - if delta~=0 then - for i=1,#rules do - local name=rules[i] - local value=mathparameters[name] - if value then - mathparameters[name]=(squeeze or 1)*(value+dx) +local setmathparameters +local setmathcharacters +if CONTEXTLMTXMODE and CONTEXTLMTXMODE>0 then + setmathparameters=function(tfmdata,characters,mathparameters,dx,dy,squeeze,multiplier) + if delta~=0 then + for i=1,#rules do + local name=rules[i] + local value=mathparameters[name] + if value then + mathparameters[name]=(squeeze or 1)*(value+dy) + end end end end -end -local function setmathcharacters(tfmdata,characters,mathparameters,dx,dy,squeeze,wdelta,hdelta,ddelta) - local function wdpatch(char) - if wsnap~=0 then - char.width=char.width+wdelta/2 - end + setmathcharacters=function() end - local function htpatch(char) - if hsnap~=0 then - local height=char.height - if height then - char.height=char.height+2*dy +else + setmathparameters=function(tfmdata,characters,mathparameters,dx,dy,squeeze,multiplier) + if delta~=0 then + for i=1,#rules do + local name=rules[i] + local value=mathparameters[name] + if value then + mathparameters[name]=(squeeze or 1)*(value+dy) + end end end end - local character=characters[0x221A] - if character and character.next then - local char=character - local next=character.next - wdpatch(char) - htpatch(char) - while next do - char=characters[next] + setmathcharacters=function(tfmdata,characters,mathparameters,dx,dy,squeeze,wdelta,hdelta,ddelta) + local function wdpatch(char) + if wsnap~=0 then + char.width=char.width+wdelta/2 + end + end + local function htpatch(char) + if hsnap~=0 then + local height=char.height + if height then + char.height=char.height+2*dy + end + end + end + local character=characters[0x221A] + if character and character.next then + local char=character + local next=character.next wdpatch(char) htpatch(char) - next=char.next - end - if char then - local v=char.vert_variants - if v then - local top=v[#v] - if top then - local char=characters[top.glyph] - htpatch(char) + while next do + char=characters[next] + wdpatch(char) + htpatch(char) + next=char.next + end + if char then + local v=char.vert_variants + if v then + local top=v[#v] + if top then + local char=characters[top.glyph] + htpatch(char) + end end end end end end -local shiftmode=CONTEXTLMTXMODE>0 +local shiftmode=CONTEXTLMTXMODE and CONTEXTLMTXMODE>0 local function manipulateeffect(tfmdata) local effect=tfmdata.properties.effect if effect then @@ -37205,7 +37266,7 @@ local function manipulateeffect(tfmdata) end end if mathparameters then - setmathparameters(tfmdata,characters,mathparameters,dx,dy,squeeze) + setmathparameters(tfmdata,characters,mathparameters,dx,dy,squeeze,multiplier) setmathcharacters(tfmdata,characters,mathparameters,dx,dy,squeeze,wdelta,hdelta,ddelta) end parameters.factor=factor diff --git a/Master/texmf-dist/tex/luatex/luaotfload/luaotfload-auxiliary.lua b/Master/texmf-dist/tex/luatex/luaotfload/luaotfload-auxiliary.lua index 14a66da3591..2d4e757bc0c 100644 --- a/Master/texmf-dist/tex/luatex/luaotfload/luaotfload-auxiliary.lua +++ b/Master/texmf-dist/tex/luatex/luaotfload/luaotfload-auxiliary.lua @@ -4,19 +4,14 @@ -- AUTHOR: Khaled Hosny, Élie Roux, Philipp Gesang ----------------------------------------------------------------------- -local ProvidesLuaModule = { +assert(luaotfload_module, "This is a part of luaotfload and should not be loaded independently") { name = "luaotfload-auxiliary", - version = "3.15", --TAGVERSION - date = "2020-09-02", --TAGDATE + version = "3.16", --TAGVERSION + date = "2020-12-31", --TAGDATE description = "luaotfload submodule / auxiliary functions", license = "GPL v2.0" } -if luatexbase and luatexbase.provides_module then - luatexbase.provides_module (ProvidesLuaModule) -end - - luaotfload = luaotfload or { } local log = luaotfload.log local logreport = log.report @@ -912,6 +907,53 @@ function aux.get_quad(font_id) end ----------------------------------------------------------------------- +--- Script/language fixup +----------------------------------------------------------------------- +local otftables = fonts.constructors.handlers.otf.tables +local function setscript(tfmdata, value) + if value then + local cleanvalue = string.lower(value) + local scripts = otftables and otftables.scripts + local properties = tfmdata.properties + if not scripts then + properties.script = cleanvalue + elseif scripts[value] then + properties.script = cleanvalue + else + properties.script = "dflt" + end + end + local resources = tfmdata.resources + local features = resources and resources.features + if features then + local properties = tfmdata.properties + local script, language = properties.script, properties.language + local script_found, language_found = false, false + for _, data in next, features do for _, feature_data in next, data do + local scr = feature_data[script] + if scr then + script_found = true + if scr[language] then + language_found = true + goto double_break + end + end + end end + ::double_break:: + if not script_found then properties.script = "dflt" end + if not language_found then properties.language = "dflt" end + end +end +fonts.constructors.features.otf.register { + name = "script", + initializers = { + base = setscript, + node = setscript, + plug = setscript, + }, +} + +----------------------------------------------------------------------- --- initialization ----------------------------------------------------------------------- diff --git a/Master/texmf-dist/tex/luatex/luaotfload/luaotfload-case.lua b/Master/texmf-dist/tex/luatex/luaotfload/luaotfload-case.lua new file mode 100644 index 00000000000..33bb1bc9246 --- /dev/null +++ b/Master/texmf-dist/tex/luatex/luaotfload/luaotfload-case.lua @@ -0,0 +1,239 @@ +local unicode_data = require'luaotfload-unicode' + +local mapping_tables = unicode_data.casemapping +local soft_dotted = unicode_data.soft_dotted +local ccc = unicode_data.ccc + +local uppercase = mapping_tables.uppercase +local lowercase = mapping_tables.lowercase +local cased = mapping_tables.cased +local case_ignorable = mapping_tables.case_ignorable + +local otfregister = fonts.constructors.features.otf.register + +local direct = node.direct +local is_char = direct.is_char +local has_glyph = direct.has_glyph +local uses_font = direct.uses_font +local getnext = direct.getnext +local setchar = direct.setchar +local setdisc = direct.setdisc +local getdisc = direct.getdisc +local getfield = direct.getfield +local remove = direct.remove +local copy = direct.copy +local insert_after = direct.insert_after +local traverse = direct.traverse + +local disc = node.id'disc' + +--[[ We make some implicit assumptions about contexts in SpecialCasing.txt here which happened to be true when I wrote the code: +-- +-- * Before_Dot only appears as Not_Before_Dot +-- * No other context appears with Not_ +-- * Final_Sigma is never language dependent +-- * Other contexts are always language dependent +-- * The only languages with special mappings are Lithuanian (lt/"LTH "/lit), Turkish (tr/"TRK "/tur), and Azeri/Azerbaijani (az/"AZE "/aze) +]] + +local font_lang = setmetatable({}, {__index = function(t, fid) + local f = font.getfont(fid) + local lang = f.specification.features.normal.language + lang = lang == 'lth' and 'lt' or lang == 'trk' and 'tr' or lang == 'aze' and 'az' or false + t[fid] = lang + return lang +end}) + +local function is_Final_Sigma(font, mapping, n, after) + mapping = mapping.Final_Sigma + if not mapping then return false end + mapping = mapping._ + if not mapping then return false end + n = getnext(n) + repeat + while n do + local char, id = is_char(n, font) + if id == disc then + after = getnext(n) + n = getfield(n, 'replace') + char, id = is_char(n, font) + elseif char then + if not case_ignorable[char] then + return not cased[char] and mapping + end + n = getnext(n) + else + return mapping + end + end + n, after = after + until not n + return mapping +end + +local function is_More_Above(font, mapping, n, after) + mapping = mapping.More_Above + if not mapping then return false end + mapping = mapping._ + if not mapping then return false end + n = getnext(n) + repeat + while n do + local char, id = is_char(n, font) + if id == disc then + after = getnext(n) + n = getfield(n, 'replace') + char, id = is_char(n, font) + elseif char then + local char_ccc = ccc[char] + if not char_ccc then + return false + elseif char_ccc == 230 then + return mapping + end + n = getnext(n) + else + return false + end + end + n, after = after + until not n + return false +end + +local function is_Not_Before_Dot(font, mapping, n, after) + mapping = mapping.Not_Before_Dot + if not mapping then return false end + mapping = mapping._ + if not mapping then return false end + n = getnext(n) + repeat + while n do + local char, id = is_char(n, font) + if id == disc then + after = getnext(n) + n = getfield(n, 'replace') + char, id = is_char(n, font) + elseif char then + local char_ccc = ccc[char] + if not char_ccc then + return mapping + elseif char_ccc == 230 then + return char ~= 0x0307 and mapping + end + n = getnext(n) + else + return mapping + end + end + n, after = after + until not n + return mapping +end + +local function is_Language_Mapping(font, mapping, n, after, seen_soft_dotted, seen_I) + if not mapping then return false end + if seen_soft_dotted then + local mapping = mapping.After_Soft_Dotted + mapping = mapping and mapping._ + if mapping then + return mapping + end + end + if seen_I then + local mapping = mapping.After_I + mapping = mapping and mapping._ + if mapping then + return mapping + end + end + return is_More_Above(font, mapping, n, after) or is_Not_Before_Dot(font, mapping, n, after) or mapping._ -- Might be nil +end + +local function process(table) + local function processor(head, font, after, seen_cased, seen_soft_dotted, seen_I) + local lang = font_lang[font] + local n = head + while n do + do + local new = has_glyph(n) + if n ~= new then + seen_cased, seen_soft_dotted, seen_I = nil + end + n = new + end + if not n then break end + local char, id = is_char(n, font) + if char then + local mapping = table[char] + if mapping then + if tonumber(mapping) then + setchar(n, mapping) + else + mapping = seen_cased and is_Final_Sigma(font, mapping, n, after) + or lang and is_Language_Mapping(font, mapping[lang], n, after, seen_soft_dotted, seen_I) + or mapping._ + if #mapping == 0 then + head, n = remove(head, n) + goto continue + else + setchar(n, mapping[1]) + for i=2, #mapping do + head, n = insert_after(head, n, copy(n)) + setchar(n, mapping[i]) + end + end + end + end + if not case_ignorable[char] then + seen_cased = cased[char] or nil + end + local char_ccc = ccc[char] + if not char_ccc or char_ccc == 230 then + seen_I = char == 0x49 or nil + seen_soft_dotted = soft_dotted[char] + end + elseif id == disc and uses_font(n, font) then + local pre, post, rep = getdisc(n) + local after = getnext(n) + pre, post, rep, seen_cased, seen_soft_dotted, seen_I = + processor(pre, font, nil, seen_cased, seen_soft_dotted, seen_I), + processor(post, font, after), + processor(rep, font, after, seen_cased, seen_soft_dotted, seen_I) + setdisc(n, pre, post, rep) + else + seen_cased, seen_soft_dotted, seen_I = nil + end + n = getnext(n) + ::continue:: + end + return head, seen_cased, seen_soft_dotted, seen_I + end + return function(head, font) return (processor(head, font)) end +end + +local upper_process = process(uppercase) +otfregister { + name = 'upper', + description = 'Map to uppercase', + default = false, + processors = { + position = 1, + plug = upper_process, + node = upper_process, + base = upper_process, + }, +} + +local lower_process = process(lowercase) +otfregister { + name = 'lower', + description = 'Map to lowercase', + default = false, + processors = { + position = 1, + plug = lower_process, + node = lower_process, + base = lower_process, + }, +} diff --git a/Master/texmf-dist/tex/luatex/luaotfload/luaotfload-colors.lua b/Master/texmf-dist/tex/luatex/luaotfload/luaotfload-colors.lua index e8a8e996a86..c1f8a63a8ed 100644 --- a/Master/texmf-dist/tex/luatex/luaotfload/luaotfload-colors.lua +++ b/Master/texmf-dist/tex/luatex/luaotfload/luaotfload-colors.lua @@ -3,21 +3,16 @@ -- DESCRIPTION: part of luaotfload / font colors ----------------------------------------------------------------------- -local ProvidesLuaModule = { +assert(luaotfload_module, "This is a part of luaotfload and should not be loaded independently") { name = "luaotfload-colors", - version = "3.15", --TAGVERSION - date = "2020-09-02", --TAGDATE + version = "3.16", --TAGVERSION + date = "2020-12-31", --TAGDATE description = "luaotfload submodule / color", license = "GPL v2.0", author = "Khaled Hosny, Elie Roux, Philipp Gesang, Dohyun Kim, David Carlisle", copyright = "Luaotfload Development Team" } -if luatexbase and luatexbase.provides_module then - luatexbase.provides_module (ProvidesLuaModule) -end - - --[[doc-- buggy coloring with the pre_output_filter when expansion is enabled diff --git a/Master/texmf-dist/tex/luatex/luaotfload/luaotfload-configuration.lua b/Master/texmf-dist/tex/luatex/luaotfload/luaotfload-configuration.lua index 8f04190a434..e5e1ed24f06 100644 --- a/Master/texmf-dist/tex/luatex/luaotfload/luaotfload-configuration.lua +++ b/Master/texmf-dist/tex/luatex/luaotfload/luaotfload-configuration.lua @@ -5,18 +5,14 @@ -- AUTHOR: Dohyun Kim <nomosnomos@gmail.com> ------------------------------------------------------------------------------- -local ProvidesLuaModule = { +assert(luaotfload_module, "This is a part of luaotfload and should not be loaded independently") { name = "luaotfload-configuration", - version = "3.15", --TAGVERSION - date = "2020-09-02", --TAGDATE + version = "3.16", --TAGVERSION + date = "2020-12-31", --TAGDATE description = "luaotfload submodule / config file reader", license = "GPL v2.0" } -if luatexbase and luatexbase.provides_module then - luatexbase.provides_module (ProvidesLuaModule) -end - ------------------------------ local status_file = "luaotfload-status" diff --git a/Master/texmf-dist/tex/luatex/luaotfload/luaotfload-database.lua b/Master/texmf-dist/tex/luatex/luaotfload/luaotfload-database.lua index 6d0bcff414e..da2d9965a31 100644 --- a/Master/texmf-dist/tex/luatex/luaotfload/luaotfload-database.lua +++ b/Master/texmf-dist/tex/luatex/luaotfload/luaotfload-database.lua @@ -3,19 +3,15 @@ -- DESCRIPTION: part of luaotfload / luaotfload-tool / font database ----------------------------------------------------------------------- do -- block to avoid to many local variables error - local ProvidesLuaModule = { + assert(luaotfload_module, "This is a part of luaotfload and should not be loaded independently") { name = "luaotfload-database", - version = "3.15", --TAGVERSION - date = "2020-09-02", --TAGDATE + version = "3.16", --TAGVERSION + date = "2020-12-31", --TAGDATE description = "luaotfload submodule / database", license = "GPL v2.0", author = "Khaled Hosny, Elie Roux, Philipp Gesang, Marcel Krüger", copyright = "Luaotfload Development Team", } - - if luatexbase and luatexbase.provides_module then - luatexbase.provides_module (ProvidesLuaModule) - end end --[[doc-- @@ -2335,8 +2331,7 @@ local path_separator = os.type == "windows" and ";" or ":" --[[doc-- collect_font_filenames_texmf -- Scan texmf tree for font files - relying on the kpathsea variables $OPENTYPEFONTS and $TTFONTS of - texmf.cnf. + relying on kpathsea search paths for the respective file types. The current working directory comes as “.” (texlive) or absolute path (miktex) and will always be filtered out. @@ -2362,16 +2357,20 @@ local function collect_font_filenames_texmf () end end - fontdirs = kpseexpand_path "$OPENTYPEFONTS" - fontdirs = fontdirs .. path_separator .. kpseexpand_path "$TTFONTS" - fontdirs = fontdirs .. path_separator .. kpseexpand_path "$T1FONTS" - fontdirs = fontdirs .. path_separator .. kpseexpand_path "$AFMFONTS" + local show_path = kpse.show_path - if stringis_empty (fontdirs) then - return { } + local function expanded_path (file_type) + return kpseexpand_path (show_path (file_type)) end - local tasks = filter_out_pwd (filesplitpath (fontdirs)) + local fontdirs = expanded_path "opentype fonts" + fontdirs = fontdirs .. path_separator .. expanded_path "truetype fonts" + fontdirs = fontdirs .. path_separator .. expanded_path "type1 fonts" + fontdirs = fontdirs .. path_separator .. expanded_path "afm" + + fontdirs = filesplitpath (fontdirs) or { } + + local tasks = filter_out_pwd (fontdirs) logreport ("both", 3, "db", "Initiating scan of %d directories.", #tasks) diff --git a/Master/texmf-dist/tex/luatex/luaotfload/luaotfload-diagnostics.lua b/Master/texmf-dist/tex/luatex/luaotfload/luaotfload-diagnostics.lua index be3183cf65a..366c7c98ece 100644 --- a/Master/texmf-dist/tex/luatex/luaotfload/luaotfload-diagnostics.lua +++ b/Master/texmf-dist/tex/luatex/luaotfload/luaotfload-diagnostics.lua @@ -5,19 +5,14 @@ -- AUTHOR: Philipp Gesang <phg@phi-gamma.net> ----------------------------------------------------------------------- -local ProvidesLuaModule = { +assert(luaotfload_module, "This is a part of luaotfload and should not be loaded independently") { name = "luaotfload-diagnostics", - version = "3.15", --TAGVERSION - date = "2020-09-02", --TAGDATE + version = "3.16", --TAGVERSION + date = "2020-12-31", --TAGDATE description = "luaotfload-tool submodule / diagnostics", license = "GPL v2.0" } -if luatexbase and luatexbase.provides_module then - luatexbase.provides_module (ProvidesLuaModule) -end - - local names = fonts.names local kpse = require "kpse" diff --git a/Master/texmf-dist/tex/luatex/luaotfload/luaotfload-dvi.lua b/Master/texmf-dist/tex/luatex/luaotfload/luaotfload-dvi.lua index b57934fdb6d..33083045d48 100644 --- a/Master/texmf-dist/tex/luatex/luaotfload/luaotfload-dvi.lua +++ b/Master/texmf-dist/tex/luatex/luaotfload/luaotfload-dvi.lua @@ -4,20 +4,16 @@ ------------------------------------------------------------------------------- -local ProvidesLuaModule = { +assert(luaotfload_module, "This is a part of luaotfload and should not be loaded independently") { name = "luaotfload-dvi", - version = "3.15", --TAGVERSION - date = "2020-09-02", --TAGDATE + version = "3.16", --TAGVERSION + date = "2020-12-31", --TAGDATE description = "luaotfload submodule / DVI", license = "GPL v2.0", author = "Marcel Krüger", copyright = "Luaotfload Development Team", } -if luatexbase and luatexbase.provides_module then - luatexbase.provides_module (ProvidesLuaModule) -end - local getfont = font.getfont local setfont = node.direct.setfont local getdisc = node.direct.getdisc diff --git a/Master/texmf-dist/tex/luatex/luaotfload/luaotfload-embolden.lua b/Master/texmf-dist/tex/luatex/luaotfload/luaotfload-embolden.lua index d1d4e478c82..73993eead8b 100644 --- a/Master/texmf-dist/tex/luatex/luaotfload/luaotfload-embolden.lua +++ b/Master/texmf-dist/tex/luatex/luaotfload/luaotfload-embolden.lua @@ -3,19 +3,15 @@ -- DESCRIPTION: part of luaotfload / embolden ----------------------------------------------------------------------- -local ProvidesLuaModule = { +assert(luaotfload_module, "This is a part of luaotfload and should not be loaded independently") { name = "luaotfload-embolden", - version = "3.15", --TAGVERSION - date = "2020-09-02", --TAGDATE + version = "3.16", --TAGVERSION + date = "2020-12-31", --TAGDATE description = "luaotfload submodule / embolden", license = "GPL v2.0", author = "Marcel Krüger" } -if luatexbase and luatexbase.provides_module then - luatexbase.provides_module (ProvidesLuaModule) -end - local otffeatures = fonts.constructors.newfeatures "otf" local function enableembolden(tfmdata, _, embolden) diff --git a/Master/texmf-dist/tex/luatex/luaotfload/luaotfload-fallback.lua b/Master/texmf-dist/tex/luatex/luaotfload/luaotfload-fallback.lua index eee107c7095..17bd7ca404a 100644 --- a/Master/texmf-dist/tex/luatex/luaotfload/luaotfload-fallback.lua +++ b/Master/texmf-dist/tex/luatex/luaotfload/luaotfload-fallback.lua @@ -3,19 +3,15 @@ -- DESCRIPTION: part of luaotfload / fallback ----------------------------------------------------------------------- -local ProvidesLuaModule = { +assert(luaotfload_module, "This is a part of luaotfload and should not be loaded independently") { name = "luaotfload-fallback", - version = "3.15", --TAGVERSION - date = "2020-09-02", --TAGDATE + version = "3.16", --TAGVERSION + date = "2020-12-31", --TAGDATE description = "luaotfload submodule / fallback", license = "GPL v2.0", author = "Marcel Krüger" } -if luatexbase and luatexbase.provides_module then - luatexbase.provides_module (ProvidesLuaModule) -end - local nodenew = node.direct.new local getfont = font.getfont local setfont = node.direct.setfont diff --git a/Master/texmf-dist/tex/luatex/luaotfload/luaotfload-features.lua b/Master/texmf-dist/tex/luatex/luaotfload/luaotfload-features.lua index 2d83df10ffc..67c9f93565a 100644 --- a/Master/texmf-dist/tex/luatex/luaotfload/luaotfload-features.lua +++ b/Master/texmf-dist/tex/luatex/luaotfload/luaotfload-features.lua @@ -3,21 +3,16 @@ -- DESCRIPTION: part of luaotfload / font features ----------------------------------------------------------------------- -local ProvidesLuaModule = { +assert(luaotfload_module, "This is a part of luaotfload and should not be loaded independently") { name = "luaotfload-features", - version = "3.15", --TAGVERSION - date = "2020-09-02", --TAGDATE + version = "3.16", --TAGVERSION + date = "2020-12-31", --TAGDATE description = "luaotfload submodule / features", 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 type = type local next = next local tonumber = tonumber @@ -45,12 +40,18 @@ local otf = handlers.otf local config = config or { luaotfload = { run = { } } } -local as_script = true -local normalize = function () end +local as_script = config.luaotfload.run.live +local normalize -if config.luaotfload.run.live ~= false then +if as_script then + function normalize(features) + return { + axis = features and features.axis, + instance = features and features.instance, + } + end +else normalize = otf.features.normalize - as_script = false end --[[HH (font-xtx) -- @@ -663,7 +664,7 @@ end do local function mathfontdimen(tfmdata, _, value) - if not next(tfmdata.mathparameters) then return end + if not (tfmdata.mathparameters and next(tfmdata.mathparameters)) then return end local parameters = tfmdata.parameters local mathparameters = tfmdata.mathparameters if value == 'xetex' then diff --git a/Master/texmf-dist/tex/luatex/luaotfload/luaotfload-filelist.lua b/Master/texmf-dist/tex/luatex/luaotfload/luaotfload-filelist.lua index b8ab343402d..69195603ede 100644 --- a/Master/texmf-dist/tex/luatex/luaotfload/luaotfload-filelist.lua +++ b/Master/texmf-dist/tex/luatex/luaotfload/luaotfload-filelist.lua @@ -4,19 +4,13 @@ -- AUTHOR: Ulrike Fischer, <fischer@troubleshooting-tex.de> ----------------------------------------------------------------------- -local ProvidesLuaModule = { +if luaotfload_module then luaotfload_module { name = "luaotfload-filelist", - version = "3.15", --TAGVERSION - date = "2020-09-02", --TAGDATE + version = "3.16", --TAGVERSION + date = "2020-12-31", --TAGDATE description = "luaotfload submodule / filelist", license = "GPL v2.0" -} - -if luatexbase and luatexbase.provides_module then - luatexbase.provides_module (ProvidesLuaModule) -end - - +} end --[[doc-- diff --git a/Master/texmf-dist/tex/luatex/luaotfload/luaotfload-glyphlist.lua b/Master/texmf-dist/tex/luatex/luaotfload/luaotfload-glyphlist.lua index 19f5c2082b2..aefc8369c6c 100644 --- a/Master/texmf-dist/tex/luatex/luaotfload/luaotfload-glyphlist.lua +++ b/Master/texmf-dist/tex/luatex/luaotfload/luaotfload-glyphlist.lua @@ -1,12 +1,14 @@ -local ProvidesLuaModule = { +if luaotfload_module then + luaotfload_module { name = "luaotfload-glyphlist", - version = "3.15", --TAGVERSION - date = "2020-09-02", --TAGDATE + version = "3.16", --TAGVERSION + date = "2020-12-31", --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", dataonly = true -} + } +end if context then logs.report("fatal error","this module is not for context") diff --git a/Master/texmf-dist/tex/luatex/luaotfload/luaotfload-harf-define.lua b/Master/texmf-dist/tex/luatex/luaotfload/luaotfload-harf-define.lua index 37ada59d00f..5be4acfa650 100644 --- a/Master/texmf-dist/tex/luatex/luaotfload/luaotfload-harf-define.lua +++ b/Master/texmf-dist/tex/luatex/luaotfload/luaotfload-harf-define.lua @@ -3,19 +3,15 @@ -- DESCRIPTION: part of luaotfload / HarfBuzz / font definition ----------------------------------------------------------------------- do -- block to avoid to many local variables error - local ProvidesLuaModule = { + assert(luaotfload_module, "This is a part of luaotfload and should not be loaded independently") { name = "luaotfload-harf-define", - version = "3.15", --TAGVERSION - date = "2020-09-02", --TAGDATE + version = "3.16", --TAGVERSION + date = "2020-12-31", --TAGDATE description = "luaotfload submodule / HarfBuzz font loading", 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 unpack = string.unpack diff --git a/Master/texmf-dist/tex/luatex/luaotfload/luaotfload-harf-plug.lua b/Master/texmf-dist/tex/luatex/luaotfload/luaotfload-harf-plug.lua index 6759747fbf3..c40aa3b72e4 100644 --- a/Master/texmf-dist/tex/luatex/luaotfload/luaotfload-harf-plug.lua +++ b/Master/texmf-dist/tex/luatex/luaotfload/luaotfload-harf-plug.lua @@ -3,19 +3,15 @@ -- DESCRIPTION: part of luaotfload / HarfBuzz / fontloader plugin ----------------------------------------------------------------------- do -- block to avoid to many local variables error - local ProvidesLuaModule = { + assert(luaotfload_module, "This is a part of luaotfload and should not be loaded independently") { name = "luaotfload-harf-plug", - version = "3.15", --TAGVERSION - date = "2020-09-02", --TAGDATE + version = "3.16", --TAGVERSION + date = "2020-12-31", --TAGDATE description = "luaotfload submodule / HarfBuzz shaping", 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 @@ -36,6 +32,7 @@ local direct = node.direct local tonode = direct.tonode local todirect = direct.todirect local traverse = direct.traverse +local traverse_list = direct.traverse_list local insertbefore = direct.insert_before local insertafter = direct.insert_after local protectglyph = direct.protect_glyph @@ -46,6 +43,7 @@ local removenode = direct.remove local copynodelist = direct.copy_list local ischar = direct.is_char local uses_font = direct.uses_font +local length = direct.length local getattrs = direct.getattributelist local setattrs = direct.setattributelist @@ -78,13 +76,15 @@ local getsubtype = direct.getsubtype local setsubtype = direct.setsubtype local getwidth = direct.getwidth local setwidth = direct.setwidth +local setlist = direct.setlist local is_char = direct.is_char local tail = direct.tail +local getboth = direct.getboth +local setlink = direct.setlink local properties = direct.get_properties_table() -local imgnode = img.node - +local hlist_t = node.id("hlist") local disc_t = node.id("disc") local glue_t = node.id("glue") local glyph_t = node.id("glyph") @@ -94,7 +94,10 @@ local localpar_t = node.id("local_par") local whatsit_t = node.id("whatsit") local pdfliteral_t = node.subtype("pdf_literal") +local line_t = 1 local explicitdisc_t = 1 +local firstdisc_t = 4 +local seconddisc_t = 5 local fontkern_t = 0 local italiccorr_t = 3 local regulardisc_t = 3 @@ -179,8 +182,12 @@ local function itemize(head, fontid, direction) local currdir = direction or 0 local lastskip, lastdir = true local lastrun = {} + local lastdisc + local in_disc - for n, id, subtype in direct.traverse(head) do + for n, id, subtype in traverse(head) do + if in_disc == n then in_disc = nil end + local disc local code = 0xFFFC -- OBJECT REPLACEMENT CHARACTER local skip = lastskip local props = properties[n] @@ -189,8 +196,9 @@ local function itemize(head, fontid, direction) code = 0x200C -- skip = false -- Not sure about this, but lastskip should be a bit faster elseif id == glyph_t then - if is_char(n) and getfont(n) == fontid then - code = getchar(n) + local char = is_char(n, fontid) + if char then + code = char skip = false else skip = true @@ -199,8 +207,28 @@ local function itemize(head, fontid, direction) code = 0x0020 -- SPACE elseif id == disc_t then if uses_font(n, fontid) then - code = 0x00AD -- SOFT HYPHEN + local _, _, rep, _, _, rep_tail = getdisc(n, true) + setfield(n, 'replace', nil) + local prev, next = getboth(n) + in_disc = next + disc = { + disc = n, + anchor_cluster = #codes - (lastrun.start or 0) + 1, + after_cluster = #codes - (lastrun.start or 0) + 1 + length(rep), + } + if rep then + setlink(rep_tail, next) + setnext(n, rep) -- This one is just to keep the loop going + n = rep + else + n = next + end + setlink(prev, n) + code = nil skip = false + if not prev then + head = n + end else skip = true end @@ -220,26 +248,39 @@ local function itemize(head, fontid, direction) currdir = getdirection(n) end - codes[#codes + 1] = code + local ncodes = #codes -- Necessary to count discs correctly + codes[ncodes + 1] = code - if lastdir ~= currdir or lastskip ~= skip then + if (disc or not in_disc) and (lastdir ~= currdir or lastskip ~= skip) then + if disc then + disc.after_cluster = disc.after_cluster - disc.anchor_cluster + disc.anchor_cluster = 0 + end lastrun.after = n lastrun = { - start = #codes, - len = 1, + start = ncodes + 1, + len = code and 1 or 0, font = fontid, dir = currdir == 1 and dir_rtl or dir_ltr, skip = skip, codes = codes, + discs = disc, } runs[#runs + 1] = lastrun - lastdir, lastskip = currdir, skip - else + lastdir, lastskip, lastdisc = currdir, skip, disc + elseif code then lastrun.len = lastrun.len + 1 + elseif disc then + if lastdisc then + lastdisc.next = disc + lastdisc = disc + else + lastrun.discs, lastdisc = disc, disc + end end end - return runs + return head, runs end @@ -260,7 +301,6 @@ local function makesub(run, codes, nodelist) font = run.font, dir = run.dir, fordisc = true, - node = nodelist, codes = codes, } local glyphs @@ -294,14 +334,12 @@ end function shape(head, firstnode, run) local node = firstnode local codes = run.codes - local offset = run.start - local nodeindex = offset - run.start = offset + local offset = run.start - 1 -- -1 because we want the cluster local len = run.len local fontid = run.font local dir = run.dir - local fordisc = run.fordisc - local cluster = offset - 2 + local cluster + local discs = (not run.fordisc) and run.discs local fontdata = font.getfont(fontid) local hbdata = fontdata.hb @@ -323,7 +361,7 @@ function shape(head, firstnode, run) buf:set_script(script) buf:set_language(lang) buf:set_cluster_level(buf.CLUSTER_LEVEL_MONOTONE_CHARACTERS) - buf:add_codepoints(codes, offset - 1, len) + buf:add_codepoints(codes, offset, len) local hscale = hbdata.hscale local vscale = hbdata.vscale @@ -333,7 +371,7 @@ function shape(head, firstnode, run) features = table.merged(features) -- We don't want to modify the global features local current_features = {} local n = node - for i = offset-1, offset+len-2 do + for i = offset, offset+len-1 do local props = properties[n] or empty_table if props then local local_feat = props.glyph_features or empty_table @@ -371,187 +409,260 @@ function shape(head, firstnode, run) local glyphs = buf:get_glyphs() + local break_glyph, break_cluster, break_node = 1, offset, node + local disc_glyph, disc_cluster, disc_node + local disc_cluster 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 and getsubtype(node) == spaceskip_t) then - local code = codes[j + 1] - hex = hex..to_utf16_hex(code) - str = str..utf8.char(code) - end + local glyph + -- The following is a repeat {...} while glyph {...} loop. + while true do + repeat + i = i+1 + glyph = glyphs[i] + until not glyph or glyph.cluster ~= cluster + do + local oldcluster = cluster + cluster = glyph and glyph.cluster or offset + len + if oldcluster then + for _ = oldcluster+1, cluster do + node = getnext(node) end - glyph.tounicode = hex - glyph.string = str end - if not fordisc then - local discindex = nil - local disc = node - for j = cluster + 1, nextcluster do - local props = properties[disc] - if (not (props and props.zwnj)) and getid(disc) == disc_t then - discindex = j - break + end + + -- Is this a safe breakpoint? + if discs and ((not glyph) or codes[cluster] == 0x20 or codes[cluster+1] == 0x20 or codes[cluster+1] == 0xFFFC + or not unsafetobreak(glyph)) then + -- Should we change the discretionary state? + local anchor_cluster, after_cluster = offset + discs.anchor_cluster, offset + discs.after_cluster + local saved_anchor, saved_after = (discs.next and discs.next.anchor_cluster or math.huge) + offset + while disc_cluster and after_cluster <= cluster + or not disc_cluster and anchor_cluster <= cluster do + if disc_cluster then + if not saved_after and saved_anchor < cluster then + saved_after = discs.next.after_cluster + offset + if saved_after > cluster then + saved_after, after_cluster = after_cluster, saved_after + break + end + elseif saved_after then + saved_after, after_cluster = after_cluster, saved_after 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]) - or glyphs[startglyph].cluster == glyphs[startglyph-1].cluster) do - startglyph = startglyph - 1 + local rep_glyphs = table.move(glyphs, disc_glyph, i - 1, 1, {}) + for j = 1, #rep_glyphs do + local glyph = rep_glyphs[j] + glyph.cluster = glyph.cluster - disc_cluster + glyph.nextcluster = glyph.nextcluster - disc_cluster 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 + do + local cluster_offset = disc_cluster - cluster + (saved_after and 2 or 1) -- The offset the glyph indices will move + for j = i, #glyphs do + local glyph = glyphs[j] + glyph.cluster = glyph.cluster + cluster_offset + end + len = len + cluster_offset + table.move(glyphs, i, #glyphs + i - disc_glyph, disc_glyph + (saved_after and 2 or 1)) + + local discs = discs.next + while discs do + discs.anchor_cluster = discs.anchor_cluster + cluster_offset + discs.after_cluster = discs.after_cluster + cluster_offset + discs = discs.next + end 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) + local pre, post, _, _, lastpost, _ = getdisc(discs.disc, true) + local precodes, postcodes, repcodes = {}, {} + table.move(codes, disc_cluster + 1, anchor_cluster, 1, precodes) + for n in traverse(pre) do + precodes[#precodes + 1] = is_char(n, fontid) or 0xFFFC end - for j=nodeindex + 1, stopindex do - stopnode = getnext(stopnode) + for n in traverse(post) do + postcodes[#postcodes + 1] = is_char(n, fontid) or 0xFFFC end + table.move(codes, after_cluster + 1, cluster, #postcodes + 1, postcodes) - 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 + if saved_after then + repcodes = table.move(codes, disc_cluster + 1, cluster, 1, {}) + table.move(codes, cluster + 1, #codes + cluster - disc_cluster, disc_cluster + 3) + codes[disc_cluster + 1], codes[disc_cluster + 2] = 0xFFFC, 0xFFFC + else + table.move(codes, cluster + 1, #codes + cluster - disc_cluster, disc_cluster + 2) + codes[disc_cluster + 1] = 0xFFFC 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 + local iter = disc_node + for _ = disc_cluster, anchor_cluster-1 do iter = getnext(iter) end + if iter ~= disc_node then + local newpre = copynodelist(disc_node, iter) + setlink(tail(newpre), pre) + pre = newpre + end + for _ = anchor_cluster, after_cluster-1 do iter = getnext(iter) end + if post then + setlink(lastpost, copynodelist(iter, node)) + else + post = copynodelist(iter, node) 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 + local prev = getprev(disc_node) + if disc_cluster ~= cluster then + setprev(disc_node, nil) + setnext(getprev(node), nil) end - if post then - setnext(lastpost, copynodelist(getnext(disc), stopnode)) - else - post = copynodelist(getnext(disc), stopnode) + setlink(prev, discs.disc, node) + if disc_node == firstnode then + firstnode = discs.disc + if head == disc_node then + head = firstnode + end end - if startnode ~= disc then - local predisc = getprev(disc) - setnext(predisc, rep) - setprev(rep, predisc) - if firstnode == startnode then - firstnode = disc + glyphs[disc_glyph] = { + replace = { + glyphs = rep_glyphs, + head = disc_node ~= node and disc_node or nil, + run = { + start = 1, + font = run.font, + dir = run.dir, + }, + }, + pre = makesub(run, precodes, pre), + post = makesub(run, postcodes, post), + cluster = disc_cluster, + nextcluster = disc_cluster + 1, + codepoint = 0xFFFC, + } + if saved_after then + local next_disc = discs.next + setlink(discs.disc, next_disc.disc, node) + local next_pre, next_post, _, _, next_lastpost, _ = getdisc(next_disc.disc, true) + local next_rep = copynodelist(next_pre) + -- Let's play the game again. We need three parts: + -- The pre and post branches in the outer post branch + local next_precodes, next_postcodes, next_repcodes = {}, {}, {} + do + local saved_offset = length(post) - cluster + local saved_anchor, saved_after = saved_anchor + saved_offset, saved_after + saved_offset + table.move(postcodes, 1, saved_anchor, 1, next_precodes) + for n in traverse(next_pre) do + next_precodes[#next_precodes + 1] = is_char(n, fontid) or 0xFFFC + end + for n in traverse(next_post) do + next_postcodes[#next_postcodes + 1] = is_char(n, fontid) or 0xFFFC + end + table.move(postcodes, saved_after + 1, #postcodes, #next_postcodes + 1, next_postcodes) + + local iter = post + for _ = 1, saved_anchor do iter = getnext(iter) end + if iter ~= post then + local newpre = copynodelist(post, iter) + setlink(tail(newpre), next_pre) + next_pre = newpre + end + for _ = saved_anchor, saved_after - 1 do iter = getnext(iter) end + if next_post then + setlink(next_lastpost, copynodelist(iter)) + else + next_post = copynodelist(iter) + end end - if startnode == head then - head = disc - else - local before = getprev(startnode) - setnext(before, disc) - setprev(disc, before) + -- The pre branch in the outer replace branch. The post branch is implicitly the same as the previous one + do + local saved_anchor = saved_anchor - disc_cluster + table.move(repcodes, 1, saved_anchor, 1, next_repcodes) + for n in traverse(next_rep) do + next_repcodes[#next_repcodes + 1] = is_char(n, fontid) or 0xFFFC + end + + local rep = glyphs[disc_glyph].replace.head + local iter = rep + for _ = 1, saved_anchor do iter = getnext(iter) end + if iter ~= rep then + local newpre = copynodelist(rep, iter) + setlink(tail(newpre), next_rep) + next_rep = newpre + end end - setprev(startnode, nil) - rep = startnode - lastrep = lastrep or predisc + setsubtype(discs.disc, firstdisc_t) + setsubtype(next_disc.disc, seconddisc_t) + discs = discs.next + disc_glyph = disc_glyph + 1 + disc_cluster = disc_cluster + 1 + glyphs[disc_glyph] = { + replace = makesub(run, next_repcodes, next_rep), + pre = makesub(run, next_precodes, next_pre), + post = makesub(run, next_postcodes, next_post), + cluster = disc_cluster, + nextcluster = disc_cluster + 1, + codepoint = 0xFFFC, + } + end + i = disc_glyph + 1 + assert(node == getnext(discs.disc)) + cluster = disc_cluster + 1 + + disc_cluster = nil + discs = discs.next + while discs and discs.anchor_cluster + offset < cluster do + freenode(discs.disc) + discs = discs.next 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) + if not discs then break end + anchor_cluster, after_cluster = offset + discs.anchor_cluster, offset + discs.after_cluster + saved_anchor, saved_after = (discs.next and discs.next.anchor_cluster or math.huge) + offset + elseif anchor_cluster == cluster then + disc_glyph, disc_cluster, disc_node = i, cluster, node + else + disc_glyph, disc_cluster, disc_node = break_glyph, break_cluster, break_node + end + end + break_glyph, break_cluster, break_node = i, cluster, node + end + + if not glyph then break end + + 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 + glyph.nglyphs = #glyphs + 1 - i + ::NEXTCLUSTERFOUND:: -- end + glyph.nextcluster = nextcluster + + local disc, discindex + -- 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. + do + local hex = "" + local str = "" + local node = node + for j = cluster+1,nextcluster do + local char, id = is_char(node, fontid) + if char then + -- assert(char == codes[j]) + hex = hex .. to_utf16_hex(char) + str = str .. utf8.char(char) + elseif not discindex and id == disc_t then + local props = properties[disc] + if not (props and props.zwnj) then + disc, discindex = node, j 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 + node = getnext(node) end + glyph.tounicode = hex + glyph.string = str + end + if not fordisc and discindex then end end return head, firstnode, glyphs, run.len - len @@ -587,7 +698,7 @@ local function color_to_rgba(color) end end --- Cache of color glyph PNG data for bookkeeping, only because I couldn’t +-- 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 = {} @@ -672,7 +783,7 @@ local function tonodes(head, node, run, glyphs) end local gid = glyph.codepoint local char = nominals[gid] or gid_offset + gid - local id = getid(node) + local orig_char, id = is_char(node, fontid) if glyph.replace then -- For discretionary the glyph itself is skipped and a discretionary node @@ -681,17 +792,12 @@ local function tonodes(head, node, run, glyphs) 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)) + (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 lastprops and lastprops.zwnj and nodeindex == glyph.cluster + 1 then - elseif id == glyph_t then + elseif orig_char then local done local fontglyph = fontglyphs[gid] local character = characters[char] @@ -717,7 +823,7 @@ local function tonodes(head, node, run, glyphs) 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 + -- color, we don't check for it here explicitly since we will -- get nil anyway. local color = palette[layer.color_index] if not color or color.alpha ~= 0 then @@ -787,7 +893,7 @@ local function tonodes(head, node, run, glyphs) -- 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 + -- 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 @@ -799,7 +905,7 @@ local function tonodes(head, node, run, glyphs) end end if not done then - local oldcharacter = characters[getchar(node)] + local oldcharacter = characters[orig_char] -- 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 @@ -824,7 +930,7 @@ local function tonodes(head, node, run, glyphs) -- 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 + -- 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 @@ -837,7 +943,7 @@ local function tonodes(head, node, run, glyphs) -- * 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 + -- 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 @@ -883,7 +989,7 @@ local function tonodes(head, node, run, glyphs) 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. + -- 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 @@ -919,8 +1025,8 @@ local function shape_run(head, current, run) end function process(head, font, _attr, direction) - local newhead, current = head, head - local runs = itemize(head, font, direction) + local newhead, runs = itemize(head, font, direction) + local current = newhead local offset = 0 for i = 1,#runs do @@ -954,29 +1060,39 @@ local function post_process(head) if startactual then local actualtext = "/Span<</ActualText<FEFF"..startactual..">>>BDC" head = insertbefore(head, n, pageliteral(actualtext)) + props[startactual_p] = nil end if endactual then head = insertafter(head, n, pageliteral("EMC")) + props[endactual_p] = nil end local replace = getfield(n, "replace") if replace then setfield(n, "replace", post_process(replace)) end + end + return head +end - local subhead = getfield(n, "head") - if subhead then - setfield(n, "head", post_process(subhead)) +local function post_process_vlist(head) + for n, id, subtype, list in traverse_list(head) do + if id == hlist_t and subtype == line_t then + setlist(n, post_process(list)) end end - return head + return true end -local function post_process_nodes(head, groupcode) +local function post_process_nodes(head) return tonode(post_process(todirect(head))) end +local function post_process_vlist_nodes(head) + return tonode(post_process_vlist(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 @@ -1032,29 +1148,10 @@ 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 +local add_to_callback = luatexbase.add_to_callback -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) +add_to_callback('post_linebreak_filter', post_process_vlist_nodes, 'luaotfload.harf.finalize_vlist') +add_to_callback('hpack_filter', post_process_nodes, 'luaotfload.harf.finalize_hlist') +add_to_callback('wrapup_run', run_cleanup, 'luaotfload.cleanup_files') +add_to_callback('finish_pdffile', set_tounicode, 'luaotfload.harf.finalize_unicode') +add_to_callback('glyph_info', get_glyph_info, 'luaotfload.glyphinfo') diff --git a/Master/texmf-dist/tex/luatex/luaotfload/luaotfload-init.lua b/Master/texmf-dist/tex/luatex/luaotfload/luaotfload-init.lua index cfbcb68eab7..3b67738fe53 100644 --- a/Master/texmf-dist/tex/luatex/luaotfload/luaotfload-init.lua +++ b/Master/texmf-dist/tex/luatex/luaotfload/luaotfload-init.lua @@ -5,17 +5,13 @@ -- AUTHOR: Philipp Gesang (Phg), <phg@phi-gamma.net>, Marcel Krüger ----------------------------------------------------------------------- -local ProvidesLuaModule = { +assert(luaotfload_module, "This is a part of luaotfload and should not be loaded independently") { name = "luaotfload-init", - version = "3.15", --TAGVERSION - date = "2020-09-02", --TAGDATE + version = "3.16", --TAGVERSION + date = "2020-12-31", --TAGDATE description = "luaotfload submodule / initialization", license = "GPL v2.0" } - -if luatexbase and luatexbase.provides_module then - luatexbase.provides_module (ProvidesLuaModule) -end ----------------------------------------------------------------------- @@ -299,7 +295,6 @@ local function init_main(early_hook) local saved_exit = os.exit local errmsg function texio.reporter(msg, ...) - print(...) errmsg = msg end function os.exit() @@ -407,6 +402,11 @@ local function init_main(early_hook) -- fontloader end --- [init_main] +if not luatexbase.callbacktypes.pre_shaping_filter then + luatexbase.create_callback('pre_shaping_filter', 'list') + luatexbase.create_callback('post_shaping_filter', 'reverselist') +end + local init_post_install_callbacks = function () --[[doc-- @@ -423,17 +423,42 @@ local init_post_install_callbacks = function () local fallback = luaotfload.loaders.luaotfload "fallback".process local multiscript = luaotfload.loaders.luaotfload "multiscript".process - -- MK Pass current text direction to simple_font_handler + local call_callback = luatexbase.call_callback + local tex_get = tex.get + local flush_list = node.flush_list local handler = luaotfload.fontloader.nodes.simple_font_handler - local callback = function(head, groupcode, _, _, direction) + local function callback(head, groupcode, _, _, direction) if not direction then - direction = tex.get'textdirection' + direction = tex_get'textdirection' else direction = direction == "TRT" and 1 or 0 end + local result = call_callback("pre_shaping_filter", head, groupcode, direction) + if result == false then + return false + elseif result ~= true then + head = result + end multiscript(head, nil, nil, nil, direction) fallback(head, nil, nil, nil, direction) - return handler(head, groupcode, nil, nil, direction) + result = handler(head, groupcode, nil, nil, direction) + -- handler never returns a boolean and only returns nil if it was passed in + -- We keep it general though for consistency + if result == false then + flush_list(head) + return nil + elseif result ~= true then + head = result + end + result = call_callback("post_shaping_filter", head, groupcode, direction) + if result == false then + flush_list(head) + return nil + elseif result == true then + return head + else + return result + end end luatexbase.add_to_callback("pre_linebreak_filter", callback, @@ -443,7 +468,6 @@ local init_post_install_callbacks = function () callback, "luaotfload.node_processor", 1) - -- /MK local streams = fonts.hashes.streams luatexbase.add_to_callback("glyph_stream_provider",function(id,index,mode) diff --git a/Master/texmf-dist/tex/luatex/luaotfload/luaotfload-letterspace.lua b/Master/texmf-dist/tex/luatex/luaotfload/luaotfload-letterspace.lua index f9c24a13354..c1a3d6f1b7a 100644 --- a/Master/texmf-dist/tex/luatex/luaotfload/luaotfload-letterspace.lua +++ b/Master/texmf-dist/tex/luatex/luaotfload/luaotfload-letterspace.lua @@ -3,20 +3,16 @@ -- DESCRIPTION: part of luaotfload / letterspacing ----------------------------------------------------------------------- -local ProvidesLuaModule = { +assert(luaotfload_module, "This is a part of luaotfload and should not be loaded independently") { name = "luaotfload-letterspace", - version = "3.15", --TAGVERSION - date = "2020-09-02", --TAGDATE + version = "3.16", --TAGVERSION + date = "2020-12-31", --TAGDATE description = "luaotfload submodule / letterspacing", license = "GPL v2.0", copyright = "PRAGMA ADE / ConTeXt Development Team", author = "Hans Hagen, PRAGMA-ADE, Hasselt NL; adapted by Philipp Gesang, Ulrike Fischer, Marcel Krüger" } -if luatexbase and luatexbase.provides_module then - luatexbase.provides_module (ProvidesLuaModule) -end - --- This code diverged quite a bit from its origin in Context. Please --- do *not* report bugs on the Context list. diff --git a/Master/texmf-dist/tex/luatex/luaotfload/luaotfload-loaders.lua b/Master/texmf-dist/tex/luatex/luaotfload/luaotfload-loaders.lua index a63506237a5..84c5555f5db 100644 --- a/Master/texmf-dist/tex/luatex/luaotfload/luaotfload-loaders.lua +++ b/Master/texmf-dist/tex/luatex/luaotfload/luaotfload-loaders.lua @@ -6,17 +6,13 @@ -- AUTHOR: Hans Hagen, Khaled Hosny, Elie Roux, David Carlisle ----------------------------------------------------------------------- -local ProvidesLuaModule = { +assert(luaotfload_module, "This is a part of luaotfload and should not be loaded independently") { name = "luaotfload-loaders", - version = "3.15", --TAGVERSION - date = "2020-09-02", --TAGDATE + version = "3.16", --TAGVERSION + date = "2020-12-31", --TAGDATE description = "luaotfload submodule / callback handling", license = "GPL v2.0" } - -if luatexbase and luatexbase.provides_module then - luatexbase.provides_module (ProvidesLuaModule) -end ----------------------------------------------------------------------- diff --git a/Master/texmf-dist/tex/luatex/luaotfload/luaotfload-log.lua b/Master/texmf-dist/tex/luatex/luaotfload/luaotfload-log.lua index b102da65bf0..58fc403e62b 100644 --- a/Master/texmf-dist/tex/luatex/luaotfload/luaotfload-log.lua +++ b/Master/texmf-dist/tex/luatex/luaotfload/luaotfload-log.lua @@ -4,21 +4,16 @@ ------------------------------------------------------------------------------- -local ProvidesLuaModule = { +assert(luaotfload_module, "This is a part of luaotfload and should not be loaded independently") { name = "luaotfload-log", - version = "3.15", --TAGVERSION - date = "2020-09-02", --TAGDATE + version = "3.16", --TAGVERSION + date = "2020-12-31", --TAGDATE description = "luaotfload submodule / logging", license = "GPL v2.0", author = "Khaled Hosny, Elie Roux, Philipp Gesang", copyright = "Luaotfload Development Team", } -if luatexbase and luatexbase.provides_module then - luatexbase.provides_module (ProvidesLuaModule) -end - - --[[doc-- The logging system is slow in general, as we always have the function call overhead even if we aren’t going to output anything. On the other diff --git a/Master/texmf-dist/tex/luatex/luaotfload/luaotfload-main.lua b/Master/texmf-dist/tex/luatex/luaotfload/luaotfload-main.lua index 5fa8c54ad39..1b029bd5149 100644 --- a/Master/texmf-dist/tex/luatex/luaotfload/luaotfload-main.lua +++ b/Master/texmf-dist/tex/luatex/luaotfload/luaotfload-main.lua @@ -1,341 +1,6 @@ ----------------------------------------------------------------------- -- FILE: luaotfload-main.lua --- DESCRIPTION: OpenType layout system / luaotfload entry point --- REQUIREMENTS: luatex v.0.95.0 or later; package lualibs --- AUTHOR: Élie Roux, Khaled Hosny, Philipp Gesang, Ulrike Fischer, Marcel Krüger +-- DESCRIPTION: OpenType layout system / compatibility wrapper ----------------------------------------------------------------------- -local authors = "\z - Hans Hagen,\z - Khaled Hosny,\z - Elie Roux,\z - Will Robertson,\z - Philipp Gesang,\z - Dohyun Kim,\z - Reuben Thomas,\z - David Carlisle,\ - Ulrike Fischer,\z - Marcel Krüger\z -" --- version number is used below! -local ProvidesLuaModule = { - name = "luaotfload-main", - version = "3.15", --TAGVERSION - date = "2020-09-02", --TAGDATE - description = "luaotfload entry point", - author = authors, - copyright = authors, - license = "GPL v2.0" -} - -if luatexbase and luatexbase.provides_module then - luatexbase.provides_module (ProvidesLuaModule) -end - -local osgettimeofday = os.gettimeofday -config = config or { } -luaotfload = luaotfload or { } -local luaotfload = luaotfload -luaotfload.log = luaotfload.log or { } -local logreport -luaotfload.version = ProvidesLuaModule.version -luaotfload.loaders = { } -luaotfload.fontloader_package = "reference" --- default: from current Context - -if not tex or not tex.luatexversion then - error "this program must be run in TeX mode" --- or call tex.initialize() =) -end - ---- version check -local revno = tonumber(tex.luatexrevision) -local minimum = { 110, 0 } -if tex.luatexversion < minimum[1] or tex.luatexversion == minimum[1] and revno < minimum[2] then - texio.write_nl ("term and log", - string.format ("\tFATAL ERROR\n\z - \tLuaotfload requires a Luatex version >= %d.%d.%d.\n\z - \tPlease update your TeX distribution!\n\n", - math.floor(minimum[1] / 100), minimum[1] % 100, minimum[2])) - error "version check failed" -end - -if not utf8 then - texio.write_nl("term and log", string.format("\z - \tluaotfload: module utf8 is unavailable\n\z - \tutf8 is available in Lua 5.3+; engine\'s _VERSION is %q\n\z - \tThis probably means that the engine is not supported\n\z - \n", - _VERSION)) - error "module utf8 is unavailable" -end - -if status.safer_option ~= 0 then - texio.write_nl("term and log","luaotfload can't run with option --safer. Aborting") - error("safer_option used") -end - - - - ---[[doc-- - - This file initializes the system and loads the font loader. To - minimize potential conflicts between other packages and the code - imported from \CONTEXT, several precautions are in order. Some of - the functionality that the font loader expects to be present, like - raw access to callbacks, are assumed to have been disabled by - \identifier{luatexbase} when this file is processed. In some cases - it is possible to trick it by putting dummies into place and - restoring the behavior from \identifier{luatexbase} after - initilization. Other cases such as attribute allocation require - that we hook the functionality from \identifier{luatexbase} into - locations where they normally wouldn’t be. - - Anyways we can import the code base without modifications, which is - due mostly to the extra effort by Hans Hagen to make \LUATEX-Fonts - self-contained and encapsulate it, and especially due to his - willingness to incorporate our suggestions. - ---doc]]-- - -local luatexbase = luatexbase -local require = require -local type = type - - ---[[doc-- - - \subsection{Module loading} - We load the files imported from \CONTEXT with function derived this way. It - automatically prepends a prefix to its argument, so we can refer to the - files with their actual \CONTEXT name. - ---doc]]-- - -local function make_loader_name (prefix, name) - local msg = luaotfload.log and luaotfload.log.report - or function (stream, lvl, cat, ...) - if lvl > 1 then --[[not pressing]] return end - texio.write_nl ("log", - string.format ("luaotfload | %s : ", - tostring (cat))) - texio.write (string.format (...)) - end - if not name then - msg ("both", 0, "load", - "Fatal error: make_loader_name (%q, %q).", - tostring (prefix), tostring (name)) - return "dummy-name" - end - name = tostring (name) - if prefix == false then - msg ("log", 9, "load", - "No prefix requested, passing module name %q unmodified.", - name) - return tostring (name) .. ".lua" - end - prefix = tostring (prefix) - msg ("log", 9, "load", - "Composing module name from constituents %s, %s.", - prefix, name) - return prefix .. "-" .. name .. ".lua" -end - -local timing_info = { - t_load = { }, - t_init = { }, -} - -local function make_loader (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 (load_helper or require, modname) - local t_end = osgettimeofday () - timing_info.t_load [name] = t_end - t_0 - if not ok then - io.write "\n" - local msg = luaotfload.log and luaotfload.log.report or print - msg ("both", 0, "load", "FATAL ERROR") - msg ("both", 0, "load", " × Failed to load %q module %q.", - tostring (prefix), tostring (name)) - local lines = string.split (data, "\n\t") - if not lines then - msg ("both", 0, "load", " × Error message: %q", data) - else - msg ("both", 0, "load", " × Error message:") - for i = 1, #lines do - msg ("both", 0, "load", " × %q.", lines [i]) - end - end - io.write "\n\n" - local debug = debug - if debug then - io.write (debug.traceback()) - io.write "\n\n" - end - os.exit(-1) - end - return data - end -end - ---[[doc-- - Certain files are kept around that aren’t loaded because they are part of - the imported fontloader. In order to keep the initialization structure - intact we also provide a no-op version of the module loader that can be - called in the expected places. ---doc]]-- - -local function dummy_loader (name) - luaotfload.log.report ("log", 3, "load", - "Skipping module %q on purpose.", - 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 %q could not be found.', name)) - end - return assert(loadfile(fullname, nil, context_environment))(name) -end - -local function context_loader (name, path) - luaotfload.log.report ("log", 3, "load", - "Loading module %q from Context.", - name) - local t_0 = osgettimeofday () - local modname = make_loader_name (false, name) - local modpath = modname - if path then - if lfs.isdir (path) then - luaotfload.log.report ("log", 3, "load", - "Prepending path %q.", - path) - modpath = file.join (path, modname) - else - luaotfload.log.report ("both", 0, "load", - "Non-existant path %q specified, ignoring.", - path) - end - end - local ret = context_isolated_load (modpath) - local t_end = osgettimeofday () - timing_info.t_load [name] = t_end - t_0 - - if ret ~= nil then - --- require () returns “true” upon success unless the loaded file - --- yields a non-zero exit code. This isn’t per se indicating that - --- something isn’t right, but against HH’s coding practices. We’ll - --- silently ignore this ever happening on lower log levels. - luaotfload.log.report ("log", 4, "load", - "Module %q returned %q.", modname, ret) - end - return ret -end - -local function install_loaders () - local loaders = { } - local loadmodule = make_loader "luaotfload" - loaders.luaotfload = loadmodule - loaders.fontloader = make_loader ("fontloader", context_isolated_load) - loaders.context = context_loader - loaders.ignore = dummy_loader -----loaders.plaintex = make_loader "luatex" --=> for Luatex-Plain - - function loaders.initialize (name) - local tmp = loadmodule (name) - local init = type(tmp) == "table" and tmp.init or tmp - if init and type (init) == "function" then - local t_0 = osgettimeofday () - if not init () then - logreport ("log", 0, "load", - "Failed to load module %q.", name) - return - end - local t_end = osgettimeofday () - local d_t = t_end - t_0 - logreport ("log", 4, "load", - "Module %q loaded in %g ms.", - name, d_t * 1000) - timing_info.t_init [name] = d_t - end - end - - return loaders -end - -local luaotfload_initialized = false --- prevent multiple invocations - -luaotfload.main = function () - - if luaotfload_initialized then - logreport ("log", 0, "load", - "Luaotfload initialization requested but is already \z - loaded, ignoring.") - return - end - luaotfload_initialized = true - - luaotfload.loaders = install_loaders () - local loaders = luaotfload.loaders - local loadmodule = loaders.luaotfload - local initialize = loaders.initialize - - local starttime = osgettimeofday () - - -- Feature detect HarfBuzz. This is done early to allow easy HarfBuzz - -- detection in other modules - local harfstatus, harfbuzz = pcall(require, 'luaharfbuzz') - if harfstatus then - luaotfload.harfbuzz = harfbuzz - end - - local init = loadmodule "init" --- fontloader initialization - init (function () - - logreport = luaotfload.log.report - initialize "parsers" --- fonts.conf and syntax - initialize "configuration" --- configuration options - end) - - initialize "loaders" --- Font loading; callbacks - initialize "database" --- Font management. - initialize "colors" --- Per-font colors. - - local init_resolvers = loadmodule "resolvers" --- Font lookup - init_resolvers () - - if not config.actions.reconfigure () then - logreport ("log", 0, "load", "Post-configuration hooks failed.") - end - - initialize "features" --- font request and feature handling - - if harfstatus then - loadmodule "harf-define" - loadmodule "harf-plug" - end - loadmodule "letterspace" --- extra character kerning - loadmodule "embolden" --- fake bold - loadmodule "notdef" --- missing glyph handling - loadmodule "suppress" --- suppress ligatures by adding ZWNJ - loadmodule "szss" --- missing glyph handling - initialize "auxiliary" --- additional high-level functionality - loadmodule "tounicode" - if tex.outputmode == 0 then - loadmodule "dvi" --- allow writing fonts to DVI files - end - - luaotfload.aux.start_rewrite_fontname () --- to be migrated to fontspec - - logreport ("log", 1, "main", - "initialization completed in %0.3f seconds\n", - osgettimeofday() - starttime) -----inspect (timing_info) -end - --- vim:tw=79:sw=4:ts=4:et +return require'luaotfload' diff --git a/Master/texmf-dist/tex/luatex/luaotfload/luaotfload-multiscript.lua b/Master/texmf-dist/tex/luatex/luaotfload/luaotfload-multiscript.lua index aae924c9de8..a632ab4c6a6 100644 --- a/Master/texmf-dist/tex/luatex/luaotfload/luaotfload-multiscript.lua +++ b/Master/texmf-dist/tex/luatex/luaotfload/luaotfload-multiscript.lua @@ -3,19 +3,15 @@ -- DESCRIPTION: part of luaotfload / multiscript ----------------------------------------------------------------------- -local ProvidesLuaModule = { +assert(luaotfload_module, "This is a part of luaotfload and should not be loaded independently") { name = "luaotfload-multiscript", - version = "3.15", --TAGVERSION - date = "2020-09-02", --TAGDATE + version = "3.16", --TAGVERSION + date = "2020-12-31", --TAGDATE description = "luaotfload submodule / multiscript", license = "GPL v2.0", author = "Marcel Krüger" } -if luatexbase and luatexbase.provides_module then - luatexbase.provides_module (ProvidesLuaModule) -end - local nodenew = node.direct.new local getfont = font.getfont local setfont = node.direct.setfont diff --git a/Master/texmf-dist/tex/luatex/luaotfload/luaotfload-notdef.lua b/Master/texmf-dist/tex/luatex/luaotfload/luaotfload-notdef.lua index f2043a7ad7f..7b9664fa7e5 100644 --- a/Master/texmf-dist/tex/luatex/luaotfload/luaotfload-notdef.lua +++ b/Master/texmf-dist/tex/luatex/luaotfload/luaotfload-notdef.lua @@ -3,19 +3,15 @@ -- DESCRIPTION: part of luaotfload / notdef ----------------------------------------------------------------------- -local ProvidesLuaModule = { +assert(luaotfload_module, "This is a part of luaotfload and should not be loaded independently") { name = "luaotfload-notdef", - version = "3.15", --TAGVERSION - date = "2020-09-02", --TAGDATE + version = "3.16", --TAGVERSION + date = "2020-12-31", --TAGDATE description = "luaotfload submodule / notdef", license = "GPL v2.0", author = "Marcel Krüger" } -if luatexbase and luatexbase.provides_module then - luatexbase.provides_module (ProvidesLuaModule) -end - local harfbuzz = luaotfload.harfbuzz local flush_node = node.direct.flush_node local getfont = font.getfont diff --git a/Master/texmf-dist/tex/luatex/luaotfload/luaotfload-parsers.lua b/Master/texmf-dist/tex/luatex/luaotfload/luaotfload-parsers.lua index f321e9733fd..7810c3a49e6 100644 --- a/Master/texmf-dist/tex/luatex/luaotfload/luaotfload-parsers.lua +++ b/Master/texmf-dist/tex/luatex/luaotfload/luaotfload-parsers.lua @@ -5,19 +5,14 @@ -- AUTHOR: Philipp Gesang (Phg), <phg@phi-gamma.net>, Marcel Krüger ------------------------------------------------------------------------------- -local ProvidesLuaModule = { +assert(luaotfload_module, "This is a part of luaotfload and should not be loaded independently") { name = "luaotfload-parsers", - version = "3.15", --TAGVERSION - date = "2020-09-02", --TAGDATE + version = "3.16", --TAGVERSION + date = "2020-12-31", --TAGDATE description = "luaotfload submodule / parsers", license = "GPL v2.0" } -if luatexbase and luatexbase.provides_module then - luatexbase.provides_module (ProvidesLuaModule) -end - - local traversal_maxdepth = 42 --- prevent stack overflows local rawset = rawset diff --git a/Master/texmf-dist/tex/luatex/luaotfload/luaotfload-resolvers.lua b/Master/texmf-dist/tex/luatex/luaotfload/luaotfload-resolvers.lua index b7ca21ec876..2ea85de7811 100644 --- a/Master/texmf-dist/tex/luatex/luaotfload/luaotfload-resolvers.lua +++ b/Master/texmf-dist/tex/luatex/luaotfload/luaotfload-resolvers.lua @@ -9,19 +9,14 @@ --- The bare fontloader uses a set of simplistic file name resolvers --- that must be overloaded by the user (i. e. us). -local ProvidesLuaModule = { +assert(luaotfload_module, "This is a part of luaotfload and should not be loaded independently") { name = "luaotfload-resolvers", - version = "3.15", --TAGVERSION - date = "2020-09-02", --TAGDATE + version = "3.16", --TAGVERSION + date = "2020-12-31", --TAGDATE description = "luaotfload submodule / resolvers", license = "GPL v2.0" } -if luatexbase and luatexbase.provides_module then - luatexbase.provides_module (ProvidesLuaModule) -end - - if not lualibs then error "this module requires Luaotfload" end if not luaotfload then error "this module requires Luaotfload" end diff --git a/Master/texmf-dist/tex/luatex/luaotfload/luaotfload-scripts.lua b/Master/texmf-dist/tex/luatex/luaotfload/luaotfload-scripts.lua index 6ac19f14d57..b6c34b9e3eb 100644 --- a/Master/texmf-dist/tex/luatex/luaotfload/luaotfload-scripts.lua +++ b/Master/texmf-dist/tex/luatex/luaotfload/luaotfload-scripts.lua @@ -3,19 +3,15 @@ -- DESCRIPTION: part of luaotfload / script ----------------------------------------------------------------------- -local ProvidesLuaModule = { +assert(luaotfload_module, "This is a part of luaotfload and should not be loaded independently") { name = "luaotfload-script", - version = "3.15", --TAGVERSION - date = "2020-09-02", --TAGDATE + version = "3.16", --TAGVERSION + date = "2020-12-31", --TAGDATE description = "luaotfload submodule / Script helpers", license = "CC0 1.0 Universal", author = "Marcel Krüger" } -if luatexbase and luatexbase.provides_module then - luatexbase.provides_module (ProvidesLuaModule) -end - local canonical_name = { dflt = "DFLT", hira = "kana", diff --git a/Master/texmf-dist/tex/luatex/luaotfload/luaotfload-status.lua b/Master/texmf-dist/tex/luatex/luaotfload/luaotfload-status.lua index dd38631cc8d..0ad3c01ead3 100644 --- a/Master/texmf-dist/tex/luatex/luaotfload/luaotfload-status.lua +++ b/Master/texmf-dist/tex/luatex/luaotfload/luaotfload-status.lua @@ -1,97 +1,99 @@ return { ["hashes"]={ - { "fontloader-2020-08-31.lua", "70a72561e3869bcaa8554921083b3872" }, - { "fontloader-util-fil.lua", "aae2a2add764144bb58dd8216fd59260" }, - { "fontloader-util-str.lua", "c975ff7bbd178163cf47d9e9296c8b4b" }, - { "fontloader-l-unicode.lua", "f368874f11f3c525de5864fd413e4b24" }, - { "fontloader-l-math.lua", "082add08e0bb79f39191ae9534a79849" }, - { "fontloader-l-boolean.lua", "abe28515dd33e8f6c416c09bca351cf8" }, - { "fontloader-l-file.lua", "352b42b8360ada02ceb26a41f0bd2a76" }, - { "fontloader-l-io.lua", "bbcc4824d0ded30b415d7d2d5763028a" }, - { "fontloader-l-table.lua", "0330da8b3a08d39876def70df8d9c0e5" }, - { "fontloader-l-string.lua", "9457f2af85723e0e6c46d0b5122e9000" }, - { "fontloader-l-function.lua", "a7e68a9703c35238729da41a474e951b" }, - { "fontloader-l-lpeg.lua", "10bdaef44175902917691835010ae5f5" }, - { "fontloader-l-lua.lua", "420bc442e6d81f4624728a6c56fcd175" }, - { "fontloader-fonts-gbn.lua", "10ecdf01e7c926e5128ad8a9dff4d677" }, - { "fontloader-fonts-lig.lua", "fbd251eea3810a43a8d5542319361d68" }, - { "fontloader-fonts-ext.lua", "32013cbc5d5d336be8b1d1e5879d86c4" }, - { "fontloader-fonts-def.lua", "f435e0875f203f343157baeff876ec9c" }, - { "fontloader-fonts-tfm.lua", "f0eb5e2a8068b17ad401bb7efdba1630" }, - { "fontloader-fonts-enc.lua", "5ff4ca50493d7c4ecea0e15c203099f0" }, - { "fontloader-fonts-mis.lua", "17e967c9ec4d001deefd43ddf25e98f7" }, - { "fontloader-basics-chr.lua", "64fafe4eaf55d64aead6513c1e74a024" }, - { "fontloader-basics-nod.lua", "335e61ffb6dec00f88f737854a2d9ab4" }, - { "fontloader-font-imp-effects.lua", "d9b935e9b73f250a175ddd71a226b8e9" }, - { "fontloader-font-imp-italics.lua", "ae563638fa29a4ff3e8e4d1e81fd35ae" }, - { "fontloader-font-imp-ligatures.lua", "26ffcf089391445f7af59536c8814364" }, - { "fontloader-font-imp-tex.lua", "ceb087ef6fa2f89aed7179f60ddf8f35" }, - { "fontloader-font-def.lua", "b9d908c2338b7dc443ce9d1e9fcb7139" }, - { "fontloader-font-lua.lua", "1fbfdf7b689b2bdfd0e3bb9bf74ce136" }, - { "fontloader-font-afk.lua", "9da14e0fb22129c053acc599d1312544" }, - { "fontloader-font-one.lua", "5a2f244c88c8178e997c16a9b628bb6f" }, - { "fontloader-font-onr.lua", "6d161533f3437435e12a0ad64866df44" }, - { "fontloader-font-otc.lua", "0f12230ea07b5151f75d52726977e91f" }, - { "fontloader-font-ocl.lua", "797b5c71bf819c5f4fb314a4d646e9a7" }, - { "fontloader-font-osd.lua", "73c9531c79df5ada320cb20777f7ed49" }, - { "fontloader-font-ots.lua", "f018ae1f355a8ef5c8d403cc5489e3d3" }, - { "fontloader-font-ota.lua", "ad1d5de06400f88829509e1f3ff2b473" }, - { "fontloader-font-otj.lua", "8de59cb9b043e5f73c6b9f7cc8f6978e" }, - { "fontloader-font-oto.lua", "2b1d6bc63b2ebf8f2655a15e1cda6541" }, - { "fontloader-font-otl.lua", "b168cf69300873d6668203bc7afe1f56" }, - { "fontloader-font-oup.lua", "6f46aa00ae1c20c43f8ffaf329dc8695" }, - { "fontloader-font-dsp.lua", "5d6528c0673b7651600ca6b763b51df5" }, - { "fontloader-font-ttf.lua", "786a535ba0385446b7015260388bc415" }, - { "fontloader-font-cff.lua", "802a10ad12ac32329f540881f940e3f2" }, - { "fontloader-font-ott.lua", "673ed11e1d159997f535bfec5fa73808" }, - { "fontloader-font-oti.lua", "309a75f9c14b77d87e94eba827dc4e71" }, - { "fontloader-font-otr.lua", "64dcbbc7107538723990e1119a80a9f8" }, - { "fontloader-font-vfc.lua", "a81c29eda98cd62cbebdb6c93544b50d" }, - { "fontloader-font-map.lua", "c4a39db5ad822b348aa61bca5f4a599a" }, - { "fontloader-font-cid.lua", "22b0367742fb253deef84ef7ccf5e8de" }, - { "fontloader-font-con.lua", "a3eb543fa5946fa1faf0e1e50d5b3b91" }, - { "fontloader-font-ini.lua", "5343de60613adb24cdd7a8d2ee1d153c" }, - { "fontloader-data-con.lua", "23a0f5386d46a1c157ae82a373e35fa0" }, - { "fontloader-reference.lua", "c10086745bc0b8b2303572fdea86d61c" }, - { "fontloader-basics-gen.lua", "4bc43036e9796fccb0b8869f4b05bf2e" }, - { "mktests", "918cb50be9ee8bd645ac1a27dc501e8c" }, - { "mkstatus", "49692433db8a578cf3a03fbedfb2ea9c" }, - { "mkcharacters", "bfca0e96e1e351afe7077502f9595af9" }, - { "mkglyphlist", "7a8a8fdc0eac7fac2f13ec8f4e8e7aa9" }, - { "mkimport", "7d62f1042e548f8b9368f26b9ba4be5c" }, - { "luaotfload-glyphlist.lua", "af60521c7ea3f5828c83ed1d1fa23b45" }, - { "luaotfload-characters.lua", "76415ca3ede312cad6e09038323489ae" }, - { "luaotfload-tounicode.lua", "24601f0255c35508eddbb427a6e18873" }, - { "luaotfload-unicode.lua", "c7d3f282db7a0f9588cc57d8f079a3cb" }, - { "luaotfload-resolvers.lua", "ac9e134e0614ab7ab69122ec0fd99e54" }, - { "luaotfload-parsers.lua", "10afafb81544840cb0fd0ecaac3c3344" }, - { "luaotfload-fallback.lua", "9d70a346c2584834f40d83be25d53a6a" }, - { "luaotfload-szss.lua", "0e29a05f35bbd05388e5af674059c242" }, - { "luaotfload-scripts.lua", "9a1e50e55ddef481ca3863004f33703e" }, - { "luaotfload-multiscript.lua", "8a828bf429dc73742ea78ad73332d219" }, - { "luaotfload-loaders.lua", "f13bafee1dca48db5073fe4390dc8ec4" }, - { "luaotfload-harf-plug.lua", "f43e0d894cf9ca3f31ff405d1684a5ff" }, - { "luaotfload-harf-define.lua", "0aecef4ea82a6edc305be2eed7b8e9c9" }, - { "luaotfload-notdef.lua", "73762a6d7662aa090f8f950a34d55835" }, - { "luaotfload-embolden.lua", "3444350537a12803b8e255f56b33b50d" }, - { "luaotfload-letterspace.lua", "6ac6c8d6f54107984ad338a94f0acd86" }, - { "luaotfload-features.lua", "b42fbc57c4fb1306dc23bf4e3bf6cd98" }, - { "luaotfload-database.lua", "8e11e69cf6a83bc1723c95e4788cdc70" }, - { "luaotfload-configuration.lua", "d1f4d64caa58bfc5feb524ea7cd365f6" }, - { "luaotfload-colors.lua", "5d1e7e10b5a8dda7ccf3742ae90f002e" }, - { "luaotfload-auxiliary.lua", "6d4e31212b8852e5f1425dc0ea49e016" }, - { "luaotfload-filelist.lua", "5e4c15ea6e5aafc19a533289b6ac2709" }, - { "luaotfload-tool.lua", "9caf618c38bf58cf9a29f2b2d4449346" }, - { "luaotfload-diagnostics.lua", "797176921da30591e6112831ed7459a7" }, - { "luaotfload-log.lua", "932117045a6abfe303314a295c24d338" }, - { "luaotfload-init.lua", "eb1bfca3833688aba31521032ed38883" }, - { "luaotfload-main.lua", "133ee97a73e07f3116d0417c9373398b" }, + { "fontloader-2020-12-30.lua", "68ad807e7fdc2161801a16d1d404e1c4" }, + { "fontloader-util-fil.lua", "a617cad49fc028e99f0f30bce8b2b623" }, + { "fontloader-util-str.lua", "a2041dad54b982ad124cbc764f5de43b" }, + { "fontloader-l-unicode.lua", "a4464b61c123f0454bea92c1cf502891" }, + { "fontloader-l-math.lua", "a373be3ed2db0d5f98588fa81abca48f" }, + { "fontloader-l-boolean.lua", "18ed6c4b2c40dd87224ea33229548d20" }, + { "fontloader-l-file.lua", "60ddd3948d9de7bde8b4a0f5c51ff9f5" }, + { "fontloader-l-io.lua", "a4042e9d6bce71c61fdd94e6e17f2bf4" }, + { "fontloader-l-table.lua", "20c03ae1b81e902217f3f76995b9d294" }, + { "fontloader-l-string.lua", "e1347bef0eeeff9f098df83b30b32df9" }, + { "fontloader-l-function.lua", "f771cc91839ebcdfc094083434fbe00f" }, + { "fontloader-l-lpeg.lua", "c3407de16bcedd73652250b000b39e98" }, + { "fontloader-l-lua.lua", "c8dbb33df962e1b945b91b906b3c15c4" }, + { "fontloader-fonts-gbn.lua", "d25472d54c4841db43a745764a63533e" }, + { "fontloader-fonts-lig.lua", "b9dbe77ce747d4c35bb2a20ffbe5aa51" }, + { "fontloader-fonts-ext.lua", "01015ab3758cdc2af29394e6d502a91a" }, + { "fontloader-fonts-def.lua", "5ad79120ebc5e60f4d322fb3ee13bffe" }, + { "fontloader-fonts-tfm.lua", "3bbba3214fd0b8c6f35ad85592fc2917" }, + { "fontloader-fonts-enc.lua", "3e71a54297e8f85a1ac438bb0f20dd79" }, + { "fontloader-fonts-mis.lua", "bc9eb43c27f63ce9d0fff67e104fe1c6" }, + { "fontloader-basics-chr.lua", "58b7ef0c486e06090b362971b9f85e27" }, + { "fontloader-basics-nod.lua", "6549c88db8cf4c6ae005a2e08f223d4b" }, + { "fontloader-font-imp-effects.lua", "231cda056b88f6dc282fab9d7643d380" }, + { "fontloader-font-imp-italics.lua", "058fb834c11c6ac30c280b29e496966e" }, + { "fontloader-font-imp-ligatures.lua", "043daa4fcccf2560868da359d71d3a4a" }, + { "fontloader-font-imp-tex.lua", "77c374b0ef00c2fb12188ec42beb4257" }, + { "fontloader-font-shp.lua", "72de6029980ac796ec6ec76fa3ec8684" }, + { "fontloader-font-def.lua", "226b4d26ede7fa7be8e45b7f0d93e781" }, + { "fontloader-font-lua.lua", "55b281fb98f7bd848fc19928f376f647" }, + { "fontloader-font-afk.lua", "54d554530e75c57c56ee76234724e26d" }, + { "fontloader-font-one.lua", "2e52d1e42764f68b779522bda9569480" }, + { "fontloader-font-onr.lua", "7a9ece7bf3e36b5f0adf295a9a2a2989" }, + { "fontloader-font-ocl.lua", "ab81576f20e2d37bc8707e1dbd3decf2" }, + { "fontloader-font-osd.lua", "61f05fcf91add1aa5dac9bc8b235adc9" }, + { "fontloader-font-otc.lua", "1204a2fdc436e644127c0aa38ab69607" }, + { "fontloader-font-ots.lua", "a83d5992a82b706c0ffdb5c2778534f1" }, + { "fontloader-font-ota.lua", "f31232af3a694ae3d50380a5a92f88d3" }, + { "fontloader-font-oup.lua", "1700a2dac4f8b105c187d4e5b84cecdf" }, + { "fontloader-font-otj.lua", "a37a1007b8a92c9e7d24064180c2a772" }, + { "fontloader-font-oto.lua", "24238a7c600d090a8ee88312321dd9b3" }, + { "fontloader-font-otl.lua", "70237f19b76c4bc75f0c6e89038fb49a" }, + { "fontloader-font-ott.lua", "1249b7018dba80e080fc478a38aa6756" }, + { "fontloader-font-oti.lua", "dbae7722baae24d917a17176553825cf" }, + { "fontloader-font-dsp.lua", "10eb256f4bcb9c5eabd48048e2da5eab" }, + { "fontloader-font-ttf.lua", "ebef049a169c04edd19902fd66ddea44" }, + { "fontloader-font-cff.lua", "aa9038651d9fedd2b76cacd1f69fd742" }, + { "fontloader-font-otr.lua", "7a2f7a9e9627b29158e1822ea3c650ab" }, + { "fontloader-font-vfc.lua", "04fa0ffad5c51198c7c19462949f54ed" }, + { "fontloader-font-map.lua", "a03653ea3c5f042b457d54ed678d6df3" }, + { "fontloader-font-cid.lua", "4d87988efa86020a14708ee03c23415f" }, + { "fontloader-font-con.lua", "cbccccc4a5016196d62332a365aa8b72" }, + { "fontloader-font-ini.lua", "4dee96e1e1474d324dd126bd5d375df8" }, + { "fontloader-data-con.lua", "de6ae0997b0e70a23bcc9afff5d8b072" }, + { "fontloader-reference.lua", "957f358a48ea6fcbc78a8701f947d7e5" }, + { "fontloader-basics-gen.lua", "7bcfb5e4f48a1a34be6ddfcee2b1e49d" }, + { "mktests", "c7cff7025962922944376acc1ffa9c47" }, + { "mkstatus", "f3b00b5999440afce64bdc448f3fda9a" }, + { "mkcharacters", "92c24bb582fc84c0365634f29eb89863" }, + { "mkglyphlist", "95bbf91338214d40b2102114285ccd3f" }, + { "mkimport", "5dacc09f3358ba9b90cf3a804f9a535c" }, + { "luaotfload-glyphlist.lua", "bb6a9912a0944b3b21a61fce247dd728" }, + { "luaotfload-characters.lua", "6a46f4749368e4f56a863da9c61b7bd6" }, + { "luaotfload-dvi.lua", "34e1550905555da63304e07797168c69" }, + { "luaotfload-tounicode.lua", "09fa475eeb7b160d3eb124e9107d4e03" }, + { "luaotfload-unicode.lua", "153f97b086fd38dcb7f4850d95a41016" }, + { "luaotfload-resolvers.lua", "2441b9624775fbcea6617e6cc72b424d" }, + { "luaotfload-parsers.lua", "623d33f43813eda562cbfef5528753de" }, + { "luaotfload-fallback.lua", "ec702c1c9407eba7bfe80b59c36f3f67" }, + { "luaotfload-szss.lua", "ee4c0c070dcacf4d3e43f52948611392" }, + { "luaotfload-scripts.lua", "14a19085cd5288592ebd5e24acf8514a" }, + { "luaotfload-multiscript.lua", "4a283df608be713b0b666515fb6b9789" }, + { "luaotfload-loaders.lua", "f0eeb293d8f448413631b1ffff554e39" }, + { "luaotfload-harf-plug.lua", "34182344e7985d1267dacde37f387433" }, + { "luaotfload-harf-define.lua", "252c36178f4f9ab066bdc15adfe809f1" }, + { "luaotfload-notdef.lua", "06278786a6f2f8ddd3749b5d75f611db" }, + { "luaotfload-embolden.lua", "8bdfebc528d078086c7fd0747815df74" }, + { "luaotfload-letterspace.lua", "57d6026196fa62f9891d7a7a7300f63f" }, + { "luaotfload-features.lua", "2219adcecef7362bbbe46da2e5ed005b" }, + { "luaotfload-database.lua", "e2bea14191641d3a18b04064752d0fd4" }, + { "luaotfload-configuration.lua", "dfa0521ef327c68573ea587ed7b989c8" }, + { "luaotfload-colors.lua", "32bf6714aa19f6c291922cd1be01b629" }, + { "luaotfload-auxiliary.lua", "4c18ffcc0d1cbef3ad4db2b6440a863e" }, + { "luaotfload-filelist.lua", "8bb0a321254e6f04a1fa776d2f67747f" }, + { "luaotfload-tool.lua", "ac7b0adfd9d0096228bed8ae61540a70" }, + { "luaotfload-diagnostics.lua", "21bca70ad0b6f7dd1d9d57c7b1513809" }, + { "luaotfload-log.lua", "d9c45eff233d71c3824f3a579694d737" }, + { "luaotfload-init.lua", "265f1bfe8789fbb0cc3bff3a780f5494" }, + { "luaotfload-main.lua", "f5f771d1cf5c8c4a2519a8d46aed1241" }, }, ["notes"]={ - ["committer"]="Marcel Fabian Krüger <tex@2krueger.de>", - ["description"]="v3.15/2020-09-02", - ["loader"]="fontloader-2020-08-31.lua", - ["revision"]="77eede02640bef0cb596d24aa79661328a68b448", - ["timestamp"]="2020-09-02 21:02:40 +0200", + ["committer"]="Ulrike Fischer <fischer@troubleshooting-tex.de>", + ["description"]="v3.16/2020-12-31", + ["loader"]="fontloader-2020-12-30.lua", + ["revision"]="d1423b56efe2649e2881657747cee8d54cf64e12", + ["timestamp"]="2020-12-31 12:35:44 +0100", }, }
\ No newline at end of file diff --git a/Master/texmf-dist/tex/luatex/luaotfload/luaotfload-suppress.lua b/Master/texmf-dist/tex/luatex/luaotfload/luaotfload-suppress.lua index 768cf814024..c4c0c1010e6 100644 --- a/Master/texmf-dist/tex/luatex/luaotfload/luaotfload-suppress.lua +++ b/Master/texmf-dist/tex/luatex/luaotfload/luaotfload-suppress.lua @@ -3,19 +3,15 @@ -- DESCRIPTION: part of luaotfload / suppress ----------------------------------------------------------------------- -local ProvidesLuaModule = { +assert(luaotfload_module, "This is a part of luaotfload and should not be loaded independently") { name = "luaotfload-suppress", - version = "3.15", --TAGVERSION - date = "2020-09-02", --TAGDATE + version = "3.16", --TAGVERSION + date = "2020-12-31", --TAGDATE description = "luaotfload submodule / suppress", license = "GPL v2.0", author = "Marcel Krüger" } -if luatexbase and luatexbase.provides_module then - luatexbase.provides_module (ProvidesLuaModule) -end - local direct = node.direct local otfregister = fonts.constructors.features.otf.register diff --git a/Master/texmf-dist/tex/luatex/luaotfload/luaotfload-szss.lua b/Master/texmf-dist/tex/luatex/luaotfload/luaotfload-szss.lua index 751964cdd10..4c7de4d11bc 100644 --- a/Master/texmf-dist/tex/luatex/luaotfload/luaotfload-szss.lua +++ b/Master/texmf-dist/tex/luatex/luaotfload/luaotfload-szss.lua @@ -3,19 +3,15 @@ -- DESCRIPTION: part of luaotfload / szss ----------------------------------------------------------------------- -local ProvidesLuaModule = { +assert(luaotfload_module, "This is a part of luaotfload and should not be loaded independently") { name = "luaotfload-szss", - version = "3.15", --TAGVERSION - date = "2020-09-02", --TAGDATE + version = "3.16", --TAGVERSION + date = "2020-12-31", --TAGDATE description = "luaotfload submodule / Special feature handling", license = "GPL v2.0", author = "Marcel Krüger" } -if luatexbase and luatexbase.provides_module then - luatexbase.provides_module (ProvidesLuaModule) -end - local direct = node.direct local otfregister = fonts.constructors.features.otf.register diff --git a/Master/texmf-dist/tex/luatex/luaotfload/luaotfload-tounicode.lua b/Master/texmf-dist/tex/luatex/luaotfload/luaotfload-tounicode.lua index 028aef9d125..f4eeec1125b 100644 --- a/Master/texmf-dist/tex/luatex/luaotfload/luaotfload-tounicode.lua +++ b/Master/texmf-dist/tex/luatex/luaotfload/luaotfload-tounicode.lua @@ -3,20 +3,16 @@ -- DESCRIPTION: part of luaotfload / tounicode overwrites ----------------------------------------------------------------------- -local ProvidesLuaModule = { +assert(luaotfload_module, "This is a part of luaotfload and should not be loaded independently") { name = "luaotfload-tounicode", - version = "3.15", --TAGVERSION - date = "2020-09-02", --TAGDATE + version = "3.16", --TAGVERSION + date = "2020-12-31", --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 diff --git a/Master/texmf-dist/tex/luatex/luaotfload/luaotfload-unicode.lua b/Master/texmf-dist/tex/luatex/luaotfload/luaotfload-unicode.lua index 2e9b28cf790..a05c660a363 100644 --- a/Master/texmf-dist/tex/luatex/luaotfload/luaotfload-unicode.lua +++ b/Master/texmf-dist/tex/luatex/luaotfload/luaotfload-unicode.lua @@ -3,19 +3,15 @@ -- DESCRIPTION: part of luaotfload / unicode ----------------------------------------------------------------------- -local ProvidesLuaModule = { +assert(luaotfload_module, "This is a part of luaotfload and should not be loaded independently") { name = "luaotfload-unicode", - version = "3.15", --TAGVERSION - date = "2020-09-02", --TAGDATE + version = "3.16", --TAGVERSION + date = "2020-12-31", --TAGDATE description = "luaotfload submodule / Unicode helpers", license = "CC0 1.0 Universal", author = "Marcel Krüger" } -if luatexbase and luatexbase.provides_module then - luatexbase.provides_module (ProvidesLuaModule) -end - local utf8codes = utf8.codes local utf8char = utf8.char local sub = string.sub @@ -103,7 +99,149 @@ local alphnum_only do end end +local uppercase, lowercase, ccc, cased, case_ignorable, titlecase = {}, {}, {}, {}, {}, nil do + titlecase = nil -- Not implemented yet(?) + local ignored_field = (1-lpeg.P';')^0 * ';' + local cased_category = lpeg.P'Ll;' + 'Lu;' + 'Lt;' + local case_ignore_category = lpeg.P'Mn;' + 'Me;' + 'Cf;' + 'Lm;' + 'Sk;' + + local simple_entry = + codepoint/0 * ';' + * ignored_field -- Name + * (ignored_field - cased_category - case_ignore_category) -- General_Category + * '0;' -- ccc + * ignored_field -- Bidi + * ignored_field -- Decomp + * ignored_field -- Numeric + * ignored_field -- Numeric + * ignored_field -- Numeric + * ignored_field -- Mirrored + * ignored_field -- Obsolete + * ignored_field -- Obsolete + * ';;\n' + local entry = simple_entry + + codepoint * ';' + * ignored_field -- Name + * (cased_category * lpeg.Cc(cased) + case_ignore_category * lpeg.Cc(case_ignorable) + ignored_field * lpeg.Cc(nil)) -- General_Category + * ('0;' * lpeg.Cc(nil) + lpeg.R'09'^1/tonumber * ';') -- ccc + * ignored_field -- Bidi + * ignored_field -- Decomp + * ignored_field -- Numeric + * ignored_field -- Numeric + * ignored_field -- Numeric + * ignored_field -- Mirrored + * ignored_field -- Obsolete + * ignored_field -- Obsolete + * (codepoint + lpeg.Cc(nil)) * ';' -- uppercase + * (codepoint + lpeg.Cc(nil)) * ';' -- lowercase + * (codepoint + lpeg.Cc(nil)) * '\n' -- titlecase + / function(codepoint, cased_flag, ccc_val, upper, lower, title) + if cased_flag then cased_flag[codepoint] = true end + ccc[codepoint] = ccc_val + uppercase[codepoint] = upper + lowercase[codepoint] = lower + -- if title then titlecase[codepoint] = title end -- Not implemented yet(?) + end + local file = entry^0 * -1 + + local f = io.open(kpse.find_file"UnicodeData.txt") + assert(file:match(f:read'*a')) + f:close() +end + +local props do + local ws = lpeg.P' '^0 + local nl = ws * ('#' * (1-lpeg.P'\n')^0)^-1 * '\n' + local entry = codepoint * (".." * codepoint + lpeg.Cc(false)) * ws * ";" * ws * lpeg.C(lpeg.R("AZ", "az", "__")^1) * nl + local file = lpeg.Cf( + lpeg.Ct( + lpeg.Cg(lpeg.Ct"", "Soft_Dotted") + * lpeg.Cg(lpeg.Cc(cased), "Other_Lowercase") + * lpeg.Cg(lpeg.Cc(cased), "Other_Uppercase")) + * (lpeg.Cg(entry) + nl)^0 + , function(t, cp_start, cp_end, prop) + local prop_table = t[prop] + if prop_table then + for cp = cp_start, cp_end or cp_start do + prop_table[cp] = true + end + end + return t + end) * -1 + + local f = io.open(kpse.find_file"PropList.txt") + props = file:match(f:read'*a') + f:close() +end + +do + local ws = lpeg.P' '^0 + local nl = ws * ('#' * (1-lpeg.P'\n')^0)^-1 * '\n' + local file = (codepoint * (".." * codepoint + lpeg.Cc(false)) * ws * ";" * ws * (lpeg.P'Single_Quote' + 'MidLetter' + 'MidNumLet') * nl / function(cp_start, cp_end) + for cp = cp_start, cp_end or cp_start do + case_ignorable[cp] = true + end + end + (1-lpeg.P'\n')^0 * '\n')^0 * -1 + + local f = io.open(kpse.find_file"WordBreakProperty.txt") + assert(file:match(f:read'*a')) + f:close() +end + +do + local ws = lpeg.P' '^0 + local nl = ws * ('#' * (1-lpeg.P'\n')^0)^-1 * '\n' + local empty = {} + local function set(t, cp, condition, value) + local old = t[cp] or cp + if not condition then + if #value == 1 and tonumber(old) then + t[cp] = value[1] + return + end + condition = empty + end + if tonumber(old or cp) then + old = {_ = {old}} + t[cp] = old + end + for i=1, #condition do + local cond = condition[i] + local step = old[cond] + if not step then + step = {} + old[cond] = step + end + old = step + end + old._ = value + end + local entry = codepoint * ";" + * lpeg.Ct((ws * codepoint)^1 + ws) * ";" + * lpeg.Ct((ws * codepoint)^1 + ws) * ";" + * lpeg.Ct((ws * codepoint)^1 + ws) * ";" + * (lpeg.Ct((ws * lpeg.C(lpeg.R('AZ', 'az', '__')^1))^1) * ";")^-1 + * ws * nl / function(cp, lower, title, upper, condition) + set(lowercase, cp, condition, lower) + set(uppercase, cp, condition, upper) + end + local file = (entry + nl)^0 * -1 + + local f = io.open(kpse.find_file"SpecialCasing.txt") + assert(file:match(f:read'*a')) + f:close() +end + return { casefold = casefold, alphnum_only = alphnum_only, + casemapping = { + uppercase = uppercase, + lowercase = lowercase, + cased = cased, + case_ignorable = case_ignorable, + -- titlecase = titlecase, + }, + ccc = ccc, + soft_dotted = props.Soft_Dotted, } diff --git a/Master/texmf-dist/tex/luatex/luaotfload/luaotfload.lua b/Master/texmf-dist/tex/luatex/luaotfload/luaotfload.lua new file mode 100644 index 00000000000..843c84a3bf5 --- /dev/null +++ b/Master/texmf-dist/tex/luatex/luaotfload/luaotfload.lua @@ -0,0 +1,375 @@ +----------------------------------------------------------------------- +-- FILE: luaotfload.lua +-- DESCRIPTION: OpenType layout system / luaotfload entry point +-- REQUIREMENTS: luatex v.0.95.0 or later; package lualibs +-- AUTHOR: Élie Roux, Khaled Hosny, Philipp Gesang, Ulrike Fischer, Marcel Krüger +----------------------------------------------------------------------- + +local authors = "\z + Hans Hagen,\z + Khaled Hosny,\z + Elie Roux,\z + Will Robertson,\z + Philipp Gesang,\z + Dohyun Kim,\z + Reuben Thomas,\z + David Carlisle,\ + Ulrike Fischer,\z + Marcel Krüger\z +" +-- version number is used below! +local ProvidesLuaModule = { + name = "luaotfload", + version = "3.16", --TAGVERSION + date = "2020-12-31", --TAGDATE + description = "Lua based OpenType font support", + author = authors, + copyright = authors, + license = "GPL v2.0" +} + +if luatexbase and luatexbase.provides_module then + luatexbase.provides_module (ProvidesLuaModule) +end + +if luaotfload_module == nil then + local print_warning = luatexbase and luatexbase.module_warning or function(module, text) + return texio.write_nl("%s WARNING: %s", module, text) + end + local saved_version = ProvidesLuaModule.version + local trace_submodules = tonumber(os.getenv'LUAOTFLOAD_TRACE_SUBMODULES') + if luatexbase and luatexbase.provides_module and trace_submodules and trace_submodules ~= 0 then + luaotfload_module = luatexbase.provides_module + else + function luaotfload_module(module) + local module_version = module.version + if module_version ~= saved_version then + local filenames + if debug then + filenames = string.format("luaotfload.lua is found at\n%q\n%s.lua is found at\n%q\n", + debug.getinfo(1, "S").source:sub(2), + module.name, + debug.getinfo(2, "S").source:sub(2)) + else + filenames = "" + end + print_warning("luaotfload", string.format("Version inconsistency detected.\n\z + luaotfload is loaded in version %s, while %q is loaded \z + in version %s.\n%sI will try to continue anyway.\nHIC SUNT DRACONES", + saved_version, module.name, module_version, filenames)) + end + end + end +else + error[[luaotfload is reloading itself nested. This can't happen.]] +end + +local osgettimeofday = os.gettimeofday +config = config or { } +luaotfload = luaotfload or { } +local luaotfload = luaotfload +luaotfload.log = luaotfload.log or { } +local logreport +luaotfload.version = ProvidesLuaModule.version +luaotfload.loaders = { } +luaotfload.fontloader_package = "reference" --- default: from current Context + +if not tex or not tex.luatexversion then + error "this program must be run in TeX mode" --- or call tex.initialize() =) +end + +--- version check +local revno = tonumber(tex.luatexrevision) +local minimum = { 110, 0 } +if tex.luatexversion < minimum[1] or tex.luatexversion == minimum[1] and revno < minimum[2] then + texio.write_nl ("term and log", + string.format ("\tFATAL ERROR\n\z + \tLuaotfload requires a Luatex version >= %d.%d.%d.\n\z + \tPlease update your TeX distribution!\n\n", + math.floor(minimum[1] / 100), minimum[1] % 100, minimum[2])) + error "version check failed" +end + +if not utf8 then + texio.write_nl("term and log", string.format("\z + \tluaotfload: module utf8 is unavailable\n\z + \tutf8 is available in Lua 5.3+; engine\'s _VERSION is %q\n\z + \tThis probably means that the engine is not supported\n\z + \n", + _VERSION)) + error "module utf8 is unavailable" +end + +if status.safer_option ~= 0 then + texio.write_nl("term and log","luaotfload can't run with option --safer. Aborting") + error("safer_option used") +end + + + + +--[[doc-- + + This file initializes the system and loads the font loader. To + minimize potential conflicts between other packages and the code + imported from \CONTEXT, several precautions are in order. Some of + the functionality that the font loader expects to be present, like + raw access to callbacks, are assumed to have been disabled by + \identifier{luatexbase} when this file is processed. In some cases + it is possible to trick it by putting dummies into place and + restoring the behavior from \identifier{luatexbase} after + initilization. Other cases such as attribute allocation require + that we hook the functionality from \identifier{luatexbase} into + locations where they normally wouldn’t be. + + Anyways we can import the code base without modifications, which is + due mostly to the extra effort by Hans Hagen to make \LUATEX-Fonts + self-contained and encapsulate it, and especially due to his + willingness to incorporate our suggestions. + +--doc]]-- + +local luatexbase = luatexbase +local require = require +local type = type + + +--[[doc-- + + \subsection{Module loading} + We load the files imported from \CONTEXT with function derived this way. It + automatically prepends a prefix to its argument, so we can refer to the + files with their actual \CONTEXT name. + +--doc]]-- + +local function make_loader_name (prefix, name) + local msg = luaotfload.log and luaotfload.log.report + or function (stream, lvl, cat, ...) + if lvl > 1 then --[[not pressing]] return end + texio.write_nl ("log", + string.format ("luaotfload | %s : ", + tostring (cat))) + texio.write (string.format (...)) + end + if not name then + msg ("both", 0, "load", + "Fatal error: make_loader_name (%q, %q).", + tostring (prefix), tostring (name)) + return "dummy-name" + end + name = tostring (name) + if prefix == false then + msg ("log", 9, "load", + "No prefix requested, passing module name %q unmodified.", + name) + return tostring (name) .. ".lua" + end + prefix = tostring (prefix) + msg ("log", 9, "load", + "Composing module name from constituents %s, %s.", + prefix, name) + return prefix .. "-" .. name .. ".lua" +end + +local timing_info = { + t_load = { }, + t_init = { }, +} + +local function make_loader (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 (load_helper or require, modname) + local t_end = osgettimeofday () + timing_info.t_load [name] = t_end - t_0 + if not ok then + io.write "\n" + local msg = luaotfload.log and luaotfload.log.report or print + msg ("both", 0, "load", "FATAL ERROR") + msg ("both", 0, "load", " × Failed to load %q module %q.", + tostring (prefix), tostring (name)) + local lines = string.split (data, "\n\t") + if not lines then + msg ("both", 0, "load", " × Error message: %q", data) + else + msg ("both", 0, "load", " × Error message:") + for i = 1, #lines do + msg ("both", 0, "load", " × %q.", lines [i]) + end + end + io.write "\n\n" + local debug = debug + if debug then + io.write (debug.traceback()) + io.write "\n\n" + end + os.exit(-1) + end + return data + end +end + +--[[doc-- + Certain files are kept around that aren’t loaded because they are part of + the imported fontloader. In order to keep the initialization structure + intact we also provide a no-op version of the module loader that can be + called in the expected places. +--doc]]-- + +local function dummy_loader (name) + luaotfload.log.report ("log", 3, "load", + "Skipping module %q on purpose.", + 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 %q could not be found.', name)) + end + return assert(loadfile(fullname, nil, context_environment))(name) +end + +local function context_loader (name, path) + luaotfload.log.report ("log", 3, "load", + "Loading module %q from Context.", + name) + local t_0 = osgettimeofday () + local modname = make_loader_name (false, name) + local modpath = modname + if path then + if lfs.isdir (path) then + luaotfload.log.report ("log", 3, "load", + "Prepending path %q.", + path) + modpath = file.join (path, modname) + else + luaotfload.log.report ("both", 0, "load", + "Non-existant path %q specified, ignoring.", + path) + end + end + local ret = context_isolated_load (modpath) + local t_end = osgettimeofday () + timing_info.t_load [name] = t_end - t_0 + + if ret ~= nil then + --- require () returns “true” upon success unless the loaded file + --- yields a non-zero exit code. This isn’t per se indicating that + --- something isn’t right, but against HH’s coding practices. We’ll + --- silently ignore this ever happening on lower log levels. + luaotfload.log.report ("log", 4, "load", + "Module %q returned %q.", modname, ret) + end + return ret +end + +local function install_loaders () + local loaders = { } + local loadmodule = make_loader "luaotfload" + loaders.luaotfload = loadmodule + loaders.fontloader = make_loader ("fontloader", context_isolated_load) + loaders.context = context_loader + loaders.ignore = dummy_loader +----loaders.plaintex = make_loader "luatex" --=> for Luatex-Plain + + function loaders.initialize (name) + local tmp = loadmodule (name) + local init = type(tmp) == "table" and tmp.init or tmp + if init and type (init) == "function" then + local t_0 = osgettimeofday () + if not init () then + logreport ("log", 0, "load", + "Failed to load module %q.", name) + return + end + local t_end = osgettimeofday () + local d_t = t_end - t_0 + logreport ("log", 4, "load", + "Module %q loaded in %g ms.", + name, d_t * 1000) + timing_info.t_init [name] = d_t + end + end + + return loaders +end + +local luaotfload_initialized = false --- prevent multiple invocations + +luaotfload.main = function () + + if luaotfload_initialized then + logreport ("log", 0, "load", + "Luaotfload initialization requested but is already \z + loaded, ignoring.") + return + end + luaotfload_initialized = true + + luaotfload.loaders = install_loaders () + local loaders = luaotfload.loaders + local loadmodule = loaders.luaotfload + local initialize = loaders.initialize + + local starttime = osgettimeofday () + + -- Feature detect HarfBuzz. This is done early to allow easy HarfBuzz + -- detection in other modules + local harfstatus, harfbuzz = pcall(require, 'luaharfbuzz') + if harfstatus then + luaotfload.harfbuzz = harfbuzz + end + + local init = loadmodule "init" --- fontloader initialization + init (function () + + logreport = luaotfload.log.report + initialize "parsers" --- fonts.conf and syntax + initialize "configuration" --- configuration options + end) + + initialize "loaders" --- Font loading; callbacks + initialize "database" --- Font management. + initialize "colors" --- Per-font colors. + + local init_resolvers = loadmodule "resolvers" --- Font lookup + init_resolvers () + + if not config.actions.reconfigure () then + logreport ("log", 0, "load", "Post-configuration hooks failed.") + end + + initialize "features" --- font request and feature handling + + if harfstatus then + loadmodule "harf-define" + loadmodule "harf-plug" + end + loadmodule "letterspace" --- extra character kerning + loadmodule "embolden" --- fake bold + loadmodule "notdef" --- missing glyph handling + loadmodule "suppress" --- suppress ligatures by adding ZWNJ + loadmodule "szss" --- missing glyph handling + initialize "auxiliary" --- additional high-level functionality + loadmodule "tounicode" + loadmodule "case" + if tex.outputmode == 0 then + loadmodule "dvi" --- allow writing fonts to DVI files + end + + luaotfload.aux.start_rewrite_fontname () --- to be migrated to fontspec + + logreport ("log", 1, "main", + "initialization completed in %0.3f seconds\n", + osgettimeofday() - starttime) +----inspect (timing_info) + luaotfload_module = nil +end + +-- vim:tw=79:sw=4:ts=4:et diff --git a/Master/texmf-dist/tex/luatex/luaotfload/luaotfload.sty b/Master/texmf-dist/tex/luatex/luaotfload/luaotfload.sty index 33e15ba7c3f..d9a3397d142 100644 --- a/Master/texmf-dist/tex/luatex/luaotfload/luaotfload.sty +++ b/Master/texmf-dist/tex/luatex/luaotfload/luaotfload.sty @@ -39,11 +39,11 @@ \fi \ifdefined\ProvidesPackage \ProvidesPackage{luaotfload}% - [2020/09/02 v3.15 OpenType layout system] + [2020/12/31 v3.16 OpenType layout system] \fi \directlua{ if xpcall(function ()% - require('luaotfload-main')% + require('luaotfload')% end,texio.write_nl) then % local _void = luaotfload.main ()% else % |