summaryrefslogtreecommitdiff
path: root/macros/luatex/generic/luaotfload/fontloader-reference.lua
diff options
context:
space:
mode:
Diffstat (limited to 'macros/luatex/generic/luaotfload/fontloader-reference.lua')
-rw-r--r--macros/luatex/generic/luaotfload/fontloader-reference.lua843
1 files changed, 473 insertions, 370 deletions
diff --git a/macros/luatex/generic/luaotfload/fontloader-reference.lua b/macros/luatex/generic/luaotfload/fontloader-reference.lua
index c539d886cc..6997a417a7 100644
--- a/macros/luatex/generic/luaotfload/fontloader-reference.lua
+++ b/macros/luatex/generic/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 : 2022-09-16 14:39
+-- merge date : 2023-08-16 19:31
do -- begin closure to overcome local limits and interference
@@ -927,7 +927,7 @@ if not modules then modules={} end modules ['l-string']={
license="see context related readme files"
}
local string=string
-local sub,gmatch,format,char,byte,rep,lower=string.sub,string.gmatch,string.format,string.char,string.byte,string.rep,string.lower
+local sub,gmatch,format,char,byte,rep,lower,find=string.sub,string.gmatch,string.format,string.char,string.byte,string.rep,string.lower,string.find
local lpegmatch,patterns=lpeg.match,lpeg.patterns
local P,S,C,Ct,Cc,Cs=lpeg.P,lpeg.S,lpeg.C,lpeg.Ct,lpeg.Cc,lpeg.Cs
local unquoted=patterns.squote*C(patterns.nosquote)*patterns.squote+patterns.dquote*C(patterns.nodquote)*patterns.dquote
@@ -937,10 +937,18 @@ end
function string.quoted(str)
return format("%q",str)
end
-function string.count(str,pattern)
+function string.count(str,pattern)
local n=0
- for _ in gmatch(str,pattern) do
- n=n+1
+ local i=1
+ local l=#pattern
+ while true do
+ i=find(str,pattern,i)
+ if i then
+ n=n+1
+ i=i+l
+ else
+ break
+ end
end
return n
end
@@ -1542,7 +1550,11 @@ local function do_serialize(root,name,depth,level,indexed)
elseif tv=="number" then
if tk=="number" then
if hexify then
- handle(format("%s [0x%X]=0x%X,",depth,k,v))
+ if accurate then
+ handle(format("%s [0x%X]=%q,",depth,k,v))
+ else
+ handle(format("%s [0x%X]=%s,",depth,k,v))
+ end
elseif accurate then
handle(format("%s [%s]=%q,",depth,k,v))
else
@@ -1550,7 +1562,11 @@ local function do_serialize(root,name,depth,level,indexed)
end
elseif tk=="boolean" then
if hexify then
- handle(format("%s [%s]=0x%X,",depth,k and "true" or "false",v))
+ if accurate then
+ handle(format("%s [%s]=%q,",depth,k and "true" or "false",v))
+ else
+ handle(format("%s [%s]=%s,",depth,k and "true" or "false",v))
+ end
elseif accurate then
handle(format("%s [%s]=%q,",depth,k and "true" or "false",v))
else
@@ -1559,7 +1575,11 @@ local function do_serialize(root,name,depth,level,indexed)
elseif tk~="string" then
elseif noquotes and not reserved[k] and lpegmatch(propername,k) then
if hexify then
- handle(format("%s %s=0x%X,",depth,k,v))
+ if accurate then
+ handle(format("%s %s=%q,",depth,k,v))
+ else
+ handle(format("%s %s=%s,",depth,k,v))
+ end
elseif accurate then
handle(format("%s %s=%q,",depth,k,v))
else
@@ -1567,7 +1587,11 @@ local function do_serialize(root,name,depth,level,indexed)
end
else
if hexify then
- handle(format("%s [%q]=0x%X,",depth,k,v))
+ if accurate then
+ handle(format("%s [%q]=%q,",depth,k,v))
+ else
+ handle(format("%s [%q]=%s,",depth,k,v))
+ end
elseif accurate then
handle(format("%s [%q]=%q,",depth,k,v))
else
@@ -2944,9 +2968,23 @@ function file.withinbase(path)
end
return true
end
-local symlinkattributes=lfs.symlinkattributes
-function lfs.readlink(name)
- return symlinkattributes(name,"target") or nil
+do
+ local symlinktarget=lfs.symlinktarget
+ local symlinkattributes=lfs.symlinkattributes
+ if symlinktarget then
+ function lfs.readlink(name)
+ local target=symlinktarget(name)
+ return name~=target and name or nil
+ end
+ elseif symlinkattributes then
+ function lfs.readlink(name)
+ return symlinkattributes(name,"target") or nil
+ end
+ else
+ function lfs.readlink(name)
+ return nil
+ end
+ end
end
end -- closure
@@ -3309,6 +3347,7 @@ local p_prune_intospace=Cs (noleading*(notrailing+intospace+1 )^0 )
local p_retain_normal=Cs ((normalline+normalempty )^0 )
local p_retain_collapse=Cs ((normalline+doubleempty )^0 )
local p_retain_noempty=Cs ((normalline+singleempty )^0 )
+local p_collapse_all=Cs (stripstart*(stripend+((whitespace+newline)^1/" ")+1)^0 )
local striplinepatterns={
["prune"]=p_prune_normal,
["prune and collapse"]=p_prune_collapse,
@@ -3317,6 +3356,7 @@ local striplinepatterns={
["retain"]=p_retain_normal,
["retain and collapse"]=p_retain_collapse,
["retain and no empty"]=p_retain_noempty,
+ ["collapse all"]=p_collapse_all,
["collapse"]=patterns.collapser,
}
setmetatable(striplinepatterns,{ __index=function(t,k) return p_prune_collapse end })
@@ -4852,7 +4892,7 @@ local mt={
end,
__storage__=true
}
-function containers.define(category,subcategory,version,enabled)
+function containers.define(category,subcategory,version,enabled,reload)
if category and subcategory then
local c=allocated[category]
if not c then
@@ -4866,6 +4906,7 @@ function containers.define(category,subcategory,version,enabled)
subcategory=subcategory,
storage={},
enabled=enabled,
+ reload=reload,
version=version or math.pi,
trace=false,
}
@@ -4888,7 +4929,8 @@ function containers.is_valid(container,name)
end
function containers.read(container,name)
local storage=container.storage
- local stored=storage[name]
+ local reload=container.reload
+ local stored=not reload and storage[name]
if not stored and container.enabled and caches and containers.usecache then
stored=loaddatafromcache(container.readables,name,container.writable)
if stored and stored.cache_version==container.version then
@@ -9406,19 +9448,9 @@ function constructors.scale(tfmdata,specification)
target.unscaled=tfmdata
local mathsize=tonumber(specification.mathsize) or 0
local textsize=tonumber(specification.textsize) or scaledpoints
- local forcedsize=tonumber(parameters.mathsize ) or 0
local extrafactor=tonumber(specification.factor ) or 1
- if (mathsize==2 or forcedsize==2) and parameters.scriptpercentage then
- scaledpoints=parameters.scriptpercentage*textsize/100
- elseif (mathsize==3 or forcedsize==3) and parameters.scriptscriptpercentage then
- scaledpoints=parameters.scriptscriptpercentage*textsize/100
- elseif forcedsize>1000 then
- scaledpoints=forcedsize
- else
- end
targetparameters.mathsize=mathsize
- targetparameters.textsize=textsize
- targetparameters.forcedsize=forcedsize
+ targetparameters.textsize=textsize
targetparameters.extrafactor=extrafactor
local addtounicode=constructors.addtounicode
local tounicode=fonts.mappings.tounicode
@@ -11316,6 +11348,7 @@ if not modules then modules={} end modules ['font-otr']={
copyright="PRAGMA ADE / ConTeXt Development Team",
license="see context related readme files"
}
+local number=number
local next,type,tonumber,rawget=next,type,tonumber,rawget
local byte,lower,char,gsub=string.byte,string.lower,string.char,string.gsub
local fullstrip=string.fullstrip
@@ -12399,7 +12432,7 @@ end
function readers.cmap(f,fontdata,specification)
local tableoffset=gotodatatable(f,fontdata,"cmap",specification.glyphs)
if tableoffset then
- local version=readushort(f)
+ local version=readushort(f)
local noftables=readushort(f)
local records={}
local unicodecid=false
@@ -13060,6 +13093,10 @@ function readers.loadfont(filename,n,instance)
cidinfo=fontdata.cidinfo,
mathconstants=fontdata.mathconstants,
colorpalettes=fontdata.colorpalettes,
+ colorpaintdata=fontdata.colorpaintdata,
+ colorpaintlist=fontdata.colorpaintlist,
+ colorlinesdata=fontdata.colorlinesdata,
+ coloraffinedata=fontdata.coloraffinedata,
svgshapes=fontdata.svgshapes,
pngshapes=fontdata.pngshapes,
variabledata=fontdata.variabledata,
@@ -13418,10 +13455,10 @@ do
result.familyotherblues={ unpack(stack,1,top) }
top=0
end+P("\10")/function()
- result.strhw=stack[top]
+ result.stdhw=stack[top]
top=0
end+P("\11")/function()
- result.strvw=stack[top]
+ result.stdvw=stack[top]
top=0
end+P("\13")/function()
result.uniqueid=stack[top]
@@ -13493,7 +13530,7 @@ do
result.bluescale=stack[top]
top=0
end+P("\10")/function()
- result.bluesnap=stack[top]
+ result.blueshift=stack[top]
top=0
end+P("\11")/function()
result.bluefuzz=stack[top]
@@ -13547,7 +13584,7 @@ do
top=0
end
)
- local remap={
+ local remap_1={
["\x00"]="00",["\x01"]="01",["\x02"]="02",["\x03"]="03",["\x04"]="04",["\x05"]="05",["\x06"]="06",["\x07"]="07",["\x08"]="08",["\x09"]="09",["\x0A"]="0.",["\x0B"]="0E",["\x0C"]="0E-",["\x0D"]="0",["\x0E"]="0-",["\x0F"]="0",
["\x10"]="10",["\x11"]="11",["\x12"]="12",["\x13"]="13",["\x14"]="14",["\x15"]="15",["\x16"]="16",["\x17"]="17",["\x18"]="18",["\x19"]="19",["\x1A"]="1.",["\x1B"]="1E",["\x1C"]="1E-",["\x1D"]="1",["\x1E"]="1-",["\x1F"]="1",
["\x20"]="20",["\x21"]="21",["\x22"]="22",["\x23"]="23",["\x24"]="24",["\x25"]="25",["\x26"]="26",["\x27"]="27",["\x28"]="28",["\x29"]="29",["\x2A"]="2.",["\x2B"]="2E",["\x2C"]="2E-",["\x2D"]="2",["\x2E"]="2-",["\x2F"]="2",
@@ -13563,8 +13600,13 @@ do
["\xC0"]="E-0",["\xC1"]="E-1",["\xC2"]="E-2",["\xC3"]="E-3",["\xC4"]="E-4",["\xC5"]="E-5",["\xC6"]="E-6",["\xC7"]="E-7",["\xC8"]="E-8",["\xC9"]="E-9",["\xCA"]="E-.",["\xCB"]="E-E",["\xCC"]="E-E-",["\xCD"]="E-",["\xCE"]="E--",["\xCF"]="E-",
["\xD0"]="-0",["\xD1"]="-1",["\xD2"]="-2",["\xD3"]="-3",["\xD4"]="-4",["\xD5"]="-5",["\xD6"]="-6",["\xD7"]="-7",["\xD8"]="-8",["\xD9"]="-9",["\xDA"]="-.",["\xDB"]="-E",["\xDC"]="-E-",["\xDD"]="-",["\xDE"]="--",["\xDF"]="-",
}
- local p_last=S("\x0F\x1F\x2F\x3F\x4F\x5F\x6F\x7F\x8F\x9F\xAF\xBF")+R("\xF0\xFF")
- local p_nibbles=P("\30")*Cs(((1-p_last)/remap)^0*(P(1)/remap))/function(n)
+ local remap_2={
+ ["\x0F"]="0",["\x1F"]="1",["\x2F"]="2",["\x3F"]="3",["\x4F"]="4",
+ ["\x5F"]="5",["\x6F"]="6",["\x7F"]="7",["\x8F"]="8",["\x9F"]="9",
+ }
+ local p_last_1=S("\x0F\x1F\x2F\x3F\x4F\x5F\x6F\x7F\x8F\x9F\xAF\xBF")
+ local p_last_2=R("\xF0\xFF")
+ local p_nibbles=P("\30")*Cs(((1-(p_last_1+p_last_2))/remap_1)^0*(p_last_1/remap_2+p_last_2/""))/function(n)
top=top+1
stack[top]=tonumber(n) or 0
end
@@ -13675,7 +13717,7 @@ do
local y=0
local width=false
local lsb=0
-local result={}
+ local result={}
local r=0
local stems=0
local globalbias=0
@@ -14568,6 +14610,7 @@ end
end)
local c_endchar=chars[14]
local encode={}
+ local typeone=false
setmetatableindex(encode,function(t,i)
for i=-2048,-1130 do
t[i]=char(28,band(rshift(i,8),0xFF),band(i,0xFF))
@@ -14693,6 +14736,13 @@ end
elseif t<=254 then
stack[top]=-t*256+64148-tab[i+1]
i=i+2
+ elseif typeone then
+ local n=0x1000000*tab[i+1]+0x10000*tab[i+2]+0x100*tab[i+3]+tab[i+4]
+ if n>=0x8000000 then
+ n=n-0xFFFFFFFF-1
+ end
+ stack[top]=n
+ i=i+5
else
local n1=0x100*tab[i+1]+tab[i+2]
local n2=0x100*tab[i+3]+tab[i+4]
@@ -14838,20 +14888,7 @@ end
local n=0
for i=1,top do
if n==48 then
- local zero=encode[0]
- local res3=result[r-3]
- local res2=result[r-2]
- local res1=result[r-1]
- local res0=result[r]
- result[r-3]=zero
- result[r-2]=zero
r=r+1;result[r]=chars[t]
- r=r+1;result[r]=zero
- r=r+1;result[r]=zero
- r=r+1;result[r]=res3
- r=r+1;result[r]=res2
- r=r+1;result[r]=res1
- r=r+1;result[r]=res0
n=1
else
n=n+1
@@ -14898,7 +14935,7 @@ end
((l<1240 and 107) or (l<33900 and 1131) or 32768)+1
end
end
- local function processshape(tab,index,hack)
+ local function processshape(glyphs,tab,index,hack)
if not tab then
glyphs[index]={
boundingbox={ 0,0,0,0 },
@@ -14953,8 +14990,9 @@ end
result=nil
if glyph then
glyph.stream=stream
+ glyph.width=width
else
- glyphs[index]={ stream=stream }
+ glyphs[index]={ stream=stream,width=width }
end
elseif glyph then
glyph.segments=keepcurve~=false and result or nil
@@ -15022,23 +15060,24 @@ result=nil
end
return privatedata.nominalwidthx or 0,privatedata.defaultwidthx or 0
end
- parsecharstrings=function(fontdata,data,glphs,doshapes,tversion,streams,nobias)
+ parsecharstrings=function(fontdata,data,glphs,doshapes,tversion,streams,nobias,istypeone)
local dictionary=data.dictionaries[1]
local charstrings=dictionary.charstrings
keepcurve=doshapes
version=tversion
+ typeone=istypeone or false
strings=data.strings
globals=data.routines or {}
locals=dictionary.subroutines or {}
charset=dictionary.charset
vsindex=dictionary.vsindex or 0
- glyphs=glphs or {}
+ local glyphs=glphs or {}
globalbias,localbias=setbias(globals,locals,nobias)
nominalwidth,defaultwidth=setwidths(dictionary.private)
if charstrings then
startparsing(fontdata,data,streams)
for index=1,#charstrings do
- processshape(charstrings[index],index-1)
+ processshape(glyphs,charstrings[index],index-1)
end
if justpass and next(seacs) then
local charset=data.dictionaries[1].charset
@@ -15052,7 +15091,7 @@ result=nil
if bglyph and aglyph then
local jp=justpass
justpass=false
- local x,y=processshape(charstrings[bindex+1],bindex,true)
+ local x,y=processshape(glyphs,charstrings[bindex+1],bindex,true)
justpass=jp
local base=bglyph.stream
local accent=aglyph.stream
@@ -15077,12 +15116,13 @@ result=nil
locals=dictionary.subroutines or {}
charset=false
vsindex=dictionary.vsindex or 0
- glyphs=glphs or {}
+ local glyphs=glphs or {}
justpass=streams==true
seacs={}
globalbias,localbias=setbias(globals,locals,nobias)
nominalwidth,defaultwidth=setwidths(dictionary.private)
- processshape(tab,index-1)
+ processshape(glyphs,tab,index-1)
+ return glyphs[index]
end
end
local function readglobals(f,data,version)
@@ -15230,7 +15270,7 @@ local function readnoselect(f,fontdata,data,glyphs,doshapes,version,streams)
parseprivates(data,data.dictionaries)
readlocals(f,data,dictionary,version)
startparsing(fontdata,data,streams)
- parsecharstrings(fontdata,data,glyphs,doshapes,version,streams)
+ parsecharstrings(fontdata,data,glyphs,doshapes,version,streams,false)
stopparsing(fontdata,data)
end
local function readfdselect(f,fontdata,data,glyphs,doshapes,version,streams)
@@ -15378,6 +15418,8 @@ function readers.cff(f,fontdata,specification)
cffinfo.bluefuzz=data.bluefuzz
cffinfo.stdhw=data.stdhw
cffinfo.stdvw=data.stdvw
+ cffinfo.stemsnaph=data.stemsnaph
+ cffinfo.stemsnapv=data.stemsnapv
end
end
cleanup(data,dictionaries)
@@ -15420,39 +15462,6 @@ function readers.cff2(f,fontdata,specification)
cleanup(data,dictionaries)
end
end
-function readers.cffcheck(filename)
- local f=io.open(filename,"rb")
- if f then
- local fontdata={
- glyphs={},
- }
- local header=readheader(f)
- if header.major~=1 then
- report("only version %s is supported for table %a",1,"cff")
- return
- end
- local names=readfontnames(f)
- local dictionaries=readtopdictionaries(f)
- local strings=readstrings(f)
- local glyphs={}
- local data={
- header=header,
- names=names,
- dictionaries=dictionaries,
- strings=strings,
- glyphs=glyphs,
- nofglyphs=0,
- }
- parsedictionaries(data,dictionaries,"cff")
- local cid=data.dictionaries[1].cid
- if cid and cid.fdselect then
- readfdselect(f,fontdata,data,glyphs,false)
- else
- readnoselect(f,fontdata,data,glyphs,false)
- end
- return data
- end
-end
end -- closure
@@ -15622,20 +15631,7 @@ local function applyaxis(glyph,shape,deltas,dowidth)
if dowidth then
cnt=cnt-4
end
- if cnt==1 then
- local d=dpoints[1]
- local x=xvalues[d]*factor
- local y=yvalues[d]*factor
- for i=1,nofpoints do
- local p=points[i]
- if x~=0 then
- p[1]=p[1]+x
- end
- if y~=0 then
- p[2]=p[2]+y
- end
- end
- elseif cnt>0 then
+ if cnt>0 then
local contours=shape.contours
local nofcontours=#contours
local first=1
@@ -15652,8 +15648,11 @@ local function applyaxis(glyph,shape,deltas,dowidth)
end
if found==last then
lastindex=currentindex
- break;
+ break
elseif found>last then
+ while lastindex>1 and dpoints[lastindex]>last do
+ lastindex=lastindex-1
+ end
break
end
end
@@ -15661,7 +15660,7 @@ local function applyaxis(glyph,shape,deltas,dowidth)
local function find(i)
local prv=lastindex
for j=firstindex,lastindex do
- local nxt=dpoints[j]
+ local nxt=dpoints[j]
if nxt==i then
return false,j,false
elseif nxt>i then
@@ -16109,6 +16108,12 @@ local function contours2outlines_shaped(glyphs,shapes,keepcurve)
end
first=last+1
end
+ xmin=glyph.boundingbox[1]
+ local dlsb=glyph.dlsb
+ if dlsb then
+ xmin=xmin+dlsb
+ glyph.dlsb=nil
+ end
glyph.boundingbox={ round(xmin),round(ymin),round(xmax),round(ymax) }
end
end
@@ -16883,6 +16888,20 @@ local read_integer={
streamreader.readinteger3,
streamreader.readinteger4,
}
+directives.register("fonts.streamreader",function()
+ read_cardinal={
+ streamreader.readcardinal1,
+ streamreader.readcardinal2,
+ streamreader.readcardinal3,
+ streamreader.readcardinal4,
+ }
+ read_integer={
+ streamreader.readinteger1,
+ streamreader.readinteger2,
+ streamreader.readinteger3,
+ streamreader.readinteger4,
+ }
+end)
local lookupnames={
gsub={
single="gsub_single",
@@ -16957,7 +16976,6 @@ local function getaxisscale(segments,minimum,default,maximum,user)
for i=1,#segments do
local s=segments[i]
if type(s)~="number" then
- report("using default axis scale")
return default
elseif s[1]>=default then
if s[2]==default then
@@ -18461,6 +18479,7 @@ do
local noflookups=#lookups
local lookupprefix=sub(what,2,2)
local usedlookups=false
+ local allsteps={}
for lookupid=1,noflookups do
local lookup=lookups[lookupid]
local lookuptype=lookup.type
@@ -18495,6 +18514,7 @@ do
steps[nofsteps]=step
local rules=step.rules
if rules then
+ allsteps[#allsteps+1]=step
for i=1,#rules do
local rule=rules[i]
local before=rule.before
@@ -18593,25 +18613,18 @@ do
report("used %s lookups: % t",what,sortedkeys(usedlookups))
end
local reported={}
- local function report_issue(i,what,sequence,kind)
- local name=sequence.name
- if not reported[name] then
- report("rule %i in %s lookup %a has %s lookups",i,what,name,kind)
- reported[name]=true
- end
+ local function report_issue(i,what,step,kind)
+ report("rule %i in step %i of %s has %s lookups",i,step,what,kind)
end
- for i=lastsequence+1,nofsequences do
- local sequence=sequences[i]
- local steps=sequence.steps
- for i=1,#steps do
- local step=steps[i]
+ for s=1,#allsteps do
+ local step=allsteps[s]
local rules=step.rules
if rules then
for i=1,#rules do
local rule=rules[i]
local rlookups=rule.lookups
if not rlookups then
- report_issue(i,what,sequence,"no")
+ report_issue(i,what,s,"no")
elseif not next(rlookups) then
rule.lookups=nil
else
@@ -18647,12 +18660,12 @@ do
sublookupcheck[lookupid]=1
h=nofsublookups
else
- report_issue(i,what,sequence,"missing")
+ report_issue(i,what,s,"missing")
rule.lookups=nil
break
end
else
- report_issue(i,what,sequence,"bad")
+ report_issue(i,what,s,"bad")
rule.lookups=nil
break
end
@@ -18674,7 +18687,6 @@ do
end
end
end
- end
for i,n in sortedhash(sublookupcheck) do
local l=lookups[i]
local t=l.type
@@ -19097,7 +19109,7 @@ local function readmathglyphinfo(f,fontdata,offset)
if not math then
glyph.math={ accent=accent }
else
- math.accent=accent
+ math.accent=accent
end
end
end
@@ -19178,7 +19190,7 @@ local function readmathvariants(f,fontdata,offset)
local vconstruction=readcardinaltable(f,vnofglyphs,ushort)
local hconstruction=readcardinaltable(f,hnofglyphs,ushort)
fontdata.mathconstants.MinConnectorOverlap=minoverlap
- local function get(offset,coverage,nofglyphs,construction,kvariants,kparts,kitalic)
+ local function get(offset,coverage,nofglyphs,construction,kvariants,kparts,kitalic,korientation,orientation)
if coverage~=0 and nofglyphs>0 then
local coverage=readcoverage(f,offset+coverage,true)
for i=1,nofglyphs do
@@ -19241,13 +19253,21 @@ local function readmathvariants(f,fontdata,offset)
if italic and italic~=0 then
math[kitalic]=italic
end
+ if orientation then
+ math[korientation]=orientation
+ end
end
end
end
end
end
- get(offset,vcoverage,vnofglyphs,vconstruction,"vvariants","vparts","vitalic")
- get(offset,hcoverage,hnofglyphs,hconstruction,"hvariants","hparts","hitalic")
+ if CONTEXTLMTXMODE and CONTEXTLMTXMODE>0 then
+ get(offset,hcoverage,hnofglyphs,hconstruction,"variants","parts","partsitalic","partsorientation","horizontal")
+ get(offset,vcoverage,vnofglyphs,vconstruction,"variants","parts","partsitalic","partsorientation","vertical")
+ else
+ get(offset,vcoverage,vnofglyphs,vconstruction,"vvariants","vparts","vitalic")
+ get(offset,hcoverage,hnofglyphs,hconstruction,"hvariants","hparts","hitalic")
+ end
end
function readers.math(f,fontdata,specification)
local tableoffset=gotodatatable(f,fontdata,"math",specification.glyphs)
@@ -19273,9 +19293,10 @@ function readers.colr(f,fontdata,specification)
local tableoffset=gotodatatable(f,fontdata,"colr",specification.glyphs)
if tableoffset then
local version=readushort(f)
- if version~=0 then
+ if version~=0 and version~=1 then
report("table version %a of %a is not supported (yet), maybe font %s is bad",version,"colr",fontdata.filename)
return
+ else
end
if not fontdata.tables.cpal then
report("color table %a in font %a has no mandate %a table","colr",fontdata.filename,"cpal")
@@ -19887,7 +19908,6 @@ function readers.hvar(f,fontdata,specification)
end
local tableoffset=gotodatatable(f,fontdata,"hvar",specification.variable)
if not tableoffset then
- report("no hvar table, expect problems due to messy widths")
return
end
local version=readulong(f)
@@ -20192,16 +20212,20 @@ local scripts=allocate {
["cari"]="carian",
["cham"]="cham",
["cher"]="cherokee",
+ ["chrs"]="chorasmian",
["copt"]="coptic",
+ ["cpmn"]="cypro-minoan",
["cprt"]="cypriot syllabary",
["cyrl"]="cyrillic",
["dev2"]="devanagari variant 2",
["deva"]="devanagari",
+ ["diak"]="dives akuru",
["dogr"]="dogra",
["dsrt"]="deseret",
["dupl"]="duployan",
["egyp"]="egyptian heiroglyphs",
["elba"]="elbasan",
+ ["elym"]="elymaic",
["ethi"]="ethiopic",
["geor"]="georgian",
["gjr2"]="gujarati variant 2",
@@ -20221,6 +20245,7 @@ local scripts=allocate {
["hebr"]="hebrew",
["hluw"]="anatolian hieroglyphs",
["hmng"]="pahawh hmong",
+ ["hmnp"]="nyiakeng puachue hmong",
["hung"]="old hungarian",
["ital"]="old italic",
["jamo"]="hangul jamo",
@@ -20230,6 +20255,7 @@ local scripts=allocate {
["khar"]="kharosthi",
["khmr"]="khmer",
["khoj"]="khojki",
+ ["kits"]="khitan small script",
["knd2"]="kannada variant 2",
["knda"]="kannada",
["kthi"]="kaithi",
@@ -20263,6 +20289,7 @@ local scripts=allocate {
["musc"]="musical symbols",
["mym2"]="myanmar variant 2",
["mymr"]="myanmar",
+ ["nand"]="nandinagari",
["narb"]="old north arabian",
["nbat"]="nabataean",
["newa"]="newa",
@@ -20272,9 +20299,10 @@ local scripts=allocate {
["olck"]="ol chiki",
["orkh"]="old turkic and orkhon runic",
["ory2"]="odia variant 2",
- ["orya"]="oriya",
+ ["orya"]="odia",
["osge"]="osage",
["osma"]="osmanya",
+ ["ougr"]="old uyghur",
["palm"]="palmyrene",
["pauc"]="pau cin hau",
["perm"]="old permic",
@@ -20306,7 +20334,7 @@ local scripts=allocate {
["tagb"]="tagbanwa",
["takr"]="takri",
["tale"]="tai le",
- ["talu"]="tai lu",
+ ["talu"]="new tai lue",
["taml"]="tamil",
["tang"]="tangut",
["tavt"]="tai viet",
@@ -20318,12 +20346,16 @@ local scripts=allocate {
["thai"]="thai",
["tibt"]="tibetan",
["tirh"]="tirhuta",
+ ["tnsa"]="tangsa",
["tml2"]="tamil variant 2",
+ ["toto"]="toto",
["ugar"]="ugaritic cuneiform",
["vai" ]="vai",
["wara"]="warang citi",
+ ["wcho"]="wancho",
["xpeo"]="old persian cuneiform",
["xsux"]="sumero-akkadian cuneiform",
+ ["yezi"]="yezidi",
["yi" ]="yi",
["zanb"]="zanabazar square",
}
@@ -20338,6 +20370,7 @@ local languages=allocate {
["agw" ]="agaw",
["aio" ]="aiton",
["aka" ]="akan",
+ ["akb" ]="batak angkola",
["als" ]="alsatian",
["alt" ]="altai",
["amh" ]="amharic",
@@ -20350,6 +20383,7 @@ local languages=allocate {
["asm" ]="assamese",
["ast" ]="asturian",
["ath" ]="athapaskan",
+ ["avn" ]="avatime",
["avr" ]="avar",
["awa" ]="awadhi",
["aym" ]="aymara",
@@ -20395,8 +20429,12 @@ local languages=allocate {
["brx" ]="bodo",
["bsh" ]="bashkir",
["bsk" ]="burushaski",
+ ["bta" ]="batak alas kluet",
+ ["btd" ]="batak dairi (pakpak)",
["bti" ]="beti",
+ ["btm" ]="batak mandailing",
["bts" ]="batak simalungun",
+ ["btx" ]="batak karo",
["bug" ]="bugis",
["byv" ]="medumba",
["cak" ]="kaqchikel",
@@ -20431,14 +20469,16 @@ local languages=allocate {
["csl" ]="church slavonic",
["csy" ]="czech",
["ctg" ]="chittagonian",
+ ["ctt" ]="wayanad chetti",
["cuk" ]="san blas kuna",
+ ["dag" ]="dagbani",
["dan" ]="danish",
["dar" ]="dargwa",
["dax" ]="dayi",
["dcr" ]="woods cree",
["deu" ]="german",
- ["dgo" ]="dogri",
- ["dgr" ]="dogri",
+ ["dgo" ]="dogri (individual language)",
+ ["dgr" ]="dogri (macro language)",
["dhg" ]="dhangu",
["dhv" ]="divehi (dhivehi, maldivian)",
["diq" ]="dimli",
@@ -20510,13 +20550,16 @@ local languages=allocate {
["guj" ]="gujarati",
["guz" ]="gusii",
["hai" ]="haitian (haitian creole)",
+ ["hai0"]="haida",
["hal" ]="halam",
["har" ]="harauti",
["hau" ]="hausa",
["haw" ]="hawaiian",
["hay" ]="haya",
["haz" ]="hazaragi",
+ ["hmz" ]="hmong shuat",
["hbn" ]="hammer-banna",
+ ["hei" ]="heiltsuk",
["her" ]="herero",
["hil" ]="hiligaynon",
["hin" ]="hindi",
@@ -20541,10 +20584,12 @@ local languages=allocate {
["ind" ]="indonesian",
["ing" ]="ingush",
["inu" ]="inuktitut",
+ ["inuk"]="nunavik inuktitut",
["ipk" ]="inupiat",
["ipph"]="phonetic transcription—ipa conventions",
["iri" ]="irish",
["irt" ]="irish traditional",
+ ["uri" ]="irula",
["isl" ]="icelandic",
["ism" ]="inari sami",
["ita" ]="italian",
@@ -20564,6 +20609,7 @@ local languages=allocate {
["kan" ]="kannada",
["kar" ]="karachay",
["kat" ]="georgian",
+ ["kaw" ]="kawi (old javanese)",
["kaz" ]="kazakh",
["kde" ]="makonde",
["kea" ]="kabuverdianu (crioulo)",
@@ -20621,6 +20667,7 @@ local languages=allocate {
["kur" ]="kurdish",
["kuu" ]="kurukh",
["kuy" ]="kuy",
+ ["kwk" ]="kwakʼwala",
["kyk" ]="koryak",
["kyu" ]="western kayah",
["lad" ]="ladin",
@@ -20632,6 +20679,7 @@ local languages=allocate {
["laz" ]="laz",
["lcr" ]="l-cree",
["ldk" ]="ladakhi",
+ ["lef" ]="lelemi",
["lez" ]="lezgi",
["lij" ]="ligurian",
["lim" ]="limburgish",
@@ -20644,6 +20692,7 @@ local languages=allocate {
["lmo" ]="lombard",
["lmw" ]="lomwe",
["lom" ]="loma",
+ ["lpo" ]="lipo",
["lrc" ]="luri",
["lsb" ]="lower sorbian",
["lsm" ]="lule sami",
@@ -20660,7 +20709,7 @@ local languages=allocate {
["mah" ]="marshallese",
["maj" ]="majang",
["mak" ]="makhuwa",
- ["mal" ]="malayalam reformed",
+ ["mal" ]="malayalam",
["mam" ]="mam",
["man" ]="mansi",
["map" ]="mapudungun",
@@ -20695,6 +20744,7 @@ local languages=allocate {
["mok" ]="moksha",
["mol" ]="moldavian",
["mon" ]="mon",
+ ["mnw" ]="thailand mon",
["mor" ]="moroccan",
["mos" ]="mossi",
["mri" ]="maori",
@@ -20733,7 +20783,7 @@ local languages=allocate {
["nor" ]="norwegian",
["nov" ]="novial",
["nsm" ]="northern sami",
- ["nso" ]="sotho, northern",
+ ["nso" ]="northern sotho",
["nta" ]="northern tai",
["nto" ]="esperanto",
["nym" ]="nyamwezi",
@@ -20781,6 +20831,7 @@ local languages=allocate {
["rbu" ]="russian buriat",
["rcr" ]="r-cree",
["rej" ]="rejang",
+ ["rhg" ]="rohingya",
["ria" ]="riang",
["rif" ]="tarifit",
["rit" ]="ritarungo",
@@ -20805,6 +20856,7 @@ local languages=allocate {
["scs" ]="north slavey",
["sek" ]="sekota",
["sel" ]="selkup",
+ ["sfm" ]="small flowery miao",
["sga" ]="old irish",
["sgo" ]="sango",
["sgs" ]="samogitian",
@@ -20826,7 +20878,7 @@ local languages=allocate {
["snk" ]="soninke",
["sog" ]="sodo gurage",
["sop" ]="songe",
- ["sot" ]="sotho, southern",
+ ["sot" ]="southern sotho",
["sqi" ]="albanian",
["srb" ]="serbian",
["srd" ]="sardinian",
@@ -20867,7 +20919,9 @@ local languages=allocate {
["tht" ]="tahitian",
["tib" ]="tibetan",
["tiv" ]="tiv",
+ ["tj;" ]="tai laing",
["tkm" ]="turkmen",
+ ["tli" ]="tlingit",
["tmh" ]="tamashek",
["tmn" ]="temne",
["tna" ]="tswana",
@@ -20881,7 +20935,7 @@ local languages=allocate {
["tsj" ]="tshangla",
["tua" ]="turoyo aramaic",
["tul" ]="tulu",
- ["tum" ]="tulu",
+ ["tum" ]="tumbuka",
["tuv" ]="tuvin",
["tvl" ]="tuvalu",
["twi" ]="twi",
@@ -20903,6 +20957,7 @@ local languages=allocate {
["wa" ]="wa",
["wag" ]="wagdi",
["war" ]="waray-waray",
+ ["wci" ]="waci gbe",
["wcr" ]="west-cree",
["wel" ]="welsh",
["wlf" ]="wolof",
@@ -20914,17 +20969,23 @@ local languages=allocate {
["xkf" ]="khengkha",
["xog" ]="soga",
["xpe" ]="kpelle (liberia)",
+ ["xub" ]="bette kuruma",
+ ["xuj" ]="jennu kuruma",
["yak" ]="sakha",
["yao" ]="yao",
["yap" ]="yapese",
["yba" ]="yoruba",
["ycr" ]="y-cree",
+ ["ygp" ]="gepo",
["yic" ]="yi classic",
["yim" ]="yi modern",
+ ["yna" ]="aluo",
+ ["ywq" ]="wuding-luquan",
["zea" ]="zealandic",
["zgh" ]="standard morrocan tamazigh",
["zha" ]="zhuang",
["zhh" ]="chinese, hong kong sar",
+ ["zho" ]="chinese traditional, macao",
["zhp" ]="chinese phonetic",
["zhs" ]="chinese simplified",
["zht" ]="chinese traditional",
@@ -20948,6 +21009,7 @@ local features=allocate {
["case"]="case-sensitive forms",
["ccmp"]="glyph composition/decomposition",
["cfar"]="conjunct form after ro",
+ ["chws"]="contextual half-width spacing",
["cjct"]="conjunct forms",
["clig"]="contextual ligatures",
["cpct"]="centered cjk punctuation",
@@ -21024,8 +21086,8 @@ local features=allocate {
["rtbd"]="right bounds",
["rtla"]="right-to-left alternates",
["rtlm"]="right to left mirrored forms",
- ["rvrn"]="required variation alternates",
["ruby"]="ruby notation forms",
+ ["rvrn"]="required variation alternates",
["salt"]="stylistic alternates",
["sinf"]="scientific inferiors",
["size"]="optical size",
@@ -21045,6 +21107,7 @@ local features=allocate {
["unic"]="unicase",
["valt"]="alternate vertical metrics",
["vatu"]="vattu variants",
+ ["vchw"]="vertical contextual half-width spacing",
["vert"]="vertical writing",
["vhal"]="alternate vertical half metrics",
["vjmo"]="vowel jamo forms",
@@ -21289,7 +21352,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.120
+otf.version=3.133
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)
@@ -21772,24 +21835,6 @@ local function read_from_otf(specification)
end
return tfmdata
end
-local function checkmathsize(tfmdata,mathsize)
- local mathdata=tfmdata.shared.rawdata.metadata.math
- local mathsize=tonumber(mathsize)
- if mathdata then
- local parameters=tfmdata.parameters
- parameters.scriptpercentage=mathdata.ScriptPercentScaleDown
- parameters.scriptscriptpercentage=mathdata.ScriptScriptPercentScaleDown
- parameters.mathsize=mathsize
- end
-end
-registerotffeature {
- name="mathsize",
- description="apply mathsize specified in the font",
- initializers={
- base=checkmathsize,
- node=checkmathsize,
- }
-}
function otf.collectlookups(rawdata,kind,script,language)
if not kind then
return
@@ -24781,24 +24826,40 @@ local function unifyglyphs(fontdata,usenames)
descriptions[unicode]=glyph
end
end
- for index=1,nofglyphs do
- local math=glyphs[index].math
- if math then
- local list=math.vparts
- if list then
- for i=1,#list do local l=list[i] l.glyph=indices[l.glyph] end
- end
- local list=math.hparts
- if list then
- for i=1,#list do local l=list[i] l.glyph=indices[l.glyph] end
- end
- local list=math.vvariants
- if list then
- for i=1,#list do list[i]=indices[list[i]] end
+ if LUATEXENGINE=="luametatex" then
+ for index=1,nofglyphs do
+ local math=glyphs[index].math
+ if math then
+ local list=math.parts
+ if list then
+ for i=1,#list do local l=list[i] l.glyph=indices[l.glyph] end
+ end
+ local list=math.variants
+ if list then
+ for i=1,#list do list[i]=indices[list[i]] end
+ end
end
- local list=math.hvariants
- if list then
- for i=1,#list do list[i]=indices[list[i]] end
+ end
+ else
+ for index=1,nofglyphs do
+ local math=glyphs[index].math
+ if math then
+ local list=math.vparts
+ if list then
+ for i=1,#list do local l=list[i] l.glyph=indices[l.glyph] end
+ end
+ local list=math.hparts
+ if list then
+ for i=1,#list do local l=list[i] l.glyph=indices[l.glyph] end
+ end
+ local list=math.vvariants
+ if list then
+ for i=1,#list do list[i]=indices[list[i]] end
+ end
+ local list=math.hvariants
+ if list then
+ for i=1,#list do list[i]=indices[list[i]] end
+ end
end
end
end
@@ -24809,7 +24870,9 @@ local function unifyglyphs(fontdata,usenames)
if colors then
for i=1,#colors do
local c=colors[i]
- c.slot=indices[c.slot]
+ if c then
+ c.slot=indices[c.slot]
+ end
end
end
end
@@ -27329,12 +27392,8 @@ local trace_testruns=false registertracker("otf.testruns",function(v) trace_tes
local forcediscretionaries=false
local forcepairadvance=false
local repeatablemultiples=context or false
-directives.register("otf.forcediscretionaries",function(v)
- forcediscretionaries=v
-end)
-directives.register("otf.forcepairadvance",function(v)
- forcepairadvance=v
-end)
+directives.register("otf.forcediscretionaries",function(v) forcediscretionaries=v end)
+directives.register("otf.forcepairadvance",function(v) forcepairadvance=v end)
local report_direct=logs.reporter("fonts","otf direct")
local report_subchain=logs.reporter("fonts","otf subchain")
local report_chain=logs.reporter("fonts","otf chain")
@@ -27356,7 +27415,6 @@ local setboth=nuts.setboth
local getid=nuts.getid
local getstate=nuts.getstate
local getsubtype=nuts.getsubtype
-local setsubtype=nuts.setsubtype
local getchar=nuts.getchar
local setchar=nuts.setchar
local getdisc=nuts.getdisc
@@ -27376,10 +27434,10 @@ local flushcomponents=components.flush
local ischar=nuts.ischar
local usesfont=nuts.usesfont
local insertnodeafter=nuts.insertafter
-local copy_node=nuts.copy
-local copy_node_list=nuts.copylist
-local remove_node=nuts.remove
-local find_node_tail=nuts.tail
+local copynode=nuts.copy
+local copynodelist=nuts.copylist
+local removenode=nuts.remove
+local findnodetail=nuts.tail
local flushnodelist=nuts.flushlist
local flushnode=nuts.flushnode
local endofmath=nuts.endofmath
@@ -27389,7 +27447,6 @@ local setmetatableindex=table.setmetatableindex
local nextnode=nuts.traversers.node
local nodecodes=nodes.nodecodes
local glyphcodes=nodes.glyphcodes
-local disccodes=nodes.disccodes
local glyph_code=nodecodes.glyph
local glue_code=nodecodes.glue
local disc_code=nodecodes.disc
@@ -27398,8 +27455,7 @@ local dir_code=nodecodes.dir
local par_code=nodecodes.par
local lefttoright_code=nodes.dirvalues.lefttoright
local righttoleft_code=nodes.dirvalues.righttoleft
-local discretionarydisc_code=disccodes.discretionary
-local ligatureglyph_code=glyphcodes.ligature
+local discretionarydisc_code=nodes.disccodes.discretionary
local a_noligature=attributes.private("noligature")
local injections=nodes.injections
local setmark=injections.setmark
@@ -27490,7 +27546,7 @@ local function cref(dataset,sequence,index)
return "no valid dataset"
end
local merged=sequence.merged and "merged " or ""
- if index then
+ if index and index>1 then
return formatters["feature %a, type %a, %schain lookup %a, index %a"](
dataset[4],sequence.type,merged,sequence.name,index)
else
@@ -27547,7 +27603,7 @@ end
local function appenddisc(disc,list)
local pre,post,replace,pretail,posttail,replacetail=getdisc(disc,true)
local posthead=list
- local replacehead=copy_node_list(list)
+ local replacehead=copynodelist(list)
if post then
setlink(posttail,posthead)
else
@@ -27574,7 +27630,6 @@ local function markstoligature(head,start,stop,char)
end
resetinjection(base)
setchar(base,char)
- setsubtype(base,ligatureglyph_code)
setcomponents(base,start)
setlink(prev,base,next)
flushcomponents(start)
@@ -27612,7 +27667,6 @@ local function toligature(head,start,stop,char,dataset,sequence,skiphash,discfou
end
resetinjection(base)
setchar(base,char)
- setsubtype(base,ligatureglyph_code)
setcomponents(base,comp)
setlink(prev,base,next)
if not discfound then
@@ -27632,7 +27686,7 @@ local function toligature(head,start,stop,char,dataset,sequence,skiphash,discfou
if trace_marks then
logwarning("%s: keep ligature mark %s, gets index %s",pref(dataset,sequence),gref(char),getligaindex(start))
end
- local n=copy_node(start)
+ local n=copynode(start)
copyinjection(n,start)
head,current=insertnodeafter(head,current,n)
elseif trace_marks then
@@ -27696,57 +27750,57 @@ end
local function multiple_glyphs(head,start,multiple,skiphash,what,stop)
local nofmultiples=#multiple
if nofmultiples>0 then
+ local first=start
resetinjection(start)
setchar(start,multiple[1])
if nofmultiples>1 then
- local sn=getnext(start)
- for k=2,nofmultiples do
- local n=copy_node(start)
+ for i=2,nofmultiples do
+ local n=copynode(start)
resetinjection(n)
- setchar(n,multiple[k])
+ setchar(n,multiple[i])
insertnodeafter(head,start,n)
start=n
end
- if what~=true and repeatablemultiples then
- local kind=type(what)
- local m,f,l
- if kind=="string" then
- local what,n=string.match(what,"^repeat(.-)[:=](%d+)$")
- if what=="middle" then
- m=tonumber(n)
- elseif what=="first" then
- f=tonumber(n)
- elseif what=="last" then
- l=tonumber(n)
- end
- elseif kind=="table" then
- m=what.middle
- f=what.first
- l=what.last
- end
- if f or m or l then
- if m and m>1 and nofmultiples==3 then
- local middle=getnext(first)
- for i=2,m do
- local n=copynode(middle)
- resetinjection(n)
- insertnodeafter(head,first,n)
- end
- end
- if f and f>1 then
- for i=2,f do
- local n=copynode(first)
- resetinjection(n)
- insertnodeafter(head,first,n)
- end
- end
- if l and l>1 then
- for i=2,l do
- local n=copynode(start)
- resetinjection(n)
- insertnodeafter(head,start,n)
- start=n
- end
+ end
+ if what~=true and repeatablemultiples then
+ local kind=type(what)
+ local m,f,l
+ if kind=="string" then
+ local what,n=string.match(what,"^repeat(.-)[:=](%d+)$")
+ if what=="middle" then
+ m=tonumber(n)
+ elseif what=="first" then
+ f=tonumber(n)
+ elseif what=="last" then
+ l=tonumber(n)
+ end
+ elseif kind=="table" then
+ m=what.middle
+ f=what.first
+ l=what.last
+ end
+ if f or m or l then
+ if m and m>1 and nofmultiples==3 then
+ local middle=getnext(first)
+ for i=2,m do
+ local n=copynode(middle)
+ resetinjection(n)
+ insertnodeafter(head,first,n)
+ end
+ end
+ if f and f>1 then
+ for i=2,f do
+ local n=copynode(first)
+ resetinjection(n)
+ insertnodeafter(head,first,n)
+ end
+ end
+ if l and l>1 then
+ for i=2,l do
+ local n=copynode(start)
+ resetinjection(n)
+ insertnodeafter(head,start,n)
+ start=n
end
end
end
@@ -27918,9 +27972,9 @@ function handlers.gsub_ligature(head,start,dataset,sequence,ligature,rlmode,skip
local prev=getprev(start)
if stop then
setnext(stop)
- local copy=copy_node_list(start)
+ local copy=copynodelist(start)
local tail=stop
- local liat=find_node_tail(copy)
+ local liat=findnodetail(copy)
if pre then
setlink(liat,pre)
end
@@ -27931,7 +27985,7 @@ function handlers.gsub_ligature(head,start,dataset,sequence,ligature,rlmode,skip
replace=start
else
setnext(start)
- local copy=copy_node(start)
+ local copy=copynode(start)
if pre then
setlink(copy,pre)
end
@@ -28308,7 +28362,7 @@ function chainprocs.gsub_remove(head,start,stop,dataset,sequence,currentlookup,r
if trace_chains then
logprocess("%s: removing character %s",cref(dataset,sequence,chainindex),gref(getchar(start)))
end
- head,start=remove_node(head,start,true)
+ head,start=removenode(head,start,true)
return head,getprev(start),true
end
function chainprocs.gsub_single(head,start,stop,dataset,sequence,currentlookup,rlmode,skiphash,chainindex)
@@ -28821,7 +28875,7 @@ do if not userkern then
local thekern=nuts.new("kern",1)
local setkern=nuts.setkern
userkern=function(k)
- local n=copy_node(thekern)
+ local n=copynode(thekern)
setkern(n,k)
return n
end
@@ -28858,26 +28912,33 @@ local function setdiscchecked(d,pre,post,replace)
setdisc(d,pre,post,replace)
end
local noflags={ false,false,false,false }
-local function chainrun(head,start,last,dataset,sequence,rlmode,skiphash,ck)
+local function chainrun(head,start,last,dataset,sequence,rlmode,skiphash,ck,where)
local size=ck[5]-ck[4]+1
local chainlookups=ck[6]
local done=false
if chainlookups then
if size==1 then
local chainlookup=chainlookups[1]
- for j=1,#chainlookup do
- local chainstep=chainlookup[j]
- local chainkind=chainstep.type
- local chainproc=chainprocs[chainkind]
- if chainproc then
- local ok
- head,start,ok=chainproc(head,start,last,dataset,sequence,chainstep,rlmode,skiphash,1)
- if ok then
- done=true
+ if chainlookup then
+ for j=1,#chainlookup do
+ local chainstep=chainlookup[j]
+ if chainstep then
+ local chainkind=chainstep.type
+ local chainproc=chainprocs[chainkind]
+ if chainproc then
+ local ok
+ head,start,ok=chainproc(head,start,last,dataset,sequence,chainstep,rlmode,skiphash,1)
+ if ok then
+ done=true
+ end
+ else
+ logprocess("%s: %s is not yet supported (1)",cref(dataset,sequence),chainkind)
+ end
+ else
+ logprocess("%s: has an issue (1)",cref(dataset,sequence))
end
- else
- logprocess("%s: %s is not yet supported (1)",cref(dataset,sequence),chainkind)
end
+ else
end
else
local i=1
@@ -28902,20 +28963,24 @@ local function chainrun(head,start,last,dataset,sequence,rlmode,skiphash,ck)
if chainlookup then
for j=1,#chainlookup do
local chainstep=chainlookup[j]
- local chainkind=chainstep.type
- local chainproc=chainprocs[chainkind]
- if chainproc then
- local ok,n
- head,start,ok,n=chainproc(head,start,last,dataset,sequence,chainstep,rlmode,skiphash,i)
- if ok then
- done=true
- if n and n>1 and i+n>nofchainlookups then
- i=size
- break
+ if chainstep then
+ local chainkind=chainstep.type
+ local chainproc=chainprocs[chainkind]
+ if chainproc then
+ local ok,n
+ head,start,ok,n=chainproc(head,start,last,dataset,sequence,chainstep,rlmode,skiphash,i)
+ if ok then
+ done=true
+ if n and n>1 and i+n>nofchainlookups then
+ i=size
+ break
+ end
end
+ else
+ logprocess("%s: %s is not yet supported (2)",cref(dataset,sequence),chainkind)
end
else
- logprocess("%s: %s is not yet supported (2)",cref(dataset,sequence),chainkind)
+ logprocess("%s: has an issue (2)",cref(dataset,sequence))
end
end
else
@@ -28939,7 +29004,7 @@ local function chainrun(head,start,last,dataset,sequence,rlmode,skiphash,ck)
else
done=true
if trace_contexts then
- logprocess("%s: skipping match",cref(dataset,sequence))
+ logprocess("%s: skipping match @ %i",cref(dataset,sequence),where)
end
end
end
@@ -28966,6 +29031,8 @@ local function chaindisk(head,start,dataset,sequence,rlmode,skiphash,ck)
local last=start
local prev=getprev(start)
local hasglue=false
+ local useddisc=nil
+ local usedstart=start
local i=f
while i<=l do
local id=getid(current)
@@ -29028,7 +29095,7 @@ local function chaindisk(head,start,dataset,sequence,rlmode,skiphash,ck)
tail=prev
setprev(current,sweepnode)
else
- tail=find_node_tail(head)
+ tail=findnodetail(head)
end
setnext(sweepnode,current)
setprev(head)
@@ -29139,13 +29206,13 @@ local function chaindisk(head,start,dataset,sequence,rlmode,skiphash,ck)
head=lookaheaddisc
end
local pre,post,replace=getdisc(lookaheaddisc)
- local new=copy_node_list(cf)
+ local new=copynodelist(cf)
local cnew=new
if pre then
- setlink(find_node_tail(cf),pre)
+ setlink(findnodetail(cf),pre)
end
if replace then
- local tail=find_node_tail(new)
+ local tail=findnodetail(new)
setlink(tail,replace)
end
for i=1,insertedmarks do
@@ -29159,14 +29226,14 @@ local function chaindisk(head,start,dataset,sequence,rlmode,skiphash,ck)
end
if not notmatchpre[lookaheaddisc] then
local ok=false
- cf,start,ok=chainrun(cf,start,cl,dataset,sequence,rlmode,skiphash,ck)
+ cf,start,ok=chainrun(cf,start,cl,dataset,sequence,rlmode,skiphash,ck,1)
if ok then
done=true
end
end
if not notmatchreplace[lookaheaddisc] then
local ok=false
- new,cnew,ok=chainrun(new,cnew,clast,dataset,sequence,rlmode,skiphash,ck)
+ new,cnew,ok=chainrun(new,cnew,clast,dataset,sequence,rlmode,skiphash,ck,2)
if ok then
done=true
end
@@ -29177,6 +29244,7 @@ local function chaindisk(head,start,dataset,sequence,rlmode,skiphash,ck)
setdisc(lookaheaddisc,cf,post,new)
end
start=getprev(lookaheaddisc)
+ useddisc=lookaheaddisc
sweephead[cf]=getnext(clast) or false
sweephead[new]=getnext(cl) or false
elseif backtrackdisc then
@@ -29198,8 +29266,8 @@ local function chaindisk(head,start,dataset,sequence,rlmode,skiphash,ck)
setprev(cf)
setnext(cl)
local pre,post,replace,pretail,posttail,replacetail=getdisc(backtrackdisc,true)
- local new=copy_node_list(cf)
- local cnew=find_node_tail(new)
+ local new=copynodelist(cf)
+ local cnew=findnodetail(new)
for i=1,insertedmarks do
cnew=getprev(cnew)
end
@@ -29209,14 +29277,14 @@ local function chaindisk(head,start,dataset,sequence,rlmode,skiphash,ck)
end
if not notmatchpost[backtrackdisc] then
local ok=false
- cf,start,ok=chainrun(cf,start,last,dataset,sequence,rlmode,skiphash,ck)
+ cf,start,ok=chainrun(cf,start,last,dataset,sequence,rlmode,skiphash,ck,3)
if ok then
done=true
end
end
if not notmatchreplace[backtrackdisc] then
local ok=false
- new,cnew,ok=chainrun(new,cnew,clast,dataset,sequence,rlmode,skiphash,ck)
+ new,cnew,ok=chainrun(new,cnew,clast,dataset,sequence,rlmode,skiphash,ck,4)
if ok then
done=true
end
@@ -29237,30 +29305,55 @@ local function chaindisk(head,start,dataset,sequence,rlmode,skiphash,ck)
setdisc(backtrackdisc,pre,post,replace)
end
start=getprev(backtrackdisc)
+ useddisc=backtrackdisc
sweephead[post]=getnext(clast) or false
sweephead[replace]=getnext(last) or false
else
local ok=false
- head,start,ok=chainrun(head,start,last,dataset,sequence,rlmode,skiphash,ck)
+ head,start,ok=chainrun(head,start,last,dataset,sequence,rlmode,skiphash,ck,5)
if ok then
done=true
end
end
- return head,start,done
-end
-local function chaintrac(head,start,dataset,sequence,rlmode,skiphash,ck,match,discseen,sweepnode)
- local rule=ck[1]
- local lookuptype=ck[8] or ck[2]
- local nofseq=#ck[3]
- local first=ck[4]
- local last=ck[5]
- local char=getchar(start)
- logwarning("%s: rule %s %s at char %s for (%s,%s,%s) chars, lookuptype %a, %sdisc seen, %ssweeping",
- cref(dataset,sequence),rule,match and "matches" or "nomatch",
- gref(char),first-1,last-first+1,nofseq-last,lookuptype,
- discseen and "" or "no ",sweepnode and "" or "not ")
+ if useddisc and start~=usedstart then
+ start=getnext(start)
+ end
+ return head,start,done,useddisc
+end
+local chaintrac do
+ local level=0
+ local last={}
+ chaintrac=function(head,start,dataset,sequence,rlmode,skiphash,ck,match,discseen,sweepnode)
+ if dataset then
+ level=level+1
+ last[level]=start
+ local rule=ck[1]
+ local lookuptype=ck[8] or ck[2]
+ local nofseq=#ck[3]
+ local first=ck[4]
+ local last=ck[5]
+ local char=getchar(start)
+ logwarning("+ %i : %s: rule %s %s at char %s for (%s,%s,%s) chars, lookuptype %a, %sdisc seen, %ssweeping",
+ level,cref(dataset,sequence),rule,match and "matches" or "nomatch",
+ gref(char),first-1,last-first+1,nofseq-last,lookuptype,
+ discseen and "" or "no ",sweepnode and "" or "not ")
+ else
+ local what=start and "done" or "continue"
+ local where=head==last[level] and "same" or "different"
+ local char=getchar(head)
+ if char then
+ logwarning("- %i : %s at char %s, %s node",level,what,gref(char),where)
+ else
+ logwarning("- %i : %s, %s node",level,what,where)
+ end
+ level=level-1
+ end
+ end
end
local function handle_contextchain(head,start,dataset,sequence,contexts,rlmode,skiphash)
+ if not contexts then
+ return head,start,false
+ end
local sweepnode=sweepnode
local sweeptype=sweeptype
local postreplace
@@ -29288,7 +29381,7 @@ local function handle_contextchain(head,start,dataset,sequence,contexts,rlmode,s
local ck=contexts[k]
local seq=ck[3]
local f=ck[4]
-local last=start
+ local last=start
if not startchar or not seq[f][startchar] then
goto next
end
@@ -29399,7 +29492,6 @@ local last=start
end
end
if f>1 then
- if startprev then
local prev=startprev
if prereplace and prev==checkdisc then
prev=getprev(sweepnode)
@@ -29514,9 +29606,6 @@ local last=start
else
goto next
end
- else
- goto next
- end
end
if s>l then
local current=last and getnext(last)
@@ -29640,12 +29729,15 @@ local last=start
if discseen or sweepnode then
head,start,done=chaindisk(head,start,dataset,sequence,rlmode,skipped and skiphash,ck)
else
- head,start,done=chainrun(head,start,last,dataset,sequence,rlmode,skipped and skiphash,ck)
+ head,start,done=chainrun(head,start,last,dataset,sequence,rlmode,skipped and skiphash,ck,6)
+ end
+ if trace_contexts then
+ chaintrac(start,done)
end
if done then
break
end
- ::next::
+ ::next::
end
if discseen then
notmatchpre={}
@@ -29662,15 +29754,26 @@ handlers.gpos_context=handle_contextchain
local function chained_contextchain(head,start,stop,dataset,sequence,currentlookup,rlmode,skiphash)
local steps=currentlookup.steps
local nofsteps=currentlookup.nofsteps
- if nofsteps>1 then
- reportmoresteps(dataset,sequence)
- end
- local l=steps[1].coverage[getchar(start)]
- if l then
- return handle_contextchain(head,start,dataset,sequence,l,rlmode,skiphash)
+ local char=getchar(start)
+ if nofsteps==1 then
+ local s=steps[1]
+ local l=s.coverage[char]
+ if l then
+ return handle_contextchain(head,start,dataset,sequence,l,rlmode,skiphash)
+ end
else
- return head,start,false
+ for i=1,nofsteps do
+ local s=steps[i]
+ local l=s.coverage[char]
+ if l then
+ local h,s,d=handle_contextchain(head,start,dataset,sequence,l,rlmode,skiphash)
+ if d then
+ return h,s,d
+ end
+ end
+ end
end
+ return head,start,false
end
chainprocs.gsub_context=chained_contextchain
chainprocs.gsub_contextchain=chained_contextchain
@@ -29853,7 +29956,7 @@ local function kernrun(disc,k_run,font,attr,...)
if done and trace_testruns then
report_disc("done",disc)
end
- return nextstart,done
+ return nextstart
end
local function comprun(disc,c_run,...)
if trace_compruns then
@@ -29896,8 +29999,12 @@ local function comprun(disc,c_run,...)
end
setdisc(disc,pre,post,replace)
end
- return getnext(disc),renewed
+ return getnext(disc)
end
+local test_flatten_start=2
+directives.register("otf.testrun.forceflatten",function(v)
+ test_flatten_start=v and 1 or 2
+end)
local function testrun(disc,t_run,c_run,...)
if trace_testruns then
report_disc("test",disc)
@@ -29925,7 +30032,7 @@ local function testrun(disc,t_run,c_run,...)
local d=d_replace>d_post and d_replace or d_post
local head=getnext(disc)
local tail=head
- for i=2,d do
+ for i=test_flatten_start,d do
local nx=getnext(tail)
local id=getid(nx)
if id==disc_code then
@@ -29939,7 +30046,7 @@ local function testrun(disc,t_run,c_run,...)
next=getnext(tail)
setnext(tail)
setprev(head)
- local new=copy_node_list(head)
+ local new=copynodelist(head)
if posttail then
setlink(posttail,head)
else
@@ -30002,7 +30109,7 @@ local function testrun(disc,t_run,c_run,...)
report_disc("done",disc)
end
end
- return getnext(disc),renewed
+ return getnext(disc)
end
local nesting=0
local function c_run_single(head,font,attr,lookupcache,step,dataset,sequence,rlmode,skiphash,handler)
@@ -30420,7 +30527,7 @@ do
head=h
end
elseif typ=="gsub_reversecontextchain" then
- local start=find_node_tail(head)
+ local start=findnodetail(head)
local rlmode=0
local merged=steps.merged
while start do
@@ -30498,13 +30605,12 @@ do
start=getnext(start)
elseif id==disc_code then
if not discs or discs[start]==true then
- local ok
if gpossing then
- start,ok=kernrun(start,k_run_single,font,attr,lookupcache,step,dataset,sequence,rlmode,skiphash,handler)
+ start=kernrun(start,k_run_single,font,attr,lookupcache,step,dataset,sequence,rlmode,skiphash,handler)
elseif forcetestrun then
- start,ok=testrun(start,t_run_single,c_run_single,font,attr,lookupcache,step,dataset,sequence,rlmode,skiphash,handler)
+ start=testrun(start,t_run_single,c_run_single,font,attr,lookupcache,step,dataset,sequence,rlmode,skiphash,handler)
else
- start,ok=comprun(start,c_run_single,font,attr,lookupcache,step,dataset,sequence,rlmode,skiphash,handler)
+ start=comprun(start,c_run_single,font,attr,lookupcache,step,dataset,sequence,rlmode,skiphash,handler)
end
else
start=getnext(start)
@@ -30568,13 +30674,12 @@ do
start=getnext(start)
elseif id==disc_code then
if not discs or discs[start]==true then
- local ok
if gpossing then
- start,ok=kernrun(start,k_run_multiple,font,attr,steps,nofsteps,dataset,sequence,rlmode,skiphash,handler)
+ start=kernrun(start,k_run_multiple,font,attr,steps,nofsteps,dataset,sequence,rlmode,skiphash,handler)
elseif forcetestrun then
- start,ok=testrun(start,t_run_multiple,c_run_multiple,font,attr,steps,nofsteps,dataset,sequence,rlmode,skiphash,handler)
+ start=testrun(start,t_run_multiple,c_run_multiple,font,attr,steps,nofsteps,dataset,sequence,rlmode,skiphash,handler)
else
- start,ok=comprun(start,c_run_multiple,font,attr,steps,nofsteps,dataset,sequence,rlmode,skiphash,handler)
+ start=comprun(start,c_run_multiple,font,attr,steps,nofsteps,dataset,sequence,rlmode,skiphash,handler)
end
else
start=getnext(start)
@@ -31074,6 +31179,10 @@ local function addfeature(data,feature,specifications,prepareonly)
end
local descriptions=data.descriptions
local resources=data.resources
+ if not descriptions or not resources then
+ report_otf("missing specification")
+ return
+ end
local features=resources.features
local sequences=resources.sequences
if not features or not sequences then
@@ -31651,7 +31760,11 @@ local function addfeature(data,feature,specifications,prepareonly)
local list=askedsteps[i]
local coverage=nil
local format=nil
- if featuretype=="substitution" then
+if type(list)=="function" then
+ list=list(data,specification,list,i)
+end
+ if not list then
+ elseif featuretype=="substitution" then
category="gsub"
coverage=(mapping and list) or prepare_substitution(list,featuretype,nocheck)
elseif featuretype=="ligature" then
@@ -33297,7 +33410,7 @@ local function reorder_two(head,start,stop,font,attr,nbspaces)
local subpos=nil
local postpos=nil
reorderreph.coverage={}
- rephbase[font]={}
+ rephbase[font]={}
for i=1,#seqsubset do
local subset=seqsubset[i]
local kind=subset[1]
@@ -33418,7 +33531,7 @@ local function reorder_two(head,start,stop,font,attr,nbspaces)
end
end
end
- local current,base,firstcons=start,nil,nil
+ local current,base,firstcons,subnotafterbase,postnotafterbase=start,nil,nil,nil,nil
if getstate(start,s_rphf) then
current=getnext(getnext(start))
end
@@ -33474,10 +33587,16 @@ local function reorder_two(head,start,stop,font,attr,nbspaces)
logprocess("reorder two, handle nbsp")
end
end
- else
+ else
local last=getnext(stop)
while current~=last do
local next=getnext(current)
+ if current==subpos then
+ subnotafterbase=current
+ end
+ if current==postpos then
+ postnotafterbase=current
+ end
if consonant[getchar(current)] then
if not (current~=stop and next~=stop and halant[getchar(next)] and getchar(getnext(next))==c_zwj) then
if not firstcons then
@@ -33486,6 +33605,12 @@ local function reorder_two(head,start,stop,font,attr,nbspaces)
local a=getstate(current)
if not (a==s_blwf or a==s_pstf or (a~=s_rphf and a~=s_blwf and ra[getchar(current)])) then
base=current
+ if subnotafterbase then
+ subpos=base
+ end
+ if postnotafterbase then
+ postpos=base
+ end
end
end
end
@@ -33537,7 +33662,7 @@ local function reorder_two(head,start,stop,font,attr,nbspaces)
logprocess("reorder two, handle matra")
end
end
- if dependent_vowel[char] then
+ if not moved[current] and dependent_vowel[char] then
if pre_mark[char] then
moved[current]=true
local prev,next=getboth(current)
@@ -33580,14 +33705,11 @@ local function reorder_two(head,start,stop,font,attr,nbspaces)
logprocess("reorder two, handle pre mark")
end
elseif above_mark[char] then
- target=basepos
- if subpos==basepos then
- subpos=current
- end
- if postpos==basepos then
+ target=subpos
+ if postpos==subpos then
postpos=current
end
- basepos=current
+ subpos=current
elseif below_mark[char] then
target=subpos
if postpos==subpos then
@@ -33807,11 +33929,7 @@ local function analyze_next_chars_one(c,font,variant)
if pre_mark[v] and not already_pre_mark then
already_pre_mark=true
elseif post_mark[v] and not already_post_mark then
- if devanagarihash[font].conjuncts=="mixed" then
- return c
- else
already_post_mark=true
- end
elseif below_mark[v] and not already_below_mark then
already_below_mark=true
elseif above_mark[v] and not already_above_mark then
@@ -34012,11 +34130,7 @@ local function analyze_next_chars_two(c,font)
if pre_mark[v] and not already_pre_mark then
already_pre_mark=true
elseif post_mark[v] and not already_post_mark then
- if devanagarihash[font].conjuncts=="mixed" then
- return c
- else
- already_post_mark=true
- end
+ already_post_mark=true
elseif below_mark[v] and not already_below_mark then
already_below_mark=true
elseif above_mark[v] and not already_above_mark then
@@ -37079,7 +37193,7 @@ local afm=fonts.handlers.afm
local pfb=fonts.handlers.pfb
local hashes=fonts.hashes
local identifiers=hashes.identifiers
-local version=otf.version or 0.011
+local version=otf.version or 0.015
local shapescache=containers.define("fonts","shapes",version,true)
local streamscache=containers.define("fonts","streams",version,true)
local compact_streams=false
@@ -37305,7 +37419,8 @@ local function loadstreams(cache,filename,sub,instance)
if streams then
local fontbbox=metadata.fontbbox or { 0,0,0,0 }
for i=0,#streams do
- streams[i]=streams[i].stream or "\14"
+ local s=streams[i]
+ streams[i]=s.stream or "\14"
end
data={
filename=filename,
@@ -37387,7 +37502,8 @@ local function getstreamhash(fontid)
local fontdata=identifiers[fontid]
if fontdata then
local properties=fontdata.properties
- return makehash(properties.filename,properties.subfont,properties.instance),fontdata
+ local fonthash=makehash(properties.filename,properties.subfont,properties.instance)
+ return fonthash,fontdata
end
end
local function loadstreamdata(fontdata)
@@ -37716,7 +37832,7 @@ local fonts=fonts
local otf=fonts.handlers.otf
local registerotffeature=otf.features.register
local addotffeature=otf.addfeature
-local specification={
+local tlig={
type="ligature",
order={ "tlig" },
prepend=true,
@@ -37725,12 +37841,17 @@ local specification={
[0x2014]={ 0x002D,0x002D,0x002D },
},
}
-addotffeature("tlig",specification)
-registerotffeature {
- name="tlig",
- description="tex ligatures",
+local tquo={
+ type="ligature",
+ order={ "tquo" },
+ prepend=true,
+ data={
+ [0x201C]={ 0x0060,0x0060 },
+ [0x201D]={ 0x0027,0x0027 },
+ [0x201E]={ 0x002C,0x002C },
+ },
}
-local specification={
+local trep={
type="substitution",
order={ "trep" },
prepend=true,
@@ -37738,11 +37859,12 @@ local specification={
[0x0027]=0x2019,
},
}
-addotffeature("trep",specification)
-registerotffeature {
- name="trep",
- description="tex replacements",
-}
+addotffeature("trep",trep)
+addotffeature("tlig",tlig)
+addotffeature("tquo",tquo)
+registerotffeature { name="tlig",description="tex ligatures" }
+registerotffeature { name="tquo",description="tex quotes" }
+registerotffeature { name="trep",description="tex replacements" }
local anum_arabic={
[0x0030]=0x0660,
[0x0031]=0x0661,
@@ -37926,30 +38048,11 @@ if not modules then modules={} end modules ['font-imp-italics']={
copyright="PRAGMA ADE / ConTeXt Development Team",
license="see context related readme files"
}
-local next=next
+local next,tonumber=next,tonumber
local fonts=fonts
local handlers=fonts.handlers
local registerotffeature=handlers.otf.features.register
local registerafmfeature=handlers.afm.features.register
-local function initialize(tfmdata,key,value)
- for unicode,character in next,tfmdata.characters do
- local olditalic=character.italic
- if olditalic and olditalic~=0 then
- character.width=character.width+olditalic
- character.italic=0
- end
- end
-end
-local specification={
- name="italicwidths",
- description="add italic to width",
- manipulators={
- base=initialize,
- node=initialize,
- }
-}
-registerotffeature(specification)
-registerafmfeature(specification)
local function initialize(tfmdata,value)
if value then
local parameters=tfmdata.parameters