summaryrefslogtreecommitdiff
path: root/macros/luatex
diff options
context:
space:
mode:
authorNorbert Preining <norbert@preining.info>2023-08-21 03:03:40 +0000
committerNorbert Preining <norbert@preining.info>2023-08-21 03:03:40 +0000
commitf4e4c48e897bec27fd8d07ba278c03c6f0c64336 (patch)
treeb8c47431b940055b5095271c39a9db123375efd6 /macros/luatex
parent53b22757814343c6071be2e64dc0639f7afc5468 (diff)
CTAN sync 202308210303
Diffstat (limited to 'macros/luatex')
-rw-r--r--macros/luatex/generic/lualibs/NEWS3
-rw-r--r--macros/luatex/generic/lualibs/README.md6
-rw-r--r--macros/luatex/generic/lualibs/lualibs-basic-merged.lua66
-rw-r--r--macros/luatex/generic/lualibs/lualibs-dir.lua40
-rw-r--r--macros/luatex/generic/lualibs/lualibs-extended-merged.lua271
-rw-r--r--macros/luatex/generic/lualibs/lualibs-file.lua22
-rw-r--r--macros/luatex/generic/lualibs/lualibs-string.lua24
-rw-r--r--macros/luatex/generic/lualibs/lualibs-unicode.lua1
-rw-r--r--macros/luatex/generic/lualibs/lualibs-util-dim.lua234
-rw-r--r--macros/luatex/generic/lualibs/lualibs-util-prs.lua27
-rw-r--r--macros/luatex/generic/lualibs/lualibs-util-sac.lua12
-rw-r--r--macros/luatex/generic/lualibs/lualibs-util-str.lua5
-rw-r--r--macros/luatex/generic/lualibs/lualibs-util-tab.lua2
-rw-r--r--macros/luatex/generic/lualibs/lualibs-util-zip.lua363
-rw-r--r--macros/luatex/generic/lualibs/lualibs.dtx18
-rw-r--r--macros/luatex/generic/lualibs/lualibs.pdfbin81128 -> 82357 bytes
-rw-r--r--macros/luatex/generic/luaotfload/NEWS10
-rw-r--r--macros/luatex/generic/luaotfload/README.md4
-rw-r--r--macros/luatex/generic/luaotfload/filegraph.pdfbin40007 -> 40007 bytes
-rw-r--r--macros/luatex/generic/luaotfload/fontloader-2023-08-19.lua (renamed from macros/luatex/generic/luaotfload/fontloader-2022-10-03.lua)943
-rw-r--r--macros/luatex/generic/luaotfload/fontloader-data-con.lua30
-rw-r--r--macros/luatex/generic/luaotfload/fontloader-font-afk.lua8
-rw-r--r--macros/luatex/generic/luaotfload/fontloader-font-cff.lua201
-rw-r--r--macros/luatex/generic/luaotfload/fontloader-font-con.lua99
-rw-r--r--macros/luatex/generic/luaotfload/fontloader-font-def.lua92
-rw-r--r--macros/luatex/generic/luaotfload/fontloader-font-dsp.lua80
-rw-r--r--macros/luatex/generic/luaotfload/fontloader-font-imp-italics.lua49
-rw-r--r--macros/luatex/generic/luaotfload/fontloader-font-imp-tex.lua47
-rw-r--r--macros/luatex/generic/luaotfload/fontloader-font-ini.lua4
-rw-r--r--macros/luatex/generic/luaotfload/fontloader-font-one.lua90
-rw-r--r--macros/luatex/generic/luaotfload/fontloader-font-onr.lua42
-rw-r--r--macros/luatex/generic/luaotfload/fontloader-font-osd.lua78
-rw-r--r--macros/luatex/generic/luaotfload/fontloader-font-ota.lua6
-rw-r--r--macros/luatex/generic/luaotfload/fontloader-font-otc.lua13
-rw-r--r--macros/luatex/generic/luaotfload/fontloader-font-otl.lua48
-rw-r--r--macros/luatex/generic/luaotfload/fontloader-font-oto.lua14
-rw-r--r--macros/luatex/generic/luaotfload/fontloader-font-otr.lua48
-rw-r--r--macros/luatex/generic/luaotfload/fontloader-font-ots.lua636
-rw-r--r--macros/luatex/generic/luaotfload/fontloader-font-ott.lua64
-rw-r--r--macros/luatex/generic/luaotfload/fontloader-font-oup.lua59
-rw-r--r--macros/luatex/generic/luaotfload/fontloader-font-shp.lua17
-rw-r--r--macros/luatex/generic/luaotfload/fontloader-font-ttf.lua52
-rw-r--r--macros/luatex/generic/luaotfload/fontloader-l-file.lua22
-rw-r--r--macros/luatex/generic/luaotfload/fontloader-l-string.lua24
-rw-r--r--macros/luatex/generic/luaotfload/fontloader-l-table.lua24
-rw-r--r--macros/luatex/generic/luaotfload/fontloader-reference.lua843
-rw-r--r--macros/luatex/generic/luaotfload/fontloader-util-str.lua5
-rw-r--r--macros/luatex/generic/luaotfload/luaotfload-auxiliary.lua4
-rw-r--r--macros/luatex/generic/luaotfload/luaotfload-colors.lua4
-rw-r--r--macros/luatex/generic/luaotfload/luaotfload-conf.pdfbin77520 -> 79696 bytes
-rw-r--r--macros/luatex/generic/luaotfload/luaotfload-configuration.lua127
-rw-r--r--macros/luatex/generic/luaotfload/luaotfload-database.lua69
-rw-r--r--macros/luatex/generic/luaotfload/luaotfload-diagnostics.lua4
-rw-r--r--macros/luatex/generic/luaotfload/luaotfload-dvi.lua26
-rw-r--r--macros/luatex/generic/luaotfload/luaotfload-embolden.lua4
-rw-r--r--macros/luatex/generic/luaotfload/luaotfload-fallback.lua4
-rw-r--r--macros/luatex/generic/luaotfload/luaotfload-features.lua11
-rw-r--r--macros/luatex/generic/luaotfload/luaotfload-filelist.lua4
-rw-r--r--macros/luatex/generic/luaotfload/luaotfload-glyphlist.lua4
-rw-r--r--macros/luatex/generic/luaotfload/luaotfload-harf-define.lua22
-rw-r--r--macros/luatex/generic/luaotfload/luaotfload-harf-plug.lua4
-rw-r--r--macros/luatex/generic/luaotfload/luaotfload-harf-var-cff2.lua35
-rw-r--r--macros/luatex/generic/luaotfload/luaotfload-harf-var-t2-writer.lua4
-rw-r--r--macros/luatex/generic/luaotfload/luaotfload-harf-var-ttf.lua6
-rw-r--r--macros/luatex/generic/luaotfload/luaotfload-init.lua4
-rw-r--r--macros/luatex/generic/luaotfload/luaotfload-latex.pdfbin500170 -> 506631 bytes
-rw-r--r--macros/luatex/generic/luaotfload/luaotfload-letterspace.lua4
-rw-r--r--macros/luatex/generic/luaotfload/luaotfload-loaders.lua4
-rw-r--r--macros/luatex/generic/luaotfload/luaotfload-log.lua4
-rw-r--r--macros/luatex/generic/luaotfload/luaotfload-main.tex35
-rw-r--r--macros/luatex/generic/luaotfload/luaotfload-multiscript.lua4
-rw-r--r--macros/luatex/generic/luaotfload/luaotfload-notdef.lua6
-rw-r--r--macros/luatex/generic/luaotfload/luaotfload-parsers.lua4
-rw-r--r--macros/luatex/generic/luaotfload/luaotfload-resolvers.lua4
-rw-r--r--macros/luatex/generic/luaotfload/luaotfload-scripts.lua4
-rw-r--r--macros/luatex/generic/luaotfload/luaotfload-status.lua118
-rw-r--r--macros/luatex/generic/luaotfload/luaotfload-suppress.lua4
-rw-r--r--macros/luatex/generic/luaotfload/luaotfload-szss.lua4
-rw-r--r--macros/luatex/generic/luaotfload/luaotfload-tool.12
-rw-r--r--macros/luatex/generic/luaotfload/luaotfload-tool.lua4
-rw-r--r--macros/luatex/generic/luaotfload/luaotfload-tool.pdfbin76791 -> 77111 bytes
-rw-r--r--macros/luatex/generic/luaotfload/luaotfload-tool.rst4
-rw-r--r--macros/luatex/generic/luaotfload/luaotfload-tounicode.lua4
-rw-r--r--macros/luatex/generic/luaotfload/luaotfload-unicode.lua4
-rw-r--r--macros/luatex/generic/luaotfload/luaotfload.conf.538
-rw-r--r--macros/luatex/generic/luaotfload/luaotfload.conf.example2
-rw-r--r--macros/luatex/generic/luaotfload/luaotfload.conf.rst95
-rw-r--r--macros/luatex/generic/luaotfload/luaotfload.lua4
-rw-r--r--macros/luatex/generic/luaotfload/luaotfload.sty2
-rw-r--r--macros/luatex/generic/luaotfload/scripts-demo.pdfbin21682 -> 21682 bytes
-rw-r--r--macros/luatex/generic/luaotfload/shaper-demo-graphite.pdfbin8562 -> 8562 bytes
-rw-r--r--macros/luatex/generic/luaotfload/shaper-demo.pdfbin8478 -> 8478 bytes
92 files changed, 3170 insertions, 2266 deletions
diff --git a/macros/luatex/generic/lualibs/NEWS b/macros/luatex/generic/lualibs/NEWS
index 889232dc47..6117812375 100644
--- a/macros/luatex/generic/lualibs/NEWS
+++ b/macros/luatex/generic/lualibs/NEWS
@@ -1,4 +1,7 @@
History of the lualibs package
+2023/07/13 v2.76/
+ * sync with Context current as of 2023/07/13.
+
2022/10/04 v2.75/
* sync with Context current as of 2022/10/04.
* add util-sac
diff --git a/macros/luatex/generic/lualibs/README.md b/macros/luatex/generic/lualibs/README.md
index 09194115ce..f4f2e7162c 100644
--- a/macros/luatex/generic/lualibs/README.md
+++ b/macros/luatex/generic/lualibs/README.md
@@ -1,10 +1,10 @@
# The Lualibs Package
-VERSION: 2.75
+VERSION: 2.76
-DATE: 2022-10-04
+DATE: 2023-07-13
-FONTLOADERDATE: 2022-10-04
+FONTLOADERDATE: 2023-07-13
Lualibs is a collection of Lua modules useful for general programming.
diff --git a/macros/luatex/generic/lualibs/lualibs-basic-merged.lua b/macros/luatex/generic/lualibs/lualibs-basic-merged.lua
index 690a3160ac..b201cfab04 100644
--- a/macros/luatex/generic/lualibs/lualibs-basic-merged.lua
+++ b/macros/luatex/generic/lualibs/lualibs-basic-merged.lua
@@ -1,6 +1,6 @@
-- merged file : lualibs-basic-merged.lua
-- parent file : lualibs-basic.lua
--- merge date : 2022-10-04 17:16
+-- merge date : 2023-07-13 12:55
do -- begin closure to overcome local limits and interference
@@ -1274,7 +1274,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
@@ -1284,10 +1284,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
@@ -4022,9 +4030,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
@@ -4136,7 +4158,7 @@ dir=dir or {}
local dir=dir
local lfs=lfs
local attributes=lfs.attributes
-local walkdir=lfs.dir
+local scandir=lfs.dir
local isdir=lfs.isdir
local isfile=lfs.isfile
local currentdir=lfs.currentdir
@@ -4167,6 +4189,15 @@ else
lfs.isdir=isdir
lfs.isfile=isfile
end
+local isreadable=file.isreadable
+local walkdir=function(p,...)
+ if isreadable(p.."/.") then
+ return scandir(p,...)
+ else
+ return function() end
+ end
+end
+lfs.walkdir=walkdir
function dir.current()
return (gsub(currentdir(),"\\","/"))
end
@@ -4582,6 +4613,23 @@ do
return str
end
end
+ function dir.expandlink(dir,report)
+ local curdir=currentdir()
+ local trace=type(report)=="function"
+ if chdir(dir) then
+ local newdir=currentdir()
+ if newdir~=dir and trace then
+ report("following symlink %a to %a",dir,newdir)
+ end
+ chdir(curdir)
+ return newdir
+ else
+ if trace then
+ report("unable to check path %a",dir)
+ end
+ return dir
+ end
+ end
end
file.expandname=dir.expandname
local stack={}
diff --git a/macros/luatex/generic/lualibs/lualibs-dir.lua b/macros/luatex/generic/lualibs/lualibs-dir.lua
index ac8e2f4e8e..3164068505 100644
--- a/macros/luatex/generic/lualibs/lualibs-dir.lua
+++ b/macros/luatex/generic/lualibs/lualibs-dir.lua
@@ -21,7 +21,8 @@ local dir = dir
local lfs = lfs
local attributes = lfs.attributes
-local walkdir = lfs.dir
+----- walkdir = lfs.dir
+local scandir = lfs.dir
local isdir = lfs.isdir -- not robust, will be overloaded anyway
local isfile = lfs.isfile -- not robust, will be overloaded anyway
local currentdir = lfs.currentdir
@@ -69,6 +70,20 @@ else
end
+-- safeguard
+
+local isreadable = file.isreadable
+
+local walkdir = function(p,...)
+ if isreadable(p.."/.") then
+ return scandir(p,...)
+ else
+ return function() end
+ end
+end
+
+lfs.walkdir = walkdir
+
-- handy
function dir.current()
@@ -197,7 +212,7 @@ local function collectpattern(path,patt,recurse,result)
if not find(path,"/$") then
path = path .. '/'
end
- for name in scanner, first do -- cna be optimized
+ for name in scanner, first do -- can be optimized
if name == "." then
-- skip
elseif name == ".." then
@@ -596,6 +611,27 @@ do
end
+ -- This go there anc check works okay in tricky situation as we encounter
+ -- on osx, where tex installations use rather complex chains of links.
+
+ function dir.expandlink(dir,report)
+ local curdir = currentdir()
+ local trace = type(report) == "function"
+ if chdir(dir) then
+ local newdir = currentdir()
+ if newdir ~= dir and trace then
+ report("following symlink %a to %a",dir,newdir)
+ end
+ chdir(curdir)
+ return newdir
+ else
+ if trace then
+ report("unable to check path %a",dir)
+ end
+ return dir
+ end
+ end
+
end
file.expandname = dir.expandname -- for convenience
diff --git a/macros/luatex/generic/lualibs/lualibs-extended-merged.lua b/macros/luatex/generic/lualibs/lualibs-extended-merged.lua
index 08428c51ac..ceecbf3013 100644
--- a/macros/luatex/generic/lualibs/lualibs-extended-merged.lua
+++ b/macros/luatex/generic/lualibs/lualibs-extended-merged.lua
@@ -1,6 +1,6 @@
-- merged file : lualibs-extended-merged.lua
-- parent file : lualibs-extended.lua
--- merge date : 2022-10-04 17:16
+-- merge date : 2023-07-13 12:55
do -- begin closure to overcome local limits and interference
@@ -481,13 +481,13 @@ if bit32 and not streams.tocardinal1 then
local extract=bit32.extract
local char=string.char
streams.tocardinal1=char
- function streams.tocardinal2(n) return char(extract(8,8),extract(0,8)) end
- function streams.tocardinal3(n) return char(extract(16,8),extract(8,8),extract(0,8)) end
- function streams.tocardinal4(n) return char(extract(24,8),extract(16,8),extract(8,8),extract(0,8)) end
+ function streams.tocardinal2(n) return char(extract(n,8,8),extract(n,0,8)) end
+ function streams.tocardinal3(n) return char(extract(n,16,8),extract(n,8,8),extract(n,0,8)) end
+ function streams.tocardinal4(n) return char(extract(n,24,8),extract(n,16,8),extract(n,8,8),extract(n,0,8)) end
streams.tocardinal1le=char
- function streams.tocardinal2le(n) return char(extract(0,8),extract(8,8)) end
- function streams.tocardinal3le(n) return char(extract(0,8),extract(8,8),extract(16,8)) end
- function streams.tocardinal4le(n) return char(extract(0,8),extract(8,8),extract(16,8),extract(24,8)) end
+ function streams.tocardinal2le(n) return char(extract(n,0,8),extract(n,8,8)) end
+ function streams.tocardinal3le(n) return char(extract(n,0,8),extract(n,8,8),extract(n,16,8)) end
+ function streams.tocardinal4le(n) return char(extract(n,0,8),extract(n,8,8),extract(n,16,8),extract(n,24,8)) end
end
if not streams.readcstring then
local readchar=streams.readchar
@@ -701,6 +701,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,
@@ -709,6 +710,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 })
@@ -2090,7 +2092,7 @@ else
local v=t[0]
if v then
m=m+1
- r[m]="[0]='"
+ r[m]="[0]="
if type(v)=="table" then
fastserialize(v)
else
@@ -2879,7 +2881,9 @@ function parsers.groupedsplitat(symbol,withaction)
if not pattern then
local symbols=S(symbol)
local separator=space^0*symbols*space^0
- local value=lbrace*C((nobrace+nestedbraces)^0)*rbrace+C((nestedbraces+(1-(space^0*(symbols+P(-1)))))^0)
+ local value=lbrace*C((nobrace+nestedbraces)^0)
+*(rbrace*(#symbols+P(-1)))
++C((nestedbraces+(1-(space^0*(symbols+P(-1)))))^0)
if withaction then
local withvalue=Carg(1)*value/function(f,s) return f(s) end
pattern=spaces*withvalue*(separator*withvalue)^0
@@ -2965,7 +2969,17 @@ hashes.settings_to_set=table.setmetatableindex(function(t,k)
t[k]=v
return v
end)
-getmetatable(hashes.settings_to_set).__mode="kv"
+function parsers.settings_to_set(str)
+ return str and lpegmatch(pattern,str) or {}
+end
+local pattern=Ct((C((1-S(", "))^1)*S(", ")^0)^1)
+hashes.settings_to_list=table.setmetatableindex(function(t,k)
+ local v=k and lpegmatch(pattern,k) or {}
+ t[k]=v
+ return v
+end)
+getmetatable(hashes.settings_to_set ).__mode="kv"
+getmetatable(hashes.settings_to_list).__mode="kv"
function parsers.simple_hash_to_string(h,separator)
local t={}
local tn=0
@@ -3298,6 +3312,8 @@ local dimenfactors=allocate {
["pc"]=(1/12)/65536,
["dd"]=(1157/1238)/65536,
["cc"]=(1157/14856)/65536,
+ ["es"]=(9176/129)/65536,
+ ["ts"]=(4588/645)/65536,
}
local f_none=formatters["%s%s"]
local f_true=formatters["%0.5F%s"]
@@ -3323,12 +3339,13 @@ function number.topoints (n,fmt) return numbertodimen(n,"pt",fmt) end
function number.toinches (n,fmt) return numbertodimen(n,"in",fmt) end
function number.tocentimeters (n,fmt) return numbertodimen(n,"cm",fmt) end
function number.tomillimeters (n,fmt) return numbertodimen(n,"mm",fmt) end
-function number.toscaledpoints(n,fmt) return numbertodimen(n,"sp",fmt) end
function number.toscaledpoints(n) return n.."sp" end
function number.tobasepoints (n,fmt) return numbertodimen(n,"bp",fmt) end
function number.topicas (n,fmt) return numbertodimen(n "pc",fmt) end
function number.todidots (n,fmt) return numbertodimen(n,"dd",fmt) end
function number.tociceros (n,fmt) return numbertodimen(n,"cc",fmt) end
+function number.toediths (n,fmt) return numbertodimen(n,"es",fmt) end
+function number.totoves (n,fmt) return numbertodimen(n,"ts",fmt) end
local amount=(S("+-")^0*R("09")^0*P(".")^0*R("09")^0)+Cc("0")
local unit=R("az")^1+P("%")
local dimenpair=amount/tonumber*(unit^1/dimenfactors+Cc(1))
@@ -3342,7 +3359,7 @@ setmetatableindex(dimenfactors,function(t,s)
end)
local stringtodimen
local amount=S("+-")^0*R("09")^0*S(".,")^0*R("09")^0
-local unit=P("pt")+P("cm")+P("mm")+P("sp")+P("bp")+P("in")+P("pc")+P("dd")+P("cc")+P("nd")+P("nc")
+local unit=P("pt")+P("cm")+P("mm")+P("sp")+P("bp")+P("es")+P("ts")+P("pc")+P("dd")+P("cc")+P("in")
local validdimen=amount*unit
lpeg.patterns.validdimen=validdimen
local dimensions={}
@@ -3392,8 +3409,9 @@ function dimensions.__index(tab,key)
end
return 1/d
end
- dimenfactors["ex"]=4*1/65536
- dimenfactors["em"]=10*1/65536
+ dimenfactors["ex"]=4/65536
+ dimenfactors["em"]=10/65536
+ dimenfactors["eu"]=(9176/129)/65536
local known={} setmetatable(known,{ __mode="v" })
function dimen(a)
if a then
@@ -4984,11 +5002,13 @@ end
local files=utilities.files
local openfile=files.open
local closefile=files.close
+local getsize=files.size
local readstring=files.readstring
local readcardinal2=files.readcardinal2le
local readcardinal4=files.readcardinal4le
local setposition=files.setposition
local getposition=files.getposition
+local skipbytes=files.skip
local band=bit32.band
local rshift=bit32.rshift
local lshift=bit32.lshift
@@ -5011,6 +5031,55 @@ local openzipfile,closezipfile,unzipfile,foundzipfile,getziphash,getziplist do
handle=openfile(name,0),
}
end
+ local function update(handle,data)
+ position=data.offset
+ setposition(handle,position)
+ local signature=readstring(handle,4)
+ if signature=="PK\3\4" then
+ local version=readcardinal2(handle)
+ local flag=readcardinal2(handle)
+ local method=readcardinal2(handle)
+ skipbytes(handle,4)
+ local crc32=readcardinal4(handle)
+ local compressed=readcardinal4(handle)
+ local uncompressed=readcardinal4(handle)
+ local namelength=readcardinal2(handle)
+ local extralength=readcardinal2(handle)
+ local filename=readstring(handle,namelength)
+ local descriptor=band(flag,8)~=0
+ local encrypted=band(flag,1)~=0
+ local acceptable=method==0 or method==8
+ local skipped=0
+ local size=0
+ if encrypted then
+ size=readcardinal2(handle)
+ skipbytes(handle,size)
+ skipped=skipped+size+2
+ skipbytes(8)
+ skipped=skipped+8
+ size=readcardinal2(handle)
+ skipbytes(handle,size)
+ skipped=skipped+size+2
+ size=readcardinal4(handle)
+ skipbytes(handle,size)
+ skipped=skipped+size+4
+ size=readcardinal2(handle)
+ skipbytes(handle,size)
+ skipped=skipped+size+2
+ end
+ if acceptable then
+ if filename~=data.filename then
+ else
+ position=position+30+namelength+extralength+skipped
+ data.position=position
+ return position
+ end
+ else
+ end
+ end
+ data.position=false
+ return false
+ end
local function collect(z)
if not z.list then
local list={}
@@ -5018,72 +5087,68 @@ local openzipfile,closezipfile,unzipfile,foundzipfile,getziphash,getziplist do
local position=0
local index=0
local handle=z.handle
- while true do
- setposition(handle,position)
- local signature=readstring(handle,4)
- if signature=="PK\3\4" then
- local version=readcardinal2(handle)
- local flag=readcardinal2(handle)
- local method=readcardinal2(handle)
- local filetime=readcardinal2(handle)
- local filedate=readcardinal2(handle)
- local crc32=readcardinal4(handle)
- local compressed=readcardinal4(handle)
- local uncompressed=readcardinal4(handle)
- local namelength=readcardinal2(handle)
- local extralength=readcardinal2(handle)
- local filename=readstring(handle,namelength)
- local descriptor=band(flag,8)~=0
- local encrypted=band(flag,1)~=0
- local acceptable=method==0 or method==8
- local skipped=0
- local size=0
- if encrypted then
- size=readcardinal2(handle)
- skipbytes(size)
- skipped=skipped+size+2
- skipbytes(8)
- skipped=skipped+8
- size=readcardinal2(handle)
- skipbytes(size)
- skipped=skipped+size+2
- size=readcardinal4(handle)
- skipbytes(size)
- skipped=skipped+size+4
- size=readcardinal2(handle)
- skipbytes(size)
- skipped=skipped+size+2
- end
- position=position+30+namelength+extralength+skipped
- if descriptor then
- setposition(handle,position+compressed)
- crc32=readcardinal4(handle)
- compressed=readcardinal4(handle)
- uncompressed=readcardinal4(handle)
- end
- if acceptable then
- index=index+1
- local data={
- filename=filename,
- index=index,
- position=position,
- method=method,
- compressed=compressed,
- uncompressed=uncompressed,
- crc32=crc32,
- encrypted=encrypted,
- }
- hash[filename]=data
- list[index]=data
- else
+ local size=getsize(handle)
+ for i=size-4,size-64*1024,-1 do
+ setposition(handle,i)
+ local enddirsignature=readcardinal4(handle)
+ if enddirsignature==0x06054B50 then
+ local thisdisknumber=readcardinal2(handle)
+ local centraldisknumber=readcardinal2(handle)
+ local thisnofentries=readcardinal2(handle)
+ local totalnofentries=readcardinal2(handle)
+ local centralsize=readcardinal4(handle)
+ local centraloffset=readcardinal4(handle)
+ local commentlength=readcardinal2(handle)
+ local comment=readstring(handle,length)
+ if size-i>=22 then
+ if thisdisknumber==centraldisknumber then
+ setposition(handle,centraloffset)
+ while true do
+ if readcardinal4(handle)==0x02014B50 then
+ skipbytes(handle,4)
+ local flag=readcardinal2(handle)
+ local method=readcardinal2(handle)
+ skipbytes(handle,4)
+ local crc32=readcardinal4(handle)
+ local compressed=readcardinal4(handle)
+ local uncompressed=readcardinal4(handle)
+ local namelength=readcardinal2(handle)
+ local extralength=readcardinal2(handle)
+ local commentlength=readcardinal2(handle)
+ skipbytes(handle,8)
+ local headeroffset=readcardinal4(handle)
+ local filename=readstring(handle,namelength)
+ skipbytes(handle,extralength+commentlength)
+ local descriptor=band(flag,8)~=0
+ local encrypted=band(flag,1)~=0
+ local acceptable=method==0 or method==8
+ if acceptable then
+ index=index+1
+ local data={
+ filename=filename,
+ index=index,
+ position=nil,
+ method=method,
+ compressed=compressed,
+ uncompressed=uncompressed,
+ crc32=crc32,
+ encrypted=encrypted,
+ offset=headeroffset,
+ }
+ hash[filename]=data
+ list[index]=data
+ end
+ else
+ break
+ end
+ end
+ end
+ break
end
- position=position+compressed
- else
- break
end
- z.list=list
- z.hash=hash
end
+ z.list=list
+ z.hash=hash
end
end
function getziplist(z)
@@ -5122,7 +5187,10 @@ local openzipfile,closezipfile,unzipfile,foundzipfile,getziphash,getziplist do
local handle=z.handle
local position=data.position
local compressed=data.compressed
- if compressed>0 then
+ if position==nil then
+ position=update(handle,data)
+ end
+ if position and compressed>0 then
setposition(handle,position)
local result=readstring(handle,compressed)
if data.method==8 then
@@ -5333,8 +5401,10 @@ if xzip then
closezip(zipf)
end
end
- local function unzipdir(zipname,path,verbose)
+ local function unzipdir(zipname,path,verbose,collect,validate)
if type(zipname)=="table" then
+ validate=zipname.validate
+ collect=zipname.collect
verbose=zipname.verbose
path=zipname.path
zipname=zipname.zipname
@@ -5355,34 +5425,47 @@ if xzip then
local done=0
local steps=verbose=="steps"
local time=steps and osclock()
+ if collect then
+ collect={}
+ else
+ collect=false
+ end
for i=1,count do
local l=list[i]
local n=l.filename
- local d=unzipfile(z,n)
- if d then
- local p=filejoin(path,n)
- if mkdirs(dirname(p)) then
- if steps then
- total=total+#d
- done=done+1
- if done>=step then
- done=0
- logwriter(format("%4i files of %4i done, %10i bytes, %0.3f seconds",i,count,total,osclock()-time))
+ if not validate or validate(n) then
+ local d=unzipfile(z,n)
+ if d then
+ local p=filejoin(path,n)
+ if mkdirs(dirname(p)) then
+ if steps then
+ total=total+#d
+ done=done+1
+ if done>=step then
+ done=0
+ logwriter(format("%4i files of %4i done, %10i bytes, %0.3f seconds",i,count,total,osclock()-time))
+ end
+ elseif verbose then
+ logwriter(n)
+ end
+ savedata(p,d)
+ if collect then
+ collect[#collect+1]=p
end
- elseif verbose then
- logwriter(n)
end
- savedata(p,d)
+ else
+ logwriter(format("problem with file %s",n))
end
else
- logwriter(format("problem with file %s",n))
end
end
if steps then
logwriter(format("%4i files of %4i done, %10i bytes, %0.3f seconds",count,count,total,osclock()-time))
end
closezipfile(z)
- return true
+ if collect then
+ return collect
+ end
else
closezipfile(z)
end
diff --git a/macros/luatex/generic/lualibs/lualibs-file.lua b/macros/luatex/generic/lualibs/lualibs-file.lua
index 9f8fd65483..70f8188dc1 100644
--- a/macros/luatex/generic/lualibs/lualibs-file.lua
+++ b/macros/luatex/generic/lualibs/lualibs-file.lua
@@ -741,8 +741,24 @@ end
-- not used in context but was in luatex once:
-local symlinkattributes = lfs.symlinkattributes
+do
+
+ local symlinktarget = lfs.symlinktarget -- luametatex (always returns string)
+ local symlinkattributes = lfs.symlinkattributes -- luatex (can return nil)
+
+ 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
-function lfs.readlink(name)
- return symlinkattributes(name,"target") or nil
end
diff --git a/macros/luatex/generic/lualibs/lualibs-string.lua b/macros/luatex/generic/lualibs/lualibs-string.lua
index 1dee85e289..476820a175 100644
--- a/macros/luatex/generic/lualibs/lualibs-string.lua
+++ b/macros/luatex/generic/lualibs/lualibs-string.lua
@@ -7,7 +7,7 @@ if not modules then modules = { } end modules ['l-string'] = {
}
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
@@ -52,10 +52,26 @@ function string.quoted(str)
return format("%q",str) -- always double quote
end
-function string.count(str,pattern) -- variant 3
+-- function string.count(str,pattern) -- variant 3
+-- local n = 0
+-- for _ in gmatch(str,pattern) do -- not for utf
+-- n = n + 1
+-- end
+-- return n
+-- end
+
+function string.count(str,pattern)
local n = 0
- for _ in gmatch(str,pattern) do -- not for utf
- 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
diff --git a/macros/luatex/generic/lualibs/lualibs-unicode.lua b/macros/luatex/generic/lualibs/lualibs-unicode.lua
index 5d9a7149bd..f98686c6b6 100644
--- a/macros/luatex/generic/lualibs/lualibs-unicode.lua
+++ b/macros/luatex/generic/lualibs/lualibs-unicode.lua
@@ -32,7 +32,6 @@ if not modules then modules = { } end modules ['l-unicode'] = {
-- dump, find, format, gfind, gmatch, gsub, lower, match, rep, reverse, upper
utf = utf or { }
--- unicode = nil
if not string.utfcharacters then
diff --git a/macros/luatex/generic/lualibs/lualibs-util-dim.lua b/macros/luatex/generic/lualibs/lualibs-util-dim.lua
index bb9eca9668..6462f3e492 100644
--- a/macros/luatex/generic/lualibs/lualibs-util-dim.lua
+++ b/macros/luatex/generic/lualibs/lualibs-util-dim.lua
@@ -6,14 +6,10 @@ if not modules then modules = { } end modules ['util-dim'] = {
license = "see context related readme files"
}
---[[ldx--
-<p>Internally <l n='luatex'/> work with scaled point, which are
-represented by integers. However, in practice, at east at the
-<l n='tex'/> end we work with more generic units like points (pt). Going
-from scaled points (numbers) to one of those units can be
-done by using the conversion factors collected in the following
-table.</p>
---ldx]]--
+-- Internally LuaTeX work with scaled point, which are represented by integers.
+-- However, in practice, at east at the TeX end we work with more generic units like
+-- points (pt). Going from scaled points (numbers) to one of those units can be done
+-- by using the conversion factors collected in the following table.
local format, match, gsub, type, setmetatable = string.format, string.match, string.gsub, type, setmetatable
local P, S, R, Cc, C, lpegmatch = lpeg.P, lpeg.S, lpeg.R, lpeg.Cc, lpeg.C, lpeg.match
@@ -45,7 +41,9 @@ local dimenfactors = allocate {
["dd"] = ( 1157/ 1238)/65536,
["cc"] = ( 1157/14856)/65536,
-- ["nd"] = (20320/21681)/65536,
- -- ["nc"] = ( 5080/65043)/65536
+ -- ["nc"] = ( 5080/65043)/65536,
+ ["es"] = ( 9176/ 129)/65536,
+ ["ts"] = ( 4588/ 645)/65536,
}
-- print(table.serialize(dimenfactors))
@@ -86,10 +84,8 @@ local dimenfactors = allocate {
-- ["sp"]=1,
-- }
---[[ldx--
-<p>A conversion function that takes a number, unit (string) and optional
-format (string) is implemented using this table.</p>
---ldx]]--
+-- A conversion function that takes a number, unit (string) and optional format
+-- (string) is implemented using this table.
local f_none = formatters["%s%s"]
local f_true = formatters["%0.5F%s"]
@@ -110,9 +106,7 @@ local function numbertodimen(n,unit,fmt) -- will be redefined later !
end
end
---[[ldx--
-<p>We collect a bunch of converters in the <type>number</type> namespace.</p>
---ldx]]--
+-- We collect a bunch of converters in the 'number' namespace.
number.maxdimen = 1073741823
number.todimen = numbertodimen
@@ -122,7 +116,7 @@ function number.topoints (n,fmt) return numbertodimen(n,"pt",fmt) end
function number.toinches (n,fmt) return numbertodimen(n,"in",fmt) end
function number.tocentimeters (n,fmt) return numbertodimen(n,"cm",fmt) end
function number.tomillimeters (n,fmt) return numbertodimen(n,"mm",fmt) end
-function number.toscaledpoints(n,fmt) return numbertodimen(n,"sp",fmt) end
+-------- number.toscaledpoints(n,fmt) return numbertodimen(n,"sp",fmt) end
function number.toscaledpoints(n) return n .. "sp" end
function number.tobasepoints (n,fmt) return numbertodimen(n,"bp",fmt) end
function number.topicas (n,fmt) return numbertodimen(n "pc",fmt) end
@@ -130,14 +124,13 @@ function number.todidots (n,fmt) return numbertodimen(n,"dd",fmt) end
function number.tociceros (n,fmt) return numbertodimen(n,"cc",fmt) end
-------- number.tonewdidots (n,fmt) return numbertodimen(n,"nd",fmt) end
-------- number.tonewciceros (n,fmt) return numbertodimen(n,"nc",fmt) end
+function number.toediths (n,fmt) return numbertodimen(n,"es",fmt) end
+function number.totoves (n,fmt) return numbertodimen(n,"ts",fmt) end
---[[ldx--
-<p>More interesting it to implement a (sort of) dimen datatype, one
-that permits calculations too. First we define a function that
-converts a string to scaledpoints. We use <l n='lpeg'/>. We capture
-a number and optionally a unit. When no unit is given a constant
-capture takes place.</p>
---ldx]]--
+-- More interesting it to implement a (sort of) dimen datatype, one that permits
+-- calculations too. First we define a function that converts a string to
+-- scaledpoints. We use LPEG. We capture a number and optionally a unit. When no
+-- unit is given a constant capture takes place.
local amount = (S("+-")^0 * R("09")^0 * P(".")^0 * R("09")^0) + Cc("0")
local unit = R("az")^1 + P("%")
@@ -152,21 +145,16 @@ function number.splitdimen(str)
return lpegmatch(splitter,str)
end
---[[ldx--
-<p>We use a metatable to intercept errors. When no key is found in
-the table with factors, the metatable will be consulted for an
-alternative index function.</p>
---ldx]]--
+-- We use a metatable to intercept errors. When no key is found in the table with
+-- factors, the metatable will be consulted for an alternative index function.
setmetatableindex(dimenfactors, function(t,s)
-- error("wrong dimension: " .. (s or "?")) -- better a message
return false
end)
---[[ldx--
-<p>We redefine the following function later on, so we comment it
-here (which saves us bytecodes.</p>
---ldx]]--
+-- We redefine the following function later on, so we comment it here (which saves
+-- us bytecodes.
-- function string.todimen(str)
-- if type(str) == "number" then
@@ -182,44 +170,38 @@ here (which saves us bytecodes.</p>
local stringtodimen -- assigned later (commenting saves bytecode)
local amount = S("+-")^0 * R("09")^0 * S(".,")^0 * R("09")^0
-local unit = P("pt") + P("cm") + P("mm") + P("sp") + P("bp") + P("in") +
- P("pc") + P("dd") + P("cc") + P("nd") + P("nc")
+local unit = P("pt") + P("cm") + P("mm") + P("sp") + P("bp")
+ + P("es") + P("ts") + P("pc") + P("dd") + P("cc")
+ + P("in")
+ -- + P("nd") + P("nc")
local validdimen = amount * unit
lpeg.patterns.validdimen = validdimen
---[[ldx--
-<p>This converter accepts calls like:</p>
-
-<typing>
-string.todimen("10")
-string.todimen(".10")
-string.todimen("10.0")
-string.todimen("10.0pt")
-string.todimen("10pt")
-string.todimen("10.0pt")
-</typing>
-
-<p>With this in place, we can now implement a proper datatype for dimensions, one
-that permits us to do this:</p>
-
-<typing>
-s = dimen "10pt" + dimen "20pt" + dimen "200pt"
- - dimen "100sp" / 10 + "20pt" + "0pt"
-</typing>
-
-<p>We create a local metatable for this new type:</p>
---ldx]]--
+-- This converter accepts calls like:
+--
+-- string.todimen("10")
+-- string.todimen(".10")
+-- string.todimen("10.0")
+-- string.todimen("10.0pt")
+-- string.todimen("10pt")
+-- string.todimen("10.0pt")
+--
+-- With this in place, we can now implement a proper datatype for dimensions, one
+-- that permits us to do this:
+--
+-- s = dimen "10pt" + dimen "20pt" + dimen "200pt"
+-- - dimen "100sp" / 10 + "20pt" + "0pt"
+--
+-- We create a local metatable for this new type:
local dimensions = { }
---[[ldx--
-<p>The main (and globally) visible representation of a dimen is defined next: it is
-a one-element table. The unit that is returned from the match is normally a number
-(one of the previously defined factors) but we also accept functions. Later we will
-see why. This function is redefined later.</p>
---ldx]]--
+-- The main (and globally) visible representation of a dimen is defined next: it is
+-- a one-element table. The unit that is returned from the match is normally a
+-- number (one of the previously defined factors) but we also accept functions.
+-- Later we will see why. This function is redefined later.
-- function dimen(a)
-- if a then
@@ -241,11 +223,9 @@ see why. This function is redefined later.</p>
-- end
-- end
---[[ldx--
-<p>This function return a small hash with a metatable attached. It is
-through this metatable that we can do the calculations. We could have
-shared some of the code but for reasons of speed we don't.</p>
---ldx]]--
+-- This function return a small hash with a metatable attached. It is through this
+-- metatable that we can do the calculations. We could have shared some of the code
+-- but for reasons of speed we don't.
function dimensions.__add(a, b)
local ta, tb = type(a), type(b)
@@ -281,20 +261,16 @@ function dimensions.__unm(a)
return setmetatable({ - a }, dimensions)
end
---[[ldx--
-<p>It makes no sense to implement the power and modulo function but
-the next two do make sense because they permits is code like:</p>
-
-<typing>
-local a, b = dimen "10pt", dimen "11pt"
-...
-if a > b then
- ...
-end
-</typing>
---ldx]]--
-
--- makes no sense: dimensions.__pow and dimensions.__mod
+-- It makes no sense to implement the power and modulo function but
+-- the next two do make sense because they permits is code like:
+--
+-- local a, b = dimen "10pt", dimen "11pt"
+-- ...
+-- if a > b then
+-- ...
+-- end
+--
+-- This also makes no sense: dimensions.__pow and dimensions.__mod.
function dimensions.__lt(a, b)
return a[1] < b[1]
@@ -304,24 +280,17 @@ function dimensions.__eq(a, b)
return a[1] == b[1]
end
---[[ldx--
-<p>We also need to provide a function for conversion to string (so that
-we can print dimensions). We print them as points, just like <l n='tex'/>.</p>
---ldx]]--
+-- We also need to provide a function for conversion to string (so that we can print
+-- dimensions). We print them as points, just like TeX.
function dimensions.__tostring(a)
return a[1]/65536 .. "pt" -- instead of todimen(a[1])
end
---[[ldx--
-<p>Since it does not take much code, we also provide a way to access
-a few accessors</p>
-
-<typing>
-print(dimen().pt)
-print(dimen().sp)
-</typing>
---ldx]]--
+-- Since it does not take much code, we also provide a way to access a few accessors
+--
+-- print(dimen().pt)
+-- print(dimen().sp)
function dimensions.__index(tab,key)
local d = dimenfactors[key]
@@ -332,41 +301,34 @@ function dimensions.__index(tab,key)
return 1/d
end
---[[ldx--
-<p>In the converter from string to dimension we support functions as
-factors. This is because in <l n='tex'/> we have a few more units:
-<type>ex</type> and <type>em</type>. These are not constant factors but
-depend on the current font. They are not defined by default, but need
-an explicit function call. This is because at the moment that this code
-is loaded, the relevant tables that hold the functions needed may not
-yet be available.</p>
---ldx]]--
-
- dimenfactors["ex"] = 4 * 1/65536 -- 4pt
- dimenfactors["em"] = 10 * 1/65536 -- 10pt
--- dimenfactors["%"] = 4 * 1/65536 -- 400pt/100
-
---[[ldx--
-<p>The previous code is rather efficient (also thanks to <l n='lpeg'/>) but we
-can speed it up by caching converted dimensions. On my machine (2008) the following
-loop takes about 25.5 seconds.</p>
-
-<typing>
-for i=1,1000000 do
- local s = dimen "10pt" + dimen "20pt" + dimen "200pt"
- - dimen "100sp" / 10 + "20pt" + "0pt"
-end
-</typing>
-
-<p>When we cache converted strings this becomes 16.3 seconds. In order not
-to waste too much memory on it, we tag the values of the cache as being
-week which mean that the garbage collector will collect them in a next
-sweep. This means that in most cases the speed up is mostly affecting the
-current couple of calculations and as such the speed penalty is small.</p>
-
-<p>We redefine two previous defined functions that can benefit from
-this:</p>
---ldx]]--
+-- In the converter from string to dimension we support functions as factors. This
+-- is because in TeX we have a few more units: 'ex' and 'em'. These are not constant
+-- factors but depend on the current font. They are not defined by default, but need
+-- an explicit function call. This is because at the moment that this code is
+-- loaded, the relevant tables that hold the functions needed may not yet be
+-- available.
+
+ dimenfactors["ex"] = 4 /65536 -- 4pt
+ dimenfactors["em"] = 10 /65536 -- 10pt
+-- dimenfactors["%"] = 4 /65536 -- 400pt/100
+ dimenfactors["eu"] = (9176/129)/65536 -- 1es
+
+-- The previous code is rather efficient (also thanks to LPEG) but we can speed it
+-- up by caching converted dimensions. On my machine (2008) the following loop takes
+-- about 25.5 seconds.
+--
+-- for i=1,1000000 do
+-- local s = dimen "10pt" + dimen "20pt" + dimen "200pt"
+-- - dimen "100sp" / 10 + "20pt" + "0pt"
+-- end
+--
+-- When we cache converted strings this becomes 16.3 seconds. In order not to waste
+-- too much memory on it, we tag the values of the cache as being week which mean
+-- that the garbage collector will collect them in a next sweep. This means that in
+-- most cases the speed up is mostly affecting the current couple of calculations
+-- and as such the speed penalty is small.
+--
+-- We redefine two previous defined functions that can benefit from this:
local known = { } setmetatable(known, { __mode = "v" })
@@ -436,14 +398,10 @@ function number.toscaled(d)
return format("%0.5f",d/0x10000) -- 2^16
end
---[[ldx--
-<p>In a similar fashion we can define a glue datatype. In that case we
-probably use a hash instead of a one-element table.</p>
---ldx]]--
-
---[[ldx--
-<p>Goodie:s</p>
---ldx]]--
+-- In a similar fashion we can define a glue datatype. In that case we probably use
+-- a hash instead of a one-element table.
+--
+-- A goodie:
function number.percent(n,d) -- will be cleaned up once luatex 0.30 is out
d = d or texget("hsize")
diff --git a/macros/luatex/generic/lualibs/lualibs-util-prs.lua b/macros/luatex/generic/lualibs/lualibs-util-prs.lua
index 635b610e07..a527555db7 100644
--- a/macros/luatex/generic/lualibs/lualibs-util-prs.lua
+++ b/macros/luatex/generic/lualibs/lualibs-util-prs.lua
@@ -264,8 +264,13 @@ function parsers.groupedsplitat(symbol,withaction)
if not pattern then
local symbols = S(symbol)
local separator = space^0 * symbols * space^0
- local value = lbrace * C((nobrace + nestedbraces)^0) * rbrace
- + C((nestedbraces + (1-(space^0*(symbols+P(-1)))))^0)
+ local value =
+ lbrace
+ * C((nobrace + nestedbraces)^0)
+ -- * rbrace
+ * (rbrace * (#symbols + P(-1))) -- new per 2023-03-11
+ +
+ C((nestedbraces + (1-(space^0*(symbols+P(-1)))))^0)
if withaction then
local withvalue = Carg(1) * value / function(f,s) return f(s) end
pattern = spaces * withvalue * (separator*withvalue)^0
@@ -378,9 +383,25 @@ hashes.settings_to_set = table.setmetatableindex(function(t,k) -- experiment, n
return v
end)
+function parsers.settings_to_set(str)
+ return str and lpegmatch(pattern,str) or { }
+end
+
+local pattern = Ct((C((1-S(", "))^1) * S(", ")^0)^1)
+
+hashes.settings_to_list = table.setmetatableindex(function(t,k) -- experiment, not public
+ local v = k and lpegmatch(pattern,k) or { }
+ t[k] = v
+ return v
+end)
+
+-- inspect(hashes.settings_to_set["a,b, c, d"])
+-- inspect(hashes.settings_to_list["a,b, c, d"])
+
-- as we use a next, we are not sure when the gc kicks in
-getmetatable(hashes.settings_to_set).__mode = "kv" -- could be an option (maybe sharing makes sense)
+getmetatable(hashes.settings_to_set ).__mode = "kv" -- could be an option (maybe sharing makes sense)
+getmetatable(hashes.settings_to_list).__mode = "kv" -- could be an option (maybe sharing makes sense)
function parsers.simple_hash_to_string(h, separator)
local t = { }
diff --git a/macros/luatex/generic/lualibs/lualibs-util-sac.lua b/macros/luatex/generic/lualibs/lualibs-util-sac.lua
index 36daef8167..9d2e8356da 100644
--- a/macros/luatex/generic/lualibs/lualibs-util-sac.lua
+++ b/macros/luatex/generic/lualibs/lualibs-util-sac.lua
@@ -551,14 +551,14 @@ if bit32 and not streams.tocardinal1 then
local char = string.char
streams.tocardinal1 = char
- function streams.tocardinal2(n) return char(extract( 8,8),extract( 0,8)) end
- function streams.tocardinal3(n) return char(extract(16,8),extract( 8,8),extract(0,8)) end
- function streams.tocardinal4(n) return char(extract(24,8),extract(16,8),extract(8,8),extract(0,8)) end
+ function streams.tocardinal2(n) return char(extract(n, 8,8),extract(n, 0,8)) end
+ function streams.tocardinal3(n) return char(extract(n,16,8),extract(n, 8,8),extract(n,0,8)) end
+ function streams.tocardinal4(n) return char(extract(n,24,8),extract(n,16,8),extract(n,8,8),extract(n,0,8)) end
streams.tocardinal1le = char
- function streams.tocardinal2le(n) return char(extract(0,8),extract(8,8)) end
- function streams.tocardinal3le(n) return char(extract(0,8),extract(8,8),extract(16,8)) end
- function streams.tocardinal4le(n) return char(extract(0,8),extract(8,8),extract(16,8),extract(24,8)) end
+ function streams.tocardinal2le(n) return char(extract(n,0,8),extract(n,8,8)) end
+ function streams.tocardinal3le(n) return char(extract(n,0,8),extract(n,8,8),extract(n,16,8)) end
+ function streams.tocardinal4le(n) return char(extract(n,0,8),extract(n,8,8),extract(n,16,8),extract(n,24,8)) end
end
diff --git a/macros/luatex/generic/lualibs/lualibs-util-str.lua b/macros/luatex/generic/lualibs/lualibs-util-str.lua
index b5c721a41d..a9150b886a 100644
--- a/macros/luatex/generic/lualibs/lualibs-util-str.lua
+++ b/macros/luatex/generic/lualibs/lualibs-util-str.lua
@@ -269,6 +269,7 @@ local p_prune_intospace = Cs ( noleading * ( notrailing + intospace + 1
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 )
-- function striplines(str,prune,collapse,noempty)
-- if prune then
@@ -298,6 +299,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,
}
@@ -313,6 +315,9 @@ function strings.collapse(str) -- maybe also in strings
return str and lpegmatch(p_prune_intospace,str) or str
end
+-- local s = "\naa\n\naa\na a\n\n"
+-- print("["..strings.striplines(s,"collapse all").."]")
+
-- also see: string.collapsespaces
strings.striplong = strings.striplines -- for old times sake
diff --git a/macros/luatex/generic/lualibs/lualibs-util-tab.lua b/macros/luatex/generic/lualibs/lualibs-util-tab.lua
index 64fa1af4fb..58ca3bcb10 100644
--- a/macros/luatex/generic/lualibs/lualibs-util-tab.lua
+++ b/macros/luatex/generic/lualibs/lualibs-util-tab.lua
@@ -432,7 +432,7 @@ else
local v = t[0]
if v then
m = m + 1
- r[m] = "[0]='"
+ r[m] = "[0]="
if type(v) == "table" then
fastserialize(v)
else
diff --git a/macros/luatex/generic/lualibs/lualibs-util-zip.lua b/macros/luatex/generic/lualibs/lualibs-util-zip.lua
index bd8fdf287f..194eb56972 100644
--- a/macros/luatex/generic/lualibs/lualibs-util-zip.lua
+++ b/macros/luatex/generic/lualibs/lualibs-util-zip.lua
@@ -34,11 +34,13 @@ end
local files = utilities.files
local openfile = files.open
local closefile = files.close
+local getsize = files.size
local readstring = files.readstring
local readcardinal2 = files.readcardinal2le
local readcardinal4 = files.readcardinal4le
local setposition = files.setposition
local getposition = files.getposition
+local skipbytes = files.skip
local band = bit32.band
local rshift = bit32.rshift
@@ -69,6 +71,158 @@ local openzipfile, closezipfile, unzipfile, foundzipfile, getziphash, getziplist
}
end
+ -- https://pkware.cachefly.net/webdocs/casestudies/APPNOTE.TXT
+
+-- local function collect(z)
+-- if not z.list then
+-- local list = { }
+-- local hash = { }
+-- local position = 0
+-- local index = 0
+-- local handle = z.handle
+-- while true do
+-- setposition(handle,position)
+-- local signature = readstring(handle,4)
+-- if signature == "PK\3\4" then
+-- -- [local file header 1]
+-- -- [encryption header 1]
+-- -- [file data 1]
+-- -- [data descriptor 1]
+-- local version = readcardinal2(handle)
+-- local flag = readcardinal2(handle)
+-- local method = readcardinal2(handle)
+-- local filetime = readcardinal2(handle)
+-- local filedate = readcardinal2(handle)
+-- local crc32 = readcardinal4(handle)
+-- local compressed = readcardinal4(handle)
+-- local uncompressed = readcardinal4(handle)
+-- local namelength = readcardinal2(handle)
+-- local extralength = readcardinal2(handle)
+-- local filename = readstring(handle,namelength)
+-- local descriptor = band(flag,8) ~= 0
+-- local encrypted = band(flag,1) ~= 0
+-- local acceptable = method == 0 or method == 8
+-- -- 30 bytes of header including the signature
+-- local skipped = 0
+-- local size = 0
+-- if encrypted then
+-- size = readcardinal2(handle)
+-- skipbytes(handle,size)
+-- skipped = skipped + size + 2
+-- skipbytes(8)
+-- skipped = skipped + 8
+-- size = readcardinal2(handle)
+-- skipbytes(handle,size)
+-- skipped = skipped + size + 2
+-- size = readcardinal4(handle)
+-- skipbytes(handle,size)
+-- skipped = skipped + size + 4
+-- size = readcardinal2(handle)
+-- skipbytes(handle,size)
+-- skipped = skipped + size + 2
+-- end
+-- position = position + 30 + namelength + extralength + skipped
+-- -- if descriptor then
+-- -- -- where is this one located
+-- -- setposition(handle,position + compressed)
+-- -- crc32 = readcardinal4(handle)
+-- -- compressed = readcardinal4(handle)
+-- -- uncompressed = readcardinal4(handle)
+-- -- end
+-- if acceptable then
+-- index = index + 1
+-- local data = {
+-- filename = filename,
+-- index = index,
+-- position = position,
+-- method = method,
+-- compressed = compressed,
+-- uncompressed = uncompressed,
+-- crc32 = crc32,
+-- encrypted = encrypted,
+-- }
+-- hash[filename] = data
+-- list[index] = data
+-- else
+-- -- maybe a warning when encrypted
+-- end
+-- position = position + compressed
+-- else
+-- break
+-- end
+-- z.list = list
+-- z.hash = hash
+-- end
+-- end
+-- end
+-- end
+
+-- end
+-- end
+
+ local function update(handle,data)
+ position = data.offset
+ setposition(handle,position)
+ local signature = readstring(handle,4)
+ if signature == "PK\3\4" then -- 0x04034B50
+ -- [local file header 1]
+ -- [encryption header 1]
+ -- [file data 1]
+ -- [data descriptor 1]
+ local version = readcardinal2(handle)
+ local flag = readcardinal2(handle)
+ local method = readcardinal2(handle)
+ skipbytes(handle,4)
+ ----- filetime = readcardinal2(handle)
+ ----- filedate = readcardinal2(handle)
+ local crc32 = readcardinal4(handle)
+ local compressed = readcardinal4(handle)
+ local uncompressed = readcardinal4(handle)
+ local namelength = readcardinal2(handle)
+ local extralength = readcardinal2(handle)
+ local filename = readstring(handle,namelength)
+ local descriptor = band(flag,8) ~= 0
+ local encrypted = band(flag,1) ~= 0
+ local acceptable = method == 0 or method == 8
+ -- 30 bytes of header including the signature
+ local skipped = 0
+ local size = 0
+ if encrypted then
+ size = readcardinal2(handle)
+ skipbytes(handle,size)
+ skipped = skipped + size + 2
+ skipbytes(8)
+ skipped = skipped + 8
+ size = readcardinal2(handle)
+ skipbytes(handle,size)
+ skipped = skipped + size + 2
+ size = readcardinal4(handle)
+ skipbytes(handle,size)
+ skipped = skipped + size + 4
+ size = readcardinal2(handle)
+ skipbytes(handle,size)
+ skipped = skipped + size + 2
+ end
+ if acceptable then
+ if filename ~= data.filename then
+ -- elseif method ~= data.method then
+ -- elseif encrypted ~= data.encrypted then
+ -- elseif crc32 ~= 0 and crc32 ~= data.crc32 then
+ -- elseif uncompressed ~= 0 and uncompressed ~= data.uncompressed then
+ -- elseif compressed ~= 0 and compressed ~= data.compressed then
+ else
+ position = position + 30 + namelength + extralength + skipped
+ data.position = position
+ return position
+ end
+ else
+ -- maybe a warning when encrypted
+ end
+ end
+ data.position = false
+ return false
+ end
+
local function collect(z)
if not z.list then
local list = { }
@@ -76,78 +230,88 @@ local openzipfile, closezipfile, unzipfile, foundzipfile, getziphash, getziplist
local position = 0
local index = 0
local handle = z.handle
- while true do
- setposition(handle,position)
- local signature = readstring(handle,4)
- if signature == "PK\3\4" then
- -- [local file header 1]
- -- [encryption header 1]
- -- [file data 1]
- -- [data descriptor 1]
- local version = readcardinal2(handle)
- local flag = readcardinal2(handle)
- local method = readcardinal2(handle)
- local filetime = readcardinal2(handle)
- local filedate = readcardinal2(handle)
- local crc32 = readcardinal4(handle)
- local compressed = readcardinal4(handle)
- local uncompressed = readcardinal4(handle)
- local namelength = readcardinal2(handle)
- local extralength = readcardinal2(handle)
- local filename = readstring(handle,namelength)
- local descriptor = band(flag,8) ~= 0
- local encrypted = band(flag,1) ~= 0
- local acceptable = method == 0 or method == 8
- -- 30 bytes of header including the signature
- local skipped = 0
- local size = 0
- if encrypted then
- size = readcardinal2(handle)
- skipbytes(size)
- skipped = skipped + size + 2
- skipbytes(8)
- skipped = skipped + 8
- size = readcardinal2(handle)
- skipbytes(size)
- skipped = skipped + size + 2
- size = readcardinal4(handle)
- skipbytes(size)
- skipped = skipped + size + 4
- size = readcardinal2(handle)
- skipbytes(size)
- skipped = skipped + size + 2
- end
- position = position + 30 + namelength + extralength + skipped
- if descriptor then
- setposition(handle,position + compressed)
- crc32 = readcardinal4(handle)
- compressed = readcardinal4(handle)
- uncompressed = readcardinal4(handle)
- end
- if acceptable then
- index = index + 1
- local data = {
- filename = filename,
- index = index,
- position = position,
- method = method,
- compressed = compressed,
- uncompressed = uncompressed,
- crc32 = crc32,
- encrypted = encrypted,
- }
- hash[filename] = data
- list[index] = data
- else
- -- maybe a warning when encrypted
+ local size = getsize(handle)
+ --
+ -- Not all files have the compressed into set so we need to get the directory
+ -- first. We only handle single disk zip files.
+ --
+ for i=size-4,size-64*1024,-1 do
+ setposition(handle,i)
+ local enddirsignature = readcardinal4(handle)
+ if enddirsignature == 0x06054B50 then
+ local thisdisknumber = readcardinal2(handle)
+ local centraldisknumber = readcardinal2(handle)
+ local thisnofentries = readcardinal2(handle)
+ local totalnofentries = readcardinal2(handle)
+ local centralsize = readcardinal4(handle)
+ local centraloffset = readcardinal4(handle)
+ local commentlength = readcardinal2(handle)
+ local comment = readstring(handle,length)
+ if size - i >= 22 then
+ if thisdisknumber == centraldisknumber then
+ setposition(handle,centraloffset)
+ while true do
+ if readcardinal4(handle) == 0x02014B50 then
+ skipbytes(handle,4)
+ ----- versionmadeby = readcardinal2(handle)
+ ----- versionneeded = readcardinal2(handle)
+ local flag = readcardinal2(handle)
+ local method = readcardinal2(handle)
+ skipbytes(handle,4)
+ ----- filetime = readcardinal2(handle)
+ ----- filedate = readcardinal2(handle)
+ local crc32 = readcardinal4(handle)
+ local compressed = readcardinal4(handle)
+ local uncompressed = readcardinal4(handle)
+ local namelength = readcardinal2(handle)
+ local extralength = readcardinal2(handle)
+ local commentlength = readcardinal2(handle)
+ skipbytes(handle,8)
+ ----- disknumber = readcardinal2(handle)
+ ----- intattributes = readcardinal2(handle)
+ ----- extattributes = readcardinal4(handle)
+ local headeroffset = readcardinal4(handle)
+ local filename = readstring(handle,namelength)
+ skipbytes(handle,extralength+commentlength)
+ ----- extradata = readstring(handle,extralength)
+ ----- comment = readstring(handle,commentlength)
+ --
+ local descriptor = band(flag,8) ~= 0
+ local encrypted = band(flag,1) ~= 0
+ local acceptable = method == 0 or method == 8
+ if acceptable then
+ index = index + 1
+ local data = {
+ filename = filename,
+ index = index,
+ position = nil,
+ method = method,
+ compressed = compressed,
+ uncompressed = uncompressed,
+ crc32 = crc32,
+ encrypted = encrypted,
+ offset = headeroffset,
+ }
+ hash[filename] = data
+ list[index] = data
+ end
+ else
+ break
+ end
+ end
+ end
+ break
end
- position = position + compressed
- else
- break
end
- z.list = list
- z.hash = hash
end
+ -- for i=1,index do -- delayed
+ -- local data = list[i]
+ -- if not data.position then
+ -- update(handle,list[i])
+ -- end
+ -- end
+ z.list = list
+ z.hash = hash
end
end
@@ -156,6 +320,7 @@ local openzipfile, closezipfile, unzipfile, foundzipfile, getziphash, getziplist
if not list then
collect(z)
end
+ -- inspect(z.list)
return z.list
end
@@ -193,7 +358,10 @@ local openzipfile, closezipfile, unzipfile, foundzipfile, getziphash, getziplist
local handle = z.handle
local position = data.position
local compressed = data.compressed
- if compressed > 0 then
+ if position == nil then
+ position = update(handle,data)
+ end
+ if position and compressed > 0 then
setposition(handle,position)
local result = readstring(handle,compressed)
if data.method == 8 then
@@ -451,11 +619,13 @@ if xzip then -- flate then do
end
end
- local function unzipdir(zipname,path,verbose)
+ local function unzipdir(zipname,path,verbose,collect,validate)
if type(zipname) == "table" then
- verbose = zipname.verbose
- path = zipname.path
- zipname = zipname.zipname
+ validate = zipname.validate
+ collect = zipname.collect
+ verbose = zipname.verbose
+ path = zipname.path
+ zipname = zipname.zipname
end
if not zipname or zipname == "" then
return
@@ -473,34 +643,49 @@ if xzip then -- flate then do
local done = 0
local steps = verbose == "steps"
local time = steps and osclock()
+ -- local skip = 0
+ if collect then
+ collect = { }
+ else
+ collect = false
+ end
for i=1,count do
local l = list[i]
local n = l.filename
- local d = unzipfile(z,n) -- true for check
- if d then
- local p = filejoin(path,n)
- if mkdirs(dirname(p)) then
- if steps then
- total = total + #d
- done = done + 1
- if done >= step then
- done = 0
- logwriter(format("%4i files of %4i done, %10i bytes, %0.3f seconds",i,count,total,osclock()-time))
+ if not validate or validate(n) then
+ local d = unzipfile(z,n) -- true for check
+ if d then
+ local p = filejoin(path,n)
+ if mkdirs(dirname(p)) then
+ if steps then
+ total = total + #d
+ done = done + 1
+ if done >= step then
+ done = 0
+ logwriter(format("%4i files of %4i done, %10i bytes, %0.3f seconds",i,count,total,osclock()-time))
+ end
+ elseif verbose then
+ logwriter(n)
+ end
+ savedata(p,d)
+ if collect then
+ collect[#collect+1] = p
end
- elseif verbose then
- logwriter(n)
end
- savedata(p,d)
+ else
+ logwriter(format("problem with file %s",n))
end
else
- logwriter(format("problem with file %s",n))
+ -- skip = skip + 1
end
end
if steps then
logwriter(format("%4i files of %4i done, %10i bytes, %0.3f seconds",count,count,total,osclock()-time))
end
closezipfile(z)
- return true
+ if collect then
+ return collect
+ end
else
closezipfile(z)
end
diff --git a/macros/luatex/generic/lualibs/lualibs.dtx b/macros/luatex/generic/lualibs/lualibs.dtx
index ebdba58424..d033500527 100644
--- a/macros/luatex/generic/lualibs/lualibs.dtx
+++ b/macros/luatex/generic/lualibs/lualibs.dtx
@@ -37,7 +37,7 @@
\input docstrip.tex
\Msg{************************************************************************}
\Msg{* Installation}
-\Msg{* Package: lualibs 2022-10-04 v2.75 Lua additional functions.}
+\Msg{* Package: lualibs 2023-07-13 v2.76 Lua additional functions.}
\Msg{************************************************************************}
\keepsilent
@@ -107,7 +107,7 @@ and lualibs-extended.lua.
%<*driver>
\NeedsTeXFormat{LaTeX2e}
\ProvidesFile{lualibs.drv}
- [2022/10/04 v2.75 Lua Libraries.]
+ [2023/07/13 v2.76 Lua Libraries.]
\documentclass{ltxdoc}
\usepackage{fancyvrb,xspace}
\usepackage[x11names]{xcolor}
@@ -208,7 +208,7 @@ and lualibs-extended.lua.
% \GetFileInfo{lualibs.drv}
%
% \title{The \identifier{lualibs} package}
-% \date{2022/10/04 v2.75}
+% \date{2023/07/13 v2.76}
% \author{Élie Roux · \email{elie.roux@telecom-bretagne.eu}\\
% Philipp Gesang · \email{phg@phi-gamma.net}\\
% The \LaTeX{} Project · \email{https://github.com/latex3/lualibs/}\\
@@ -430,8 +430,8 @@ lualibs = lualibs or { }
lualibs.module_info = {
name = "lualibs",
- version = "2.75", --TAGVERSION
- date = "2022-10-04", --TAGDATE
+ version = "2.76", --TAGVERSION
+ date = "2023-07-13", --TAGDATE
description = "ConTeXt Lua standard libraries.",
author = "Hans Hagen, PRAGMA-ADE, Hasselt NL & Elie Roux & Philipp Gesang",
copyright = "PRAGMA ADE / ConTeXt Development Team",
@@ -584,8 +584,8 @@ local loadmodule = lualibs.loadmodule
local lualibs_basic_module = {
name = "lualibs-basic",
- version = "2.75", --TAGVERSION
- date = "2022-10-04", --TAGDATE
+ version = "2.76", --TAGVERSION
+ date = "2023-07-13", --TAGDATE
description = "ConTeXt Lua libraries -- basic collection.",
author = "Hans Hagen, PRAGMA-ADE, Hasselt NL & Elie Roux & Philipp Gesang",
copyright = "PRAGMA ADE / ConTeXt Development Team",
@@ -665,8 +665,8 @@ lualibs = lualibs or { }
local lualibs_extended_module = {
name = "lualibs-extended",
- version = "2.75", --TAGVERSION
- date = "2022-10-04", --TAGDATE
+ version = "2.76", --TAGVERSION
+ date = "2023-07-13", --TAGDATE
description = "ConTeXt Lua libraries -- extended collection.",
author = "Hans Hagen, PRAGMA-ADE, Hasselt NL & Elie Roux & Philipp Gesang",
copyright = "PRAGMA ADE / ConTeXt Development Team",
diff --git a/macros/luatex/generic/lualibs/lualibs.pdf b/macros/luatex/generic/lualibs/lualibs.pdf
index 175e7e9f01..00ef113d5f 100644
--- a/macros/luatex/generic/lualibs/lualibs.pdf
+++ b/macros/luatex/generic/lualibs/lualibs.pdf
Binary files differ
diff --git a/macros/luatex/generic/luaotfload/NEWS b/macros/luatex/generic/luaotfload/NEWS
index ab31f8c84c..ffc67f5fe1 100644
--- a/macros/luatex/generic/luaotfload/NEWS
+++ b/macros/luatex/generic/luaotfload/NEWS
@@ -1,5 +1,15 @@
Change History
--------------
+2023-08-19 luaotfload v3.24
+
+ * Add experimental configuration option to change default font lookup location
+ precedence.
+ * Support xdvipsk in DVI mode
+ * Preserve soft-hyphens when dropping default ignorable characters
+ * Hash cache keys to better support certain rather unflexible operating
+ systems
+ * Various bug fixes
+
2022-10-03 luaotfload v3.23
* More reliable ToUnicode mappings in Harf mode
diff --git a/macros/luatex/generic/luaotfload/README.md b/macros/luatex/generic/luaotfload/README.md
index c325c4171e..3f84eccafc 100644
--- a/macros/luatex/generic/luaotfload/README.md
+++ b/macros/luatex/generic/luaotfload/README.md
@@ -1,8 +1,8 @@
# The Luaotfload Package
-VERSION: 3.23
+VERSION: 3.24
-DATE: 2022-10-03
+DATE: 2023-08-19
## Description
diff --git a/macros/luatex/generic/luaotfload/filegraph.pdf b/macros/luatex/generic/luaotfload/filegraph.pdf
index 79a370e2b1..950b5fe6b3 100644
--- a/macros/luatex/generic/luaotfload/filegraph.pdf
+++ b/macros/luatex/generic/luaotfload/filegraph.pdf
Binary files differ
diff --git a/macros/luatex/generic/luaotfload/fontloader-2022-10-03.lua b/macros/luatex/generic/luaotfload/fontloader-2023-08-19.lua
index 4df88ec41d..dd457f0221 100644
--- a/macros/luatex/generic/luaotfload/fontloader-2022-10-03.lua
+++ b/macros/luatex/generic/luaotfload/fontloader-2023-08-19.lua
@@ -1,9 +1,9 @@
--[[info-----------------------------------------------------------------------
Luaotfload fontloader package
- build 2022-10-03 20:21:57
+ build 2023-08-19 22:30:03
-------------------------------------------------------------------------------
- © 2022 PRAGMA ADE / ConTeXt Development Team
+ © 2023 PRAGMA ADE / ConTeXt Development Team
The code in this file is provided under the GPL v2.0 license. See the
file COPYING in the Luaotfload repository for details.
@@ -63,7 +63,7 @@
--info]]-----------------------------------------------------------------------
-do --- [luaotfload, fontloader-2022-10-03.lua scope for “data-con” 23a0f5386d46a1c157ae82a373e35fa0] ---
+do --- [luaotfload, fontloader-2023-08-19.lua scope for “data-con” b4ab51aaeab872d86d827f3e216bf05e] ---
if not modules then modules={} end modules ['data-con']={
version=1.100,
@@ -101,7 +101,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
@@ -115,6 +115,7 @@ function containers.define(category,subcategory,version,enabled)
subcategory=subcategory,
storage={},
enabled=enabled,
+ reload=reload,
version=version or math.pi,
trace=false,
}
@@ -137,7 +138,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
@@ -184,10 +186,10 @@ function containers.cleanname(name)
return (gsub(lower(name),"[^%w\128-\255]+","-"))
end
-end --- [luaotfload, fontloader-2022-10-03.lua scope for “data-con”] ---
+end --- [luaotfload, fontloader-2023-08-19.lua scope for “data-con”] ---
-do --- [luaotfload, fontloader-2022-10-03.lua scope for “basics-nod” 1750af43148def9e7a75c6900a96f9dc] ---
+do --- [luaotfload, fontloader-2023-08-19.lua scope for “basics-nod” 1750af43148def9e7a75c6900a96f9dc] ---
if not modules then modules={} end modules ['luatex-fonts-nod']={
version=1.001,
@@ -454,10 +456,10 @@ do
end
end
-end --- [luaotfload, fontloader-2022-10-03.lua scope for “basics-nod”] ---
+end --- [luaotfload, fontloader-2023-08-19.lua scope for “basics-nod”] ---
-do --- [luaotfload, fontloader-2022-10-03.lua scope for “basics-chr” ce4afac7ba19471f3c8f90800839f315] ---
+do --- [luaotfload, fontloader-2023-08-19.lua scope for “basics-chr” ce4afac7ba19471f3c8f90800839f315] ---
characters=characters or {}
@@ -4291,10 +4293,10 @@ characters.indicgroups={
},
}
-end --- [luaotfload, fontloader-2022-10-03.lua scope for “basics-chr”] ---
+end --- [luaotfload, fontloader-2023-08-19.lua scope for “basics-chr”] ---
-do --- [luaotfload, fontloader-2022-10-03.lua scope for “font-ini” 5343de60613adb24cdd7a8d2ee1d153c] ---
+do --- [luaotfload, fontloader-2023-08-19.lua scope for “font-ini” 16b855c98602e4a3e9df39512916a427] ---
if not modules then modules={} end modules ['font-ini']={
version=1.001,
@@ -4335,10 +4337,10 @@ if node and not tex.getfontoffamily then
tex.getfontoffamily=node.family_font
end
-end --- [luaotfload, fontloader-2022-10-03.lua scope for “font-ini”] ---
+end --- [luaotfload, fontloader-2023-08-19.lua scope for “font-ini”] ---
-do --- [luaotfload, fontloader-2022-10-03.lua scope for “fonts-mis” 17e967c9ec4d001deefd43ddf25e98f7] ---
+do --- [luaotfload, fontloader-2023-08-19.lua scope for “fonts-mis” 17e967c9ec4d001deefd43ddf25e98f7] ---
if not modules then modules={} end modules ['luatex-font-mis']={
version=1.001,
@@ -4370,10 +4372,10 @@ function font.each()
return table.sortedhash(fonts.hashes.identifiers)
end
-end --- [luaotfload, fontloader-2022-10-03.lua scope for “fonts-mis”] ---
+end --- [luaotfload, fontloader-2023-08-19.lua scope for “fonts-mis”] ---
-do --- [luaotfload, fontloader-2022-10-03.lua scope for “font-con” 724e5dd14aec2d4d189f8619898004cf] ---
+do --- [luaotfload, fontloader-2023-08-19.lua scope for “font-con” bdbaaa361308c9ccc0a7dac0bf6c17ec] ---
if not modules then modules={} end modules ['font-con']={
version=1.001,
@@ -4660,19 +4662,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
@@ -5741,10 +5733,10 @@ function constructors.addcoreunicodes(unicodes)
return unicodes
end
-end --- [luaotfload, fontloader-2022-10-03.lua scope for “font-con”] ---
+end --- [luaotfload, fontloader-2023-08-19.lua scope for “font-con”] ---
-do --- [luaotfload, fontloader-2022-10-03.lua scope for “fonts-enc” c24fd6b4f34f87b9c4ff5e6193ce2656] ---
+do --- [luaotfload, fontloader-2023-08-19.lua scope for “fonts-enc” c24fd6b4f34f87b9c4ff5e6193ce2656] ---
if not modules then modules={} end modules ['luatex-font-enc']={
version=1.001,
@@ -5819,10 +5811,10 @@ function encodings.load(filename)
return containers.write(encodings.cache,name,data)
end
-end --- [luaotfload, fontloader-2022-10-03.lua scope for “fonts-enc”] ---
+end --- [luaotfload, fontloader-2023-08-19.lua scope for “fonts-enc”] ---
-do --- [luaotfload, fontloader-2022-10-03.lua scope for “font-cid” 22b0367742fb253deef84ef7ccf5e8de] ---
+do --- [luaotfload, fontloader-2023-08-19.lua scope for “font-cid” 22b0367742fb253deef84ef7ccf5e8de] ---
if not modules then modules={} end modules ['font-cid']={
version=1.001,
@@ -5973,10 +5965,10 @@ function cid.getmap(specification)
return found
end
-end --- [luaotfload, fontloader-2022-10-03.lua scope for “font-cid”] ---
+end --- [luaotfload, fontloader-2023-08-19.lua scope for “font-cid”] ---
-do --- [luaotfload, fontloader-2022-10-03.lua scope for “font-map” 27ee748150e56f5f0e5f0fefc864f35e] ---
+do --- [luaotfload, fontloader-2023-08-19.lua scope for “font-map” 27ee748150e56f5f0e5f0fefc864f35e] ---
if not modules then modules={} end modules ['font-map']={
version=1.001,
@@ -6384,10 +6376,10 @@ function mappings.addtounicode(data,filename,checklookups,forceligatures)
end
end
-end --- [luaotfload, fontloader-2022-10-03.lua scope for “font-map”] ---
+end --- [luaotfload, fontloader-2023-08-19.lua scope for “font-map”] ---
-do --- [luaotfload, fontloader-2022-10-03.lua scope for “font-vfc” a81c29eda98cd62cbebdb6c93544b50d] ---
+do --- [luaotfload, fontloader-2023-08-19.lua scope for “font-vfc” a81c29eda98cd62cbebdb6c93544b50d] ---
if not modules then modules={} end modules ['font-vfc']={
version=1.001,
@@ -6484,10 +6476,10 @@ helpers.commands=utilities.storage.allocate {
dummy=dummy,
}
-end --- [luaotfload, fontloader-2022-10-03.lua scope for “font-vfc”] ---
+end --- [luaotfload, fontloader-2023-08-19.lua scope for “font-vfc”] ---
-do --- [luaotfload, fontloader-2022-10-03.lua scope for “font-otr” 1896ac990a961f6d6fec551ca9b52a83] ---
+do --- [luaotfload, fontloader-2023-08-19.lua scope for “font-otr” 2958a21bebcf0579f4e11f0646d1b402] ---
if not modules then modules={} end modules ['font-otr']={
version=1.001,
@@ -6497,6 +6489,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
@@ -7580,7 +7573,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
@@ -8241,6 +8234,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,
@@ -8331,10 +8328,10 @@ function readers.extend(fontdata)
end
end
-end --- [luaotfload, fontloader-2022-10-03.lua scope for “font-otr”] ---
+end --- [luaotfload, fontloader-2023-08-19.lua scope for “font-otr”] ---
-do --- [luaotfload, fontloader-2022-10-03.lua scope for “font-oti” 309a75f9c14b77d87e94eba827dc4e71] ---
+do --- [luaotfload, fontloader-2023-08-19.lua scope for “font-oti” 309a75f9c14b77d87e94eba827dc4e71] ---
if not modules then modules={} end modules ['font-oti']={
version=1.001,
@@ -8477,10 +8474,10 @@ function otffeatures.checkeddefaultlanguage(featuretype,autolanguage,languages)
end
end
-end --- [luaotfload, fontloader-2022-10-03.lua scope for “font-oti”] ---
+end --- [luaotfload, fontloader-2023-08-19.lua scope for “font-oti”] ---
-do --- [luaotfload, fontloader-2022-10-03.lua scope for “font-ott” 3f67b1b1d40bbc222681d8db4aff0f42] ---
+do --- [luaotfload, fontloader-2023-08-19.lua scope for “font-ott” 427bdc77dd187158eafb79b7193400dc] ---
if not modules then modules={} end modules ["font-ott"]={
version=1.001,
@@ -8529,16 +8526,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",
@@ -8558,6 +8559,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",
@@ -8567,6 +8569,7 @@ local scripts=allocate {
["khar"]="kharosthi",
["khmr"]="khmer",
["khoj"]="khojki",
+ ["kits"]="khitan small script",
["knd2"]="kannada variant 2",
["knda"]="kannada",
["kthi"]="kaithi",
@@ -8600,6 +8603,7 @@ local scripts=allocate {
["musc"]="musical symbols",
["mym2"]="myanmar variant 2",
["mymr"]="myanmar",
+ ["nand"]="nandinagari",
["narb"]="old north arabian",
["nbat"]="nabataean",
["newa"]="newa",
@@ -8609,9 +8613,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",
@@ -8643,7 +8648,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",
@@ -8655,12 +8660,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",
}
@@ -8675,6 +8684,7 @@ local languages=allocate {
["agw" ]="agaw",
["aio" ]="aiton",
["aka" ]="akan",
+ ["akb" ]="batak angkola",
["als" ]="alsatian",
["alt" ]="altai",
["amh" ]="amharic",
@@ -8687,6 +8697,7 @@ local languages=allocate {
["asm" ]="assamese",
["ast" ]="asturian",
["ath" ]="athapaskan",
+ ["avn" ]="avatime",
["avr" ]="avar",
["awa" ]="awadhi",
["aym" ]="aymara",
@@ -8732,8 +8743,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",
@@ -8768,14 +8783,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",
@@ -8847,13 +8864,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",
@@ -8878,10 +8898,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",
@@ -8901,6 +8923,7 @@ local languages=allocate {
["kan" ]="kannada",
["kar" ]="karachay",
["kat" ]="georgian",
+ ["kaw" ]="kawi (old javanese)",
["kaz" ]="kazakh",
["kde" ]="makonde",
["kea" ]="kabuverdianu (crioulo)",
@@ -8958,6 +8981,7 @@ local languages=allocate {
["kur" ]="kurdish",
["kuu" ]="kurukh",
["kuy" ]="kuy",
+ ["kwk" ]="kwakʼwala",
["kyk" ]="koryak",
["kyu" ]="western kayah",
["lad" ]="ladin",
@@ -8969,6 +8993,7 @@ local languages=allocate {
["laz" ]="laz",
["lcr" ]="l-cree",
["ldk" ]="ladakhi",
+ ["lef" ]="lelemi",
["lez" ]="lezgi",
["lij" ]="ligurian",
["lim" ]="limburgish",
@@ -8981,6 +9006,7 @@ local languages=allocate {
["lmo" ]="lombard",
["lmw" ]="lomwe",
["lom" ]="loma",
+ ["lpo" ]="lipo",
["lrc" ]="luri",
["lsb" ]="lower sorbian",
["lsm" ]="lule sami",
@@ -8997,7 +9023,7 @@ local languages=allocate {
["mah" ]="marshallese",
["maj" ]="majang",
["mak" ]="makhuwa",
- ["mal" ]="malayalam reformed",
+ ["mal" ]="malayalam",
["mam" ]="mam",
["man" ]="mansi",
["map" ]="mapudungun",
@@ -9032,6 +9058,7 @@ local languages=allocate {
["mok" ]="moksha",
["mol" ]="moldavian",
["mon" ]="mon",
+ ["mnw" ]="thailand mon",
["mor" ]="moroccan",
["mos" ]="mossi",
["mri" ]="maori",
@@ -9070,7 +9097,7 @@ local languages=allocate {
["nor" ]="norwegian",
["nov" ]="novial",
["nsm" ]="northern sami",
- ["nso" ]="sotho, northern",
+ ["nso" ]="northern sotho",
["nta" ]="northern tai",
["nto" ]="esperanto",
["nym" ]="nyamwezi",
@@ -9118,6 +9145,7 @@ local languages=allocate {
["rbu" ]="russian buriat",
["rcr" ]="r-cree",
["rej" ]="rejang",
+ ["rhg" ]="rohingya",
["ria" ]="riang",
["rif" ]="tarifit",
["rit" ]="ritarungo",
@@ -9142,6 +9170,7 @@ local languages=allocate {
["scs" ]="north slavey",
["sek" ]="sekota",
["sel" ]="selkup",
+ ["sfm" ]="small flowery miao",
["sga" ]="old irish",
["sgo" ]="sango",
["sgs" ]="samogitian",
@@ -9163,7 +9192,7 @@ local languages=allocate {
["snk" ]="soninke",
["sog" ]="sodo gurage",
["sop" ]="songe",
- ["sot" ]="sotho, southern",
+ ["sot" ]="southern sotho",
["sqi" ]="albanian",
["srb" ]="serbian",
["srd" ]="sardinian",
@@ -9204,7 +9233,9 @@ local languages=allocate {
["tht" ]="tahitian",
["tib" ]="tibetan",
["tiv" ]="tiv",
+ ["tj;" ]="tai laing",
["tkm" ]="turkmen",
+ ["tli" ]="tlingit",
["tmh" ]="tamashek",
["tmn" ]="temne",
["tna" ]="tswana",
@@ -9218,7 +9249,7 @@ local languages=allocate {
["tsj" ]="tshangla",
["tua" ]="turoyo aramaic",
["tul" ]="tulu",
- ["tum" ]="tulu",
+ ["tum" ]="tumbuka",
["tuv" ]="tuvin",
["tvl" ]="tuvalu",
["twi" ]="twi",
@@ -9240,6 +9271,7 @@ local languages=allocate {
["wa" ]="wa",
["wag" ]="wagdi",
["war" ]="waray-waray",
+ ["wci" ]="waci gbe",
["wcr" ]="west-cree",
["wel" ]="welsh",
["wlf" ]="wolof",
@@ -9251,17 +9283,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",
@@ -9285,6 +9323,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",
@@ -9361,8 +9400,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",
@@ -9382,6 +9421,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",
@@ -9596,10 +9636,10 @@ function otffeatures.normalize(features,wrap)
end
end
-end --- [luaotfload, fontloader-2022-10-03.lua scope for “font-ott”] ---
+end --- [luaotfload, fontloader-2023-08-19.lua scope for “font-ott”] ---
-do --- [luaotfload, fontloader-2022-10-03.lua scope for “font-cff” 651c74e4804fbb85d31267210298f466] ---
+do --- [luaotfload, fontloader-2023-08-19.lua scope for “font-cff” 999da544079698ce70178fd84bcdd67a] ---
if not modules then modules={} end modules ['font-cff']={
version=1.001,
@@ -9865,10 +9905,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]
@@ -9940,7 +9980,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]
@@ -9994,7 +10034,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",
@@ -10010,8 +10050,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
@@ -10122,7 +10167,7 @@ do
local y=0
local width=false
local lsb=0
-local result={}
+ local result={}
local r=0
local stems=0
local globalbias=0
@@ -11015,6 +11060,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))
@@ -11140,6 +11186,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]
@@ -11285,20 +11338,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
@@ -11345,7 +11385,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 },
@@ -11400,8 +11440,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
@@ -11469,23 +11510,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
@@ -11499,7 +11541,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
@@ -11524,12 +11566,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)
@@ -11677,7 +11720,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)
@@ -11825,6 +11868,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)
@@ -11867,44 +11912,11 @@ 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 --- [luaotfload, fontloader-2022-10-03.lua scope for “font-cff”] ---
+end --- [luaotfload, fontloader-2023-08-19.lua scope for “font-cff”] ---
-do --- [luaotfload, fontloader-2022-10-03.lua scope for “font-ttf” a3ff07150b3535fd32f68748d53fcd36] ---
+do --- [luaotfload, fontloader-2023-08-19.lua scope for “font-ttf” ff94e130d7c71edd899c4bae7745b7db] ---
if not modules then modules={} end modules ['font-ttf']={
version=1.001,
@@ -12070,20 +12082,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
@@ -12100,8 +12099,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
@@ -12109,7 +12111,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
@@ -12557,6 +12559,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
@@ -13164,10 +13172,10 @@ function readers.gvar(f,fontdata,specification,glyphdata,shapedata)
end
end
-end --- [luaotfload, fontloader-2022-10-03.lua scope for “font-ttf”] ---
+end --- [luaotfload, fontloader-2023-08-19.lua scope for “font-ttf”] ---
-do --- [luaotfload, fontloader-2022-10-03.lua scope for “font-dsp” 23a82ec8fdb9f226427e78904402e48a] ---
+do --- [luaotfload, fontloader-2023-08-19.lua scope for “font-dsp” 755beef1b31e9dfd050e9d221d4e9ae3] ---
if not modules then modules={} end modules ['font-dsp']={
version=1.001,
@@ -13332,6 +13340,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",
@@ -13406,7 +13428,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
@@ -14910,6 +14931,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
@@ -14944,6 +14966,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
@@ -15042,25 +15065,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
@@ -15096,12 +15112,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
@@ -15123,7 +15139,6 @@ do
end
end
end
- end
for i,n in sortedhash(sublookupcheck) do
local l=lookups[i]
local t=l.type
@@ -15546,7 +15561,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
@@ -15627,7 +15642,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
@@ -15690,13 +15705,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)
@@ -15722,9 +15745,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")
@@ -16336,7 +16360,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)
@@ -16445,10 +16468,10 @@ function readers.mvar(f,fontdata,specification)
end
end
-end --- [luaotfload, fontloader-2022-10-03.lua scope for “font-dsp”] ---
+end --- [luaotfload, fontloader-2023-08-19.lua scope for “font-dsp”] ---
-do --- [luaotfload, fontloader-2022-10-03.lua scope for “font-oup” 76dc3379061e5650f772909966b5759e] ---
+do --- [luaotfload, fontloader-2023-08-19.lua scope for “font-oup” aaff9c28233bbea56e6d27ae50e04ff0] ---
if not modules then modules={} end modules ['font-oup']={
version=1.001,
@@ -17279,24 +17302,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
@@ -17307,7 +17346,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
@@ -19286,10 +19327,10 @@ end
expandlookups(sublookups,sequences)
end
-end --- [luaotfload, fontloader-2022-10-03.lua scope for “font-oup”] ---
+end --- [luaotfload, fontloader-2023-08-19.lua scope for “font-oup”] ---
-do --- [luaotfload, fontloader-2022-10-03.lua scope for “font-otl” 308b1aab04bc131da7eb8e8c3b0471d4] ---
+do --- [luaotfload, fontloader-2023-08-19.lua scope for “font-otl” 21196d193ce16f3996c9aa75e81e440c] ---
if not modules then modules={} end modules ['font-otl']={
version=1.001,
@@ -19317,7 +19358,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)
@@ -19800,24 +19841,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
@@ -20017,10 +20040,10 @@ otf.coverup={
end
}
-end --- [luaotfload, fontloader-2022-10-03.lua scope for “font-otl”] ---
+end --- [luaotfload, fontloader-2023-08-19.lua scope for “font-otl”] ---
-do --- [luaotfload, fontloader-2022-10-03.lua scope for “font-oto” 9febc4d75d17a543cd73fb17918f7307] ---
+do --- [luaotfload, fontloader-2023-08-19.lua scope for “font-oto” 1cc20f34606fb55d4646a0dd323499ef] ---
if not modules then modules={} end modules ['font-oto']={
version=1.001,
@@ -20489,10 +20512,10 @@ registerotffeature {
}
otf.basemodeinitializer=featuresinitializer
-end --- [luaotfload, fontloader-2022-10-03.lua scope for “font-oto”] ---
+end --- [luaotfload, fontloader-2023-08-19.lua scope for “font-oto”] ---
-do --- [luaotfload, fontloader-2022-10-03.lua scope for “font-otj” b2c165bd6771a57633f992d07384b739] ---
+do --- [luaotfload, fontloader-2023-08-19.lua scope for “font-otj” b2c165bd6771a57633f992d07384b739] ---
if not modules then modules={} end modules ['font-otj']={
version=1.001,
@@ -21985,10 +22008,10 @@ function injections.handler(head,where)
end
end
-end --- [luaotfload, fontloader-2022-10-03.lua scope for “font-otj”] ---
+end --- [luaotfload, fontloader-2023-08-19.lua scope for “font-otj”] ---
-do --- [luaotfload, fontloader-2022-10-03.lua scope for “font-ota” 2bb12d708e35bc05443eba791e2554e7] ---
+do --- [luaotfload, fontloader-2023-08-19.lua scope for “font-ota” 7407b709ae7b2cdf36f68d5c98d51d12] ---
if not modules then modules={} end modules ['font-ota']={
version=1.001,
@@ -22482,10 +22505,10 @@ directives.register("otf.analyze.useunicodemarks",function(v)
analyzers.useunicodemarks=v
end)
-end --- [luaotfload, fontloader-2022-10-03.lua scope for “font-ota”] ---
+end --- [luaotfload, fontloader-2023-08-19.lua scope for “font-ota”] ---
-do --- [luaotfload, fontloader-2022-10-03.lua scope for “font-ots” 55316a605d11a1d07d38795224c90a63] ---
+do --- [luaotfload, fontloader-2023-08-19.lua scope for “font-ots” c039b20490b526ec469e41a8584ebe6d] ---
if not modules then modules={} end modules ['font-ots']={
version=1.001,
@@ -22528,12 +22551,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")
@@ -22555,7 +22574,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
@@ -22575,10 +22593,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
@@ -22588,7 +22606,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
@@ -22597,8 +22614,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
@@ -22689,7 +22705,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
@@ -22746,7 +22762,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
@@ -22773,7 +22789,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)
@@ -22811,7 +22826,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
@@ -22831,7 +22845,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
@@ -22895,57 +22909,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
@@ -23117,9 +23131,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
@@ -23130,7 +23144,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
@@ -23507,7 +23521,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)
@@ -24020,7 +24034,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
@@ -24057,26 +24071,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
@@ -24101,20 +24122,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
@@ -24138,7 +24163,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
@@ -24165,6 +24190,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)
@@ -24227,7 +24254,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)
@@ -24338,13 +24365,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
@@ -24358,14 +24385,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
@@ -24376,6 +24403,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
@@ -24397,8 +24425,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
@@ -24408,14 +24436,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
@@ -24436,30 +24464,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
@@ -24487,7 +24540,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
@@ -24598,7 +24651,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)
@@ -24713,9 +24765,6 @@ local last=start
else
goto next
end
- else
- goto next
- end
end
if s>l then
local current=last and getnext(last)
@@ -24839,12 +24888,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={}
@@ -24861,15 +24913,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
@@ -25052,7 +25115,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
@@ -25095,8 +25158,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)
@@ -25124,7 +25191,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
@@ -25138,7 +25205,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
@@ -25201,7 +25268,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)
@@ -25619,7 +25686,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
@@ -25697,13 +25764,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)
@@ -25767,13 +25833,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)
@@ -26145,10 +26210,10 @@ registerotffeature {
},
}
-end --- [luaotfload, fontloader-2022-10-03.lua scope for “font-ots”] ---
+end --- [luaotfload, fontloader-2023-08-19.lua scope for “font-ots”] ---
-do --- [luaotfload, fontloader-2022-10-03.lua scope for “font-osd” 1716513d8fe5f28e0e88daad2be0e05b] ---
+do --- [luaotfload, fontloader-2023-08-19.lua scope for “font-osd” c38c14c118680202c6f4b09734542c49] ---
if not modules then modules={} end modules ['font-osd']={
version=1.001,
@@ -27686,7 +27751,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]
@@ -27807,7 +27872,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
@@ -27863,10 +27928,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
@@ -27875,6 +27946,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
@@ -27926,7 +28003,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)
@@ -27969,14 +28046,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
@@ -28196,11 +28270,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
@@ -28401,11 +28471,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
@@ -28781,10 +28847,10 @@ for i=1,nofscripts do
methods[scripts_two[i]]=method_two
end
-end --- [luaotfload, fontloader-2022-10-03.lua scope for “font-osd”] ---
+end --- [luaotfload, fontloader-2023-08-19.lua scope for “font-osd”] ---
-do --- [luaotfload, fontloader-2022-10-03.lua scope for “font-ocl” 2a377351ae23c339764ec8ce2e8e9164] ---
+do --- [luaotfload, fontloader-2023-08-19.lua scope for “font-ocl” 2a377351ae23c339764ec8ce2e8e9164] ---
if not modules then modules={} end modules ['font-ocl']={
version=1.001,
@@ -29332,10 +29398,10 @@ if context then
}
end
-end --- [luaotfload, fontloader-2022-10-03.lua scope for “font-ocl”] ---
+end --- [luaotfload, fontloader-2023-08-19.lua scope for “font-ocl”] ---
-do --- [luaotfload, fontloader-2022-10-03.lua scope for “font-otc” 57f5270b894e40efa93149c7d3fb0209] ---
+do --- [luaotfload, fontloader-2023-08-19.lua scope for “font-otc” 0ad931eec679ebeceed5d4f02f4ba31b] ---
if not modules then modules={} end modules ['font-otc']={
version=1.001,
@@ -29459,6 +29525,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
@@ -30036,7 +30106,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
@@ -30159,10 +30233,10 @@ end
otf.enhancers.enhance=enhance
otf.enhancers.register("check extra features",enhance)
-end --- [luaotfload, fontloader-2022-10-03.lua scope for “font-otc”] ---
+end --- [luaotfload, fontloader-2023-08-19.lua scope for “font-otc”] ---
-do --- [luaotfload, fontloader-2022-10-03.lua scope for “font-onr” 6d161533f3437435e12a0ad64866df44] ---
+do --- [luaotfload, fontloader-2023-08-19.lua scope for “font-onr” a3f85c886cf22fb27760d98603d51ffd] ---
if not modules then modules={} end modules ['font-onr']={
version=1.001,
@@ -30535,10 +30609,10 @@ function readers.getinfo(filename)
end
end
-end --- [luaotfload, fontloader-2022-10-03.lua scope for “font-onr”] ---
+end --- [luaotfload, fontloader-2023-08-19.lua scope for “font-onr”] ---
-do --- [luaotfload, fontloader-2022-10-03.lua scope for “font-one” bd39d42055a44ca2002f8ddbbbbf27c3] ---
+do --- [luaotfload, fontloader-2023-08-19.lua scope for “font-one” b7fb0389462a49bc1f41bebd2da85401] ---
if not modules then modules={} end modules ['font-one']={
version=1.001,
@@ -31253,10 +31327,10 @@ registerafmenhancer("normalize features",enhance_normalize_features)
registerafmenhancer("check extra features",otfenhancers.enhance)
registerafmenhancer("fix names",enhance_fix_names)
-end --- [luaotfload, fontloader-2022-10-03.lua scope for “font-one”] ---
+end --- [luaotfload, fontloader-2023-08-19.lua scope for “font-one”] ---
-do --- [luaotfload, fontloader-2022-10-03.lua scope for “font-afk” 9da14e0fb22129c053acc599d1312544] ---
+do --- [luaotfload, fontloader-2023-08-19.lua scope for “font-afk” b7bef80aa4c18357cbfa0ae4df4d4046] ---
if not modules then modules={} end modules ['font-afk']={
version=1.001,
@@ -31423,10 +31497,10 @@ fonts.handlers.afm.helpdata={
}
}
-end --- [luaotfload, fontloader-2022-10-03.lua scope for “font-afk”] ---
+end --- [luaotfload, fontloader-2023-08-19.lua scope for “font-afk”] ---
-do --- [luaotfload, fontloader-2022-10-03.lua scope for “fonts-tfm” f0eb5e2a8068b17ad401bb7efdba1630] ---
+do --- [luaotfload, fontloader-2023-08-19.lua scope for “fonts-tfm” f0eb5e2a8068b17ad401bb7efdba1630] ---
if not modules then modules={} end modules ['luatex-fonts-tfm']={
version=1.001,
@@ -31941,10 +32015,10 @@ registertfmfeature {
}
}
-end --- [luaotfload, fontloader-2022-10-03.lua scope for “fonts-tfm”] ---
+end --- [luaotfload, fontloader-2023-08-19.lua scope for “fonts-tfm”] ---
-do --- [luaotfload, fontloader-2022-10-03.lua scope for “font-lua” 1fbfdf7b689b2bdfd0e3bb9bf74ce136] ---
+do --- [luaotfload, fontloader-2023-08-19.lua scope for “font-lua” 1fbfdf7b689b2bdfd0e3bb9bf74ce136] ---
if not modules then modules={} end modules ['font-lua']={
version=1.001,
@@ -31984,10 +32058,10 @@ function readers.lua(specification)
return check_lua(specification,fullname)
end
-end --- [luaotfload, fontloader-2022-10-03.lua scope for “font-lua”] ---
+end --- [luaotfload, fontloader-2023-08-19.lua scope for “font-lua”] ---
-do --- [luaotfload, fontloader-2022-10-03.lua scope for “font-def” b9d908c2338b7dc443ce9d1e9fcb7139] ---
+do --- [luaotfload, fontloader-2023-08-19.lua scope for “font-def” cec0e49aee881c4cbd36d541f0162c6f] ---
if not modules then modules={} end modules ['font-def']={
version=1.001,
@@ -32387,10 +32461,10 @@ if not context then
callbacks.register('define_font',definers.read,"definition of fonts (tfmdata preparation)")
end
-end --- [luaotfload, fontloader-2022-10-03.lua scope for “font-def”] ---
+end --- [luaotfload, fontloader-2023-08-19.lua scope for “font-def”] ---
-do --- [luaotfload, fontloader-2022-10-03.lua scope for “font-shp” a40862fe382d26c1f3753431254bcfdd] ---
+do --- [luaotfload, fontloader-2023-08-19.lua scope for “font-shp” a174ac26390bd0828805747500df0077] ---
if not modules then modules={} end modules ['font-shp']={
version=1.001,
@@ -32407,7 +32481,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
@@ -32633,7 +32707,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,
@@ -32715,7 +32790,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)
@@ -32755,10 +32831,10 @@ callback.register("glyph_stream_provider",function(id,index,mode)
return ""
end)
-end --- [luaotfload, fontloader-2022-10-03.lua scope for “font-shp”] ---
+end --- [luaotfload, fontloader-2023-08-19.lua scope for “font-shp”] ---
-do --- [luaotfload, fontloader-2022-10-03.lua scope for “fonts-def” f435e0875f203f343157baeff876ec9c] ---
+do --- [luaotfload, fontloader-2023-08-19.lua scope for “fonts-def” f435e0875f203f343157baeff876ec9c] ---
if not modules then modules={} end modules ['luatex-fonts-def']={
version=1.001,
@@ -32839,10 +32915,10 @@ function fonts.definers.applypostprocessors(tfmdata)
return tfmdata
end
-end --- [luaotfload, fontloader-2022-10-03.lua scope for “fonts-def”] ---
+end --- [luaotfload, fontloader-2023-08-19.lua scope for “fonts-def”] ---
-do --- [luaotfload, fontloader-2022-10-03.lua scope for “fonts-ext” 32013cbc5d5d336be8b1d1e5879d86c4] ---
+do --- [luaotfload, fontloader-2023-08-19.lua scope for “fonts-ext” 32013cbc5d5d336be8b1d1e5879d86c4] ---
if not modules then modules={} end modules ['luatex-fonts-ext']={
version=1.001,
@@ -33028,10 +33104,10 @@ registerotffeature {
}
}
-end --- [luaotfload, fontloader-2022-10-03.lua scope for “fonts-ext”] ---
+end --- [luaotfload, fontloader-2023-08-19.lua scope for “fonts-ext”] ---
-do --- [luaotfload, fontloader-2022-10-03.lua scope for “font-imp-tex” ceb087ef6fa2f89aed7179f60ddf8f35] ---
+do --- [luaotfload, fontloader-2023-08-19.lua scope for “font-imp-tex” 9882d382700e714cace08b7f09820958] ---
if not modules then modules={} end modules ['font-imp-tex']={
version=1.001,
@@ -33045,7 +33121,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,
@@ -33054,12 +33130,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,
@@ -33067,11 +33148,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,
@@ -33130,10 +33212,10 @@ registerotffeature {
description="arabic digits",
}
-end --- [luaotfload, fontloader-2022-10-03.lua scope for “font-imp-tex”] ---
+end --- [luaotfload, fontloader-2023-08-19.lua scope for “font-imp-tex”] ---
-do --- [luaotfload, fontloader-2022-10-03.lua scope for “font-imp-ligatures” 250f6f4488ee770c23177afb2ff75676] ---
+do --- [luaotfload, fontloader-2023-08-19.lua scope for “font-imp-ligatures” 250f6f4488ee770c23177afb2ff75676] ---
if not modules then modules={} end modules ['font-imp-ligatures']={
version=1.001,
@@ -33247,10 +33329,10 @@ if context then
}
end
-end --- [luaotfload, fontloader-2022-10-03.lua scope for “font-imp-ligatures”] ---
+end --- [luaotfload, fontloader-2023-08-19.lua scope for “font-imp-ligatures”] ---
-do --- [luaotfload, fontloader-2022-10-03.lua scope for “font-imp-italics” defcb415bc1e0a0999b27773902adc18] ---
+do --- [luaotfload, fontloader-2023-08-19.lua scope for “font-imp-italics” 3cc555a1fe00dc45449f1e4a47a5c990] ---
if not modules then modules={} end modules ['font-imp-italics']={
version=1.001,
@@ -33259,30 +33341,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
@@ -33354,10 +33417,10 @@ if context then
registerafmfeature(dimensions_specification)
end
-end --- [luaotfload, fontloader-2022-10-03.lua scope for “font-imp-italics”] ---
+end --- [luaotfload, fontloader-2023-08-19.lua scope for “font-imp-italics”] ---
-do --- [luaotfload, fontloader-2022-10-03.lua scope for “font-imp-effects” d05997c1826355548ec9aec1346f9f23] ---
+do --- [luaotfload, fontloader-2023-08-19.lua scope for “font-imp-effects” d05997c1826355548ec9aec1346f9f23] ---
if not modules then modules={} end modules ['font-imp-effects']={
version=1.001,
@@ -33714,10 +33777,10 @@ local specification={
registerotffeature(specification)
registerafmfeature(specification)
-end --- [luaotfload, fontloader-2022-10-03.lua scope for “font-imp-effects”] ---
+end --- [luaotfload, fontloader-2023-08-19.lua scope for “font-imp-effects”] ---
-do --- [luaotfload, fontloader-2022-10-03.lua scope for “fonts-lig” fbd251eea3810a43a8d5542319361d68] ---
+do --- [luaotfload, fontloader-2023-08-19.lua scope for “fonts-lig” fbd251eea3810a43a8d5542319361d68] ---
fonts.handlers.otf.addfeature {
@@ -35786,10 +35849,10 @@ fonts.handlers.otf.addfeature {
["type"]="ligature",
}
-end --- [luaotfload, fontloader-2022-10-03.lua scope for “fonts-lig”] ---
+end --- [luaotfload, fontloader-2023-08-19.lua scope for “fonts-lig”] ---
-do --- [luaotfload, fontloader-2022-10-03.lua scope for “fonts-gbn” 34e4543a02f6fbc8c2ade896cb6dc7df] ---
+do --- [luaotfload, fontloader-2023-08-19.lua scope for “fonts-gbn” 34e4543a02f6fbc8c2ade896cb6dc7df] ---
if not modules then modules={} end modules ['luatex-fonts-gbn']={
version=1.001,
@@ -36054,7 +36117,7 @@ function nodes.simple_font_handler(head,groupcode,size,packtype,direction)
return head
end
-end --- [luaotfload, fontloader-2022-10-03.lua scope for “fonts-gbn”] ---
+end --- [luaotfload, fontloader-2023-08-19.lua scope for “fonts-gbn”] ---
--- vim:ft=lua:sw=2:ts=8:et:tw=79
diff --git a/macros/luatex/generic/luaotfload/fontloader-data-con.lua b/macros/luatex/generic/luaotfload/fontloader-data-con.lua
index ec2251b353..d7d3c7d461 100644
--- a/macros/luatex/generic/luaotfload/fontloader-data-con.lua
+++ b/macros/luatex/generic/luaotfload/fontloader-data-con.lua
@@ -13,19 +13,17 @@ local trace_cache = false trackers.register("resolvers.cache", functi
local trace_containers = false trackers.register("resolvers.containers", function(v) trace_containers = v end)
local trace_storage = false trackers.register("resolvers.storage", function(v) trace_storage = v end)
---[[ldx--
-<p>Once we found ourselves defining similar cache constructs several times,
-containers were introduced. Containers are used to collect tables in memory and
-reuse them when possible based on (unique) hashes (to be provided by the calling
-function).</p>
-
-<p>Caching to disk is disabled by default. Version numbers are stored in the
-saved table which makes it possible to change the table structures without
-bothering about the disk cache.</p>
-
-<p>Examples of usage can be found in the font related code. This code is not
-ideal but we need it in generic too so we compromise.</p>
---ldx]]--
+-- Once we found ourselves defining similar cache constructs several times,
+-- containers were introduced. Containers are used to collect tables in memory and
+-- reuse them when possible based on (unique) hashes (to be provided by the calling
+-- function).
+--
+-- Caching to disk is disabled by default. Version numbers are stored in the saved
+-- table which makes it possible to change the table structures without bothering
+-- about the disk cache.
+--
+-- Examples of usage can be found in the font related code. This code is not ideal
+-- but we need it in generic too so we compromise.
containers = containers or { }
local containers = containers
@@ -56,7 +54,7 @@ local mt = {
__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
@@ -70,6 +68,7 @@ function containers.define(category, subcategory, version, enabled)
subcategory = subcategory,
storage = { },
enabled = enabled,
+ reload = reload,
version = version or math.pi, -- after all, this is TeX
trace = false,
-- writable = getwritablepath and getwritablepath (category,subcategory) or { "." },
@@ -97,7 +96,8 @@ 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
diff --git a/macros/luatex/generic/luaotfload/fontloader-font-afk.lua b/macros/luatex/generic/luaotfload/fontloader-font-afk.lua
index 761016d348..250c17e776 100644
--- a/macros/luatex/generic/luaotfload/fontloader-font-afk.lua
+++ b/macros/luatex/generic/luaotfload/fontloader-font-afk.lua
@@ -7,11 +7,9 @@ if not modules then modules = { } end modules ['font-afk'] = {
dataonly = true,
}
---[[ldx--
-<p>For ligatures, only characters with a code smaller than 128 make sense,
-anything larger is encoding dependent. An interesting complication is that a
-character can be in an encoding twice but is hashed once.</p>
---ldx]]--
+-- For ligatures, only characters with a code smaller than 128 make sense, anything
+-- larger is encoding dependent. An interesting complication is that a character can
+-- be in an encoding twice but is hashed once.
local allocate = utilities.storage.allocate
diff --git a/macros/luatex/generic/luaotfload/fontloader-font-cff.lua b/macros/luatex/generic/luaotfload/fontloader-font-cff.lua
index 114d7dd079..c71c3aef33 100644
--- a/macros/luatex/generic/luaotfload/fontloader-font-cff.lua
+++ b/macros/luatex/generic/luaotfload/fontloader-font-cff.lua
@@ -348,11 +348,11 @@ do
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()
@@ -453,7 +453,7 @@ do
top = 0
end
+ P("\10") / function()
- result.bluesnap = stack[top]
+ result.blueshift = stack[top]
top = 0
end
+ P("\11") / function()
@@ -528,7 +528,7 @@ do
-- the second variant is much faster. Not that it matters much as we don't see
-- such numbers often.
- 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",
@@ -544,11 +544,18 @@ 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 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_last = S("\x0F\x1F\x2F\x3F\x4F\x5F\x6F\x7F\x8F\x9F\xAF\xBF")
- + R("\xF0\xFF")
+ -- tricky, we don't want to append last
- local p_nibbles = P("\30") * Cs(((1-p_last)/remap)^0 * (P(1)/remap)) / function(n)
+ -- local p_nibbles = P("\30") * Cs(((1-p_last)/remap)^0 * (P(1)/remap)) / function(n)
+ 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)
-- 0-9=digit a=. b=E c=E- d=reserved e=- f=finish
top = top + 1
stack[top] = tonumber(n) or 0
@@ -707,7 +714,7 @@ do
local y = 0
local width = false
local lsb = 0
-local result = { }
+ local result = { }
local r = 0
local stems = 0
local globalbias = 0
@@ -1707,7 +1714,8 @@ end
-- todo: round in blend
- local encode = { }
+ local encode = { }
+ local typeone = false
-- this eventually can become a helper
@@ -1724,15 +1732,13 @@ end
end
for i=108,1131 do
local v = 0xF700 + i - 108
--- t[i] = char(band(rshift(v,8),0xFF),band(v,0xFF))
t[i] = char(extract(v,8,8),extract(v,0,8))
end
for i=1132,2048 do
t[i] = char(28,band(rshift(i,8),0xFF),band(i,0xFF))
end
- -- we could inline some ...
setmetatableindex(encode,function(t,k)
- -- 16.16-bit signed fixed value
+ -- as we're cff2 we write 16.16-bit signed fixed value
local r = round(k)
local v = rawget(t,r)
if v then
@@ -1837,42 +1843,6 @@ end
-- precompiling and reuse is much slower than redoing the calls
- -- local function decode(str)
- -- local a, b, c, d, e = byte(str,1,5)
- -- if a == 28 then
- -- if c then
- -- local n = 0x100 * b + c
- -- if n >= 0x8000 then
- -- return n - 0x10000
- -- else
- -- return n
- -- end
- -- end
- -- elseif a < 32 then
- -- return false
- -- elseif a <= 246 then
- -- return a - 139
- -- elseif a <= 250 then
- -- if b then
- -- return a*256 - 63124 + b
- -- end
- -- elseif a <= 254 then
- -- if b then
- -- return -a*256 + 64148 - b
- -- end
- -- else
- -- if e then
- -- local n = 0x100 * b + c
- -- if n >= 0x8000 then
- -- return n - 0x10000 + (0x100 * d + e)/0xFFFF
- -- else
- -- return n + (0x100 * d + e)/0xFFFF
- -- end
- -- end
- -- end
- -- return false
- -- end
-
process = function(tab)
local i = 1
local n = #tab
@@ -1896,8 +1866,14 @@ end
-- stack[top] = -t*256 + 251*256 - tab[i+1] - 108
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
- -- a 16.16 float (used for italic but pretty unreliable)
local n1 = 0x100 * tab[i+1] + tab[i+2]
local n2 = 0x100 * tab[i+3] + tab[i+4]
if n1 >= 0x8000 then
@@ -2054,24 +2030,26 @@ end
if t == 8 and top > 48 then
-- let's assume this only happens for rrcurveto .. the other ones would need some more
-- complex handling (cff2 stuff)
+ --
+ -- dx1 dy1 (dx1+dx2) (dy1+dy2) (dx1+dx2+dx3) (dy1+dy2+dy3) rcurveto.
local n = 0
for i=1,top do
-- if n == 42 then
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
+-- 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
+-- 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
@@ -2158,7 +2136,7 @@ end
end
end
- local function processshape(tab,index,hack)
+ local function processshape(glyphs,tab,index,hack)
if not tab then
glyphs[index] = {
@@ -2224,9 +2202,10 @@ result = nil
-- report("vdata: %s",stream)
-- end
if glyph then
- glyph.stream = stream
+ 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
@@ -2254,7 +2233,6 @@ result = nil
name = charset and charset[index] or nil,
}
end
-
if trace_charstrings then
report("width : %s",tostring(width))
report("boundingbox: % t",boundingbox)
@@ -2305,19 +2283,21 @@ result = nil
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)
@@ -2325,7 +2305,7 @@ result = nil
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
-- old type 1 stuff ... seacs
@@ -2341,7 +2321,7 @@ result = nil
-- this is a real ugly hack but we seldom enter this branch (e.g. old lbr)
local jp = justpass
justpass = false
- local x, y = processshape(charstrings[bindex+1],bindex,true)
+ local x, y = processshape(glyphs,charstrings[bindex+1],bindex,true)
justpass = jp
--
local base = bglyph.stream
@@ -2372,7 +2352,8 @@ result = nil
locals = dictionary.subroutines or { }
charset = false
vsindex = dictionary.vsindex or 0
- glyphs = glphs or { }
+
+ local glyphs = glphs or { }
justpass = streams == true
seacs = { }
@@ -2380,9 +2361,9 @@ result = nil
globalbias, localbias = setbias(globals,locals,nobias)
nominalwidth, defaultwidth = setwidths(dictionary.private)
- processshape(tab,index-1)
+ processshape(glyphs,tab,index-1)
- -- return glyphs[index]
+ return glyphs[index]
end
end
@@ -2547,7 +2528,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
@@ -2715,6 +2696,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)
@@ -2765,38 +2748,38 @@ end
-- temporary helper needed for checking backend patches
-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
+-- 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
diff --git a/macros/luatex/generic/luaotfload/fontloader-font-con.lua b/macros/luatex/generic/luaotfload/fontloader-font-con.lua
index f650e5b03d..10f98ca120 100644
--- a/macros/luatex/generic/luaotfload/fontloader-font-con.lua
+++ b/macros/luatex/generic/luaotfload/fontloader-font-con.lua
@@ -6,6 +6,9 @@ if not modules then modules = { } end modules ['font-con'] = {
license = "see context related readme files"
}
+-- Todo: Enable fixes from the lmt to here. Also in font-oto.lua wrt the changed
+-- assignments. (Around texlive 2024 in order not to disturb generic.)
+
-- some names of table entries will be changed (no _)
local next, tostring, tonumber, rawget = next, tostring, tonumber, rawget
@@ -22,11 +25,9 @@ local trace_scaling = false trackers.register("fonts.scaling", function(v)
local report_defining = logs.reporter("fonts","defining")
--- watch out: no negative depths and negative eights permitted in regular fonts
-
---[[ldx--
-<p>Here we only implement a few helper functions.</p>
---ldx]]--
+-- Watch out: no negative depths and negative heights are permitted in regular
+-- fonts. Also, the code in LMTX is a bit different. Here we only implement a
+-- few helper functions.
local fonts = fonts
local constructors = fonts.constructors or { }
@@ -59,11 +60,9 @@ constructors.designsizes = designsizes
local loadedfonts = allocate()
constructors.loadedfonts = loadedfonts
---[[ldx--
-<p>We need to normalize the scale factor (in scaled points). This has to
-do with the fact that <l n='tex'/> uses a negative multiple of 1000 as
-a signal for a font scaled based on the design size.</p>
---ldx]]--
+-- We need to normalize the scale factor (in scaled points). This has to do with the
+-- fact that TeX uses a negative multiple of 1000 as a signal for a font scaled
+-- based on the design size.
local factors = {
pt = 65536.0,
@@ -118,22 +117,18 @@ function constructors.getmathparameter(tfmdata,name)
end
end
---[[ldx--
-<p>Beware, the boundingbox is passed as reference so we may not overwrite it
-in the process; numbers are of course copies. Here 65536 equals 1pt. (Due to
-excessive memory usage in CJK fonts, we no longer pass the boundingbox.)</p>
---ldx]]--
-
--- The scaler is only used for otf and afm and virtual fonts. If a virtual font has italic
--- correction make sure to set the hasitalics flag. Some more flags will be added in the
--- future.
-
---[[ldx--
-<p>The reason why the scaler was originally split, is that for a while we experimented
-with a helper function. However, in practice the <l n='api'/> calls are too slow to
-make this profitable and the <l n='lua'/> based variant was just faster. A days
-wasted day but an experience richer.</p>
---ldx]]--
+-- Beware, the boundingbox is passed as reference so we may not overwrite it in the
+-- process; numbers are of course copies. Here 65536 equals 1pt. (Due to excessive
+-- memory usage in CJK fonts, we no longer pass the boundingbox.)
+--
+-- The scaler is only used for OTF and AFM and virtual fonts. If a virtual font has
+-- italic correction make sure to set the hasitalics flag. Some more flags will be
+-- added in the future.
+--
+-- The reason why the scaler was originally split, is that for a while we
+-- experimented with a helper function. However, in practice the API calls are too
+-- slow to make this profitable and the Lua based variant was just faster. A days
+-- wasted day but an experience richer.
function constructors.cleanuptable(tfmdata)
-- This no longer makes sense because the addition of font.getcopy and its
@@ -388,20 +383,20 @@ function constructors.scale(tfmdata,specification)
--
local mathsize = tonumber(specification.mathsize) or 0
local textsize = tonumber(specification.textsize) or scaledpoints
- local forcedsize = tonumber(parameters.mathsize ) or 0 -- can be set by the feature "mathsize"
+ -- local forcedsize = tonumber(parameters.mathsize ) or 0 -- can be set by the feature "mathsize"
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 -- safeguard
- scaledpoints = forcedsize
- else
- -- in context x and xx also use mathsize
- end
+ -- if context then
+ -- -- do nothing, as we moved this upstream
+ -- elseif (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 -- safeguard
+ -- scaledpoints = forcedsize
+ -- end
targetparameters.mathsize = mathsize -- context specific
targetparameters.textsize = textsize -- context specific
- targetparameters.forcedsize = forcedsize -- context specific
+ -- targetparameters.forcedsize = forcedsize -- context specific
targetparameters.extrafactor = extrafactor -- context specific
--
local addtounicode = constructors.addtounicode
@@ -534,7 +529,6 @@ function constructors.scale(tfmdata,specification)
local realdimensions = properties.realdimensions
local writingmode = properties.writingmode or "horizontal"
local identity = properties.identity or "horizontal"
- --
local vfonts = target.fonts
if vfonts and #vfonts > 0 then
target.fonts = fastcopy(vfonts) -- maybe we virtualize more afterwards
@@ -657,6 +651,14 @@ function constructors.scale(tfmdata,specification)
if changed then
local c = changed[unicode]
if c and c ~= unicode then
+ -- local cc = changed[c]
+ -- if cc then
+ -- while cc do
+ -- c = cc
+ -- cc = changed[c]
+ -- end
+ -- end
+ -- check not needed:
if c then
description = descriptions[c] or descriptions[unicode] or character
character = characters[c] or character
@@ -1094,9 +1096,7 @@ function constructors.finalize(tfmdata)
return tfmdata
end
---[[ldx--
-<p>A unique hash value is generated by:</p>
---ldx]]--
+-- A unique hash value is generated by:
local hashmethods = { }
constructors.hashmethods = hashmethods
@@ -1155,13 +1155,11 @@ hashmethods.normal = function(list)
end
end
---[[ldx--
-<p>In principle we can share tfm tables when we are in need for a font, but then
-we need to define a font switch as an id/attr switch which is no fun, so in that
-case users can best use dynamic features ... so, we will not use that speedup. Okay,
-when we get rid of base mode we can optimize even further by sharing, but then we
-loose our testcases for <l n='luatex'/>.</p>
---ldx]]--
+-- In principle we can share tfm tables when we are in need for a font, but then we
+-- need to define a font switch as an id/attr switch which is no fun, so in that
+-- case users can best use dynamic features ... so, we will not use that speedup.
+-- Okay, when we get rid of base mode we can optimize even further by sharing, but
+-- then we loose our testcases for LuaTeX.
function constructors.hashinstance(specification,force)
local hash = specification.hash
@@ -1517,10 +1515,7 @@ do
end
---[[ldx--
-<p>We need to check for default features. For this we provide
-a helper function.</p>
---ldx]]--
+-- We need to check for default features. For this we provide a helper function.
function constructors.checkedfeatures(what,features)
local defaults = handlers[what].features.defaults
diff --git a/macros/luatex/generic/luaotfload/fontloader-font-def.lua b/macros/luatex/generic/luaotfload/fontloader-font-def.lua
index b752b3258c..01bced6d16 100644
--- a/macros/luatex/generic/luaotfload/fontloader-font-def.lua
+++ b/macros/luatex/generic/luaotfload/fontloader-font-def.lua
@@ -24,10 +24,9 @@ trackers.register("fonts.loading", "fonts.defining", "otf.loading", "afm.loading
local report_defining = logs.reporter("fonts","defining")
---[[ldx--
-<p>Here we deal with defining fonts. We do so by intercepting the
-default loader that only handles <l n='tfm'/>.</p>
---ldx]]--
+-- Here we deal with defining fonts. We do so by intercepting the default loader
+-- that only handles TFM files. Although, we started out that way but in the
+-- meantime we can hardly speak of TFM any more.
local fonts = fonts
local fontdata = fonts.hashes.identifiers
@@ -53,25 +52,18 @@ local designsizes = constructors.designsizes
local resolvefile = fontgoodies and fontgoodies.filenames and fontgoodies.filenames.resolve or function(s) return s end
---[[ldx--
-<p>We hardly gain anything when we cache the final (pre scaled)
-<l n='tfm'/> table. But it can be handy for debugging, so we no
-longer carry this code along. Also, we now have quite some reference
-to other tables so we would end up with lots of catches.</p>
---ldx]]--
-
---[[ldx--
-<p>We can prefix a font specification by <type>name:</type> or
-<type>file:</type>. The first case will result in a lookup in the
-synonym table.</p>
-
-<typing>
-[ name: | file: ] identifier [ separator [ specification ] ]
-</typing>
-
-<p>The following function split the font specification into components
-and prepares a table that will move along as we proceed.</p>
---ldx]]--
+-- We hardly gain anything when we cache the final (pre scaled) TFM table. But it
+-- can be handy for debugging, so we no longer carry this code along. Also, we now
+-- have quite some reference to other tables so we would end up with lots of
+-- catches.
+--
+-- We can prefix a font specification by "name:" or "file:". The first case will
+-- result in a lookup in the synonym table.
+--
+-- [ name: | file: ] identifier [ separator [ specification ] ]
+--
+-- The following function split the font specification into components and prepares
+-- a table that will move along as we proceed.
-- beware, we discard additional specs
--
@@ -164,9 +156,7 @@ if context then
end
---[[ldx--
-<p>We can resolve the filename using the next function:</p>
---ldx]]--
+-- We can resolve the filename using the next function:
definers.resolvers = definers.resolvers or { }
local resolvers = definers.resolvers
@@ -258,23 +248,17 @@ function definers.resolve(specification)
return specification
end
---[[ldx--
-<p>The main read function either uses a forced reader (as determined by
-a lookup) or tries to resolve the name using the list of readers.</p>
-
-<p>We need to cache when possible. We do cache raw tfm data (from <l
-n='tfm'/>, <l n='afm'/> or <l n='otf'/>). After that we can cache based
-on specificstion (name) and size, that is, <l n='tex'/> only needs a number
-for an already loaded fonts. However, it may make sense to cache fonts
-before they're scaled as well (store <l n='tfm'/>'s with applied methods
-and features). However, there may be a relation between the size and
-features (esp in virtual fonts) so let's not do that now.</p>
-
-<p>Watch out, here we do load a font, but we don't prepare the
-specification yet.</p>
---ldx]]--
-
--- very experimental:
+-- The main read function either uses a forced reader (as determined by a lookup) or
+-- tries to resolve the name using the list of readers.
+--
+-- We need to cache when possible. We do cache raw tfm data (from TFM, AFM or OTF).
+-- After that we can cache based on specificstion (name) and size, that is, TeX only
+-- needs a number for an already loaded fonts. However, it may make sense to cache
+-- fonts before they're scaled as well (store TFM's with applied methods and
+-- features). However, there may be a relation between the size and features (esp in
+-- virtual fonts) so let's not do that now.
+--
+-- Watch out, here we do load a font, but we don't prepare the specification yet.
function definers.applypostprocessors(tfmdata)
local postprocessors = tfmdata.postprocessors
@@ -439,17 +423,13 @@ function constructors.readanddefine(name,size) -- no id -- maybe a dummy first
return fontdata[id], id
end
---[[ldx--
-<p>So far the specifiers. Now comes the real definer. Here we cache
-based on id's. Here we also intercept the virtual font handler. Since
-it evolved stepwise I may rewrite this bit (combine code).</p>
-
-In the previously defined reader (the one resulting in a <l n='tfm'/>
-table) we cached the (scaled) instances. Here we cache them again, but
-this time based on id. We could combine this in one cache but this does
-not gain much. By the way, passing id's back to in the callback was
-introduced later in the development.</p>
---ldx]]--
+-- So far the specifiers. Now comes the real definer. Here we cache based on id's.
+-- Here we also intercept the virtual font handler.
+--
+-- In the previously defined reader (the one resulting in a TFM table) we cached the
+-- (scaled) instances. Here we cache them again, but this time based on id. We could
+-- combine this in one cache but this does not gain much. By the way, passing id's
+-- back to in the callback was introduced later in the development.
function definers.registered(hash)
local id = internalized[hash]
@@ -522,9 +502,7 @@ function font.getfont(id)
return fontdata[id] -- otherwise issues
end
---[[ldx--
-<p>We overload the <l n='tfm'/> reader.</p>
---ldx]]--
+-- We overload the <l n='tfm'/> reader.
if not context then
callbacks.register('define_font', definers.read, "definition of fonts (tfmdata preparation)")
diff --git a/macros/luatex/generic/luaotfload/fontloader-font-dsp.lua b/macros/luatex/generic/luaotfload/fontloader-font-dsp.lua
index 8f65ed9d94..5f9cf1a62e 100644
--- a/macros/luatex/generic/luaotfload/fontloader-font-dsp.lua
+++ b/macros/luatex/generic/luaotfload/fontloader-font-dsp.lua
@@ -234,6 +234,24 @@ local read_integer = {
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)
+
-- Traditionally we use these unique names (so that we can flatten the lookup list
-- (we create subsets runtime) but I will adapt the old code to newer names.
@@ -360,7 +378,7 @@ 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")
+ -- report("using default axis scale")
return default
elseif s[1] >= default then
if s[2] == default then
@@ -2177,6 +2195,8 @@ do
--
local usedlookups = false -- setmetatableindex("number")
--
+ local allsteps = { } -- new per 2022-09-25
+
for lookupid=1,noflookups do
local lookup = lookups[lookupid]
local lookuptype = lookup.type
@@ -2214,6 +2234,7 @@ do
steps[nofsteps] = step
local rules = step.rules
if rules then
+ allsteps[#allsteps+1] = step -- new per 2022-09-25
for i=1,#rules do
local rule = rules[i]
local before = rule.before
@@ -2329,29 +2350,31 @@ do
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)
+-- if not reported[step] then
+ report("rule %i in step %i of %s has %s lookups",i,step,what,kind)
+-- reported[name] = true
+-- end
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 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 -- new per 2022-09-25
+ local step = allsteps[s] -- new per 2022-09-25
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
-- can be ok as it aborts a chain sequence
- -- report_issue(i,what,sequence,"empty")
+ -- report_issue(i,what,s,"empty")
rule.lookups = nil
else
-- we can have holes in rlookups flagged false and we can have multiple lookups
@@ -2392,12 +2415,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
@@ -2419,7 +2442,7 @@ do
end
end
end
- end
+ -- end -- new per 2022-09-25
for i, n in sortedhash(sublookupcheck) do
local l = lookups[i]
@@ -2881,7 +2904,7 @@ local function readmathglyphinfo(f,fontdata,offset)
if not math then
glyph.math = { accent = accent }
else
- math.accent = accent
+ math.accent = accent -- will become math.topanchor
end
end
end
@@ -2971,7 +2994,7 @@ local function readmathvariants(f,fontdata,offset)
-- advance = readushort(f),
-- }
- 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
@@ -3036,14 +3059,23 @@ 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 LUATEXENGINE == "luametatex" then
+ 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)
@@ -3075,9 +3107,11 @@ 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
+ -- both versions have this in common
end
if not fontdata.tables.cpal then
report("color table %a in font %a has no mandate %a table","colr",fontdata.filename,"cpal")
@@ -3809,7 +3843,7 @@ 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")
+ -- report("no hvar table, expect problems due to messy widths")
return
end
diff --git a/macros/luatex/generic/luaotfload/fontloader-font-imp-italics.lua b/macros/luatex/generic/luaotfload/fontloader-font-imp-italics.lua
index 6c432d7cf4..8b38c5893b 100644
--- a/macros/luatex/generic/luaotfload/fontloader-font-imp-italics.lua
+++ b/macros/luatex/generic/luaotfload/fontloader-font-imp-italics.lua
@@ -6,34 +6,39 @@ if not modules then modules = { } end modules ['font-imp-italics'] = {
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, -- only makes sense for math
- }
-}
-
-registerotffeature(specification)
-registerafmfeature(specification)
+-- This is a precursor to what we do in lmtx now via tweaks but at some point I
+-- might make this a mkiv features too using staircase kerns.
+
+-- local function initialize(tfmdata,key,value)
+-- local factor = tonumber(value) or 1
+-- 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
+-- character.bottomright = -factor * olditalic -- lmtx only
+-- end
+-- end
+-- end
+--
+-- local specification = {
+-- name = "italicwidths",
+-- description = "add italic to width",
+-- manipulators = {
+-- base = initialize,
+-- node = initialize, -- only makes sense for math
+-- }
+-- }
+--
+-- registerotffeature(specification)
+-- registerafmfeature(specification)
local function initialize(tfmdata,value) -- hm, always value
if value then
diff --git a/macros/luatex/generic/luaotfload/fontloader-font-imp-tex.lua b/macros/luatex/generic/luaotfload/fontloader-font-imp-tex.lua
index b4b9a7b694..87a1ae3aa2 100644
--- a/macros/luatex/generic/luaotfload/fontloader-font-imp-tex.lua
+++ b/macros/luatex/generic/luaotfload/fontloader-font-imp-tex.lua
@@ -13,36 +13,31 @@ local otf = fonts.handlers.otf
local registerotffeature = otf.features.register
local addotffeature = otf.addfeature
--- tlig (we need numbers for some fonts so ...)
+-- We provide a few old and obsolete compatibility input features. We need numbers
+-- for some fonts so no names here. Do we also need them for afm fonts?
-local specification = {
+local tlig = {
type = "ligature",
order = { "tlig" },
prepend = true,
data = {
- -- endash = "hyphen hyphen",
- -- emdash = "hyphen hyphen hyphen",
- [0x2013] = { 0x002D, 0x002D },
- [0x2014] = { 0x002D, 0x002D, 0x002D },
- -- quotedblleft = "quoteleft quoteleft",
- -- quotedblright = "quoteright quoteright",
- -- quotedblleft = "grave grave",
- -- quotedblright = "quotesingle quotesingle",
- -- quotedblbase = "comma comma",
+ [0x2013] = { 0x002D, 0x002D },
+ [0x2014] = { 0x002D, 0x002D, 0x002D },
},
}
-addotffeature("tlig",specification)
-
-registerotffeature {
- -- this makes it a known feature (in tables)
- name = "tlig",
- description = "tex ligatures",
+local tquo = {
+ type = "ligature",
+ order = { "tquo" },
+ prepend = true,
+ data = {
+ [0x201C] = { 0x0060, 0x0060 },
+ [0x201D] = { 0x0027, 0x0027 },
+ [0x201E] = { 0x002C, 0x002C },
+ },
}
--- trep
-
-local specification = {
+local trep = {
type = "substitution",
order = { "trep" },
prepend = true,
@@ -53,13 +48,13 @@ local specification = {
},
}
-addotffeature("trep",specification)
+addotffeature("trep",trep) -- last
+addotffeature("tlig",tlig)
+addotffeature("tquo",tquo) -- first
-registerotffeature {
- -- this makes it a known feature (in tables)
- name = "trep",
- description = "tex replacements",
-}
+registerotffeature { name = "tlig", description = "tex ligatures" }
+registerotffeature { name = "tquo", description = "tex quotes" }
+registerotffeature { name = "trep", description = "tex replacements" }
-- some day this will be moved to font-imp-scripts.lua
diff --git a/macros/luatex/generic/luaotfload/fontloader-font-ini.lua b/macros/luatex/generic/luaotfload/fontloader-font-ini.lua
index 8bab6d9029..201cc69f48 100644
--- a/macros/luatex/generic/luaotfload/fontloader-font-ini.lua
+++ b/macros/luatex/generic/luaotfload/fontloader-font-ini.lua
@@ -6,9 +6,7 @@ if not modules then modules = { } end modules ['font-ini'] = {
license = "see context related readme files"
}
---[[ldx--
-<p>Not much is happening here.</p>
---ldx]]--
+-- Not much is happening here.
local allocate = utilities.storage.allocate
local sortedhash = table.sortedhash
diff --git a/macros/luatex/generic/luaotfload/fontloader-font-one.lua b/macros/luatex/generic/luaotfload/fontloader-font-one.lua
index 829f52ea04..25efc2a046 100644
--- a/macros/luatex/generic/luaotfload/fontloader-font-one.lua
+++ b/macros/luatex/generic/luaotfload/fontloader-font-one.lua
@@ -7,18 +7,16 @@ if not modules then modules = { } end modules ['font-one'] = {
license = "see context related readme files"
}
---[[ldx--
-<p>Some code may look a bit obscure but this has to do with the fact that we also use
-this code for testing and much code evolved in the transition from <l n='tfm'/> to
-<l n='afm'/> to <l n='otf'/>.</p>
-
-<p>The following code still has traces of intermediate font support where we handles
-font encodings. Eventually font encoding went away but we kept some code around in
-other modules.</p>
-
-<p>This version implements a node mode approach so that users can also more easily
-add features.</p>
---ldx]]--
+-- Some code may look a bit obscure but this has to do with the fact that we also
+-- use this code for testing and much code evolved in the transition from TFM to AFM
+-- to OTF.
+--
+-- The following code still has traces of intermediate font support where we handles
+-- font encodings. Eventually font encoding went away but we kept some code around
+-- in other modules.
+--
+-- This version implements a node mode approach so that users can also more easily
+-- add features.
local fonts, logs, trackers, containers, resolvers = fonts, logs, trackers, containers, resolvers
@@ -71,15 +69,13 @@ local overloads = fonts.mappings.overloads
local applyruntimefixes = fonts.treatments and fonts.treatments.applyfixes
---[[ldx--
-<p>We cache files. Caching is taken care of in the loader. We cheat a bit by adding
-ligatures and kern information to the afm derived data. That way we can set them faster
-when defining a font.</p>
-
-<p>We still keep the loading two phased: first we load the data in a traditional
-fashion and later we transform it to sequences. Then we apply some methods also
-used in opentype fonts (like <t>tlig</t>).</p>
---ldx]]--
+-- We cache files. Caching is taken care of in the loader. We cheat a bit by adding
+-- ligatures and kern information to the afm derived data. That way we can set them
+-- faster when defining a font.
+--
+-- We still keep the loading two phased: first we load the data in a traditional
+-- fashion and later we transform it to sequences. Then we apply some methods also
+-- used in opentype fonts (like tlig).
function afm.load(filename)
filename = resolvers.findfile(filename,'afm') or ""
@@ -312,10 +308,8 @@ local function enhance_fix_names(data)
end
end
---[[ldx--
-<p>These helpers extend the basic table with extra ligatures, texligatures
-and extra kerns. This saves quite some lookups later.</p>
---ldx]]--
+-- These helpers extend the basic table with extra ligatures, texligatures and extra
+-- kerns. This saves quite some lookups later.
local addthem = function(rawdata,ligatures)
if ligatures then
@@ -349,17 +343,14 @@ local function enhance_add_ligatures(rawdata)
addthem(rawdata,afm.helpdata.ligatures)
end
---[[ldx--
-<p>We keep the extra kerns in separate kerning tables so that we can use
-them selectively.</p>
---ldx]]--
-
--- This is rather old code (from the beginning when we had only tfm). If
--- we unify the afm data (now we have names all over the place) then
--- we can use shcodes but there will be many more looping then. But we
--- could get rid of the tables in char-cmp then. Als, in the generic version
--- we don't use the character database. (Ok, we can have a context specific
--- variant).
+-- We keep the extra kerns in separate kerning tables so that we can use them
+-- selectively.
+--
+-- This is rather old code (from the beginning when we had only tfm). If we unify
+-- the afm data (now we have names all over the place) then we can use shcodes but
+-- there will be many more looping then. But we could get rid of the tables in
+-- char-cmp then. Als, in the generic version we don't use the character database.
+-- (Ok, we can have a context specific variant).
local function enhance_add_extra_kerns(rawdata) -- using shcodes is not robust here
local descriptions = rawdata.descriptions
@@ -440,9 +431,7 @@ local function enhance_add_extra_kerns(rawdata) -- using shcodes is not robust h
do_it_copy(afm.helpdata.rightkerned)
end
---[[ldx--
-<p>The copying routine looks messy (and is indeed a bit messy).</p>
---ldx]]--
+-- The copying routine looks messy (and is indeed a bit messy).
local function adddimensions(data) -- we need to normalize afm to otf i.e. indexed table instead of name
if data then
@@ -619,11 +608,9 @@ end
return nil
end
---[[ldx--
-<p>Originally we had features kind of hard coded for <l n='afm'/> files but since I
-expect to support more font formats, I decided to treat this fontformat like any
-other and handle features in a more configurable way.</p>
---ldx]]--
+-- Originally we had features kind of hard coded for AFM files but since I expect to
+-- support more font formats, I decided to treat this fontformat like any other and
+-- handle features in a more configurable way.
function afm.setfeatures(tfmdata,features)
local okay = constructors.initializefeatures("afm",tfmdata,features,trace_features,report_afm)
@@ -715,13 +702,10 @@ local function afmtotfm(specification)
end
end
---[[ldx--
-<p>As soon as we could intercept the <l n='tfm'/> reader, I implemented an
-<l n='afm'/> reader. Since traditional <l n='pdftex'/> could use <l n='opentype'/>
-fonts with <l n='afm'/> companions, the following method also could handle
-those cases, but now that we can handle <l n='opentype'/> directly we no longer
-need this features.</p>
---ldx]]--
+-- As soon as we could intercept the TFM reader, I implemented an AFM reader. Since
+-- traditional pdfTeX could use OpenType fonts with AFM companions, the following
+-- method also could handle those cases, but now that we can handle OpenType
+-- directly we no longer need this features.
local function read_from_afm(specification)
local tfmdata = afmtotfm(specification)
@@ -736,9 +720,7 @@ local function read_from_afm(specification)
return tfmdata
end
---[[ldx--
-<p>We have the usual two modes and related features initializers and processors.</p>
---ldx]]--
+-- We have the usual two modes and related features initializers and processors.
registerafmfeature {
name = "mode",
diff --git a/macros/luatex/generic/luaotfload/fontloader-font-onr.lua b/macros/luatex/generic/luaotfload/fontloader-font-onr.lua
index c33b09f9e2..6234742a3d 100644
--- a/macros/luatex/generic/luaotfload/fontloader-font-onr.lua
+++ b/macros/luatex/generic/luaotfload/fontloader-font-onr.lua
@@ -7,18 +7,16 @@ if not modules then modules = { } end modules ['font-onr'] = {
license = "see context related readme files"
}
---[[ldx--
-<p>Some code may look a bit obscure but this has to do with the fact that we also use
-this code for testing and much code evolved in the transition from <l n='tfm'/> to
-<l n='afm'/> to <l n='otf'/>.</p>
-
-<p>The following code still has traces of intermediate font support where we handles
-font encodings. Eventually font encoding went away but we kept some code around in
-other modules.</p>
-
-<p>This version implements a node mode approach so that users can also more easily
-add features.</p>
---ldx]]--
+-- Some code may look a bit obscure but this has to do with the fact that we also
+-- use this code for testing and much code evolved in the transition from TFM to AFM
+-- to OTF.
+--
+-- The following code still has traces of intermediate font support where we handles
+-- font encodings. Eventually font encoding went away but we kept some code around
+-- in other modules.
+--
+-- This version implements a node mode approach so that users can also more easily
+-- add features.
local fonts, logs, trackers, resolvers = fonts, logs, trackers, resolvers
@@ -44,12 +42,9 @@ afm.readers = readers
afm.version = 1.513 -- incrementing this number one up will force a re-cache
---[[ldx--
-<p>We start with the basic reader which we give a name similar to the built in <l n='tfm'/>
-and <l n='otf'/> reader.</p>
-<p>We use a new (unfinished) pfb loader but I see no differences between the old
-and new vectors (we actually had one bad vector with the old loader).</p>
---ldx]]--
+-- We start with the basic reader which we give a name similar to the built in TFM
+-- and OTF reader. We use a PFB loader but I see no differences between the old and
+-- new vectors (we actually had one bad vector with the old loader).
local get_indexes, get_shapes
@@ -211,6 +206,8 @@ do
+ P(1)
)^0 * Carg(1)
+ -- cache this?
+
local function loadpfbvector(filename,shapestoo,streams)
-- for the moment limited to encoding only
@@ -303,11 +300,10 @@ do
end
---[[ldx--
-<p>We start with the basic reader which we give a name similar to the built in <l n='tfm'/>
-and <l n='otf'/> reader. We only need data that is relevant for our use. We don't support
-more complex arrangements like multiple master (obsolete), direction specific kerning, etc.</p>
---ldx]]--
+-- We start with the basic reader which we give a name similar to the built in TFM
+-- and OTF reader. We only need data that is relevant for our use. We don't support
+-- more complex arrangements like multiple master (obsolete), direction specific
+-- kerning, etc.
local spacer = patterns.spacer
local whitespace = patterns.whitespace
diff --git a/macros/luatex/generic/luaotfload/fontloader-font-osd.lua b/macros/luatex/generic/luaotfload/fontloader-font-osd.lua
index ecf8009f91..4177e3035a 100644
--- a/macros/luatex/generic/luaotfload/fontloader-font-osd.lua
+++ b/macros/luatex/generic/luaotfload/fontloader-font-osd.lua
@@ -6,16 +6,6 @@ if not modules then modules = { } end modules ['font-osd'] = { -- script devanag
license = "see context related readme files"
}
--- local experiment1 = false
--- local experiment2 = false
--- local experiment2b1 = false
--- local experiment2b2 = false
-
--- experiments.register("fonts.indic.experiment1", function(v) experiment1 = v end)
--- experiments.register("fonts.indic.experiment2", function(v) experiment2 = v end)
--- experiments.register("fonts.indic.experiment2b1", function(v) experiment2b1 = v end)
--- experiments.register("fonts.indic.experiment2b2", function(v) experiment2b2 = v end)
-
-- we need to check nbsphash (context only)
-- A few remarks:
@@ -70,6 +60,10 @@ if not modules then modules = { } end modules ['font-osd'] = { -- script devanag
-- conjuncts options that can deal with fuzzy fonts. The machinery does what it has
-- to do but some fonts expect more magic to be applied.
--
+-- Some changes have been reverted because they interfere with proper fonts. We just
+-- don't support bad fonts with heuristics any longer. If needed one can use the
+-- translitaration filters that come with ConTeXt.
+--
-- Hans Hagen, PRAGMA-ADE, Hasselt NL
-- Todo:
@@ -1392,16 +1386,13 @@ local function reorder_one(head,start,stop,font,attr,nbspaces)
end
if reph or vattu then
--- print(">>> has reph or vattu")
local current = start
local cns = nil
local done = false
while current ~= stop do
--- print("\t>>> current ~= stop yet")
local c = current
local n = getnext(current)
if ra[getchar(current)] and halant[getchar(n)] then
--- print("\t\t>>> current ra; next halant")
c = n
n = getnext(n)
local b, bn = base, base
@@ -1415,7 +1406,6 @@ local function reorder_one(head,start,stop,font,attr,nbspaces)
if getstate(current,s_rphf) then
-- position Reph (Ra + H) after post-base 'matra' (if any) since these
-- become marks on the 'matra', not on the base glyph
--- print("\t\t\t>>> ra + halant form → reph")
if b ~= current then
if current == start then
if head == start then
@@ -1435,7 +1425,6 @@ local function reorder_one(head,start,stop,font,attr,nbspaces)
end
elseif cns and getnext(cns) ~= current then -- todo: optimize next
-- position below-base Ra (vattu) following the consonants on which it is placed (either the base consonant or one of the pre-base consonants)
--- print("\t\t\t>>> ra below base (vattu) → rkrf")
local cp = getprev(current)
local cnsn = getnext(cns)
setlink(cp,n)
@@ -1449,17 +1438,14 @@ local function reorder_one(head,start,stop,font,attr,nbspaces)
current = getprev(n)
end
else
--- print("\t\t>>> NOT! current ra; next halant")
local char = getchar(current)
if consonant[char] then
--- print("\t\t\t>>> is consonant")
cns = current
local next = getnext(cns)
if halant[getchar(next)] then
cns = next
end
if not vatucache[char] then
--- print("\t\t\t\t>>> is in vatucache")
next = getnext(cns)
while dependent_vowel[getchar(next)] do
cns = next
@@ -1467,7 +1453,6 @@ local function reorder_one(head,start,stop,font,attr,nbspaces)
end
end
elseif char == c_nbsp then
--- print("\t\t\t>>> is nbsp")
nbspaces = nbspaces + 1
cns = current
local next = getnext(cns)
@@ -1936,8 +1921,6 @@ local function reorder_two(head,start,stop,font,attr,nbspaces) -- maybe do a pas
reorderreph.coverage = { } -- use local
rephbase[font] = { } -- use local
--- print("!!!!!! reorder two ")
-
for i=1,#seqsubset do
-- this can be done more efficient, the last test and less getnext
@@ -2064,7 +2047,7 @@ local function reorder_two(head,start,stop,font,attr,nbspaces) -- maybe do a pas
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
-- if syllable starts with Ra + H and script has 'Reph' then exclude Reph from candidates for base consonants
@@ -2125,10 +2108,15 @@ local function reorder_two(head,start,stop,font,attr,nbspaces) -- maybe do a pas
end
end
else -- not Stand Alone cluster
--- print("!!!! not standalone cluster")
local last = getnext(stop)
while current ~= last do -- find base consonant
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
@@ -2138,6 +2126,12 @@ local function reorder_two(head,start,stop,font,attr,nbspaces) -- maybe do a pas
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
@@ -2195,10 +2189,7 @@ local function reorder_two(head,start,stop,font,attr,nbspaces) -- maybe do a pas
end
end
--
--- print("char: " .. char)
--- if not moved[current] and dependent_vowel[char] then
- if dependent_vowel[char] then
--- print(">>!! dependent vowel")
+ if not moved[current] and dependent_vowel[char] then
if pre_mark[char] then -- or: if before_main or before_half
moved[current] = true
-- can be helper to remove one node
@@ -2251,14 +2242,11 @@ local function reorder_two(head,start,stop,font,attr,nbspaces) -- maybe do a pas
end
elseif above_mark[char] then
-- after main consonant
- 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
-- after subjoined consonants
target = subpos
@@ -2502,12 +2490,7 @@ local function analyze_next_chars_one(c,font,variant) -- skip one dependent vowe
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
- -- for messy fonts
- 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
@@ -2710,10 +2693,6 @@ local function analyze_next_chars_two(c,font)
for k=1,#vowels do
local v = vowels[k]
if pre_mark[v] and not already_pre_mark then
--- print(">>> pre_mark")
--- if dependent_vowel[v] then
--- print(">>>> dependent vowel")
--- end
already_pre_mark = true
elseif above_mark[v] and not already_above_mark then
already_above_mark = true
@@ -2731,12 +2710,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
- -- for messy fonts
- 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
@@ -3068,15 +3042,12 @@ local function method_two(head,font,attr)
end
end
if independent_vowel[char] then
--- print("!!>>> independent_vowel")
-- vowel-based syllable: [Ra+H]+V+[N]+[<[<ZWJ|ZWNJ>]+H+C|ZWJ+C>]+[{M}+[N]+[H]]+[SM]+[(VD)]
current = analyze_next_chars_one(c,font,1)
syllableend = current
else
--- print("!!>>> dependent vowel")
local standalone = char == c_nbsp
if standalone then
--- print("!!>>> standalone")
nbspaces = nbspaces + 1
local p = getprev(current)
if not p then
@@ -3090,12 +3061,10 @@ local function method_two(head,font,attr)
end
end
if standalone then
--- print("!!>>>>>>> next standalone")
-- Stand Alone cluster (at the start of the word only): #[Ra+H]+NBSP+[N]+[<[<ZWJ|ZWNJ>]+H+C>]+[{M}+[N]+[H]]+[SM]+[(VD)]
current = analyze_next_chars_one(c,font,2)
syllableend = current
elseif consonant[getchar(current)] then
--- print("!!>>>>>>> a consonant")
-- WHY current INSTEAD OF c ?
-- Consonant syllable: {C+[N]+<H+[<ZWNJ|ZWJ>]|<ZWNJ|ZWJ>+H>} + C+[N]+[A] + [< H+[<ZWNJ|ZWJ>] | {M}+[N]+[H]>]+[SM]+[(VD)]
current = analyze_next_chars_two(current,font) -- not c !
@@ -3104,7 +3073,6 @@ local function method_two(head,font,attr)
end
end
if syllableend then
--- print("!!!>>> syllable end")
syllabe = syllabe + 1
local c = syllablestart
local n = getnext(syllableend)
diff --git a/macros/luatex/generic/luaotfload/fontloader-font-ota.lua b/macros/luatex/generic/luaotfload/fontloader-font-ota.lua
index a8f9f0047c..160d0d0edb 100644
--- a/macros/luatex/generic/luaotfload/fontloader-font-ota.lua
+++ b/macros/luatex/generic/luaotfload/fontloader-font-ota.lua
@@ -54,10 +54,8 @@ local chardata = characters and characters.data
local otffeatures = fonts.constructors.features.otf
local registerotffeature = otffeatures.register
---[[ldx--
-<p>Analyzers run per script and/or language and are needed in order to
-process features right.</p>
---ldx]]--
+-- Analyzers run per script and/or language and are needed in order to process
+-- features right.
local setstate = nuts.setstate
local getstate = nuts.getstate
diff --git a/macros/luatex/generic/luaotfload/fontloader-font-otc.lua b/macros/luatex/generic/luaotfload/fontloader-font-otc.lua
index 67b77b1113..0787a20359 100644
--- a/macros/luatex/generic/luaotfload/fontloader-font-otc.lua
+++ b/macros/luatex/generic/luaotfload/fontloader-font-otc.lua
@@ -142,6 +142,12 @@ local function addfeature(data,feature,specifications,prepareonly)
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
@@ -780,7 +786,12 @@ 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
+ -- see ebgaramond hack
+ elseif featuretype == "substitution" then
-- see font-imp-tweaks: we directly pass a mapping so no checks done
category = "gsub"
coverage = (mapping and list) or prepare_substitution(list,featuretype,nocheck)
diff --git a/macros/luatex/generic/luaotfload/fontloader-font-otl.lua b/macros/luatex/generic/luaotfload/fontloader-font-otl.lua
index f36e533ca0..0825077b3f 100644
--- a/macros/luatex/generic/luaotfload/fontloader-font-otl.lua
+++ b/macros/luatex/generic/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.120 -- beware: also sync font-mis.lua and in mtx-fonts
+otf.version = 3.133 -- 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)
@@ -643,25 +643,33 @@ local function read_from_otf(specification)
return tfmdata
end
-local function checkmathsize(tfmdata,mathsize)
- local mathdata = tfmdata.shared.rawdata.metadata.math
- local mathsize = tonumber(mathsize)
- if mathdata then -- we cannot use mathparameters as luatex will complain
- local parameters = tfmdata.parameters
- parameters.scriptpercentage = mathdata.ScriptPercentScaleDown
- parameters.scriptscriptpercentage = mathdata.ScriptScriptPercentScaleDown
- parameters.mathsize = mathsize -- only when a number !
- end
-end
-
-registerotffeature {
- name = "mathsize",
- description = "apply mathsize specified in the font",
- initializers = {
- base = checkmathsize,
- node = checkmathsize,
- }
-}
+-- if context then
+--
+-- -- so the next will go to some generic module instead
+--
+-- else
+--
+-- local function checkmathsize(tfmdata,mathsize)
+-- local mathdata = tfmdata.shared.rawdata.metadata.math
+-- local mathsize = tonumber(mathsize)
+-- if mathdata then -- we cannot use mathparameters as luatex will complain
+-- local parameters = tfmdata.parameters
+-- parameters.scriptpercentage = mathdata.ScriptPercentScaleDown
+-- parameters.scriptscriptpercentage = mathdata.ScriptScriptPercentScaleDown
+-- parameters.mathsize = mathsize -- only when a number !
+-- end
+-- end
+--
+-- registerotffeature {
+-- name = "mathsize",
+-- description = "apply mathsize specified in the font",
+-- initializers = {
+-- base = checkmathsize,
+-- node = checkmathsize,
+-- }
+-- }
+--
+-- end
-- readers
diff --git a/macros/luatex/generic/luaotfload/fontloader-font-oto.lua b/macros/luatex/generic/luaotfload/fontloader-font-oto.lua
index 1475fcf678..0689f4dfb5 100644
--- a/macros/luatex/generic/luaotfload/fontloader-font-oto.lua
+++ b/macros/luatex/generic/luaotfload/fontloader-font-oto.lua
@@ -6,6 +6,9 @@ if not modules then modules = { } end modules ['font-oto'] = { -- original tex
license = "see context related readme files"
}
+-- Todo: Enable fixes from the lmt to here. Also in font-con.lua wrt the changed
+-- assignments. (Around texlive 2024 in order not to disturb generic.)
+
local concat, unpack = table.concat, table.unpack
local insert, remove = table.insert, table.remove
local format, gmatch, gsub, find, match, lower, strip = string.format, string.gmatch, string.gsub, string.find, string.match, string.lower, string.strip
@@ -260,7 +263,9 @@ local function preparesubstitutions(tfmdata,feature,value,validlookups,lookuplis
for i=1,#steps do
for unicode, data in next, steps[i].coverage do
if unicode ~= data then
+-- if not changed[unicode] then
changed[unicode] = data
+-- end
end
if trace_singles then
report_substitution(feature,sequence,descriptions,unicode,data)
@@ -273,7 +278,9 @@ local function preparesubstitutions(tfmdata,feature,value,validlookups,lookuplis
local replacement = data[alternate]
if replacement then
if unicode ~= replacement then
+-- if not changed[unicode] then
changed[unicode] = replacement
+-- end
end
if trace_alternatives then
report_alternate(feature,sequence,descriptions,unicode,replacement,value,"normal")
@@ -281,7 +288,9 @@ local function preparesubstitutions(tfmdata,feature,value,validlookups,lookuplis
elseif defaultalt == "first" then
replacement = data[1]
if unicode ~= replacement then
+-- if not changed[unicode] then
changed[unicode] = replacement
+-- end
end
if trace_alternatives then
report_alternate(feature,sequence,descriptions,unicode,replacement,value,defaultalt)
@@ -289,7 +298,9 @@ local function preparesubstitutions(tfmdata,feature,value,validlookups,lookuplis
elseif defaultalt == "last" then
replacement = data[#data]
if unicode ~= replacement then
+-- if not changed[unicode] then
changed[unicode] = replacement
+-- end
end
if trace_alternatives then
report_alternate(feature,sequence,descriptions,unicode,replacement,value,defaultalt)
@@ -504,6 +515,9 @@ local function featuresinitializer(tfmdata,value)
local value = features[feature]
if value then
local validlookups, lookuplist = collectlookups(rawdata,feature,script,language)
+-- if not validlookups and not lookuplist and script == "math" then
+-- validlookups, lookuplist = collectlookups(rawdata,feature,"dflt","dflt")
+-- end
if not validlookups then
-- skip
elseif basesubstitutions and basesubstitutions[feature] then
diff --git a/macros/luatex/generic/luaotfload/fontloader-font-otr.lua b/macros/luatex/generic/luaotfload/fontloader-font-otr.lua
index 339de109f8..1e6f94e455 100644
--- a/macros/luatex/generic/luaotfload/fontloader-font-otr.lua
+++ b/macros/luatex/generic/luaotfload/fontloader-font-otr.lua
@@ -66,6 +66,7 @@ if not modules then modules = { } end modules ['font-otr'] = {
-- require("char-ini")
-- end
+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
@@ -1189,6 +1190,9 @@ readers.hmtx = function(f,fontdata,specification)
-- if leftsidebearing ~= 0 then
-- glyph.lsb = leftsidebearing
-- end
+-- if leftsidebearing ~= 0 then
+-- glyph.lsb = leftsidebearing
+-- end
end
-- The next can happen in for instance a monospace font or in a cjk font
-- with fixed widths.
@@ -1683,7 +1687,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) -- check later versions
local noftables = readushort(f)
local records = { }
local unicodecid = false
@@ -2425,25 +2429,29 @@ function readers.loadfont(filename,n,instance)
nofsubfonts = fontdata.subfonts and #fontdata.subfonts or nil,
},
resources = {
- -- filename = fontdata.filename,
- filename = filename,
- private = privateoffset,
- duplicates = fontdata.duplicates or { },
- features = fontdata.features or { }, -- we need to add these in the loader
- sublookups = fontdata.sublookups or { }, -- we need to add these in the loader
- marks = fontdata.marks or { }, -- we need to add these in the loader
- markclasses = fontdata.markclasses or { }, -- we need to add these in the loader
- marksets = fontdata.marksets or { }, -- we need to add these in the loader
- sequences = fontdata.sequences or { }, -- we need to add these in the loader
- variants = fontdata.variants, -- variant -> unicode -> glyph
- version = getname(fontdata,"version"),
- cidinfo = fontdata.cidinfo,
- mathconstants = fontdata.mathconstants,
- colorpalettes = fontdata.colorpalettes,
- svgshapes = fontdata.svgshapes,
- pngshapes = fontdata.pngshapes,
- variabledata = fontdata.variabledata,
- foundtables = fontdata.foundtables,
+ -- filename = fontdata.filename,
+ filename = filename,
+ private = privateoffset,
+ duplicates = fontdata.duplicates or { },
+ features = fontdata.features or { }, -- we need to add these in the loader
+ sublookups = fontdata.sublookups or { }, -- we need to add these in the loader
+ marks = fontdata.marks or { }, -- we need to add these in the loader
+ markclasses = fontdata.markclasses or { }, -- we need to add these in the loader
+ marksets = fontdata.marksets or { }, -- we need to add these in the loader
+ sequences = fontdata.sequences or { }, -- we need to add these in the loader
+ variants = fontdata.variants, -- variant -> unicode -> glyph
+ version = getname(fontdata,"version"),
+ 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,
+ foundtables = fontdata.foundtables,
},
}
end
diff --git a/macros/luatex/generic/luaotfload/fontloader-font-ots.lua b/macros/luatex/generic/luaotfload/fontloader-font-ots.lua
index 7de108d4c8..48f85c3658 100644
--- a/macros/luatex/generic/luaotfload/fontloader-font-ots.lua
+++ b/macros/luatex/generic/luaotfload/fontloader-font-ots.lua
@@ -7,87 +7,90 @@ if not modules then modules = { } end modules ['font-ots'] = { -- sequences
license = "see context related readme files",
}
---[[ldx--
-<p>This module is a bit more split up that I'd like but since we also want to test
-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 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
-and is a better reference. There is also some information in the FontForge help
-files. In the end we rely most on the Microsoft specification.</p>
-
-<p>Because there is so much possible, fonts might contain bugs and/or be made to
-work with certain rederers. These may evolve over time which may have the side
-effect that suddenly fonts behave differently. We don't want to catch all font
-issues.</p>
-
-<p>After a lot of experiments (mostly by Taco, me and Idris) the first implementation
-was already quite useful. When it did most of what we wanted, a more optimized version
-evolved. Of course all errors are mine and of course the code can be improved. There
-are quite some optimizations going on here and processing speed is currently quite
-acceptable and has been improved over time. Many complex scripts are not yet supported
-yet, but I will look into them as soon as <l n='context'/> users ask for it.</p>
-
-<p>The specification leaves room for interpretation. In case of doubt the Microsoft
-implementation is the reference as it is the most complete one. As they deal with
-lots of scripts and fonts, Kai and Ivo did a lot of testing of the generic code and
-their suggestions help improve the code. I'm aware that not all border cases can be
-taken care of, unless we accept excessive runtime, and even then the interference
-with other mechanisms (like hyphenation) are not trivial.</p>
-
-<p>Especially discretionary handling has been improved much by Kai Eigner who uses complex
-(latin) fonts. The current implementation is a compromis between his patches and my code
-and in the meantime performance is quite ok. We cannot check all border cases without
-compromising speed but so far we're okay. Given good test cases we can probably improve
-it here and there. Especially chain lookups are non trivial with discretionaries but
-things got much better over time thanks to Kai.</p>
-
-<p>Glyphs are indexed not by unicode but in their own way. This is because there is no
-relationship with unicode at all, apart from the fact that a font might cover certain
-ranges of characters. One character can have multiple shapes. However, at the
-<l n='tex'/> end we use unicode so and all extra glyphs are mapped into a private
-space. This is needed because we need to access them and <l n='tex'/> has to include
-then in the output eventually.</p>
-
-<p>The initial data table is rather close to the open type specification and also not
-that different from the one produced by <l n='fontforge'/> but we uses hashes instead.
-In <l n='context'/> that table is packed (similar tables are shared) and cached on disk
-so that successive runs can use the optimized table (after loading the table is
-unpacked).</p>
-
-<p>This module is sparsely documented because it is has been a moving target. The
-table format of the reader changed a bit over time and we experiment a lot with
-different methods for supporting features. By now the structures are quite stable</p>
-
-<p>Incrementing the version number will force a re-cache. We jump the number by one
-when there's a fix in the reader or processing code that can result in different
-results.</p>
-
-<p>This code is also used outside context but in context it has to work with other
-mechanisms. Both put some constraints on the code here.</p>
-
---ldx]]--
-
--- Remark: We assume that cursives don't cross discretionaries which is okay because it
--- is only used in semitic scripts.
+-- I need to check the description at the microsoft site ... it has been improved so
+-- maybe there are some interesting details there. Most below is based on old and
+-- incomplete documentation and involved quite a bit of guesswork (checking with the
+-- abstract uniscribe of those days. But changing things is tricky!
+--
+-- This module is a bit more split up that I'd like but since we also want to test
+-- with plain TeX it has to be so. This module is part of ConTeXt and discussion
+-- about improvements and functionality mostly happens on the ConTeXt mailing list.
+--
+-- 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
+-- and is a better reference. There is also some information in the FontForge help
+-- files. In the end we rely most on the Microsoft specification.
+--
+-- Because there is so much possible, fonts might contain bugs and/or be made to
+-- work with certain rederers. These may evolve over time which may have the side
+-- effect that suddenly fonts behave differently. We don't want to catch all font
+-- issues.
+--
+-- After a lot of experiments (mostly by Taco, me and Idris) the first
+-- implementation was already quite useful. When it did most of what we wanted, a
+-- more optimized version evolved. Of course all errors are mine and of course the
+-- code can be improved. There are quite some optimizations going on here and
+-- processing speed is currently quite acceptable and has been improved over time.
+-- Many complex scripts are not yet supported yet, but I will look into them as soon
+-- as ConTeXt users ask for it.
+--
+-- The specification leaves room for interpretation. In case of doubt the Microsoft
+-- implementation is the reference as it is the most complete one. As they deal with
+-- lots of scripts and fonts, Kai and Ivo did a lot of testing of the generic code
+-- and their suggestions help improve the code. I'm aware that not all border cases
+-- can be taken care of, unless we accept excessive runtime, and even then the
+-- interference with other mechanisms (like hyphenation) are not trivial.
+--
+-- Especially discretionary handling has been improved much by Kai Eigner who uses
+-- complex (latin) fonts. The current implementation is a compromis between his
+-- patches and my code and in the meantime performance is quite ok. We cannot check
+-- all border cases without compromising speed but so far we're okay. Given good
+-- test cases we can probably improve it here and there. Especially chain lookups
+-- are non trivial with discretionaries but things got much better over time thanks
+-- to Kai.
+--
+-- Glyphs are indexed not by unicode but in their own way. This is because there is
+-- no relationship with unicode at all, apart from the fact that a font might cover
+-- certain ranges of characters. One character can have multiple shapes. However, at
+-- the TeX end we use unicode so and all extra glyphs are mapped into a private
+-- space. This is needed because we need to access them and TeX has to include then
+-- in the output eventually.
+--
+-- The initial data table is rather close to the open type specification and also
+-- not that different from the one produced by Fontforge but we uses hashes instead.
+-- In ConTeXt that table is packed (similar tables are shared) and cached on disk so
+-- that successive runs can use the optimized table (after loading the table is
+-- unpacked).
+--
+-- This module is sparsely documented because it is has been a moving target. The
+-- table format of the reader changed a bit over time and we experiment a lot with
+-- different methods for supporting features. By now the structures are quite stable
+--
+-- Incrementing the version number will force a re-cache. We jump the number by one
+-- when there's a fix in the reader or processing code that can result in different
+-- results.
+--
+-- This code is also used outside ConTeXt but in ConTeXt it has to work with other
+-- mechanisms. Both put some constraints on the code here.
+--
+-- Remark: We assume that cursives don't cross discretionaries which is okay because
+-- it is only used in semitic scripts.
--
-- Remark: We assume that marks precede base characters.
--
--- Remark: When complex ligatures extend into discs nodes we can get side effects. Normally
--- this doesn't happen; ff\d{l}{l}{l} in lm works but ff\d{f}{f}{f}.
+-- Remark: When complex ligatures extend into discs nodes we can get side effects.
+-- Normally this doesn't happen; ff\d{l}{l}{l} in lm works but ff\d{f}{f}{f}.
--
-- Todo: check if we copy attributes to disc nodes if needed.
--
--- Todo: it would be nice if we could get rid of components. In other places we can use
--- the unicode properties. We can just keep a lua table.
+-- Todo: it would be nice if we could get rid of components. In other places we can
+-- use the unicode properties. We can just keep a lua table.
--
--- Remark: We do some disc juggling where we need to keep in mind that the pre, post and
--- replace fields can have prev pointers to a nesting node ... I wonder if that is still
--- needed.
+-- Remark: We do some disc juggling where we need to keep in mind that the pre, post
+-- and replace fields can have prev pointers to a nesting node ... I wonder if that
+-- is still needed.
--
-- Remark: This is not possible:
--
@@ -165,13 +168,8 @@ local forcepairadvance = false -- for testing
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")
@@ -197,7 +195,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
@@ -229,10 +226,10 @@ 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
@@ -244,12 +241,8 @@ local setmetatableindex = table.setmetatableindex
local nextnode = nuts.traversers.node
------ zwnj = 0x200C
------ zwj = 0x200D
-
local nodecodes = nodes.nodecodes
local glyphcodes = nodes.glyphcodes
-local disccodes = nodes.disccodes
local glyph_code = nodecodes.glyph
local glue_code = nodecodes.glue
@@ -261,8 +254,7 @@ 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")
@@ -377,7 +369,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
@@ -455,7 +447,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
@@ -483,7 +475,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)
@@ -536,7 +527,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
@@ -560,7 +550,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) -- is this ok ? we position later anyway
head, current = insertnodeafter(head,current,n) -- unlikely that mark has components
elseif trace_marks then
@@ -634,67 +624,68 @@ end
local function multiple_glyphs(head,start,multiple,skiphash,what,stop) -- what to do with skiphash matches here
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 sn = getnext(start)
+ for i=2,nofmultiples do
-- untested:
--
-- while ignoremarks and marks[getchar(sn)] then
-- local sn = getnext(sn)
-- end
- local n = copy_node(start) -- ignore components
+ local n = copynode(start) -- ignore components
resetinjection(n)
- setchar(n,multiple[k])
+ setchar(n,multiple[i])
insertnodeafter(head,start,n)
start = n
end
- if what ~= true and repeatablemultiples then
- -- This is just some experimental code; we might introduce gsub_extensible
- -- some day instead. Beware: when we have a feature that mixes alternates and
- -- multiples we need to make sure we don't handle the alternate string values
- -- here. This might eventually become an lmtx only feature.
- 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
- -- won't happen because currently we don't split these values
- m = what.middle
- f = what.first
- l = what.last
+ end
+ if what ~= true and repeatablemultiples then
+ -- This is just some experimental code; we might introduce gsub_extensible
+ -- some day instead. Beware: when we have a feature that mixes alternates and
+ -- multiples we need to make sure we don't handle the alternate string values
+ -- here.
+ 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
- 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) -- ignore components
- resetinjection(n)
- insertnodeafter(head,first,n)
- end
+ elseif kind == "table" then
+ -- won't happen because currently we don't split these values
+ 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) -- ignore components
+ resetinjection(n)
+ insertnodeafter(head,first,n)
end
- if f and f > 1 then
- for i=2,f do
- local n = copynode(first) -- ignore components
- resetinjection(n)
- insertnodeafter(head,first,n)
- end
+ end
+ if f and f > 1 then
+ for i=2,f do
+ local n = copynode(first) -- ignore components
+ resetinjection(n)
+ insertnodeafter(head,first,n)
end
- if l and l > 1 then
- for i=2,l do
- local n = copynode(start) -- ignore components
- resetinjection(n)
- insertnodeafter(head,start,n)
- start = n
- end
+ end
+ if l and l > 1 then
+ for i=2,l do
+ local n = copynode(start) -- ignore components
+ resetinjection(n)
+ insertnodeafter(head,start,n)
+ start = n
end
end
end
@@ -894,9 +885,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 -- was: getprev(stop) -- Kai: needs checking on your samples
- local liat = find_node_tail(copy)
+ local liat = findnodetail(copy)
if pre then
setlink(liat,pre)
end
@@ -907,7 +898,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
@@ -1045,10 +1036,8 @@ function handlers.gpos_pair(head,start,dataset,sequence,kerns,rlmode,skiphash,st
end
end
---[[ldx--
-<p>We get hits on a mark, but we're not sure if the it has to be applied so
-we need to explicitly test for basechar, baselig and basemark entries.</p>
---ldx]]--
+-- We get hits on a mark, but we're not sure if the it has to be applied so we need
+-- to explicitly test for basechar, baselig and basemark entries.
function handlers.gpos_mark2base(head,start,dataset,sequence,markanchors,rlmode,skiphash)
local markchar = getchar(start)
@@ -1243,10 +1232,8 @@ function handlers.gpos_cursive(head,start,dataset,sequence,exitanchors,rlmode,sk
return head, start, false
end
---[[ldx--
-<p>I will implement multiple chain replacements once I run into a font that uses
-it. It's not that complex to handle.</p>
---ldx]]--
+-- I will implement multiple chain replacements once I run into a font that uses it.
+-- It's not that complex to handle.
local chainprocs = { }
@@ -1299,29 +1286,22 @@ end
chainprocs.reversesub = reversesub
---[[ldx--
-<p>This chain stuff is somewhat tricky since we can have a sequence of actions to be
-applied: single, alternate, multiple or ligature where ligature can be an invalid
-one in the sense that it will replace multiple by one but not neccessary one that
-looks like the combination (i.e. it is the counterpart of multiple then). For
-example, the following is valid:</p>
-
-<typing>
-<line>xxxabcdexxx [single a->A][multiple b->BCD][ligature cde->E] xxxABCDExxx</line>
-</typing>
-
-<p>Therefore we we don't really do the replacement here already unless we have the
-single lookup case. The efficiency of the replacements can be improved by deleting
-as less as needed but that would also make the code even more messy.</p>
---ldx]]--
-
---[[ldx--
-<p>Here we replace start by a single variant.</p>
---ldx]]--
-
--- To be done (example needed): what if > 1 steps
-
--- this is messy: do we need this disc checking also in alternaties?
+-- This chain stuff is somewhat tricky since we can have a sequence of actions to be
+-- applied: single, alternate, multiple or ligature where ligature can be an invalid
+-- one in the sense that it will replace multiple by one but not neccessary one that
+-- looks like the combination (i.e. it is the counterpart of multiple then). For
+-- example, the following is valid:
+--
+-- xxxabcdexxx [single a->A][multiple b->BCD][ligature cde->E] xxxABCDExxx
+--
+-- Therefore we we don't really do the replacement here already unless we have the
+-- single lookup case. The efficiency of the replacements can be improved by
+-- deleting as less as needed but that would also make the code even more messy.
+--
+-- Here we replace start by a single variant.
+--
+-- To be done : what if > 1 steps (example needed)
+-- This is messy: do we need this disc checking also in alternates?
local function reportzerosteps(dataset,sequence)
logwarning("%s: no steps",cref(dataset,sequence))
@@ -1357,7 +1337,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
@@ -1397,9 +1377,7 @@ function chainprocs.gsub_single(head,start,stop,dataset,sequence,currentlookup,r
return head, start, false
end
---[[ldx--
-<p>Here we replace start by new glyph. First we delete the rest of the match.</p>
---ldx]]--
+-- Here we replace start by new glyph. First we delete the rest of the match.
-- char_1 mark_1 -> char_x mark_1 (ignore marks)
-- char_1 mark_1 -> char_x
@@ -1451,9 +1429,7 @@ function chainprocs.gsub_alternate(head,start,stop,dataset,sequence,currentlooku
return head, start, false
end
---[[ldx--
-<p>Here we replace start by a sequence of new glyphs.</p>
---ldx]]--
+-- Here we replace start by a sequence of new glyphs.
function chainprocs.gsub_multiple(head,start,stop,dataset,sequence,currentlookup,rlmode,skiphash,chainindex)
local mapping = currentlookup.mapping
@@ -1477,11 +1453,9 @@ function chainprocs.gsub_multiple(head,start,stop,dataset,sequence,currentlookup
return head, start, false
end
---[[ldx--
-<p>When we replace ligatures we use a helper that handles the marks. I might change
-this function (move code inline and handle the marks by a separate function). We
-assume rather stupid ligatures (no complex disc nodes).</p>
---ldx]]--
+-- When we replace ligatures we use a helper that handles the marks. I might change
+-- this function (move code inline and handle the marks by a separate function). We
+-- assume rather stupid ligatures (no complex disc nodes).
-- compare to handlers.gsub_ligature which is more complex ... why
@@ -1952,7 +1926,7 @@ do if not userkern then -- generic
local setkern = nuts.setkern -- not injections.setkern
userkern = function(k)
- local n = copy_node(thekern)
+ local n = copynode(thekern)
setkern(n,k)
return n
end
@@ -1994,12 +1968,11 @@ 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
-
-- current match
if chainlookups then
-- Lookups can be like { 1, false, 3 } or { false, 2 } or basically anything and
@@ -2010,23 +1983,30 @@ local function chainrun(head,start,last,dataset,sequence,rlmode,skiphash,ck)
-- if nofchainlookups > size then
-- -- bad rules
-- end
-
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
- -- HH: chainindex 1 added here (for KAI to check too), there are weird ligatures e.g.
- -- char + mark -> char where mark has to disappear
- 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
+ -- HH: chainindex 1 added here (for KAI to check too), there are weird ligatures e.g.
+ -- char + mark -> char where mark has to disappear
+ 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
+ -- whatever
end
else
@@ -2067,23 +2047,28 @@ 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)
- -- messy since last can be changed !
- if ok then
- done = true
- if n and n > 1 and i + n > nofchainlookups then
- -- this is a safeguard, we just ignore the rest of the lookups
- i = size -- prevents an advance
- 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)
+ -- messy since last can be changed !
+ if ok then
+ done = true
+ if n and n > 1 and i + n > nofchainlookups then
+ -- this is a safeguard, we just ignore the rest of the lookups
+ i = size -- prevents an advance
+ break
+ end
end
+ else
+ -- actually an error
+ logprocess("%s: %s is not yet supported (2)",cref(dataset,sequence),chainkind)
end
else
-- actually an error
- logprocess("%s: %s is not yet supported (2)",cref(dataset,sequence),chainkind)
+ logprocess("%s: has an issue (2)",cref(dataset,sequence))
end
end
else
@@ -2111,7 +2096,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
@@ -2141,6 +2126,8 @@ local function chaindisk(head,start,dataset,sequence,rlmode,skiphash,ck)
local last = start
local prev = getprev(start)
local hasglue = false
+ local useddisc = nil -- new 2022-09-25
+ local usedstart = start -- new 2022-09-25
-- fishy: so we can overflow and then go on in the sweep?
-- todo : id can also be glue_code as we checked spaces
@@ -2211,7 +2198,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)
@@ -2302,15 +2289,14 @@ local function chaindisk(head,start,dataset,sequence,rlmode,skiphash,ck)
end
end
end
+
local done = false
if lookaheaddisc then
-
local cf = start
local cl = getprev(lookaheaddisc)
local cprev = getprev(start)
local insertedmarks = 0
-
while cprev do
local char = ischar(cf,currentfont)
if char and marks[char] then
@@ -2329,13 +2315,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) -- br, how often does that happen
+ local new = copynodelist(cf) -- br, how often does that happen
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
@@ -2349,14 +2335,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
@@ -2367,16 +2353,14 @@ local function chaindisk(head,start,dataset,sequence,rlmode,skiphash,ck)
setdisc(lookaheaddisc,cf,post,new)
end
start = getprev(lookaheaddisc)
+ useddisc = lookaheaddisc -- new 2022-09-25
sweephead[cf] = getnext(clast) or false
sweephead[new] = getnext(cl) or false
-
elseif backtrackdisc then
-
local cf = getnext(backtrackdisc)
local cl = start
local cnext = getnext(start)
local insertedmarks = 0
-
while cnext do
local char = ischar(cnext,currentfont)
if char and marks[char] then
@@ -2391,8 +2375,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
@@ -2402,14 +2386,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
@@ -2430,33 +2414,57 @@ local function chaindisk(head,start,dataset,sequence,rlmode,skiphash,ck)
setdisc(backtrackdisc,pre,post,replace)
end
start = getprev(backtrackdisc)
+ useddisc = backtrackdisc -- new 2022-09-25
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
+ if useddisc and start ~= usedstart then -- make this option per font -- new 2022-09-25
+ start = getnext(start) -- new 2022-09-25
+ end -- new 2022-09-25
+ return head, start, done, useddisc -- new 2022-09-25
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 ")
+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] -- ck[3].n
+ 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
+ -- (start,done)
+ 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
-- The next one is quite optimized but still somewhat slow, fonts like ebgaramond
@@ -2470,6 +2478,9 @@ end
-- the previous disc .. such be it (<before><disc><current=fl><after> with only f done)
local function handle_contextchain(head,start,dataset,sequence,contexts,rlmode,skiphash)
+ if not contexts then
+ return head, start, false
+ end
-- optimizing for rlmode gains nothing
local sweepnode = sweepnode
local sweeptype = sweeptype
@@ -2502,7 +2513,7 @@ local function handle_contextchain(head,start,dataset,sequence,contexts,rlmode,s
-- fonts can have many steps (each doing one check) or many contexts
-- todo: make a per-char cache so that we have small contexts (when we have a context
- -- n == 1 and otherwise it can be more so we can even distingish n == 1 or more)
+ -- n == 1 and otherwise it can be more so we can even distinguish n == 1 or more)
local nofcontexts = contexts.n -- #contexts
@@ -2510,10 +2521,10 @@ local function handle_contextchain(head,start,dataset,sequence,contexts,rlmode,s
for k=1,nofcontexts do -- does this disc mess work well with n > 1
- local ck = contexts[k]
- local seq = ck[3]
- local f = ck[4] -- first current
-local last = start
+ local ck = contexts[k]
+ local seq = ck[3]
+ local f = ck[4] -- first current
+ local last = start
if not startchar or not seq[f][startchar] then
-- report("no hit in %a at %i of %i contexts",sequence.type,k,nofcontexts)
goto next
@@ -2524,7 +2535,7 @@ local last = start
else
local l = ck[5] -- last current
local current = start
--- local last = start
+ -- local last = start
-- current match
@@ -2638,7 +2649,7 @@ local last = start
-- before
if f > 1 then
- if startprev then
+ -- if startprev then -- new 2022-09-25
local prev = startprev
if prereplace and prev == checkdisc then
prev = getprev(sweepnode)
@@ -2762,9 +2773,9 @@ local last = start
else
goto next
end
- else
- goto next
- end
+ -- else -- new 2022-09-25
+ -- goto next -- new 2022-09-25
+ -- end -- new 2022-09-25
end
-- after
@@ -2888,24 +2899,25 @@ local last = start
end
end
end
-
if trace_contexts then
chaintrac(head,start,dataset,sequence,rlmode,skipped and skiphash,ck,true,discseen,sweepnode)
end
if discseen or sweepnode then
+ -- When we process a disc we can collapse and therefore we backtrack one node (start) and
+ -- reprocess. This is needed because there might be more in the collapsed list.
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
-- else
-- next context
end
- ::next::
- -- if trace_chains then
- -- chaintrac(head,start,dataset,sequence,rlmode,skipped and skiphash,ck,false,discseen,sweepnode)
- -- end
+ ::next::
end
if discseen then
notmatchpre = { }
@@ -2924,21 +2936,46 @@ handlers.gsub_reversecontextchain = handle_contextchain
handlers.gpos_contextchain = handle_contextchain
handlers.gpos_context = handle_contextchain
--- this needs testing
+-- 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
+-- -- probably wrong
+-- local l = steps[1].coverage[getchar(start)]
+-- if l then
+-- return handle_contextchain(head,start,dataset,sequence,l,rlmode,skiphash)
+-- else
+-- return head, start, false
+-- end
+-- end
+
+-- new 2022-09-25
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
- -- probably wrong
- 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
@@ -3077,7 +3114,7 @@ do -- overcome local limit
end
-- Functions like kernrun, comprun etc evolved over time and in the end look rather
--- complex. It's a bit of a compromis between extensive copying and creating subruns.
+-- complex. It's a bit of a compromise between extensive copying and creating subruns.
-- The logic has been improved a lot by Kai and Ivo who use complex fonts which
-- really helped to identify border cases on the one hand and get insight in the diverse
-- ways fonts implement features (not always that consistent and efficient). At the same
@@ -3184,7 +3221,8 @@ local function kernrun(disc,k_run,font,attr,...)
if done and trace_testruns then
report_disc("done",disc)
end
- return nextstart, done
+ -- return nextstart, done
+ return nextstart
end
-- fonts like ebgaramond do ligatures this way (less efficient than e.g. dejavu which
@@ -3237,12 +3275,19 @@ local function comprun(disc,c_run,...) -- vararg faster than the whole list
setdisc(disc,pre,post,replace)
end
--
- return getnext(disc), renewed
+ -- return getnext(disc), renewed
+ return getnext(disc)
end
-- if we can hyphenate in a lig then unlikely a lig so we
-- could have a option here to ignore lig
+local test_flatten_start = 2 -- must start at 2 according to Kai
+
+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)
@@ -3271,7 +3316,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) -- is: next
local tail = head
- for i=2,d do -- must start at 2 according to Kai
+ for i=test_flatten_start,d do
local nx = getnext(tail)
local id = getid(nx)
if id == disc_code then
@@ -3286,7 +3331,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
@@ -3359,7 +3404,8 @@ local function testrun(disc,t_run,c_run,...)
end
end
-- next can have changed (copied list)
- return getnext(disc), renewed
+ -- return getnext(disc), renewed
+ return getnext(disc)
end
-- 1{2{\oldstyle\discretionary{3}{4}{5}}6}7\par
@@ -3882,7 +3928,7 @@ do
-- the before and after lists in the loader. But first I need to see a font that uses multiple
-- matches.
--
- local start = find_node_tail(head)
+ local start = findnodetail(head)
local rlmode = 0 -- how important is this .. do we need to check for dir?
local merged = steps.merged
while start do
@@ -3968,17 +4014,13 @@ 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
- -- if ok then
- -- done = true
- -- end
else
start = getnext(start)
end
@@ -4052,17 +4094,13 @@ 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
- -- if ok then
- -- done = true
- -- end
else
start = getnext(start)
end
@@ -4184,7 +4222,7 @@ do
start = getnext(start)
-- elseif id == par_code and startofpar(start) then
-- rlparmode, rlmode = pardirstate(start)
- -- start = getnext(start)
+ -- start = nxt
else
start = getnext(start)
end
@@ -4274,8 +4312,8 @@ registerotffeature {
}
}
--- Moved here (up) a bit. This doesn't really belong in generic so it will
--- move to a context module some day.
+-- Moved here (up) a bit. This doesn't really belong in generic so it will move to a
+-- context module some day.
local function markinitializer(tfmdata,value)
local properties = tfmdata.properties
diff --git a/macros/luatex/generic/luaotfload/fontloader-font-ott.lua b/macros/luatex/generic/luaotfload/fontloader-font-ott.lua
index aa1defd6a1..74fd583758 100644
--- a/macros/luatex/generic/luaotfload/fontloader-font-ott.lua
+++ b/macros/luatex/generic/luaotfload/fontloader-font-ott.lua
@@ -52,16 +52,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",
@@ -81,6 +85,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",
@@ -90,6 +95,7 @@ local scripts = allocate {
["khar"] = "kharosthi",
["khmr"] = "khmer",
["khoj"] = "khojki",
+ ["kits"] = "khitan small script",
["knd2"] = "kannada variant 2",
["knda"] = "kannada",
["kthi"] = "kaithi",
@@ -123,6 +129,7 @@ local scripts = allocate {
["musc"] = "musical symbols",
["mym2"] = "myanmar variant 2",
["mymr"] = "myanmar",
+ ["nand"] = "nandinagari",
["narb"] = "old north arabian",
["nbat"] = "nabataean",
["newa"] = "newa",
@@ -132,9 +139,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",
@@ -166,7 +174,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",
@@ -178,12 +186,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",
}
@@ -199,6 +211,7 @@ local languages = allocate {
["agw" ] = "agaw",
["aio" ] = "aiton",
["aka" ] = "akan",
+ ["akb" ] = "batak angkola",
["als" ] = "alsatian",
["alt" ] = "altai",
["amh" ] = "amharic",
@@ -211,6 +224,7 @@ local languages = allocate {
["asm" ] = "assamese",
["ast" ] = "asturian",
["ath" ] = "athapaskan",
+ ["avn" ] = "avatime",
["avr" ] = "avar",
["awa" ] = "awadhi",
["aym" ] = "aymara",
@@ -256,8 +270,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",
@@ -292,14 +310,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",
@@ -371,13 +391,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",
@@ -402,10 +425,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",
@@ -425,6 +450,7 @@ local languages = allocate {
["kan" ] = "kannada",
["kar" ] = "karachay",
["kat" ] = "georgian",
+ ["kaw" ] = "kawi (old javanese)",
["kaz" ] = "kazakh",
["kde" ] = "makonde",
["kea" ] = "kabuverdianu (crioulo)",
@@ -482,6 +508,7 @@ local languages = allocate {
["kur" ] = "kurdish",
["kuu" ] = "kurukh",
["kuy" ] = "kuy",
+ ["kwk" ] = "kwakʼwala",
["kyk" ] = "koryak",
["kyu" ] = "western kayah",
["lad" ] = "ladin",
@@ -493,6 +520,7 @@ local languages = allocate {
["laz" ] = "laz",
["lcr" ] = "l-cree",
["ldk" ] = "ladakhi",
+ ["lef" ] = "lelemi",
["lez" ] = "lezgi",
["lij" ] = "ligurian",
["lim" ] = "limburgish",
@@ -505,6 +533,7 @@ local languages = allocate {
["lmo" ] = "lombard",
["lmw" ] = "lomwe",
["lom" ] = "loma",
+ ["lpo" ] = "lipo",
["lrc" ] = "luri",
["lsb" ] = "lower sorbian",
["lsm" ] = "lule sami",
@@ -521,7 +550,7 @@ local languages = allocate {
["mah" ] = "marshallese",
["maj" ] = "majang",
["mak" ] = "makhuwa",
- ["mal" ] = "malayalam reformed",
+ ["mal" ] = "malayalam",
["mam" ] = "mam",
["man" ] = "mansi",
["map" ] = "mapudungun",
@@ -556,6 +585,7 @@ local languages = allocate {
["mok" ] = "moksha",
["mol" ] = "moldavian",
["mon" ] = "mon",
+ ["mnw" ] = "thailand mon",
["mor" ] = "moroccan",
["mos" ] = "mossi",
["mri" ] = "maori",
@@ -594,7 +624,7 @@ local languages = allocate {
["nor" ] = "norwegian",
["nov" ] = "novial",
["nsm" ] = "northern sami",
- ["nso" ] = "sotho, northern",
+ ["nso" ] = "northern sotho",
["nta" ] = "northern tai",
["nto" ] = "esperanto",
["nym" ] = "nyamwezi",
@@ -642,6 +672,7 @@ local languages = allocate {
["rbu" ] = "russian buriat",
["rcr" ] = "r-cree",
["rej" ] = "rejang",
+ ["rhg" ] = "rohingya",
["ria" ] = "riang",
["rif" ] = "tarifit",
["rit" ] = "ritarungo",
@@ -666,6 +697,7 @@ local languages = allocate {
["scs" ] = "north slavey",
["sek" ] = "sekota",
["sel" ] = "selkup",
+ ["sfm" ] = "small flowery miao",
["sga" ] = "old irish",
["sgo" ] = "sango",
["sgs" ] = "samogitian",
@@ -687,7 +719,7 @@ local languages = allocate {
["snk" ] = "soninke",
["sog" ] = "sodo gurage",
["sop" ] = "songe",
- ["sot" ] = "sotho, southern",
+ ["sot" ] = "southern sotho",
["sqi" ] = "albanian",
["srb" ] = "serbian",
["srd" ] = "sardinian",
@@ -728,7 +760,9 @@ local languages = allocate {
["tht" ] = "tahitian",
["tib" ] = "tibetan",
["tiv" ] = "tiv",
+ ["tj;" ] = "tai laing",
["tkm" ] = "turkmen",
+ ["tli" ] = "tlingit",
["tmh" ] = "tamashek",
["tmn" ] = "temne",
["tna" ] = "tswana",
@@ -742,7 +776,7 @@ local languages = allocate {
["tsj" ] = "tshangla",
["tua" ] = "turoyo aramaic",
["tul" ] = "tulu",
- ["tum" ] = "tulu",
+ ["tum" ] = "tumbuka",
["tuv" ] = "tuvin",
["tvl" ] = "tuvalu",
["twi" ] = "twi",
@@ -764,6 +798,7 @@ local languages = allocate {
["wa" ] = "wa",
["wag" ] = "wagdi",
["war" ] = "waray-waray",
+ ["wci" ] = "waci gbe",
["wcr" ] = "west-cree",
["wel" ] = "welsh",
["wlf" ] = "wolof",
@@ -775,17 +810,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",
@@ -794,7 +835,6 @@ local languages = allocate {
["zza" ] = "zazaki",
}
-
local features = allocate {
["aalt"] = "access all alternates",
["abvf"] = "above-base forms",
@@ -811,6 +851,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",
@@ -866,7 +907,7 @@ local features = allocate {
["nukt"] = "nukta forms",
["numr"] = "numerators",
["onum"] = "old style figures",
- ["opbd"] = "optical bounds",
+ ["opbd"] = "optical bounds", -- funny, this is obsolete (too hard?) (and was recomended always true)
["ordn"] = "ordinals",
["ornm"] = "ornaments",
["palt"] = "proportional alternate width",
@@ -887,8 +928,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", -- now stat table
@@ -928,6 +969,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",
diff --git a/macros/luatex/generic/luaotfload/fontloader-font-oup.lua b/macros/luatex/generic/luaotfload/fontloader-font-oup.lua
index 248aad04d2..0d1f9d6a61 100644
--- a/macros/luatex/generic/luaotfload/fontloader-font-oup.lua
+++ b/macros/luatex/generic/luaotfload/fontloader-font-oup.lua
@@ -898,26 +898,42 @@ local function unifyglyphs(fontdata,usenames)
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 local l = list[i] l.glyph = indices[l.glyph] end
- 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 local l = list[i] l.glyph = indices[l.glyph] end
- 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 local l = list[i] l.glyph = indices[l.glyph] end
+ for i=1,#list do list[i] = indices[list[i]] end
+ end
+ local list = math.hvariants
+ if list then
+ -- for i=1,#list do local l = list[i] l.glyph = indices[l.glyph] end
+ for i=1,#list do list[i] = indices[list[i]] end
+ end
end
end
end
@@ -929,7 +945,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 -- safeguard
+ c.slot = indices[c.slot]
+ end
end
end
end
@@ -947,7 +965,6 @@ end
local stripredundant do
-
local p_hex = R("af","AF","09")
local p_digit = R("09")
local p_done = S("._-")^0 + P(-1)
diff --git a/macros/luatex/generic/luaotfload/fontloader-font-shp.lua b/macros/luatex/generic/luaotfload/fontloader-font-shp.lua
index 2ca3011a5b..197a3f1ccb 100644
--- a/macros/luatex/generic/luaotfload/fontloader-font-shp.lua
+++ b/macros/luatex/generic/luaotfload/fontloader-font-shp.lua
@@ -17,7 +17,7 @@ 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)
@@ -150,6 +150,8 @@ end
local readers = otf.readers
local cleanname = otf.readers.helpers.cleanname
+-- todo: shared hash for this but not accessed often
+
local function makehash(filename,sub,instance)
local name = cleanname(file.basename(filename))
if instance then
@@ -234,17 +236,21 @@ local function loadstreams(cache,filename,sub,instance)
if data then
local glyphs = data.glyphs
local streams = { }
+ -- local widths = { }
if glyphs then
for i=0,#glyphs do
local glyph = glyphs[i]
if glyph then
streams[i] = glyph.stream or ""
+ -- widths [i] = glyph.width or 0
else
streams[i] = ""
+ -- widths [i] = 0
end
end
end
data.streams = streams
+ -- data.widths = widths -- maybe more reliable!
data.glyphs = nil
data.size = size
data.format = data.format or (kind == "otf" and "opentype") or "truetype"
@@ -259,8 +265,11 @@ local function loadstreams(cache,filename,sub,instance)
local names, encoding, streams, metadata = pfb.loadvector(filename,false,true)
if streams then
local fontbbox = metadata.fontbbox or { 0, 0, 0, 0 }
+ -- local widths = { }
for i=0,#streams do
- streams[i] = streams[i].stream or "\14"
+ local s = streams[i]
+ streams[i] = s.stream or "\14"
+ -- widths [i] = s.width or 0
end
data = {
filename = filename,
@@ -268,6 +277,7 @@ local function loadstreams(cache,filename,sub,instance)
time = time,
format = "type1",
streams = streams,
+ -- widths = widths,
fontheader = {
fontversion = metadata.version,
units = 1000, -- can this be different?
@@ -346,7 +356,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
diff --git a/macros/luatex/generic/luaotfload/fontloader-font-ttf.lua b/macros/luatex/generic/luaotfload/fontloader-font-ttf.lua
index d1a3972b2c..1fee9fa88d 100644
--- a/macros/luatex/generic/luaotfload/fontloader-font-ttf.lua
+++ b/macros/luatex/generic/luaotfload/fontloader-font-ttf.lua
@@ -230,20 +230,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
-- Not the most efficient solution but we seldom do this. We
-- actually need to avoid the extra points here but I'll deal
-- with that when needed.
@@ -263,20 +250,27 @@ local function applyaxis(glyph,shape,deltas,dowidth)
end
if found == last then
lastindex = currentindex
- break;
+ break
elseif found > last then
+ -- \definefontfeature[book][default][axis={weight=800}]
+ -- \definefont[testfont][file:Commissioner-vf-test.ttf*book]
+ -- \testfont EΘÄΞ
+ while lastindex > 1 and dpoints[lastindex] > last do
+ lastindex = lastindex - 1
+ end
+ --
break
end
end
end
- -- print("unicode: ",glyph.unicode or "?")
- -- print("contour: ",first,contour,last)
- -- print("index : ",firstindex,lastindex,cnt)
- -- print("points : ",dpoints[firstindex],dpoints[lastindex])
+ -- print("unicode: ",glyph.unicode or "?")
+ -- print("contour: ",first,contour,last)
+ -- print("index : ",firstindex,lastindex,cnt)
+ -- print("points : ",dpoints[firstindex],dpoints[lastindex])
local function find(i)
local prv = lastindex
for j=firstindex,lastindex do
- local nxt = dpoints[j]
+ local nxt = dpoints[j] -- we could save this lookup when we return it
if nxt == i then
return false, j, false
elseif nxt > i then
@@ -343,6 +337,7 @@ local function applyaxis(glyph,shape,deltas,dowidth)
end
else
fx = (p2x - p1x)/(p3x - p1x)
+-- fx = round(fx)
fx = (1 - fx) * x1 + fx * x3
end
--
@@ -366,6 +361,7 @@ local function applyaxis(glyph,shape,deltas,dowidth)
end
else
fy = (p2y - p1y)/(p3y - p1y)
+-- fy = round(fy)
fy = (1 - fy) * y1 + fy * y3
end
-- -- maybe:
@@ -769,6 +765,18 @@ local function contours2outlines_shaped(glyphs,shapes,keepcurve)
end
first = last + 1
end
+ -- See readers.hvar where we set the delta lsb as well as the adapted
+ -- width. At this point we do know the boundingbox's llx. The xmax is
+ -- not that relevant. It needs more testing!
+ --
+ xmin = glyph.boundingbox[1]
+ --
+ local dlsb = glyph.dlsb
+ if dlsb then
+ xmin = xmin + dlsb
+ glyph.dlsb = nil -- save space
+ end
+ --
glyph.boundingbox = { round(xmin), round(ymin), round(xmax), round(ymax) }
end
end
@@ -980,8 +988,8 @@ local function readglyph(f,nofcontours) -- read deltas here, saves space
local x = 0
for i=1,nofpoints do
local flag = flags[i]
- -- local short = band(flag,0x04) ~= 0
- -- local same = band(flag,0x20) ~= 0
+ -- local short = band(flag,0x02) ~= 0
+ -- local same = band(flag,0x10) ~= 0
if band(flag,0x02) ~= 0 then
if band(flag,0x10) ~= 0 then
x = x + readbyte(f)
diff --git a/macros/luatex/generic/luaotfload/fontloader-l-file.lua b/macros/luatex/generic/luaotfload/fontloader-l-file.lua
index 9f8fd65483..70f8188dc1 100644
--- a/macros/luatex/generic/luaotfload/fontloader-l-file.lua
+++ b/macros/luatex/generic/luaotfload/fontloader-l-file.lua
@@ -741,8 +741,24 @@ end
-- not used in context but was in luatex once:
-local symlinkattributes = lfs.symlinkattributes
+do
+
+ local symlinktarget = lfs.symlinktarget -- luametatex (always returns string)
+ local symlinkattributes = lfs.symlinkattributes -- luatex (can return nil)
+
+ 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
-function lfs.readlink(name)
- return symlinkattributes(name,"target") or nil
end
diff --git a/macros/luatex/generic/luaotfload/fontloader-l-string.lua b/macros/luatex/generic/luaotfload/fontloader-l-string.lua
index 1dee85e289..476820a175 100644
--- a/macros/luatex/generic/luaotfload/fontloader-l-string.lua
+++ b/macros/luatex/generic/luaotfload/fontloader-l-string.lua
@@ -7,7 +7,7 @@ if not modules then modules = { } end modules ['l-string'] = {
}
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
@@ -52,10 +52,26 @@ function string.quoted(str)
return format("%q",str) -- always double quote
end
-function string.count(str,pattern) -- variant 3
+-- function string.count(str,pattern) -- variant 3
+-- local n = 0
+-- for _ in gmatch(str,pattern) do -- not for utf
+-- n = n + 1
+-- end
+-- return n
+-- end
+
+function string.count(str,pattern)
local n = 0
- for _ in gmatch(str,pattern) do -- not for utf
- 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
diff --git a/macros/luatex/generic/luaotfload/fontloader-l-table.lua b/macros/luatex/generic/luaotfload/fontloader-l-table.lua
index c20bd4733c..b6c3744b8b 100644
--- a/macros/luatex/generic/luaotfload/fontloader-l-table.lua
+++ b/macros/luatex/generic/luaotfload/fontloader-l-table.lua
@@ -711,7 +711,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
@@ -719,7 +723,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
@@ -729,7 +737,11 @@ local function do_serialize(root,name,depth,level,indexed)
-- ignore
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
@@ -737,7 +749,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
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
diff --git a/macros/luatex/generic/luaotfload/fontloader-util-str.lua b/macros/luatex/generic/luaotfload/fontloader-util-str.lua
index b5c721a41d..a9150b886a 100644
--- a/macros/luatex/generic/luaotfload/fontloader-util-str.lua
+++ b/macros/luatex/generic/luaotfload/fontloader-util-str.lua
@@ -269,6 +269,7 @@ local p_prune_intospace = Cs ( noleading * ( notrailing + intospace + 1
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 )
-- function striplines(str,prune,collapse,noempty)
-- if prune then
@@ -298,6 +299,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,
}
@@ -313,6 +315,9 @@ function strings.collapse(str) -- maybe also in strings
return str and lpegmatch(p_prune_intospace,str) or str
end
+-- local s = "\naa\n\naa\na a\n\n"
+-- print("["..strings.striplines(s,"collapse all").."]")
+
-- also see: string.collapsespaces
strings.striplong = strings.striplines -- for old times sake
diff --git a/macros/luatex/generic/luaotfload/luaotfload-auxiliary.lua b/macros/luatex/generic/luaotfload/luaotfload-auxiliary.lua
index bcbdd74b2a..6325ba19d2 100644
--- a/macros/luatex/generic/luaotfload/luaotfload-auxiliary.lua
+++ b/macros/luatex/generic/luaotfload/luaotfload-auxiliary.lua
@@ -6,8 +6,8 @@
assert(luaotfload_module, "This is a part of luaotfload and should not be loaded independently") {
name = "luaotfload-auxiliary",
- version = "3.23", --TAGVERSION
- date = "2022-10-03", --TAGDATE
+ version = "3.24", --TAGVERSION
+ date = "2023-08-19", --TAGDATE
description = "luaotfload submodule / auxiliary functions",
license = "GPL v2.0"
}
diff --git a/macros/luatex/generic/luaotfload/luaotfload-colors.lua b/macros/luatex/generic/luaotfload/luaotfload-colors.lua
index 378b0f62b6..35962ee074 100644
--- a/macros/luatex/generic/luaotfload/luaotfload-colors.lua
+++ b/macros/luatex/generic/luaotfload/luaotfload-colors.lua
@@ -5,8 +5,8 @@
assert(luaotfload_module, "This is a part of luaotfload and should not be loaded independently") {
name = "luaotfload-colors",
- version = "3.23", --TAGVERSION
- date = "2022-10-03", --TAGDATE
+ version = "3.24", --TAGVERSION
+ date = "2023-08-19", --TAGDATE
description = "luaotfload submodule / color",
license = "GPL v2.0",
author = "Khaled Hosny, Elie Roux, Philipp Gesang, Dohyun Kim, David Carlisle",
diff --git a/macros/luatex/generic/luaotfload/luaotfload-conf.pdf b/macros/luatex/generic/luaotfload/luaotfload-conf.pdf
index c735e60a99..9a1cbab1a8 100644
--- a/macros/luatex/generic/luaotfload/luaotfload-conf.pdf
+++ b/macros/luatex/generic/luaotfload/luaotfload-conf.pdf
Binary files differ
diff --git a/macros/luatex/generic/luaotfload/luaotfload-configuration.lua b/macros/luatex/generic/luaotfload/luaotfload-configuration.lua
index 9ed614b17e..fda9b4dbff 100644
--- a/macros/luatex/generic/luaotfload/luaotfload-configuration.lua
+++ b/macros/luatex/generic/luaotfload/luaotfload-configuration.lua
@@ -7,8 +7,8 @@
assert(luaotfload_module, "This is a part of luaotfload and should not be loaded independently") {
name = "luaotfload-configuration",
- version = "3.23", --TAGVERSION
- date = "2022-10-03", --TAGDATE
+ version = "3.24", --TAGVERSION
+ date = "2023-08-19", --TAGDATE
description = "luaotfload submodule / config file reader",
license = "GPL v2.0"
}
@@ -91,6 +91,13 @@ local valid_formats = tabletohash {
"otf", "ttc", "ttf", "afm", "pfb"
}
+local default_location_precedence = {
+ "system", "texmf", "local"
+}
+local valid_locations = tabletohash {
+ "system", "texmf", "local"
+}
+
local default_anon_sequence = {
"tex", "path", "name"
}
@@ -189,6 +196,10 @@ local permissible_color_callbacks = {
pre_output_filter = "pre_output_filter",
}
+local known_dvi_drivers = {
+ xdvipsk = 'xdvipsk',
+ dvisvgm = 'dvisvgm',
+}
-------------------------------------------------------------------------------
--- DEFAULTS
@@ -196,22 +207,24 @@ local permissible_color_callbacks = {
local default_config = {
db = {
- formats = "otf,ttf,ttc",
- scan_local = false,
- skip_read = false,
- strip = true,
- update_live = true,
- compress = true,
- max_fonts = 2^51,
- designsize_dimen= "bp",
+ location_precedence = default_location_precedence,
+ formats = "otf,ttf,ttc",
+ scan_local = false,
+ skip_read = false,
+ strip = true,
+ update_live = true,
+ compress = true,
+ max_fonts = 2^51,
+ designsize_dimen = "bp",
},
run = {
- anon_sequence = default_anon_sequence,
- resolver = "cached",
- definer = "patch",
- log_level = 0,
- color_callback = "post_linebreak_filter",
- fontloader = default_fontloader (),
+ anon_sequence = default_anon_sequence,
+ resolver = "cached",
+ definer = "patch",
+ log_level = 0,
+ color_callback = "post_linebreak_filter",
+ fontloader = default_fontloader (),
+ default_dvi_driver = "dvisvgm"
},
misc = {
bisect = false,
@@ -313,6 +326,18 @@ local function set_font_filter ()
return true
end
+local function set_location_precedence_list ()
+ local names = fonts.names
+ if names and names.set_location_precedence then
+ local locations = config.luaotfload.db.location_precedence
+ if not locations or locations == "" then
+ locations = default_config.db.location_precedence
+ end
+ fonts.names.set_location_precedence (locations)
+ end
+ return true
+end
+
local function set_size_dimension ()
local names = fonts.names
if names and names.set_size_dimension then
@@ -396,6 +421,7 @@ reconf_tasks = {
{ "Set design size dimension" , set_size_dimension },
{ "Install font name resolver", set_name_resolver },
{ "Set default features" , set_default_features },
+ { "Set location precedence" , set_location_precedence_list },
}
-------------------------------------------------------------------------------
@@ -484,6 +510,44 @@ local option_spec = {
return tableconcat (result, ",")
end
},
+ location_precedence = {
+ in_t = string_t,
+ out_t = table_t,
+ transform = function (s)
+ local bits = { lpegmatch (commasplitter, s) }
+ if next (bits) then
+ local seq = { }
+ local done = { }
+ for i = 1, #bits do
+ local bit = bits [i]
+ if valid_locations [bit] then
+ if not done [bit] then
+ done [bit] = true
+ seq [#seq + 1] = bit
+ else
+ logreport ("both", 0, "conf",
+ "ignoring duplicate location %s at position %d \z
+ in precedence list",
+ bit, i)
+ end
+ else
+ logreport ("both", 0, "conf",
+ "location precedence list contains invalid item %s \z
+ at position %d.",
+ bit, i)
+ end
+ end
+ if next (seq) then
+ logreport ("both", 2, "conf",
+ "overriding anon lookup sequence %s.",
+ tableconcat (seq, ","))
+ return seq
+ end
+ end
+ logreport ("both", 0, "conf", "no lookup locations enabled, falling back to default precedence list")
+ return default_location_precedence
+ end
+ },
scan_local = { in_t = boolean_t, },
skip_read = { in_t = boolean_t, },
strip = { in_t = boolean_t, },
@@ -596,6 +660,24 @@ local option_spec = {
return permissible_color_callbacks.default
end,
},
+ default_dvi_driver = {
+ in_t = string_t,
+ out_t = string_t,
+ transform = function (driver)
+ local mapped = known_dvi_drivers[driver]
+ if mapped then
+ logreport ("log", 5, "conf",
+ "Using default DVI driver %q if used in DVI mode.",
+ mapped)
+ return mapped
+ end
+ logreport ("log", 0, "conf",
+ "Requested default DVI driver %q invalid, "
+ .. "falling back to dvisvgm.",
+ driver)
+ return known_dvi_drivers.dvisvgm
+ end,
+ },
},
misc = {
bisect = { in_t = boolean_t, }, --- doesn’t make sense in a config file
@@ -740,12 +822,13 @@ local formatters = {
lookups_file = { false, format_string },
},
run = {
- anon_sequence = { false, format_list },
- color_callback = { false, format_string },
- definer = { false, format_string },
- fontloader = { true, format_string },
- log_level = { false, format_integer },
- resolver = { false, format_string },
+ anon_sequence = { false, format_list },
+ color_callback = { false, format_string },
+ definer = { false, format_string },
+ fontloader = { true, format_string },
+ log_level = { false, format_integer },
+ resolver = { false, format_string },
+ default_dvi_driver = { false, format_string },
},
}
diff --git a/macros/luatex/generic/luaotfload/luaotfload-database.lua b/macros/luatex/generic/luaotfload/luaotfload-database.lua
index e71e923ff6..3a2d87ead9 100644
--- a/macros/luatex/generic/luaotfload/luaotfload-database.lua
+++ b/macros/luatex/generic/luaotfload/luaotfload-database.lua
@@ -5,8 +5,8 @@
do -- block to avoid to many local variables error
assert(luaotfload_module, "This is a part of luaotfload and should not be loaded independently") {
name = "luaotfload-database",
- version = "3.23", --TAGVERSION
- date = "2022-10-03", --TAGDATE
+ version = "3.24", --TAGVERSION
+ date = "2023-08-19", --TAGDATE
description = "luaotfload submodule / database",
license = "GPL v2.0",
author = "Khaled Hosny, Elie Roux, Philipp Gesang, Marcel Krüger",
@@ -220,9 +220,20 @@ local format_precedence = {
local location_precedence = {
"local", "system", "texmf",
}
+local enabled_locations = {
+ ['local'] = true,
+ system = true,
+ texmf = true,
+}
local function set_location_precedence (precedence)
location_precedence = precedence
+ for location in next, enabled_locations do
+ enabled_locations[location] = nil
+ end
+ for _, location in ipairs(location_precedence) do
+ enabled_locations[location] = location ~= 'local' or config.luaotfload.db.scan_local == true
+ end
end
--[[doc--
@@ -852,23 +863,25 @@ Also, the fields “resolved”, “sub”, “force” etc. influence the outco
--doc]]--
-local concat_char = "#"
-local hash_fields = {
- --- order is important
- "specification", "style", "sub", "optsize", "size",
-}
-local n_hash_fields = #hash_fields
-
---- spec -> string
-local function hash_request (specification)
- local key = { } --- segments of the hash
- for i=1, n_hash_fields do
- local field = specification[hash_fields[i]]
- if field then
- key[#key+1] = field
+local hash_request do
+ local concat_char = "#"
+ local hash_fields = {
+ --- order is important
+ "specification", "style", "sub", "optsize", "size",
+ }
+ local n_hash_fields = #hash_fields
+
+ --- spec -> string
+ function hash_request (specification)
+ local key = { } --- segments of the hash
+ for i=1, n_hash_fields do
+ local field = specification[hash_fields[i]]
+ if field then
+ key[#key+1] = field
+ end
end
+ return tableconcat(key, concat_char)
end
- return tableconcat(key, concat_char)
end
--- 'a -> 'a -> table -> (string * int|boolean * boolean)
@@ -3119,10 +3132,17 @@ local function collect_font_filenames ()
local bisect = config.luaotfload.misc.bisect
local max_fonts = config.luaotfload.db.max_fonts --- XXX revisit for lua 5.3 wrt integers
- tableappend (filenames, collect_font_filenames_texmf ())
- tableappend (filenames, collect_font_filenames_system ())
- local scan_local = config.luaotfload.db.scan_local == true
- if scan_local then
+ -- We can't just scan in the order of location_precedence here since
+ -- the order is important. In the common situation of having texmf
+ -- added to the system font path, scanning system first would
+ -- classify all texmf fonts as system fonts.
+ if enabled_locations.texmf then
+ tableappend (filenames, collect_font_filenames_texmf ())
+ end
+ if enabled_locations.system then
+ tableappend (filenames, collect_font_filenames_system ())
+ end
+ if enabled_locations['local'] then
local localfonts, found = collect_font_filenames_local()
if found then
tableappend (filenames, localfonts)
@@ -3138,7 +3158,7 @@ local function collect_font_filenames ()
if bisect then
return { unpack (filenames, bisect[1], bisect[2]) }
end
- return filenames, scan_local
+ return filenames
end
--[[doc--
@@ -3409,8 +3429,8 @@ function update_names (currentnames, force, dry_run)
read_blacklist ()
--- pass 1: Collect the names of all fonts we are going to process.
- local font_filenames, local_fonts = collect_font_filenames ()
- if local_fonts then
+ local font_filenames = collect_font_filenames ()
+ if enabled_locations['local'] then
targetnames.meta['local'] = true
end
@@ -3804,6 +3824,7 @@ return function ()
names.data = nil --- contains the loaded database
names.lookups = nil --- contains the lookup cache
+ enabled_locations['local'] = enabled_locations['local'] and config.luaotfload.db.scan_local == true
for sym, ref in next, export do names[sym] = ref end
for sym, ref in next, api do names[sym] = names[sym] or ref end
return true
diff --git a/macros/luatex/generic/luaotfload/luaotfload-diagnostics.lua b/macros/luatex/generic/luaotfload/luaotfload-diagnostics.lua
index 093c171409..9bde02fc1f 100644
--- a/macros/luatex/generic/luaotfload/luaotfload-diagnostics.lua
+++ b/macros/luatex/generic/luaotfload/luaotfload-diagnostics.lua
@@ -7,8 +7,8 @@
assert(luaotfload_module, "This is a part of luaotfload and should not be loaded independently") {
name = "luaotfload-diagnostics",
- version = "3.23", --TAGVERSION
- date = "2022-10-03", --TAGDATE
+ version = "3.24", --TAGVERSION
+ date = "2023-08-19", --TAGDATE
description = "luaotfload-tool submodule / diagnostics",
license = "GPL v2.0"
}
diff --git a/macros/luatex/generic/luaotfload/luaotfload-dvi.lua b/macros/luatex/generic/luaotfload/luaotfload-dvi.lua
index eeac1c71d0..e2ea8c82ed 100644
--- a/macros/luatex/generic/luaotfload/luaotfload-dvi.lua
+++ b/macros/luatex/generic/luaotfload/luaotfload-dvi.lua
@@ -6,8 +6,8 @@
assert(luaotfload_module, "This is a part of luaotfload and should not be loaded independently") {
name = "luaotfload-dvi",
- version = "3.23", --TAGVERSION
- date = "2022-10-03", --TAGDATE
+ version = "3.24", --TAGVERSION
+ date = "2023-08-19", --TAGDATE
description = "luaotfload submodule / DVI",
license = "GPL v2.0",
author = "Marcel Krüger",
@@ -31,6 +31,9 @@ local vlist_t = node.id'vlist'
local disc_t = node.id'disc'
local glyph_t = node.id'glyph'
+require'luaotfload-configuration'
+local configuration = config.luaotfload
+
-- DVI output support
--
-- When writing DVI files, we can't assume that the DVI reader has access to our
@@ -48,7 +51,6 @@ local glyph_t = node.id'glyph'
-- mapped_fonts maps fontids from the user to fontids used in the DVI file
local mapped_fonts = setmetatable({}, {__index = function(t, fid)
local font = getfont(fid)
- print(fid, font and font.fullname)
local mapped = font and font.backend_font or false
t[fid] = mapped
return mapped
@@ -94,7 +96,6 @@ function full_hprocess(head)
end
if last_mapping then
local mapped = last_mapping[c]
- print(c, f, mapped)
if mapped then setfont(n, last_mapped_font, mapped) end
end
end
@@ -134,7 +135,11 @@ local function process(head, font)
end end
end
local function manipulate(tfmdata, _, dvi_kind)
- if dvi_kind ~= 'dvisvgm' then
+ if dvi_kind == 'xdvipsk' then
+ -- xdvipsk wants to read tea leaves instead of using reasonable interfaces.
+ -- They will have to make sense of whatever output this produces.
+ return
+ elseif dvi_kind ~= 'dvisvgm' then
texio.write_nl(string.format('WARNING (luaotfload): Unsupported DVI backend %q, falling back to dvisvgm.', dvi_kind))
end
-- Legacy fonts can be written to the DVI file directly
@@ -180,13 +185,14 @@ end
fonts.constructors.features.otf.register {
name = "dvifont",
- default = "dvisvgm",
+ default = configuration.run.default_dvi_driver,
manipulators = {
node = manipulate,
base = manipulate,
},
- processors = {
- node = process,
- base = process,
- },
+ -- Processors are not needed since we are using pre_shipout_filter
+ -- processors = {
+ -- node = process,
+ -- base = process,
+ -- },
}
diff --git a/macros/luatex/generic/luaotfload/luaotfload-embolden.lua b/macros/luatex/generic/luaotfload/luaotfload-embolden.lua
index 6070b1a9ba..66c4b1c2d6 100644
--- a/macros/luatex/generic/luaotfload/luaotfload-embolden.lua
+++ b/macros/luatex/generic/luaotfload/luaotfload-embolden.lua
@@ -5,8 +5,8 @@
assert(luaotfload_module, "This is a part of luaotfload and should not be loaded independently") {
name = "luaotfload-embolden",
- version = "3.23", --TAGVERSION
- date = "2022-10-03", --TAGDATE
+ version = "3.24", --TAGVERSION
+ date = "2023-08-19", --TAGDATE
description = "luaotfload submodule / embolden",
license = "GPL v2.0",
author = "Marcel Krüger"
diff --git a/macros/luatex/generic/luaotfload/luaotfload-fallback.lua b/macros/luatex/generic/luaotfload/luaotfload-fallback.lua
index 2f010c11d0..4b257455fb 100644
--- a/macros/luatex/generic/luaotfload/luaotfload-fallback.lua
+++ b/macros/luatex/generic/luaotfload/luaotfload-fallback.lua
@@ -5,8 +5,8 @@
assert(luaotfload_module, "This is a part of luaotfload and should not be loaded independently") {
name = "luaotfload-fallback",
- version = "3.23", --TAGVERSION
- date = "2022-10-03", --TAGDATE
+ version = "3.24", --TAGVERSION
+ date = "2023-08-19", --TAGDATE
description = "luaotfload submodule / fallback",
license = "GPL v2.0",
author = "Marcel Krüger"
diff --git a/macros/luatex/generic/luaotfload/luaotfload-features.lua b/macros/luatex/generic/luaotfload/luaotfload-features.lua
index 4b3c1a0859..9b753aac82 100644
--- a/macros/luatex/generic/luaotfload/luaotfload-features.lua
+++ b/macros/luatex/generic/luaotfload/luaotfload-features.lua
@@ -5,8 +5,8 @@
assert(luaotfload_module, "This is a part of luaotfload and should not be loaded independently") {
name = "luaotfload-features",
- version = "3.23", --TAGVERSION
- date = "2022-10-03", --TAGDATE
+ version = "3.24", --TAGVERSION
+ date = "2023-08-19", --TAGDATE
description = "luaotfload submodule / features",
license = "GPL v2.0",
author = "Hans Hagen, Khaled Hosny, Elie Roux, Philipp Gesang, Marcel Krüger",
@@ -614,6 +614,13 @@ local tlig_specification = {
},
}
+-- "substitution" features allow to replace individual characters with other
+-- characters. This is often used inside of fonts to e.g. implement stylistic
+-- sets.
+-- As an example how such features can be added in the fontloader, we have a
+-- simple implementation of the ROT13 cipher as a font feature. It can be
+-- used by enabling the `rot13` font feature in a font, but we are not aware of
+-- any practical usecase for this.
local rot13_specification = {
type = "substitution",
features = everywhere,
diff --git a/macros/luatex/generic/luaotfload/luaotfload-filelist.lua b/macros/luatex/generic/luaotfload/luaotfload-filelist.lua
index c7bfc4e43f..c428e08be9 100644
--- a/macros/luatex/generic/luaotfload/luaotfload-filelist.lua
+++ b/macros/luatex/generic/luaotfload/luaotfload-filelist.lua
@@ -6,8 +6,8 @@
if luaotfload_module then luaotfload_module {
name = "luaotfload-filelist",
- version = "3.23", --TAGVERSION
- date = "2022-10-03", --TAGDATE
+ version = "3.24", --TAGVERSION
+ date = "2023-08-19", --TAGDATE
description = "luaotfload submodule / filelist",
license = "GPL v2.0"
} end
diff --git a/macros/luatex/generic/luaotfload/luaotfload-glyphlist.lua b/macros/luatex/generic/luaotfload/luaotfload-glyphlist.lua
index 428872e8d3..484b0e63b0 100644
--- a/macros/luatex/generic/luaotfload/luaotfload-glyphlist.lua
+++ b/macros/luatex/generic/luaotfload/luaotfload-glyphlist.lua
@@ -1,8 +1,8 @@
if luaotfload_module then
luaotfload_module {
name = "luaotfload-glyphlist",
- version = "3.23", --TAGVERSION
- date = "2022-10-03", --TAGDATE
+ version = "3.24", --TAGVERSION
+ date = "2023-08-19", --TAGDATE
description = "luaotfload submodule / autogenerated glyphlist",
copyright = "derived from https://raw.githubusercontent.com/adobe-type-tools/agl-aglfn/master/glyphlist.txt",
original = "Adobe Glyph List, version 2.0, September 20, 2002",
diff --git a/macros/luatex/generic/luaotfload/luaotfload-harf-define.lua b/macros/luatex/generic/luaotfload/luaotfload-harf-define.lua
index a5923b773c..069513bc5a 100644
--- a/macros/luatex/generic/luaotfload/luaotfload-harf-define.lua
+++ b/macros/luatex/generic/luaotfload/luaotfload-harf-define.lua
@@ -5,8 +5,8 @@
do -- block to avoid to many local variables error
assert(luaotfload_module, "This is a part of luaotfload and should not be loaded independently") {
name = "luaotfload-harf-define",
- version = "3.23", --TAGVERSION
- date = "2022-10-03", --TAGDATE
+ version = "3.24", --TAGVERSION
+ date = "2023-08-19", --TAGDATE
description = "luaotfload submodule / HarfBuzz font loading",
license = "GPL v2.0",
author = "Khaled Hosny, Marcel Krüger",
@@ -76,6 +76,18 @@ local get_designsize do
end
end
+local keyhash do
+ local formatstring = string.rep('%02x', 256/8)
+ local sha256 = sha2.digest256
+ local format = string.format
+ local byte = string.byte
+ keyhash = setmetatable({}, {__index = function(t, k)
+ local h = format(formatstring, byte(sha256(k), 1, -1))
+ t[k] = h
+ return h
+ end})
+end
+
local containers = luaotfload.fontloader.containers
local hbcacheversion = 1.4
local fontcache = containers.define("fonts", "hb", hbcacheversion, true)
@@ -93,7 +105,7 @@ end
local function loadfont(spec)
local path, sub = spec.resolved, spec.sub or 1
- local key = gsub(string.format("%s:%d:%s", path, sub, instance), "[/\\]", ":")
+ local key = string.format("%s:%d:%s", path, sub, instance)
local attributes = lfs.attributes(path)
if not attributes then return end
@@ -183,6 +195,10 @@ local function loadfont(spec)
varkey = ''
end
+ -- Paths get get rather long and contain many characters which can not appear in filenames.
+ -- Therefore we hash the key to get it into a more regular form
+ key = keyhash[key]
+
local cached = containers.read(fontcache, key)
local iscached = cached and cached.date == date and cached.size == size
diff --git a/macros/luatex/generic/luaotfload/luaotfload-harf-plug.lua b/macros/luatex/generic/luaotfload/luaotfload-harf-plug.lua
index 5b93356b6b..296a99c9b6 100644
--- a/macros/luatex/generic/luaotfload/luaotfload-harf-plug.lua
+++ b/macros/luatex/generic/luaotfload/luaotfload-harf-plug.lua
@@ -4,8 +4,8 @@
-----------------------------------------------------------------------
assert(luaotfload_module, "This is a part of luaotfload and should not be loaded independently") {
name = "luaotfload-harf-plug",
- version = "3.23", --TAGVERSION
- date = "2022-10-03", --TAGDATE
+ version = "3.24", --TAGVERSION
+ date = "2023-08-19", --TAGDATE
description = "luaotfload submodule / HarfBuzz shaping",
license = "GPL v2.0",
author = "Khaled Hosny, Marcel Krüger",
diff --git a/macros/luatex/generic/luaotfload/luaotfload-harf-var-cff2.lua b/macros/luatex/generic/luaotfload/luaotfload-harf-var-cff2.lua
index 467faa8893..3cf3aec64f 100644
--- a/macros/luatex/generic/luaotfload/luaotfload-harf-var-cff2.lua
+++ b/macros/luatex/generic/luaotfload/luaotfload-harf-var-cff2.lua
@@ -5,8 +5,8 @@
do
assert(luaotfload_module, "This is a part of luaotfload and should not be loaded independently") {
name = "luaotfload-harf-var-cff2",
- version = "3.23", --TAGVERSION
- date = "2022-10-03", --TAGDATE
+ version = "3.24", --TAGVERSION
+ date = "2023-08-19", --TAGDATE
description = "luaotfload submodule / CFF2 table processing",
license = "GPL v2.0",
author = "Marcel Krüger",
@@ -51,9 +51,6 @@ local function parse_real(cs, offset)
end
local function get_number(result)
- if #result ~= 1 then
- print(require'inspect'(result))
- end
assert(#result == 1)
local num = result[1]
result[1] = nil
@@ -231,23 +228,19 @@ local function parse_charstring(buf, start, after, globalsubrs, subrs, result)
for i = before + n + 1, #lastresult do
lastresult[i] = nil
end
- elseif cmd == 12 then
- start = start+1
- cmd = buf:byte(start)
- lastresult[1] = -cmd-1
- lastresult = {false}
- result[#result+1] = lastresult
- elseif cmd == 19 or cmd == 20 then
- if #result == 1 then
- lastresult = {}
- result[#result+1] = lastresult
- end
- lastresult[1] = cmd
- local newi = start+(result.stemcount+7)//8
- lastresult[2] = buf:sub(start+1, newi)
- start = newi
else
- if cmd == 21 and #result == 1 then
+ if cmd == 12 then
+ start = start+1
+ cmd = -buf:byte(start)-1
+ elseif cmd == 19 or cmd == 20 then
+ if #result == 1 then
+ lastresult = {}
+ result[#result+1] = lastresult
+ end
+ local newi = start+(result.stemcount+7)//8
+ lastresult[2] = buf:sub(start+1, newi)
+ start = newi
+ elseif cmd == 21 and #result == 1 then
table.insert(result, 1, {false})
if #lastresult == 4 then
result[1][2] = lastresult[2]
diff --git a/macros/luatex/generic/luaotfload/luaotfload-harf-var-t2-writer.lua b/macros/luatex/generic/luaotfload/luaotfload-harf-var-t2-writer.lua
index 75a3804ea2..52feadf7f7 100644
--- a/macros/luatex/generic/luaotfload/luaotfload-harf-var-t2-writer.lua
+++ b/macros/luatex/generic/luaotfload/luaotfload-harf-var-t2-writer.lua
@@ -5,8 +5,8 @@
do
assert(luaotfload_module, "This is a part of luaotfload and should not be loaded independently") {
name = "luaotfload-harf-var-t2-writer",
- version = "3.23", --TAGVERSION
- date = "2022-10-03", --TAGDATE
+ version = "3.24", --TAGVERSION
+ date = "2023-08-19", --TAGDATE
description = "luaotfload submodule / Type 2 charstring writer",
license = "GPL v2.0",
author = "Marcel Krüger",
diff --git a/macros/luatex/generic/luaotfload/luaotfload-harf-var-ttf.lua b/macros/luatex/generic/luaotfload/luaotfload-harf-var-ttf.lua
index 0e9b83cd60..1fb8555f6d 100644
--- a/macros/luatex/generic/luaotfload/luaotfload-harf-var-ttf.lua
+++ b/macros/luatex/generic/luaotfload/luaotfload-harf-var-ttf.lua
@@ -5,8 +5,8 @@
do
assert(luaotfload_module, "This is a part of luaotfload and should not be loaded independently") {
name = "luaotfload-harf-var-ttf",
- version = "3.23", --TAGVERSION
- date = "2022-10-03", --TAGDATE
+ version = "3.24", --TAGVERSION
+ date = "2023-08-19", --TAGDATE
description = "luaotfload submodule / gvar table processing",
license = "GPL v2.0",
author = "Marcel Krüger",
@@ -350,7 +350,7 @@ local function read_points(gvar_data, offset)
return true, offset
end
if point_count & 0x80 ~= 0 then
- point_count = ((point_count & 0x7F) << 8) | sio.readcardinal1(gvar_data, suboffset)
+ point_count = ((point_count & 0x7F) << 8) | sio.readcardinal1(gvar_data, offset)
offset = offset + 1
end
local points = lua.newtable(point_count, 0)
diff --git a/macros/luatex/generic/luaotfload/luaotfload-init.lua b/macros/luatex/generic/luaotfload/luaotfload-init.lua
index 77cb1c54de..2796fff22a 100644
--- a/macros/luatex/generic/luaotfload/luaotfload-init.lua
+++ b/macros/luatex/generic/luaotfload/luaotfload-init.lua
@@ -7,8 +7,8 @@
assert(luaotfload_module, "This is a part of luaotfload and should not be loaded independently") {
name = "luaotfload-init",
- version = "3.23", --TAGVERSION
- date = "2022-10-03", --TAGDATE
+ version = "3.24", --TAGVERSION
+ date = "2023-08-19", --TAGDATE
description = "luaotfload submodule / initialization",
license = "GPL v2.0"
}
diff --git a/macros/luatex/generic/luaotfload/luaotfload-latex.pdf b/macros/luatex/generic/luaotfload/luaotfload-latex.pdf
index c9fde7abfa..0005cba543 100644
--- a/macros/luatex/generic/luaotfload/luaotfload-latex.pdf
+++ b/macros/luatex/generic/luaotfload/luaotfload-latex.pdf
Binary files differ
diff --git a/macros/luatex/generic/luaotfload/luaotfload-letterspace.lua b/macros/luatex/generic/luaotfload/luaotfload-letterspace.lua
index 505e0a8186..8942e9234c 100644
--- a/macros/luatex/generic/luaotfload/luaotfload-letterspace.lua
+++ b/macros/luatex/generic/luaotfload/luaotfload-letterspace.lua
@@ -5,8 +5,8 @@
assert(luaotfload_module, "This is a part of luaotfload and should not be loaded independently") {
name = "luaotfload-letterspace",
- version = "3.23", --TAGVERSION
- date = "2022-10-03", --TAGDATE
+ version = "3.24", --TAGVERSION
+ date = "2023-08-19", --TAGDATE
description = "luaotfload submodule / letterspacing",
license = "GPL v2.0",
copyright = "PRAGMA ADE / ConTeXt Development Team",
diff --git a/macros/luatex/generic/luaotfload/luaotfload-loaders.lua b/macros/luatex/generic/luaotfload/luaotfload-loaders.lua
index 2aec2fb15d..e2ca0c38c8 100644
--- a/macros/luatex/generic/luaotfload/luaotfload-loaders.lua
+++ b/macros/luatex/generic/luaotfload/luaotfload-loaders.lua
@@ -8,8 +8,8 @@
assert(luaotfload_module, "This is a part of luaotfload and should not be loaded independently") {
name = "luaotfload-loaders",
- version = "3.23", --TAGVERSION
- date = "2022-10-03", --TAGDATE
+ version = "3.24", --TAGVERSION
+ date = "2023-08-19", --TAGDATE
description = "luaotfload submodule / callback handling",
license = "GPL v2.0"
}
diff --git a/macros/luatex/generic/luaotfload/luaotfload-log.lua b/macros/luatex/generic/luaotfload/luaotfload-log.lua
index 03a3d7bbce..24e2dbfbbe 100644
--- a/macros/luatex/generic/luaotfload/luaotfload-log.lua
+++ b/macros/luatex/generic/luaotfload/luaotfload-log.lua
@@ -6,8 +6,8 @@
assert(luaotfload_module, "This is a part of luaotfload and should not be loaded independently") {
name = "luaotfload-log",
- version = "3.23", --TAGVERSION
- date = "2022-10-03", --TAGDATE
+ version = "3.24", --TAGVERSION
+ date = "2023-08-19", --TAGDATE
description = "luaotfload submodule / logging",
license = "GPL v2.0",
author = "Khaled Hosny, Elie Roux, Philipp Gesang",
diff --git a/macros/luatex/generic/luaotfload/luaotfload-main.tex b/macros/luatex/generic/luaotfload/luaotfload-main.tex
index b9e25919ca..cb94e854c6 100644
--- a/macros/luatex/generic/luaotfload/luaotfload-main.tex
+++ b/macros/luatex/generic/luaotfload/luaotfload-main.tex
@@ -32,7 +32,7 @@
\beginfrontmatter
\setdocumenttitle {The \identifier{luaotfload} package}
- \setdocumentdate {2022-10-03 v3.23}
+ \setdocumentdate {2023-08-19 v3.24}
\setdocumentauthor {LaTeX3 Project\\
Elie Roux · Khaled Hosny · Philipp Gesang · Ulrike Fischer · Marcel Krüger\\
Home: \hyperlink {https://github.com/latex3/luaotfload}}
@@ -62,6 +62,18 @@ Supported is the \identifier{luatex} versions of a current TeXLive 2019 (and a c
\endsection
\beginsection{Changes}
+\beginsubsection{New in version 3.24}
+\begin{itemize}
+ \item Add experimental configuration option to change default font lookup location
+ precedence.
+ \item Support xdvipsk in DVI mode
+ \item Preserve soft-hyphens when dropping default ignorable characters
+ \item Hash cache keys to better support certain rather unflexible operating
+ systems
+ \item Various bug fixes
+\end{itemize}
+\endsubsection
+
\beginsubsection{New in version 3.23}
\begin{itemize}
\item More reliable ToUnicode mappings in Harf mode
@@ -2278,6 +2290,27 @@ By inspecting the output you can get a first impression of how a font
is structured in \LuaTeX’s memory, what elements it is composed of,
and in what ways it can be rearranged.
+The \luaident{pre_shaping_filter} and \luaident{post_shaping_filter}
+callbacks is a pair of \identifier{(reverse)list} callbacks running
+immediately before and after \identifier{luaotfload} shapes the text.
+They both use the interface
+\beginlisting
+ function(head, groupcode, direction)
+\endlisting
+where \luaident{head} is the head of the to be shaped list,
+\luaident{groupcode} is the groupcode as documented for
+\luaident{pre_linebreak_filter} and \luaident{hpack_filter} and
+\luaident{direction} is the current direction.
+
+Since most font processing happens during shaping, \LuaTeX's
+\luaident{ligaturing} and \luaident{kerning} callbacks are not involved
+in most ligature generation and kerning decisions ans should therefore not be
+relied upon. Font processing for fonts loaded with \luaident{mode=base} might
+happen in any of these places.
+
+The specific time when extended features are applied is unspecified and might
+not be consistent.
+
\beginsubsubsection {Compatibility with Earlier Versions}
As has been touched on in the preface to this section, the structure
diff --git a/macros/luatex/generic/luaotfload/luaotfload-multiscript.lua b/macros/luatex/generic/luaotfload/luaotfload-multiscript.lua
index f7bb18c225..370d86d093 100644
--- a/macros/luatex/generic/luaotfload/luaotfload-multiscript.lua
+++ b/macros/luatex/generic/luaotfload/luaotfload-multiscript.lua
@@ -5,8 +5,8 @@
assert(luaotfload_module, "This is a part of luaotfload and should not be loaded independently") {
name = "luaotfload-multiscript",
- version = "3.23", --TAGVERSION
- date = "2022-10-03", --TAGDATE
+ version = "3.24", --TAGVERSION
+ date = "2023-08-19", --TAGDATE
description = "luaotfload submodule / multiscript",
license = "GPL v2.0",
author = "Marcel Krüger"
diff --git a/macros/luatex/generic/luaotfload/luaotfload-notdef.lua b/macros/luatex/generic/luaotfload/luaotfload-notdef.lua
index 3923e8392c..b8c0c02346 100644
--- a/macros/luatex/generic/luaotfload/luaotfload-notdef.lua
+++ b/macros/luatex/generic/luaotfload/luaotfload-notdef.lua
@@ -5,8 +5,8 @@
assert(luaotfload_module, "This is a part of luaotfload and should not be loaded independently") {
name = "luaotfload-notdef",
- version = "3.23", --TAGVERSION
- date = "2022-10-03", --TAGDATE
+ version = "3.24", --TAGVERSION
+ date = "2023-08-19", --TAGDATE
description = "luaotfload submodule / notdef",
license = "GPL v2.0",
author = "Marcel Krüger"
@@ -88,6 +88,8 @@ local ignorable_codepoints do
end
end
+ignorable_codepoints[0xAD] = nil
+
local function setnotdef(tfmdata, factor)
local desc = tfmdata.shared.rawdata.descriptions
-- So we have to find the .notdef glyph. We only know that it has GID
diff --git a/macros/luatex/generic/luaotfload/luaotfload-parsers.lua b/macros/luatex/generic/luaotfload/luaotfload-parsers.lua
index 0c91f4775c..00630a14a6 100644
--- a/macros/luatex/generic/luaotfload/luaotfload-parsers.lua
+++ b/macros/luatex/generic/luaotfload/luaotfload-parsers.lua
@@ -7,8 +7,8 @@
assert(luaotfload_module, "This is a part of luaotfload and should not be loaded independently") {
name = "luaotfload-parsers",
- version = "3.23", --TAGVERSION
- date = "2022-10-03", --TAGDATE
+ version = "3.24", --TAGVERSION
+ date = "2023-08-19", --TAGDATE
description = "luaotfload submodule / parsers",
license = "GPL v2.0"
}
diff --git a/macros/luatex/generic/luaotfload/luaotfload-resolvers.lua b/macros/luatex/generic/luaotfload/luaotfload-resolvers.lua
index d215aad8be..7b2c7ac6aa 100644
--- a/macros/luatex/generic/luaotfload/luaotfload-resolvers.lua
+++ b/macros/luatex/generic/luaotfload/luaotfload-resolvers.lua
@@ -11,8 +11,8 @@
assert(luaotfload_module, "This is a part of luaotfload and should not be loaded independently") {
name = "luaotfload-resolvers",
- version = "3.23", --TAGVERSION
- date = "2022-10-03", --TAGDATE
+ version = "3.24", --TAGVERSION
+ date = "2023-08-19", --TAGDATE
description = "luaotfload submodule / resolvers",
license = "GPL v2.0"
}
diff --git a/macros/luatex/generic/luaotfload/luaotfload-scripts.lua b/macros/luatex/generic/luaotfload/luaotfload-scripts.lua
index 222e893718..9430223332 100644
--- a/macros/luatex/generic/luaotfload/luaotfload-scripts.lua
+++ b/macros/luatex/generic/luaotfload/luaotfload-scripts.lua
@@ -5,8 +5,8 @@
assert(luaotfload_module, "This is a part of luaotfload and should not be loaded independently") {
name = "luaotfload-script",
- version = "3.23", --TAGVERSION
- date = "2022-10-03", --TAGDATE
+ version = "3.24", --TAGVERSION
+ date = "2023-08-19", --TAGDATE
description = "luaotfload submodule / Script helpers",
license = "CC0 1.0 Universal",
author = "Marcel Krüger"
diff --git a/macros/luatex/generic/luaotfload/luaotfload-status.lua b/macros/luatex/generic/luaotfload/luaotfload-status.lua
index 12efcf4452..263982a2ca 100644
--- a/macros/luatex/generic/luaotfload/luaotfload-status.lua
+++ b/macros/luatex/generic/luaotfload/luaotfload-status.lua
@@ -1,15 +1,15 @@
return {
["hashes"]={
- { "fontloader-2022-10-03.lua", "f5384fb6e665b4c3af844e55c9890073" },
+ { "fontloader-2023-08-19.lua", "5e8a5e13801cd8eff23f5e8dc4cbbc10" },
{ "fontloader-util-fil.lua", "d0accf4180201efd567816a25ad5e037" },
- { "fontloader-util-str.lua", "f4a9dd15c3e40cd3915749ac13837c95" },
+ { "fontloader-util-str.lua", "9a601a851ef3595cddc01b40dc79e1d6" },
{ "fontloader-l-unicode.lua", "f368874f11f3c525de5864fd413e4b24" },
{ "fontloader-l-math.lua", "e19c80b7e700a69df942d4df2e14aa28" },
{ "fontloader-l-boolean.lua", "abe28515dd33e8f6c416c09bca351cf8" },
- { "fontloader-l-file.lua", "5839d88d4de96b9e9c7e7f8f8eb885b3" },
+ { "fontloader-l-file.lua", "525b1c6af6f94d93ae929bfbe980d656" },
{ "fontloader-l-io.lua", "3396a8644bae37e49b2cfc0c388c78f8" },
- { "fontloader-l-table.lua", "0330da8b3a08d39876def70df8d9c0e5" },
- { "fontloader-l-string.lua", "9457f2af85723e0e6c46d0b5122e9000" },
+ { "fontloader-l-table.lua", "87aad875871bba16bbf7d4c3208b3637" },
+ { "fontloader-l-string.lua", "3e97812b1d8eff26f19837ab00813e71" },
{ "fontloader-l-function.lua", "a7e68a9703c35238729da41a474e951b" },
{ "fontloader-l-lpeg.lua", "8315a56e6bc7b2ede3f70c49bf2b5af5" },
{ "fontloader-l-lua.lua", "420bc442e6d81f4624728a6c56fcd175" },
@@ -23,77 +23,77 @@ return {
{ "fontloader-basics-chr.lua", "ce4afac7ba19471f3c8f90800839f315" },
{ "fontloader-basics-nod.lua", "1750af43148def9e7a75c6900a96f9dc" },
{ "fontloader-font-imp-effects.lua", "d05997c1826355548ec9aec1346f9f23" },
- { "fontloader-font-imp-italics.lua", "defcb415bc1e0a0999b27773902adc18" },
+ { "fontloader-font-imp-italics.lua", "3cc555a1fe00dc45449f1e4a47a5c990" },
{ "fontloader-font-imp-ligatures.lua", "250f6f4488ee770c23177afb2ff75676" },
- { "fontloader-font-imp-tex.lua", "ceb087ef6fa2f89aed7179f60ddf8f35" },
- { "fontloader-font-shp.lua", "a40862fe382d26c1f3753431254bcfdd" },
- { "fontloader-font-def.lua", "b9d908c2338b7dc443ce9d1e9fcb7139" },
+ { "fontloader-font-imp-tex.lua", "9882d382700e714cace08b7f09820958" },
+ { "fontloader-font-shp.lua", "a174ac26390bd0828805747500df0077" },
+ { "fontloader-font-def.lua", "cec0e49aee881c4cbd36d541f0162c6f" },
{ "fontloader-font-lua.lua", "1fbfdf7b689b2bdfd0e3bb9bf74ce136" },
- { "fontloader-font-afk.lua", "9da14e0fb22129c053acc599d1312544" },
- { "fontloader-font-one.lua", "bd39d42055a44ca2002f8ddbbbbf27c3" },
- { "fontloader-font-onr.lua", "6d161533f3437435e12a0ad64866df44" },
+ { "fontloader-font-afk.lua", "b7bef80aa4c18357cbfa0ae4df4d4046" },
+ { "fontloader-font-one.lua", "b7fb0389462a49bc1f41bebd2da85401" },
+ { "fontloader-font-onr.lua", "a3f85c886cf22fb27760d98603d51ffd" },
{ "fontloader-font-ocl.lua", "2a377351ae23c339764ec8ce2e8e9164" },
- { "fontloader-font-osd.lua", "1716513d8fe5f28e0e88daad2be0e05b" },
- { "fontloader-font-otc.lua", "57f5270b894e40efa93149c7d3fb0209" },
- { "fontloader-font-ots.lua", "55316a605d11a1d07d38795224c90a63" },
- { "fontloader-font-ota.lua", "2bb12d708e35bc05443eba791e2554e7" },
- { "fontloader-font-oup.lua", "76dc3379061e5650f772909966b5759e" },
+ { "fontloader-font-osd.lua", "c38c14c118680202c6f4b09734542c49" },
+ { "fontloader-font-otc.lua", "0ad931eec679ebeceed5d4f02f4ba31b" },
+ { "fontloader-font-ots.lua", "c039b20490b526ec469e41a8584ebe6d" },
+ { "fontloader-font-ota.lua", "7407b709ae7b2cdf36f68d5c98d51d12" },
+ { "fontloader-font-oup.lua", "aaff9c28233bbea56e6d27ae50e04ff0" },
{ "fontloader-font-otj.lua", "b2c165bd6771a57633f992d07384b739" },
- { "fontloader-font-oto.lua", "9febc4d75d17a543cd73fb17918f7307" },
- { "fontloader-font-otl.lua", "308b1aab04bc131da7eb8e8c3b0471d4" },
- { "fontloader-font-ott.lua", "3f67b1b1d40bbc222681d8db4aff0f42" },
+ { "fontloader-font-oto.lua", "1cc20f34606fb55d4646a0dd323499ef" },
+ { "fontloader-font-otl.lua", "21196d193ce16f3996c9aa75e81e440c" },
+ { "fontloader-font-ott.lua", "427bdc77dd187158eafb79b7193400dc" },
{ "fontloader-font-oti.lua", "309a75f9c14b77d87e94eba827dc4e71" },
- { "fontloader-font-dsp.lua", "23a82ec8fdb9f226427e78904402e48a" },
- { "fontloader-font-ttf.lua", "a3ff07150b3535fd32f68748d53fcd36" },
- { "fontloader-font-cff.lua", "651c74e4804fbb85d31267210298f466" },
- { "fontloader-font-otr.lua", "1896ac990a961f6d6fec551ca9b52a83" },
+ { "fontloader-font-dsp.lua", "755beef1b31e9dfd050e9d221d4e9ae3" },
+ { "fontloader-font-ttf.lua", "ff94e130d7c71edd899c4bae7745b7db" },
+ { "fontloader-font-cff.lua", "999da544079698ce70178fd84bcdd67a" },
+ { "fontloader-font-otr.lua", "2958a21bebcf0579f4e11f0646d1b402" },
{ "fontloader-font-vfc.lua", "a81c29eda98cd62cbebdb6c93544b50d" },
{ "fontloader-font-map.lua", "27ee748150e56f5f0e5f0fefc864f35e" },
{ "fontloader-font-cid.lua", "22b0367742fb253deef84ef7ccf5e8de" },
- { "fontloader-font-con.lua", "724e5dd14aec2d4d189f8619898004cf" },
- { "fontloader-font-ini.lua", "5343de60613adb24cdd7a8d2ee1d153c" },
- { "fontloader-data-con.lua", "23a0f5386d46a1c157ae82a373e35fa0" },
- { "fontloader-reference.lua", "e4b70de7191ba92ba3b859427eeca91c" },
+ { "fontloader-font-con.lua", "bdbaaa361308c9ccc0a7dac0bf6c17ec" },
+ { "fontloader-font-ini.lua", "16b855c98602e4a3e9df39512916a427" },
+ { "fontloader-data-con.lua", "b4ab51aaeab872d86d827f3e216bf05e" },
+ { "fontloader-reference.lua", "50f2268d2d34d5f2ad630151fc1e5b8e" },
{ "fontloader-basics-gen.lua", "4bc43036e9796fccb0b8869f4b05bf2e" },
{ "mktests", "918cb50be9ee8bd645ac1a27dc501e8c" },
- { "mkstatus", "45611be8d0396d0e048e45fdb318fea0" },
+ { "mkstatus", "0c93345ef76bb5458ea7b58144f8a716" },
{ "mkcharacters", "bfca0e96e1e351afe7077502f9595af9" },
{ "mkglyphlist", "7a8a8fdc0eac7fac2f13ec8f4e8e7aa9" },
{ "mkimport", "7d62f1042e548f8b9368f26b9ba4be5c" },
- { "luaotfload-glyphlist.lua", "76f7660436e588112a74e2bbdd4a813c" },
+ { "luaotfload-glyphlist.lua", "d07f2134f3e0f2339f278b8a168f85df" },
{ "luaotfload-characters.lua", "76415ca3ede312cad6e09038323489ae" },
- { "luaotfload-dvi.lua", "34c763f62499f1bad2ae3883ef52e126" },
- { "luaotfload-tounicode.lua", "9bc62ed441ed23b5222925b019479f78" },
- { "luaotfload-unicode.lua", "30f5b1073daa0c6e85ca1db843fbd9cd" },
- { "luaotfload-resolvers.lua", "2b21b7b0f08aa03ca0d527331718dc13" },
- { "luaotfload-parsers.lua", "0dc623da7513746ee0e0d354505187b3" },
- { "luaotfload-fallback.lua", "34996c5eb80691e8e9969145a1c63fa8" },
- { "luaotfload-szss.lua", "87ac61c8fad7650fa6866518212f3a38" },
- { "luaotfload-scripts.lua", "857b55175273a8277bab059b1bbfa6a4" },
- { "luaotfload-multiscript.lua", "3436f18db0d08ee567e5051995a3165f" },
- { "luaotfload-loaders.lua", "7298c7dd711f8480f4bca2aef5df90af" },
- { "luaotfload-harf-plug.lua", "8b3b69f4c5e573212951c54336b6c75b" },
- { "luaotfload-harf-define.lua", "ed98bd38d43fbc67e6140c343475d8dd" },
- { "luaotfload-notdef.lua", "256afb391eb4010d3b69e5af1abebb7a" },
- { "luaotfload-embolden.lua", "2abe4a85a428d79cae1260908a492477" },
- { "luaotfload-letterspace.lua", "e950c4f3d6e466b7e59fd8d1d2598fa6" },
- { "luaotfload-features.lua", "edaf61a299497abb089f9f160acaf5ba" },
- { "luaotfload-database.lua", "6da3d95f9011b8320dab5c5a32a28978" },
- { "luaotfload-configuration.lua", "18bbb7350d32b6409b7c331542a886e6" },
- { "luaotfload-colors.lua", "4ad76dd049092806e62e93437674f003" },
- { "luaotfload-auxiliary.lua", "c869a8e7d2242a02b0e10928c0cdc59c" },
- { "luaotfload-filelist.lua", "105e78993704062bf12fd6773a3ed001" },
- { "luaotfload-tool.lua", "4ba963522c4182e127396e0daa1dd314" },
- { "luaotfload-diagnostics.lua", "fe454a8415defdce72fc7dbf8af92f39" },
- { "luaotfload-log.lua", "dee4da9bd54f1a5f7453826b8ecd70ea" },
- { "luaotfload-init.lua", "fdca1ee9ddbc4324dace4d89043ee1ff" },
+ { "luaotfload-dvi.lua", "1f7115699a2b1e2b2dde2b2b06ecd6ea" },
+ { "luaotfload-tounicode.lua", "57ebeb53c32ecf935c1f112e4d24e5a9" },
+ { "luaotfload-unicode.lua", "6120395bbbd42023921c1e6eb5052fd8" },
+ { "luaotfload-resolvers.lua", "84b3b14ab66c0c1b333cbd9f663908c9" },
+ { "luaotfload-parsers.lua", "23650dae431d465b1f6599ffed4ee83f" },
+ { "luaotfload-fallback.lua", "c5e14a494096dc9b1c20c04483f4fef3" },
+ { "luaotfload-szss.lua", "3407719a32287f12a3f807f71ab5f24e" },
+ { "luaotfload-scripts.lua", "01e3be892a2a4faa9d84d84ada15c367" },
+ { "luaotfload-multiscript.lua", "5967d18a69e3b0dda2c5c1413e793984" },
+ { "luaotfload-loaders.lua", "de540857896f6407e991dd00d8a9ccef" },
+ { "luaotfload-harf-plug.lua", "7c8b3a70bc9e3989195ef8023620bb41" },
+ { "luaotfload-harf-define.lua", "c39204ae392eebf0b121023a77b97e8e" },
+ { "luaotfload-notdef.lua", "5dd6d665246f2af6225936cfde4a90c0" },
+ { "luaotfload-embolden.lua", "7c1a7a88620b651b2564bfd6c2080e72" },
+ { "luaotfload-letterspace.lua", "9907c492ff6c0c917578d1477ac3c16d" },
+ { "luaotfload-features.lua", "902db5fc4316aa7c63c9f3e6565a2302" },
+ { "luaotfload-database.lua", "99e8682432de72337f4f635c31b373c2" },
+ { "luaotfload-configuration.lua", "261b1e6e7c1d79958008162bd376be52" },
+ { "luaotfload-colors.lua", "238f8d1c9a0a296341ebc9b6522d668e" },
+ { "luaotfload-auxiliary.lua", "a1a411bc17c7d147250ab04da62d205e" },
+ { "luaotfload-filelist.lua", "c141386c0b9262d1e6e54228b35dac13" },
+ { "luaotfload-tool.lua", "cea092171f0ca1ffc342aa66ad261d8f" },
+ { "luaotfload-diagnostics.lua", "c54effd99e8412784d5c9876c6d298de" },
+ { "luaotfload-log.lua", "01c847f9d12312f80971ae4eb04fa0ce" },
+ { "luaotfload-init.lua", "aa5b3603a1b2696a27cd055e9174478a" },
{ "luaotfload-main.lua", "b19c9cc34cf1d676c39f872cfb41aef6" },
},
["notes"]={
["committer"]="Marcel Fabian Krüger <tex@2krueger.de>",
- ["description"]="v3.23/2022-10-03",
- ["loader"]="fontloader-2022-10-03.lua",
- ["revision"]="a36774ba186e3bacab9398e50d0069a0372d3c12",
- ["timestamp"]="2022-10-03 20:33:45 +0200",
+ ["description"]="v3.24/2023-08-19",
+ ["loader"]="fontloader-2023-08-19.lua",
+ ["revision"]="fc1177f247ae78a916f4ef5387ec7e29b8cd8155",
+ ["timestamp"]="2023-08-19 23:56:21 +0200",
},
} \ No newline at end of file
diff --git a/macros/luatex/generic/luaotfload/luaotfload-suppress.lua b/macros/luatex/generic/luaotfload/luaotfload-suppress.lua
index 0e67e4eada..a8f283d972 100644
--- a/macros/luatex/generic/luaotfload/luaotfload-suppress.lua
+++ b/macros/luatex/generic/luaotfload/luaotfload-suppress.lua
@@ -5,8 +5,8 @@
assert(luaotfload_module, "This is a part of luaotfload and should not be loaded independently") {
name = "luaotfload-suppress",
- version = "3.23", --TAGVERSION
- date = "2022-10-03", --TAGDATE
+ version = "3.24", --TAGVERSION
+ date = "2023-08-19", --TAGDATE
description = "luaotfload submodule / suppress",
license = "GPL v2.0",
author = "Marcel Krüger"
diff --git a/macros/luatex/generic/luaotfload/luaotfload-szss.lua b/macros/luatex/generic/luaotfload/luaotfload-szss.lua
index f8aca2bd64..30e9000064 100644
--- a/macros/luatex/generic/luaotfload/luaotfload-szss.lua
+++ b/macros/luatex/generic/luaotfload/luaotfload-szss.lua
@@ -5,8 +5,8 @@
assert(luaotfload_module, "This is a part of luaotfload and should not be loaded independently") {
name = "luaotfload-szss",
- version = "3.23", --TAGVERSION
- date = "2022-10-03", --TAGDATE
+ version = "3.24", --TAGVERSION
+ date = "2023-08-19", --TAGDATE
description = "luaotfload submodule / Special feature handling",
license = "GPL v2.0",
author = "Marcel Krüger"
diff --git a/macros/luatex/generic/luaotfload/luaotfload-tool.1 b/macros/luatex/generic/luaotfload/luaotfload-tool.1
index bd0617503a..58b9122109 100644
--- a/macros/luatex/generic/luaotfload/luaotfload-tool.1
+++ b/macros/luatex/generic/luaotfload/luaotfload-tool.1
@@ -1,6 +1,6 @@
.\" Man page generated from reStructuredText.
.
-.TH LUAOTFLOAD-TOOL 1 "2022-10-03" "3.23" "text processing"
+.TH LUAOTFLOAD-TOOL 1 "2023-08-19" "3.24" "text processing"
.SH NAME
luaotfload-tool \- generate and query the Luaotfload font names database
.
diff --git a/macros/luatex/generic/luaotfload/luaotfload-tool.lua b/macros/luatex/generic/luaotfload/luaotfload-tool.lua
index dc9dec543e..0883ee5ad2 100644
--- a/macros/luatex/generic/luaotfload/luaotfload-tool.lua
+++ b/macros/luatex/generic/luaotfload/luaotfload-tool.lua
@@ -9,8 +9,8 @@
local ProvidesLuaModule = {
name = "luaotfload-tool",
- version = "3.23", --TAGVERSION
- date = "2022-10-03", --TAGDATE
+ version = "3.24", --TAGVERSION
+ date = "2023-08-19", --TAGDATE
description = "luaotfload-tool / database functionality",
license = "GPL v2.0"
}
diff --git a/macros/luatex/generic/luaotfload/luaotfload-tool.pdf b/macros/luatex/generic/luaotfload/luaotfload-tool.pdf
index 640a657ea3..9f39d422c1 100644
--- a/macros/luatex/generic/luaotfload/luaotfload-tool.pdf
+++ b/macros/luatex/generic/luaotfload/luaotfload-tool.pdf
Binary files differ
diff --git a/macros/luatex/generic/luaotfload/luaotfload-tool.rst b/macros/luatex/generic/luaotfload/luaotfload-tool.rst
index 68f761bdb0..92c7839ddf 100644
--- a/macros/luatex/generic/luaotfload/luaotfload-tool.rst
+++ b/macros/luatex/generic/luaotfload/luaotfload-tool.rst
@@ -6,9 +6,9 @@
generate and query the Luaotfload font names database
-----------------------------------------------------------------------
-:Date: 2022-10-03
+:Date: 2023-08-19
:Copyright: GPL v2.0
-:Version: 3.23
+:Version: 3.24
:Manual section: 1
:Manual group: text processing
diff --git a/macros/luatex/generic/luaotfload/luaotfload-tounicode.lua b/macros/luatex/generic/luaotfload/luaotfload-tounicode.lua
index cb34d12aeb..a78218f09b 100644
--- a/macros/luatex/generic/luaotfload/luaotfload-tounicode.lua
+++ b/macros/luatex/generic/luaotfload/luaotfload-tounicode.lua
@@ -5,8 +5,8 @@
assert(luaotfload_module, "This is a part of luaotfload and should not be loaded independently") {
name = "luaotfload-tounicode",
- version = "3.23", --TAGVERSION
- date = "2022-10-03", --TAGDATE
+ version = "3.24", --TAGVERSION
+ date = "2023-08-19", --TAGDATE
description = "luaotfload submodule / tounicode",
license = "GPL v2.0",
author = "Hans Hagen, Khaled Hosny, Elie Roux, Philipp Gesang, Marcel Krüger",
diff --git a/macros/luatex/generic/luaotfload/luaotfload-unicode.lua b/macros/luatex/generic/luaotfload/luaotfload-unicode.lua
index 64a1eed448..cd67be7b75 100644
--- a/macros/luatex/generic/luaotfload/luaotfload-unicode.lua
+++ b/macros/luatex/generic/luaotfload/luaotfload-unicode.lua
@@ -5,8 +5,8 @@
assert(luaotfload_module, "This is a part of luaotfload and should not be loaded independently") {
name = "luaotfload-unicode",
- version = "3.23", --TAGVERSION
- date = "2022-10-03", --TAGDATE
+ version = "3.24", --TAGVERSION
+ date = "2023-08-19", --TAGDATE
description = "luaotfload submodule / Unicode helpers",
license = "CC0 1.0 Universal",
author = "Marcel Krüger"
diff --git a/macros/luatex/generic/luaotfload/luaotfload.conf.5 b/macros/luatex/generic/luaotfload/luaotfload.conf.5
index 7617508bc3..56160f89fe 100644
--- a/macros/luatex/generic/luaotfload/luaotfload.conf.5
+++ b/macros/luatex/generic/luaotfload/luaotfload.conf.5
@@ -1,6 +1,6 @@
.\" Man page generated from reStructuredText.
.
-.TH LUAOTFLOAD.CONF 5 "2022-10-03" "3.23" "text processing"
+.TH LUAOTFLOAD.CONF 5 "2023-08-19" "3.24" "text processing"
.SH NAME
luaotfload.conf \- Luaotfload configuration file
.
@@ -216,6 +216,14 @@ T} T{
T}
_
T{
+location\-precedence
+T} T{
+s
+T} T{
+\fB"system,texmf,local\fP
+T}
+_
+T{
max\-fonts
T} T{
n
@@ -287,6 +295,12 @@ It corresponds loosely to the \fB\-\-formats\fP option to
list does not contain any useful identifiers, the default list
\fB"otf,ttf,ttc"\fP will be used.
.sp
+The variable \fBlocation\-precedence\fP selects where and in which order
+luaotfload searches for fonts. Fonts in earlier locations are preferred.
+The three supported locations are \fBsystem\fP for system specific font
+directories, \fBtexmf\fP for fonts which are part of the TeX{} distribution
+and \fBlocal\fP for local fonts.
+.sp
The variable \fBmax\-fonts\fP determines after processing how many font
files the font scanner will terminate the search. This is useful for
debugging issues with the font index and has the same effect as the
@@ -296,7 +310,8 @@ The \fBscan\-local\fP flag, if set, will incorporate the current working
directory as a font search location. NB: This will potentially slow
down document processing because a font index with local fonts will not
be saved to disk, so these fonts will have to be re\-indexed whenever
-the document is built.
+the document is built. Setting \fBscan_local\fP to \fBfalse\fP is the same
+as removing \fBlocal\fP from \fBlocation\-precedence\fP\&.
.sp
The \fBskip\-read\fP flag is only useful for debugging: It makes
Luaotfload skip reading fonts. The font information for rebuilding the
@@ -515,6 +530,14 @@ T} T{
\fB"default"\fP
T}
_
+T{
+default_dvi_driver
+T} T{
+s
+T} T{
+\fB"dvisvgm"\fP
+T}
+_
.TE
.sp
Unqualified font lookups are treated with the flexible “anonymous”
@@ -588,6 +611,17 @@ subsequent lookups. The alternative, \fBnormal\fP circumvents the cache
and resolves every request individually. (Since to the restructuring of
the font name index in Luaotfload 2.4 the performance difference
between the cached and uncached lookups should be marginal.)
+.sp
+When luaotfload is used in \fBDVI\fP mode, the \fBdefault_dvi_driver\fP option
+determines how OpenType fonts are represented in the DVI output. In most
+cases the default value \fBdvisvgm\fP should be set, it uses a format
+supported by multiple backends including \fBdvipdfmx\fP and \fBdvisvgm\fP
+which uses GIDs to identify characters.
+Setting this to \fBxdvipsk\fP uses an unstable internal format instead
+which will change depending on the luaotfload, engine, or font version.
+No one should rely on the mapping between DVI character codes and font glyphs
+in this mode unless they tightly control all involved versions and are deeply
+familiar with the implementation.
.SH FILES
.sp
Luaotfload only processes the first configuration file it encounters at
diff --git a/macros/luatex/generic/luaotfload/luaotfload.conf.example b/macros/luatex/generic/luaotfload/luaotfload.conf.example
index b0323afe51..c307f3611a 100644
--- a/macros/luatex/generic/luaotfload/luaotfload.conf.example
+++ b/macros/luatex/generic/luaotfload/luaotfload.conf.example
@@ -2,6 +2,7 @@
;; defaults only, see luaotfload.conf(5) for more information.
[db]
+ location-precedence = system, texmf, local
compress = true
formats = otf, ttf, ttc
max-fonts = 2.2517998136852e15
@@ -25,6 +26,7 @@
definer = patch
log-level = 0
resolver = cached
+ default-dvi-driver = dvisvgm
;; vim:ft=dosini:et:sw=4:ts=8
diff --git a/macros/luatex/generic/luaotfload/luaotfload.conf.rst b/macros/luatex/generic/luaotfload/luaotfload.conf.rst
index 2f2bee0fa1..3604422099 100644
--- a/macros/luatex/generic/luaotfload/luaotfload.conf.rst
+++ b/macros/luatex/generic/luaotfload/luaotfload.conf.rst
@@ -6,9 +6,9 @@
Luaotfload configuration file
-----------------------------------------------------------------------
-:Date: 2022-10-03
+:Date: 2023-08-19
:Copyright: GPL v2.0
-:Version: 3.23
+:Version: 3.24
:Manual section: 5
:Manual group: text processing
@@ -125,25 +125,27 @@ the variable is unset.
Section ``db``
-----------------------------------------------------------------------
-+--------------------+--------+---------------------------+
-| variable | type | default |
-+--------------------+--------+---------------------------+
-| compress | b | ``true`` |
-+--------------------+--------+---------------------------+
-| designsize-dimen | b | ``bp`` |
-+--------------------+--------+---------------------------+
-| formats | s | ``"otf,ttf,ttc"`` |
-+--------------------+--------+---------------------------+
-| max-fonts | n | ``2^51`` |
-+--------------------+--------+---------------------------+
-| scan-local | b | ``false`` |
-+--------------------+--------+---------------------------+
-| skip-read | b | ``false`` |
-+--------------------+--------+---------------------------+
-| strip | b | ``true`` |
-+--------------------+--------+---------------------------+
-| update-live | b | ``true`` |
-+--------------------+--------+---------------------------+
++----------------------+--------+---------------------------+
+| variable | type | default |
++----------------------+--------+---------------------------+
+| compress | b | ``true`` |
++----------------------+--------+---------------------------+
+| designsize-dimen | b | ``bp`` |
++----------------------+--------+---------------------------+
+| formats | s | ``"otf,ttf,ttc"`` |
++----------------------+--------+---------------------------+
+| location-precedence | s | ``"system,texmf,local`` |
++----------------------+--------+---------------------------+
+| max-fonts | n | ``2^51`` |
++----------------------+--------+---------------------------+
+| scan-local | b | ``false`` |
++----------------------+--------+---------------------------+
+| skip-read | b | ``false`` |
++----------------------+--------+---------------------------+
+| strip | b | ``true`` |
++----------------------+--------+---------------------------+
+| update-live | b | ``true`` |
++----------------------+--------+---------------------------+
The flag ``compress`` determines whether the font index (usually
``luaotfload-names.lua[.gz]`` will be stored in compressed forms.
@@ -171,6 +173,12 @@ It corresponds loosely to the ``--formats`` option to
list does not contain any useful identifiers, the default list
``"otf,ttf,ttc"`` will be used.
+The variable ``location-precedence`` selects where and in which order
+luaotfload searches for fonts. Fonts in earlier locations are preferred.
+The three supported locations are ``system`` for system specific font
+directories, ``texmf`` for fonts which are part of the \TeX{} distribution
+and ``local`` for local fonts.
+
The variable ``max-fonts`` determines after processing how many font
files the font scanner will terminate the search. This is useful for
debugging issues with the font index and has the same effect as the
@@ -180,7 +188,8 @@ The ``scan-local`` flag, if set, will incorporate the current working
directory as a font search location. NB: This will potentially slow
down document processing because a font index with local fonts will not
be saved to disk, so these fonts will have to be re-indexed whenever
-the document is built.
+the document is built. Setting ``scan_local`` to ``false`` is the same
+as removing ``local`` from ``location-precedence``.
The ``skip-read`` flag is only useful for debugging: It makes
Luaotfload skip reading fonts. The font information for rebuilding the
@@ -277,21 +286,23 @@ version.
Section ``run``
-----------------------------------------------------------------------
-+------------------+--------+------------------------------+
-| variable | type | default |
-+------------------+--------+------------------------------+
-| anon-sequence | s | ``"tex,path,name"`` |
-+------------------+--------+------------------------------+
-| color-callback | s | ``"post_linebreak_filter"`` |
-+------------------+--------+------------------------------+
-| definer | s | ``"patch"`` |
-+------------------+--------+------------------------------+
-| log-level | n | ``0`` |
-+------------------+--------+------------------------------+
-| resolver | s | ``"cached"`` |
-+------------------+--------+------------------------------+
-| fontloader | s | ``"default"`` |
-+------------------+--------+------------------------------+
++---------------------+--------+------------------------------+
+| variable | type | default |
++---------------------+--------+------------------------------+
+| anon-sequence | s | ``"tex,path,name"`` |
++---------------------+--------+------------------------------+
+| color-callback | s | ``"post_linebreak_filter"`` |
++---------------------+--------+------------------------------+
+| definer | s | ``"patch"`` |
++---------------------+--------+------------------------------+
+| log-level | n | ``0`` |
++---------------------+--------+------------------------------+
+| resolver | s | ``"cached"`` |
++---------------------+--------+------------------------------+
+| fontloader | s | ``"default"`` |
++---------------------+--------+------------------------------+
+| default_dvi_driver | s | ``"dvisvgm"`` |
++---------------------+--------+------------------------------+
Unqualified font lookups are treated with the flexible “anonymous”
mechanism. This involves a chain of lookups applied successively until
@@ -365,6 +376,16 @@ and resolves every request individually. (Since to the restructuring of
the font name index in Luaotfload 2.4 the performance difference
between the cached and uncached lookups should be marginal.)
+When luaotfload is used in ``DVI`` mode, the ``default_dvi_driver`` option
+determines how OpenType fonts are represented in the DVI output. In most
+cases the default value ``dvisvgm`` should be set, it uses a format
+supported by multiple backends including ``dvipdfmx`` and ``dvisvgm``
+which uses GIDs to identify characters.
+Setting this to ``xdvipsk`` uses an unstable internal format instead
+which will change depending on the luaotfload, engine, or font version.
+No one should rely on the mapping between DVI character codes and font glyphs
+in this mode unless they tightly control all involved versions and are deeply
+familiar with the implementation.
FILES
=======================================================================
diff --git a/macros/luatex/generic/luaotfload/luaotfload.lua b/macros/luatex/generic/luaotfload/luaotfload.lua
index a22880e736..2125387b90 100644
--- a/macros/luatex/generic/luaotfload/luaotfload.lua
+++ b/macros/luatex/generic/luaotfload/luaotfload.lua
@@ -20,8 +20,8 @@ local authors = "\z
-- version number is used below!
local ProvidesLuaModule = {
name = "luaotfload",
- version = "3.23", --TAGVERSION
- date = "2022-10-03", --TAGDATE
+ version = "3.24", --TAGVERSION
+ date = "2023-08-19", --TAGDATE
description = "Lua based OpenType font support",
author = authors,
copyright = authors,
diff --git a/macros/luatex/generic/luaotfload/luaotfload.sty b/macros/luatex/generic/luaotfload/luaotfload.sty
index aafcfb6930..44fce07432 100644
--- a/macros/luatex/generic/luaotfload/luaotfload.sty
+++ b/macros/luatex/generic/luaotfload/luaotfload.sty
@@ -39,7 +39,7 @@
\fi
\ifdefined\ProvidesPackage
\ProvidesPackage{luaotfload}%
- [2022/10/03 v3.23 OpenType layout system]
+ [2023/08/19 v3.24 OpenType layout system]
\fi
\directlua{
if xpcall(function ()%
diff --git a/macros/luatex/generic/luaotfload/scripts-demo.pdf b/macros/luatex/generic/luaotfload/scripts-demo.pdf
index 4207a5fd7f..b6d0e7dd4c 100644
--- a/macros/luatex/generic/luaotfload/scripts-demo.pdf
+++ b/macros/luatex/generic/luaotfload/scripts-demo.pdf
Binary files differ
diff --git a/macros/luatex/generic/luaotfload/shaper-demo-graphite.pdf b/macros/luatex/generic/luaotfload/shaper-demo-graphite.pdf
index 1a8b1c182a..0c0ca16b3d 100644
--- a/macros/luatex/generic/luaotfload/shaper-demo-graphite.pdf
+++ b/macros/luatex/generic/luaotfload/shaper-demo-graphite.pdf
Binary files differ
diff --git a/macros/luatex/generic/luaotfload/shaper-demo.pdf b/macros/luatex/generic/luaotfload/shaper-demo.pdf
index f4fe93315d..a51bc51822 100644
--- a/macros/luatex/generic/luaotfload/shaper-demo.pdf
+++ b/macros/luatex/generic/luaotfload/shaper-demo.pdf
Binary files differ