summaryrefslogtreecommitdiff
path: root/macros/luatex
diff options
context:
space:
mode:
authorNorbert Preining <norbert@preining.info>2020-05-03 03:02:51 +0000
committerNorbert Preining <norbert@preining.info>2020-05-03 03:02:51 +0000
commitd78de17ddf0443233483fd98f40802cae5aa87c5 (patch)
tree1b7128cc505808a09c18e158288d6c3cdcf5c2fb /macros/luatex
parent8626a9c3cb5dc8d02d779d5b5b1e3933d5626f43 (diff)
CTAN sync 202005030302
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.lua47
-rw-r--r--macros/luatex/generic/lualibs/lualibs-extended-merged.lua274
-rw-r--r--macros/luatex/generic/lualibs/lualibs-os.lua10
-rw-r--r--macros/luatex/generic/lualibs/lualibs-table.lua106
-rw-r--r--macros/luatex/generic/lualibs/lualibs-trac-inf.lua99
-rw-r--r--macros/luatex/generic/lualibs/lualibs-util-str.lua7
-rw-r--r--macros/luatex/generic/lualibs/lualibs-util-tab.lua255
-rw-r--r--macros/luatex/generic/lualibs/lualibs.dtx18
-rw-r--r--macros/luatex/generic/lualibs/lualibs.pdfbin80955 -> 80861 bytes
-rw-r--r--macros/luatex/generic/luaotfload/NEWS18
-rw-r--r--macros/luatex/generic/luaotfload/README.md11
-rw-r--r--macros/luatex/generic/luaotfload/filegraph.pdfbin39847 -> 39877 bytes
-rw-r--r--macros/luatex/generic/luaotfload/fontloader-2020-04-30.lua (renamed from macros/luatex/generic/luaotfload/fontloader-2020-01-26.lua)656
-rw-r--r--macros/luatex/generic/luaotfload/fontloader-basics-gen.lua2
-rw-r--r--macros/luatex/generic/luaotfload/fontloader-basics-nod.lua93
-rw-r--r--macros/luatex/generic/luaotfload/fontloader-font-cff.lua9
-rw-r--r--macros/luatex/generic/luaotfload/fontloader-font-con.lua1
-rw-r--r--macros/luatex/generic/luaotfload/fontloader-font-dsp.lua57
-rw-r--r--macros/luatex/generic/luaotfload/fontloader-font-map.lua264
-rw-r--r--macros/luatex/generic/luaotfload/fontloader-font-ocl.lua6
-rw-r--r--macros/luatex/generic/luaotfload/fontloader-font-osd.lua97
-rw-r--r--macros/luatex/generic/luaotfload/fontloader-font-ota.lua116
-rw-r--r--macros/luatex/generic/luaotfload/fontloader-font-otj.lua61
-rw-r--r--macros/luatex/generic/luaotfload/fontloader-font-otl.lua5
-rw-r--r--macros/luatex/generic/luaotfload/fontloader-font-ots.lua140
-rw-r--r--macros/luatex/generic/luaotfload/fontloader-font-oup.lua59
-rw-r--r--macros/luatex/generic/luaotfload/fontloader-l-table.lua106
-rw-r--r--macros/luatex/generic/luaotfload/fontloader-reference-load-order.lua4
-rw-r--r--macros/luatex/generic/luaotfload/fontloader-reference.lua542
-rw-r--r--macros/luatex/generic/luaotfload/fontloader-util-str.lua7
-rw-r--r--macros/luatex/generic/luaotfload/luaotfload-auxiliary.lua10
-rw-r--r--macros/luatex/generic/luaotfload/luaotfload-characters.lua5768
-rw-r--r--macros/luatex/generic/luaotfload/luaotfload-colors.lua276
-rw-r--r--macros/luatex/generic/luaotfload/luaotfload-conf.pdfbin77323 -> 77392 bytes
-rw-r--r--macros/luatex/generic/luaotfload/luaotfload-configuration.lua79
-rw-r--r--macros/luatex/generic/luaotfload/luaotfload-database.lua244
-rw-r--r--macros/luatex/generic/luaotfload/luaotfload-diagnostics.lua66
-rw-r--r--macros/luatex/generic/luaotfload/luaotfload-embolden.lua17
-rw-r--r--macros/luatex/generic/luaotfload/luaotfload-fallback.lua14
-rw-r--r--macros/luatex/generic/luaotfload/luaotfload-features.lua40
-rw-r--r--macros/luatex/generic/luaotfload/luaotfload-filelist.lua6
-rw-r--r--macros/luatex/generic/luaotfload/luaotfload-glyphlist.lua4
-rw-r--r--macros/luatex/generic/luaotfload/luaotfload-harf-define.lua147
-rw-r--r--macros/luatex/generic/luaotfload/luaotfload-harf-plug.lua138
-rw-r--r--macros/luatex/generic/luaotfload/luaotfload-init.lua39
-rw-r--r--macros/luatex/generic/luaotfload/luaotfload-latex.pdfbin443581 -> 445884 bytes
-rw-r--r--macros/luatex/generic/luaotfload/luaotfload-latex.tex4
-rw-r--r--macros/luatex/generic/luaotfload/luaotfload-letterspace.lua32
-rw-r--r--macros/luatex/generic/luaotfload/luaotfload-loaders.lua34
-rw-r--r--macros/luatex/generic/luaotfload/luaotfload-log.lua32
-rw-r--r--macros/luatex/generic/luaotfload/luaotfload-main.lua69
-rw-r--r--macros/luatex/generic/luaotfload/luaotfload-main.tex36
-rw-r--r--macros/luatex/generic/luaotfload/luaotfload-multiscript.lua153
-rw-r--r--macros/luatex/generic/luaotfload/luaotfload-notdef.lua231
-rw-r--r--macros/luatex/generic/luaotfload/luaotfload-parsers.lua45
-rw-r--r--macros/luatex/generic/luaotfload/luaotfload-resolvers.lua18
-rw-r--r--macros/luatex/generic/luaotfload/luaotfload-scripts.lua4
-rw-r--r--macros/luatex/generic/luaotfload/luaotfload-status.lua95
-rw-r--r--macros/luatex/generic/luaotfload/luaotfload-suppress.lua89
-rw-r--r--macros/luatex/generic/luaotfload/luaotfload-szss.lua226
-rw-r--r--macros/luatex/generic/luaotfload/luaotfload-tool.17
-rw-r--r--macros/luatex/generic/luaotfload/luaotfload-tool.lua140
-rw-r--r--macros/luatex/generic/luaotfload/luaotfload-tool.pdfbin76686 -> 76849 bytes
-rw-r--r--macros/luatex/generic/luaotfload/luaotfload-tool.rst7
-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.52
-rw-r--r--macros/luatex/generic/luaotfload/luaotfload.conf.rst4
-rw-r--r--macros/luatex/generic/luaotfload/luaotfload.sty2
-rw-r--r--macros/luatex/generic/luaotfload/scripts-demo.pdfbin21523 -> 21523 bytes
-rw-r--r--macros/luatex/generic/luaotfload/shaper-demo-graphite.pdfbin8487 -> 8487 bytes
-rw-r--r--macros/luatex/generic/luaotfload/shaper-demo.pdfbin8411 -> 8411 bytes
74 files changed, 8883 insertions, 2282 deletions
diff --git a/macros/luatex/generic/lualibs/NEWS b/macros/luatex/generic/lualibs/NEWS
index 42846f767a..486b82bf79 100644
--- a/macros/luatex/generic/lualibs/NEWS
+++ b/macros/luatex/generic/lualibs/NEWS
@@ -1,4 +1,7 @@
History of the lualibs package
+2020/05/01 v2.71/
+ * sync with Context current as of 2020/04/30.
+
2020/02/02 v2.70/
* sync with Context current as of 2020/01/26.
diff --git a/macros/luatex/generic/lualibs/README.md b/macros/luatex/generic/lualibs/README.md
index 3a7d760a94..bbbf6993fa 100644
--- a/macros/luatex/generic/lualibs/README.md
+++ b/macros/luatex/generic/lualibs/README.md
@@ -1,10 +1,10 @@
# The Lualibs Package
-VERSION: 2.70
+VERSION: 2.71
-DATE: 2020-02-02
+DATE: 2020-05-01
-FONTLOADERDATE: 2020-01-26
+FONTLOADERDATE: 2020-04-30
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 38c4debd9b..24a62e3d17 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 : Sun Feb 2 22:31:00 2020
+-- merge date : 2020-05-01 15:49
do -- begin closure to overcome local limits and interference
@@ -1700,13 +1700,13 @@ function table.fromhash(t)
end
return hsh
end
-local noquotes,hexify,handle,compact,inline,functions,metacheck
+local noquotes,hexify,handle,compact,inline,functions,metacheck,accurate
local reserved=table.tohash {
'and','break','do','else','elseif','end','false','for','function','if',
'in','local','nil','not','or','repeat','return','then','true','until','while',
- 'NaN','goto',
+ 'NaN','goto','const',
}
-local function is_simple_table(t,hexify)
+local function is_simple_table(t,hexify,accurate)
local nt=#t
if nt>0 then
local n=0
@@ -1725,6 +1725,8 @@ local function is_simple_table(t,hexify)
if tv=="number" then
if hexify then
tt[i]=format("0x%X",v)
+ elseif accurate then
+ tt[i]=format("%q",v)
else
tt[i]=v
end
@@ -1745,6 +1747,8 @@ local function is_simple_table(t,hexify)
if tv=="number" then
if hexify then
tt[i+1]=format("0x%X",v)
+ elseif accurate then
+ tt[i+1]=format("%q",v)
else
tt[i+1]=v
end
@@ -1816,6 +1820,8 @@ local function do_serialize(root,name,depth,level,indexed)
if tv=="number" then
if hexify then
handle(format("%s 0x%X,",depth,v))
+ elseif accurate then
+ handle(format("%s %q,",depth,v))
else
handle(format("%s %s,",depth,v))
end
@@ -1825,7 +1831,7 @@ local function do_serialize(root,name,depth,level,indexed)
if next(v)==nil then
handle(format("%s {},",depth))
elseif inline then
- local st=is_simple_table(v,hexify)
+ local st=is_simple_table(v,hexify,accurate)
if st then
handle(format("%s { %s },",depth,concat(st,", ")))
else
@@ -1853,12 +1859,16 @@ local function do_serialize(root,name,depth,level,indexed)
if tk=="number" then
if hexify then
handle(format("%s [0x%X]=0x%X,",depth,k,v))
+ elseif accurate then
+ handle(format("%s [%s]=%q,",depth,k,v))
else
handle(format("%s [%s]=%s,",depth,k,v))
end
elseif tk=="boolean" then
if hexify then
handle(format("%s [%s]=0x%X,",depth,k and "true" or "false",v))
+ elseif 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
@@ -1866,12 +1876,16 @@ local function do_serialize(root,name,depth,level,indexed)
elseif noquotes and not reserved[k] and lpegmatch(propername,k) then
if hexify then
handle(format("%s %s=0x%X,",depth,k,v))
+ elseif accurate then
+ handle(format("%s %s=%q,",depth,k,v))
else
handle(format("%s %s=%s,",depth,k,v))
end
else
if hexify then
handle(format("%s [%q]=0x%X,",depth,k,v))
+ elseif accurate then
+ handle(format("%s [%q]=%q,",depth,k,v))
else
handle(format("%s [%q]=%s,",depth,k,v))
end
@@ -1880,6 +1894,8 @@ local function do_serialize(root,name,depth,level,indexed)
if tk=="number" then
if hexify then
handle(format("%s [0x%X]=%q,",depth,k,v))
+ elseif accurate then
+ handle(format("%s [%q]=%q,",depth,k,v))
else
handle(format("%s [%s]=%q,",depth,k,v))
end
@@ -1896,6 +1912,8 @@ local function do_serialize(root,name,depth,level,indexed)
if tk=="number" then
if hexify then
handle(format("%s [0x%X]={},",depth,k))
+ elseif accurate then
+ handle(format("%s [%q]={},",depth,k))
else
handle(format("%s [%s]={},",depth,k))
end
@@ -1908,11 +1926,13 @@ local function do_serialize(root,name,depth,level,indexed)
handle(format("%s [%q]={},",depth,k))
end
elseif inline then
- local st=is_simple_table(v,hexify)
+ local st=is_simple_table(v,hexify,accurate)
if st then
if tk=="number" then
if hexify then
handle(format("%s [0x%X]={ %s },",depth,k,concat(st,", ")))
+ elseif accurate then
+ handle(format("%s [%q]={ %s },",depth,k,concat(st,", ")))
else
handle(format("%s [%s]={ %s },",depth,k,concat(st,", ")))
end
@@ -1934,6 +1954,8 @@ local function do_serialize(root,name,depth,level,indexed)
if tk=="number" then
if hexify then
handle(format("%s [0x%X]=%s,",depth,k,v and "true" or "false"))
+ elseif accurate then
+ handle(format("%s [%q]=%s,",depth,k,v and "true" or "false"))
else
handle(format("%s [%s]=%s,",depth,k,v and "true" or "false"))
end
@@ -1953,6 +1975,8 @@ local function do_serialize(root,name,depth,level,indexed)
if tk=="number" then
if hexify then
handle(format("%s [0x%X]=load(%q),",depth,k,f))
+ elseif accurate then
+ handle(format("%s [%q]=load(%q),",depth,k,f))
else
handle(format("%s [%s]=load(%q),",depth,k,f))
end
@@ -1970,6 +1994,8 @@ local function do_serialize(root,name,depth,level,indexed)
if tk=="number" then
if hexify then
handle(format("%s [0x%X]=%q,",depth,k,tostring(v)))
+ elseif accurate then
+ handle(format("%s [%q]=%q,",depth,k,tostring(v)))
else
handle(format("%s [%s]=%q,",depth,k,tostring(v)))
end
@@ -1993,6 +2019,7 @@ local function serialize(_handle,root,name,specification)
if type(specification)=="table" then
noquotes=specification.noquotes
hexify=specification.hexify
+ accurate=specification.accurate
handle=_handle or specification.handle or print
functions=specification.functions
compact=specification.compact
@@ -3399,7 +3426,7 @@ function os.uuid()
end
local d
function os.timezone(delta)
- d=d or tonumber(tonumber(date("%H")-date("!%H")))
+ d=d or ((tonumber(date("%H")) or 0)-(tonumber(date("!%H")) or 0))
if delta then
if d>0 then
return format("+%02i:00",d)
@@ -3525,6 +3552,12 @@ function os.validdate(year,month,day)
end
return year,month,day
end
+function os.date(fmt,...)
+ if not fmt then
+ fmt="%Y-%m-%d %H:%M"
+ end
+ return date(fmt,...)
+end
local osexit=os.exit
local exitcode=nil
function os.setexitcode(code)
diff --git a/macros/luatex/generic/lualibs/lualibs-extended-merged.lua b/macros/luatex/generic/lualibs/lualibs-extended-merged.lua
index acf7c5a0c5..2c6ab0cf52 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 : Sun Feb 2 22:30:49 2020
+-- merge date : 2020-05-01 15:49
do -- begin closure to overcome local limits and interference
@@ -417,9 +417,12 @@ local format_left=function(f)
return format("a%s..utfpadding(a%s,%i)",n,n,-f)
end
end
-local format_q=function()
+local format_q=JITSUPPORTED and function()
n=n+1
return format("(a%s ~= nil and format('%%q',tostring(a%s)) or '')",n,n)
+end or function()
+ n=n+1
+ return format("(a%s ~= nil and format('%%q',a%s) or '')",n,n)
end
local format_Q=function()
n=n+1
@@ -1410,92 +1413,160 @@ function tables.encapsulate(core,capsule,protect)
} )
end
end
-local f_hashed_string=formatters["[%Q]=%Q,"]
-local f_hashed_number=formatters["[%Q]=%s,"]
-local f_hashed_boolean=formatters["[%Q]=%l,"]
-local f_hashed_table=formatters["[%Q]="]
-local f_indexed_string=formatters["[%s]=%Q,"]
-local f_indexed_number=formatters["[%s]=%s,"]
-local f_indexed_boolean=formatters["[%s]=%l,"]
-local f_indexed_table=formatters["[%s]="]
-local f_ordered_string=formatters["%Q,"]
-local f_ordered_number=formatters["%s,"]
-local f_ordered_boolean=formatters["%l,"]
-function table.fastserialize(t,prefix)
- local r={ type(prefix)=="string" and prefix or "return" }
- local m=1
- local function fastserialize(t,outer)
- local n=#t
- m=m+1
- r[m]="{"
- if n>0 then
- local v=t[0]
- if v then
- local tv=type(v)
- if tv=="string" then
- m=m+1 r[m]=f_indexed_string(0,v)
- elseif tv=="number" then
- m=m+1 r[m]=f_indexed_number(0,v)
- elseif tv=="table" then
- m=m+1 r[m]=f_indexed_table(0)
- fastserialize(v)
- elseif tv=="boolean" then
- m=m+1 r[m]=f_indexed_boolean(0,v)
+if JITSUPPORTED then
+ local f_hashed_string=formatters["[%Q]=%Q,"]
+ local f_hashed_number=formatters["[%Q]=%s,"]
+ local f_hashed_boolean=formatters["[%Q]=%l,"]
+ local f_hashed_table=formatters["[%Q]="]
+ local f_indexed_string=formatters["[%s]=%Q,"]
+ local f_indexed_number=formatters["[%s]=%s,"]
+ local f_indexed_boolean=formatters["[%s]=%l,"]
+ local f_indexed_table=formatters["[%s]="]
+ local f_ordered_string=formatters["%Q,"]
+ local f_ordered_number=formatters["%s,"]
+ local f_ordered_boolean=formatters["%l,"]
+ function table.fastserialize(t,prefix)
+ local r={ type(prefix)=="string" and prefix or "return" }
+ local m=1
+ local function fastserialize(t,outer)
+ local n=#t
+ m=m+1
+ r[m]="{"
+ if n>0 then
+ local v=t[0]
+ if v then
+ local tv=type(v)
+ if tv=="string" then
+ m=m+1 r[m]=f_indexed_string(0,v)
+ elseif tv=="number" then
+ m=m+1 r[m]=f_indexed_number(0,v)
+ elseif tv=="table" then
+ m=m+1 r[m]=f_indexed_table(0)
+ fastserialize(v)
+ m=m+1 r[m]=f_indexed_table(0)
+ elseif tv=="boolean" then
+ m=m+1 r[m]=f_indexed_boolean(0,v)
+ end
end
- end
- for i=1,n do
- local v=t[i]
- local tv=type(v)
- if tv=="string" then
- m=m+1 r[m]=f_ordered_string(v)
- elseif tv=="number" then
- m=m+1 r[m]=f_ordered_number(v)
- elseif tv=="table" then
- fastserialize(v)
- elseif tv=="boolean" then
- m=m+1 r[m]=f_ordered_boolean(v)
+ for i=1,n do
+ local v=t[i]
+ local tv=type(v)
+ if tv=="string" then
+ m=m+1 r[m]=f_ordered_string(v)
+ elseif tv=="number" then
+ m=m+1 r[m]=f_ordered_number(v)
+ elseif tv=="table" then
+ fastserialize(v)
+ elseif tv=="boolean" then
+ m=m+1 r[m]=f_ordered_boolean(v)
+ end
end
end
- end
- for k,v in next,t do
- local tk=type(k)
- if tk=="number" then
- if k>n or k<0 then
+ for k,v in next,t do
+ local tk=type(k)
+ if tk=="number" then
+ if k>n or k<0 then
+ local tv=type(v)
+ if tv=="string" then
+ m=m+1 r[m]=f_indexed_string(k,v)
+ elseif tv=="number" then
+ m=m+1 r[m]=f_indexed_number(k,v)
+ elseif tv=="table" then
+ m=m+1 r[m]=f_indexed_table(k)
+ fastserialize(v)
+ elseif tv=="boolean" then
+ m=m+1 r[m]=f_indexed_boolean(k,v)
+ end
+ end
+ else
local tv=type(v)
if tv=="string" then
- m=m+1 r[m]=f_indexed_string(k,v)
+ m=m+1 r[m]=f_hashed_string(k,v)
elseif tv=="number" then
- m=m+1 r[m]=f_indexed_number(k,v)
+ m=m+1 r[m]=f_hashed_number(k,v)
elseif tv=="table" then
- m=m+1 r[m]=f_indexed_table(k)
+ m=m+1 r[m]=f_hashed_table(k)
fastserialize(v)
elseif tv=="boolean" then
- m=m+1 r[m]=f_indexed_boolean(k,v)
+ m=m+1 r[m]=f_hashed_boolean(k,v)
end
end
+ end
+ m=m+1
+ if outer then
+ r[m]="}"
else
- local tv=type(v)
- if tv=="string" then
- m=m+1 r[m]=f_hashed_string(k,v)
- elseif tv=="number" then
- m=m+1 r[m]=f_hashed_number(k,v)
- elseif tv=="table" then
- m=m+1 r[m]=f_hashed_table(k)
- fastserialize(v)
- elseif tv=="boolean" then
- m=m+1 r[m]=f_hashed_boolean(k,v)
- end
+ r[m]="},"
end
+ return r
end
- m=m+1
- if outer then
- r[m]="}"
- else
- r[m]="},"
+ return concat(fastserialize(t,true))
+ end
+else
+ local f_v=formatters["[%q]=%q,"]
+ local f_t=formatters["[%q]="]
+ local f_q=formatters["%q,"]
+ function table.fastserialize(t,prefix)
+ local r={ type(prefix)=="string" and prefix or "return" }
+ local m=1
+ local function fastserialize(t,outer)
+ local n=#t
+ m=m+1
+ r[m]="{"
+ if n>0 then
+ local v=t[0]
+ if v then
+ m=m+1
+ r[m]="[0]='"
+ if type(v)=="table" then
+ fastserialize(v)
+ else
+ r[m]=format("%q,",v)
+ end
+ end
+ for i=1,n do
+ local v=t[i]
+ m=m+1
+ if type(v)=="table" then
+ r[m]=format("[%i]=",i)
+ fastserialize(v)
+ else
+ r[m]=format("[%i]=%q,",i,v)
+ end
+ end
+ end
+ for k,v in next,t do
+ local tk=type(k)
+ if tk=="number" then
+ if k>n or k<0 then
+ m=m+1
+ if type(v)=="table" then
+ r[m]=format("[%i]=",k)
+ fastserialize(v)
+ else
+ r[m]=format("[%i]=%q,",k,v)
+ end
+ end
+ else
+ m=m+1
+ if type(v)=="table" then
+ r[m]=format("[%q]=",k)
+ fastserialize(v)
+ else
+ r[m]=format("[%q]=%q,",k,v)
+ end
+ end
+ end
+ m=m+1
+ if outer then
+ r[m]="}"
+ else
+ r[m]="},"
+ end
+ return r
end
- return r
+ return concat(fastserialize(t,true))
end
- return concat(fastserialize(t,true))
end
function table.deserialize(str)
if not str or str=="" then
@@ -1589,27 +1660,27 @@ function table.twowaymapper(t)
return t
end
local f_start_key_idx=formatters["%w{"]
-local f_start_key_num=formatters["%w[%s]={"]
+local f_start_key_num=JITSUPPORTED and formatters["%w[%s]={"] or formatters["%w[%q]={"]
local f_start_key_str=formatters["%w[%q]={"]
local f_start_key_boo=formatters["%w[%l]={"]
local f_start_key_nop=formatters["%w{"]
local f_stop=formatters["%w},"]
-local f_key_num_value_num=formatters["%w[%s]=%s,"]
-local f_key_str_value_num=formatters["%w[%Q]=%s,"]
-local f_key_boo_value_num=formatters["%w[%l]=%s,"]
-local f_key_num_value_str=formatters["%w[%s]=%Q,"]
+local f_key_num_value_num=JITSUPPORTED and formatters["%w[%s]=%s,"] or formatters["%w[%s]=%q,"]
+local f_key_str_value_num=JITSUPPORTED and formatters["%w[%Q]=%s,"] or formatters["%w[%Q]=%q,"]
+local f_key_boo_value_num=JITSUPPORTED and formatters["%w[%l]=%s,"] or formatters["%w[%l]=%q,"]
+local f_key_num_value_str=JITSUPPORTED and formatters["%w[%s]=%Q,"] or formatters["%w[%q]=%Q,"]
local f_key_str_value_str=formatters["%w[%Q]=%Q,"]
local f_key_boo_value_str=formatters["%w[%l]=%Q,"]
-local f_key_num_value_boo=formatters["%w[%s]=%l,"]
+local f_key_num_value_boo=JITSUPPORTED and formatters["%w[%s]=%l,"] or formatters["%w[%q]=%l,"]
local f_key_str_value_boo=formatters["%w[%Q]=%l,"]
local f_key_boo_value_boo=formatters["%w[%l]=%l,"]
-local f_key_num_value_not=formatters["%w[%s]={},"]
+local f_key_num_value_not=JITSUPPORTED and formatters["%w[%s]={},"] or formatters["%w[%q]={},"]
local f_key_str_value_not=formatters["%w[%Q]={},"]
local f_key_boo_value_not=formatters["%w[%l]={},"]
-local f_key_num_value_seq=formatters["%w[%s]={ %, t },"]
+local f_key_num_value_seq=JITSUPPORTED and formatters["%w[%s]={ %, t },"] or formatters["%w[%q]={ %, t },"]
local f_key_str_value_seq=formatters["%w[%Q]={ %, t },"]
local f_key_boo_value_seq=formatters["%w[%l]={ %, t },"]
-local f_val_num=formatters["%w%s,"]
+local f_val_num=JITSUPPORTED and formatters["%w%s,"] or formatters["%w%q,"]
local f_val_str=formatters["%w%Q,"]
local f_val_boo=formatters["%w%l,"]
local f_val_not=formatters["%w{},"]
@@ -3178,6 +3249,37 @@ local function resettiming(instance)
end
local ticks=clock
local seconds=function(n) return n or 0 end
+if os.type~="windows" then
+elseif lua.getpreciseticks then
+ ticks=lua.getpreciseticks
+ seconds=lua.getpreciseseconds
+elseif FFISUPPORTED then
+ local okay,kernel=pcall(ffi.load,"kernel32")
+ if kernel then
+ local tonumber=ffi.number or tonumber
+ ffi.cdef[[
+ int QueryPerformanceFrequency(int64_t *lpFrequency);
+ int QueryPerformanceCounter(int64_t *lpPerformanceCount);
+ ]]
+ local target=ffi.new("__int64[1]")
+ ticks=function()
+ if kernel.QueryPerformanceCounter(target)==1 then
+ return tonumber(target[0])
+ else
+ return 0
+ end
+ end
+ local target=ffi.new("__int64[1]")
+ seconds=function(ticks)
+ if kernel.QueryPerformanceFrequency(target)==1 then
+ return ticks/tonumber(target[0])
+ else
+ return 0
+ end
+ end
+ end
+else
+end
local function starttiming(instance,reset)
local timer=timers[instance or "notimer"]
local it=timer.timing
@@ -3289,12 +3391,12 @@ function statistics.show()
end)
if LUATEXENGINE=="luametatex" then
register("used engine",function()
- return format("%s version %s, functionality level %s, format id %s",
- LUATEXENGINE,LUATEXVERSION,LUATEXFUNCTIONALITY,LUATEXFORMATID)
+ return format("%s version: %s, functionality level: %s, format id: %s, compiler: %s",
+ LUATEXENGINE,LUATEXVERSION,LUATEXFUNCTIONALITY,LUATEXFORMATID,status.used_compiler)
end)
else
register("used engine",function()
- return format("%s version %s with functionality level %s, banner: %s",
+ return format("%s version: %s, functionality level: %s, banner: %s",
LUATEXENGINE,LUATEXVERSION,LUATEXFUNCTIONALITY,lower(status.banner))
end)
end
@@ -3302,7 +3404,7 @@ function statistics.show()
return format("%s of %s + %s",status.cs_count,status.hash_size,status.hash_extra)
end)
register("callbacks",statistics.callbacks)
- if TEXENGINE=="luajittex" and JITSUPPORTED then
+ if JITSUPPORTED then
local jitstatus=jit.status
if jitstatus then
local jitstatus={ jitstatus() }
@@ -3336,7 +3438,7 @@ function statistics.show()
end
function statistics.memused()
local round=math.round or math.floor
- return format("%s MB, ctx: %s MB, max: %s MB)",
+ return format("%s MB, ctx: %s MB, max: %s MB",
round(collectgarbage("count")/1000),
round(status.luastate_bytes/1000000),
status.luastate_bytes_max and round(status.luastate_bytes_max/1000000) or "unknown"
diff --git a/macros/luatex/generic/lualibs/lualibs-os.lua b/macros/luatex/generic/lualibs/lualibs-os.lua
index 8394d19e7c..9aa8b8aa78 100644
--- a/macros/luatex/generic/lualibs/lualibs-os.lua
+++ b/macros/luatex/generic/lualibs/lualibs-os.lua
@@ -459,7 +459,7 @@ end
local d
function os.timezone(delta)
- d = d or tonumber(tonumber(date("%H")-date("!%H")))
+ d = d or ((tonumber(date("%H")) or 0) - (tonumber(date("!%H")) or 0))
if delta then
if d > 0 then
return format("+%02i:00",d)
@@ -637,6 +637,14 @@ function os.validdate(year,month,day)
return year, month, day
end
+function os.date(fmt,...)
+ if not fmt then
+ -- otherwise differences between unix, mingw and msvc
+ fmt = "%Y-%m-%d %H:%M"
+ end
+ return date(fmt,...)
+end
+
local osexit = os.exit
local exitcode = nil
diff --git a/macros/luatex/generic/lualibs/lualibs-table.lua b/macros/luatex/generic/lualibs/lualibs-table.lua
index 98b377bdc1..c20bd4733c 100644
--- a/macros/luatex/generic/lualibs/lualibs-table.lua
+++ b/macros/luatex/generic/lualibs/lualibs-table.lua
@@ -525,84 +525,15 @@ function table.fromhash(t)
return hsh
end
-local noquotes, hexify, handle, compact, inline, functions, metacheck
+local noquotes, hexify, handle, compact, inline, functions, metacheck, accurate
local reserved = table.tohash { -- intercept a language inconvenience: no reserved words as key
'and', 'break', 'do', 'else', 'elseif', 'end', 'false', 'for', 'function', 'if',
'in', 'local', 'nil', 'not', 'or', 'repeat', 'return', 'then', 'true', 'until', 'while',
- 'NaN', 'goto',
+ 'NaN', 'goto', 'const',
}
--- local function is_simple_table(t)
--- if #t > 0 then
--- local n = 0
--- for _,v in next, t do
--- n = n + 1
--- end
--- if n == #t then
--- local tt, nt = { }, 0
--- for i=1,#t do
--- local v = t[i]
--- local tv = type(v)
--- if tv == "number" then
--- nt = nt + 1
--- if hexify then
--- tt[nt] = format("0x%X",v)
--- else
--- tt[nt] = tostring(v) -- tostring not needed
--- end
--- elseif tv == "string" then
--- nt = nt + 1
--- tt[nt] = format("%q",v)
--- elseif tv == "boolean" then
--- nt = nt + 1
--- tt[nt] = v and "true" or "false"
--- else
--- return nil
--- end
--- end
--- return tt
--- end
--- end
--- return nil
--- end
-
--- local function is_simple_table(t)
--- local nt = #t
--- if nt > 0 then
--- local n = 0
--- for _,v in next, t do
--- n = n + 1
--- -- if type(v) == "table" then
--- -- return nil
--- -- end
--- end
--- if n == nt then
--- local tt = { }
--- for i=1,nt do
--- local v = t[i]
--- local tv = type(v)
--- if tv == "number" then
--- if hexify then
--- tt[i] = format("0x%X",v)
--- else
--- tt[i] = tostring(v) -- tostring not needed
--- end
--- elseif tv == "string" then
--- tt[i] = format("%q",v)
--- elseif tv == "boolean" then
--- tt[i] = v and "true" or "false"
--- else
--- return nil
--- end
--- end
--- return tt
--- end
--- end
--- return nil
--- end
-
-local function is_simple_table(t,hexify) -- also used in util-tab so maybe public
+local function is_simple_table(t,hexify,accurate) -- also used in util-tab so maybe public
local nt = #t
if nt > 0 then
local n = 0
@@ -623,6 +554,8 @@ local function is_simple_table(t,hexify) -- also used in util-tab so maybe publi
-- tt[i] = v -- not needed tostring(v)
if hexify then
tt[i] = format("0x%X",v)
+ elseif accurate then
+ tt[i] = format("%q",v)
else
tt[i] = v -- not needed tostring(v)
end
@@ -644,6 +577,8 @@ local function is_simple_table(t,hexify) -- also used in util-tab so maybe publi
-- tt[i+1] = v -- not needed tostring(v)
if hexify then
tt[i+1] = format("0x%X",v)
+ elseif accurate then
+ tt[i+1] = format("%q",v)
else
tt[i+1] = v -- not needed tostring(v)
end
@@ -738,6 +673,8 @@ local function do_serialize(root,name,depth,level,indexed)
if tv == "number" then
if hexify then
handle(format("%s 0x%X,",depth,v))
+ elseif accurate then
+ handle(format("%s %q,",depth,v))
else
handle(format("%s %s,",depth,v)) -- %.99g
end
@@ -747,7 +684,7 @@ local function do_serialize(root,name,depth,level,indexed)
if next(v) == nil then
handle(format("%s {},",depth))
elseif inline then -- and #t > 0
- local st = is_simple_table(v,hexify)
+ local st = is_simple_table(v,hexify,accurate)
if st then
handle(format("%s { %s },",depth,concat(st,", ")))
else
@@ -775,12 +712,16 @@ local function do_serialize(root,name,depth,level,indexed)
if tk == "number" then
if hexify then
handle(format("%s [0x%X]=0x%X,",depth,k,v))
+ elseif accurate then
+ handle(format("%s [%s]=%q,",depth,k,v))
else
handle(format("%s [%s]=%s,",depth,k,v)) -- %.99g
end
elseif tk == "boolean" then
if hexify then
handle(format("%s [%s]=0x%X,",depth,k and "true" or "false",v))
+ elseif 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)) -- %.99g
end
@@ -789,12 +730,16 @@ local function do_serialize(root,name,depth,level,indexed)
elseif noquotes and not reserved[k] and lpegmatch(propername,k) then
if hexify then
handle(format("%s %s=0x%X,",depth,k,v))
+ elseif accurate then
+ handle(format("%s %s=%q,",depth,k,v))
else
handle(format("%s %s=%s,",depth,k,v)) -- %.99g
end
else
if hexify then
handle(format("%s [%q]=0x%X,",depth,k,v))
+ elseif accurate then
+ handle(format("%s [%q]=%q,",depth,k,v))
else
handle(format("%s [%q]=%s,",depth,k,v)) -- %.99g
end
@@ -803,6 +748,8 @@ local function do_serialize(root,name,depth,level,indexed)
if tk == "number" then
if hexify then
handle(format("%s [0x%X]=%q,",depth,k,v))
+ elseif accurate then
+ handle(format("%s [%q]=%q,",depth,k,v))
else
handle(format("%s [%s]=%q,",depth,k,v))
end
@@ -820,6 +767,8 @@ local function do_serialize(root,name,depth,level,indexed)
if tk == "number" then
if hexify then
handle(format("%s [0x%X]={},",depth,k))
+ elseif accurate then
+ handle(format("%s [%q]={},",depth,k))
else
handle(format("%s [%s]={},",depth,k))
end
@@ -833,11 +782,13 @@ local function do_serialize(root,name,depth,level,indexed)
handle(format("%s [%q]={},",depth,k))
end
elseif inline then
- local st = is_simple_table(v,hexify)
+ local st = is_simple_table(v,hexify,accurate)
if st then
if tk == "number" then
if hexify then
handle(format("%s [0x%X]={ %s },",depth,k,concat(st,", ")))
+ elseif accurate then
+ handle(format("%s [%q]={ %s },",depth,k,concat(st,", ")))
else
handle(format("%s [%s]={ %s },",depth,k,concat(st,", ")))
end
@@ -860,6 +811,8 @@ local function do_serialize(root,name,depth,level,indexed)
if tk == "number" then
if hexify then
handle(format("%s [0x%X]=%s,",depth,k,v and "true" or "false"))
+ elseif accurate then
+ handle(format("%s [%q]=%s,",depth,k,v and "true" or "false"))
else
handle(format("%s [%s]=%s,",depth,k,v and "true" or "false"))
end
@@ -881,6 +834,8 @@ local function do_serialize(root,name,depth,level,indexed)
if tk == "number" then
if hexify then
handle(format("%s [0x%X]=load(%q),",depth,k,f))
+ elseif accurate then
+ handle(format("%s [%q]=load(%q),",depth,k,f))
else
handle(format("%s [%s]=load(%q),",depth,k,f))
end
@@ -899,6 +854,8 @@ local function do_serialize(root,name,depth,level,indexed)
if tk == "number" then
if hexify then
handle(format("%s [0x%X]=%q,",depth,k,tostring(v)))
+ elseif accurate then
+ handle(format("%s [%q]=%q,",depth,k,tostring(v)))
else
handle(format("%s [%s]=%q,",depth,k,tostring(v)))
end
@@ -927,6 +884,7 @@ local function serialize(_handle,root,name,specification) -- handle wins
if type(specification) == "table" then
noquotes = specification.noquotes
hexify = specification.hexify
+ accurate = specification.accurate
handle = _handle or specification.handle or print
functions = specification.functions
compact = specification.compact
diff --git a/macros/luatex/generic/lualibs/lualibs-trac-inf.lua b/macros/luatex/generic/lualibs/lualibs-trac-inf.lua
index 24ebc52499..244ba4604a 100644
--- a/macros/luatex/generic/lualibs/lualibs-trac-inf.lua
+++ b/macros/luatex/generic/lualibs/lualibs-trac-inf.lua
@@ -45,42 +45,59 @@ end
local ticks = clock
local seconds = function(n) return n or 0 end
--- if FFISUPPORTED and ffi and os.type == "windows" then
---
--- local okay, kernel = pcall(ffi.load,"kernel32")
---
--- if kernel then
---
--- local tonumber = ffi.number or tonumber
---
--- ffi.cdef[[
--- int QueryPerformanceFrequency(int64_t *lpFrequency);
--- int QueryPerformanceCounter(int64_t *lpPerformanceCount);
--- ]]
---
--- local target = ffi.new("__int64[1]")
---
--- ticks = function()
--- if kernel.QueryPerformanceCounter(target) == 1 then
--- return tonumber(target[0])
--- else
--- return 0
--- end
--- end
---
--- local target = ffi.new("__int64[1]")
---
--- seconds = function(ticks)
--- if kernel.QueryPerformanceFrequency(target) == 1 then
--- return ticks / tonumber(target[0])
--- else
--- return 0
--- end
--- end
---
--- end
---
--- end
+if os.type ~= "windows" then
+
+ -- doesn't work well yet on unix (system time vs process time so a mtxrun
+ -- timing with nested call gives the wrong result)
+
+elseif lua.getpreciseticks then
+
+ ticks = lua.getpreciseticks
+ seconds = lua.getpreciseseconds
+
+elseif FFISUPPORTED then
+
+ -- Do we really care when not in luametatex? For now we do, so:
+
+ local okay, kernel = pcall(ffi.load,"kernel32")
+
+ if kernel then
+
+ local tonumber = ffi.number or tonumber
+
+ ffi.cdef[[
+ int QueryPerformanceFrequency(int64_t *lpFrequency);
+ int QueryPerformanceCounter(int64_t *lpPerformanceCount);
+ ]]
+
+ local target = ffi.new("__int64[1]")
+
+ ticks = function()
+ if kernel.QueryPerformanceCounter(target) == 1 then
+ return tonumber(target[0])
+ else
+ return 0
+ end
+ end
+
+ local target = ffi.new("__int64[1]")
+
+ seconds = function(ticks)
+ if kernel.QueryPerformanceFrequency(target) == 1 then
+ return ticks / tonumber(target[0])
+ else
+ return 0
+ end
+ end
+
+ end
+
+else
+
+ -- excessive timing costs some 1-2 percent runtime
+
+end
+
local function starttiming(instance,reset)
local timer = timers[instance or "notimer"]
@@ -211,12 +228,12 @@ function statistics.show()
-- end)
if LUATEXENGINE == "luametatex" then
register("used engine", function()
- return format("%s version %s, functionality level %s, format id %s",
- LUATEXENGINE, LUATEXVERSION, LUATEXFUNCTIONALITY, LUATEXFORMATID)
+ return format("%s version: %s, functionality level: %s, format id: %s, compiler: %s",
+ LUATEXENGINE, LUATEXVERSION, LUATEXFUNCTIONALITY, LUATEXFORMATID, status.used_compiler)
end)
else
register("used engine", function()
- return format("%s version %s with functionality level %s, banner: %s",
+ return format("%s version: %s, functionality level: %s, banner: %s",
LUATEXENGINE, LUATEXVERSION, LUATEXFUNCTIONALITY, lower(status.banner))
end)
end
@@ -224,7 +241,7 @@ function statistics.show()
return format("%s of %s + %s", status.cs_count, status.hash_size,status.hash_extra)
end)
register("callbacks", statistics.callbacks)
- if TEXENGINE == "luajittex" and JITSUPPORTED then
+ if JITSUPPORTED then
local jitstatus = jit.status
if jitstatus then
local jitstatus = { jitstatus() }
@@ -262,7 +279,7 @@ end
function statistics.memused() -- no math.round yet -)
local round = math.round or math.floor
- return format("%s MB, ctx: %s MB, max: %s MB)",
+ return format("%s MB, ctx: %s MB, max: %s MB",
round(collectgarbage("count")/1000),
round(status.luastate_bytes/1000000),
status.luastate_bytes_max and round(status.luastate_bytes_max/1000000) or "unknown"
diff --git a/macros/luatex/generic/lualibs/lualibs-util-str.lua b/macros/luatex/generic/lualibs/lualibs-util-str.lua
index 68c9be5860..aba7859c31 100644
--- a/macros/luatex/generic/lualibs/lualibs-util-str.lua
+++ b/macros/luatex/generic/lualibs/lualibs-util-str.lua
@@ -701,14 +701,18 @@ local format_left = function(f)
end
end
-local format_q = function()
+local format_q = JITSUPPORTED and function()
n = n + 1
-- lua 5.3 has a different q than lua 5.2 (which does a tostring on numbers)
-- return format("(a%s ~= nil and format('%%q',a%s) or '')",n,n)
return format("(a%s ~= nil and format('%%q',tostring(a%s)) or '')",n,n)
-- return format("(a%s ~= nil and escapedquotes(tostring(a%s)) or '')",n,n)
+end or function()
+ n = n + 1
+ return format("(a%s ~= nil and format('%%q',a%s) or '')",n,n)
end
+
local format_Q = function() -- fast escaping
n = n + 1
-- return format("format('%%q',tostring(a%s))",n)
@@ -1269,7 +1273,6 @@ local function make(t,str)
f = function() return str end
end
end
- -- if jit then jit.on(f,true) end
t[str] = f
return f
end
diff --git a/macros/luatex/generic/lualibs/lualibs-util-tab.lua b/macros/luatex/generic/lualibs/lualibs-util-tab.lua
index 410292ca8a..4dafb2acd6 100644
--- a/macros/luatex/generic/lualibs/lualibs-util-tab.lua
+++ b/macros/luatex/generic/lualibs/lualibs-util-tab.lua
@@ -314,102 +314,177 @@ end
-- best keep [%q] keys (as we have some in older applications i.e. saving user data (otherwise
-- we also need to check for reserved words)
-local f_hashed_string = formatters["[%Q]=%Q,"]
-local f_hashed_number = formatters["[%Q]=%s,"]
-local f_hashed_boolean = formatters["[%Q]=%l,"]
-local f_hashed_table = formatters["[%Q]="]
-
-local f_indexed_string = formatters["[%s]=%Q,"]
-local f_indexed_number = formatters["[%s]=%s,"]
-local f_indexed_boolean = formatters["[%s]=%l,"]
-local f_indexed_table = formatters["[%s]="]
-
-local f_ordered_string = formatters["%Q,"]
-local f_ordered_number = formatters["%s,"]
-local f_ordered_boolean = formatters["%l,"]
-
-function table.fastserialize(t,prefix) -- todo, move local function out
-
- -- prefix should contain the =
- -- not sorted
- -- only number and string indices (currently)
-
- local r = { type(prefix) == "string" and prefix or "return" }
- local m = 1
- local function fastserialize(t,outer) -- no mixes
- local n = #t
- m = m + 1
- r[m] = "{"
- if n > 0 then
- local v = t[0]
- if v then
- local tv = type(v)
- if tv == "string" then
- m = m + 1 r[m] = f_indexed_string(0,v)
- elseif tv == "number" then
- m = m + 1 r[m] = f_indexed_number(0,v)
- elseif tv == "table" then
- m = m + 1 r[m] = f_indexed_table(0)
- fastserialize(v)
- elseif tv == "boolean" then
- m = m + 1 r[m] = f_indexed_boolean(0,v)
+if JITSUPPORTED then
+
+ local f_hashed_string = formatters["[%Q]=%Q,"]
+ local f_hashed_number = formatters["[%Q]=%s,"]
+ local f_hashed_boolean = formatters["[%Q]=%l,"]
+ local f_hashed_table = formatters["[%Q]="]
+
+ local f_indexed_string = formatters["[%s]=%Q,"]
+ local f_indexed_number = formatters["[%s]=%s,"]
+ local f_indexed_boolean = formatters["[%s]=%l,"]
+ local f_indexed_table = formatters["[%s]="]
+
+ local f_ordered_string = formatters["%Q,"]
+ local f_ordered_number = formatters["%s,"]
+ local f_ordered_boolean = formatters["%l,"]
+
+ function table.fastserialize(t,prefix) -- todo, move local function out
+
+ -- prefix should contain the =
+ -- not sorted
+ -- only number and string indices (currently)
+
+ local r = { type(prefix) == "string" and prefix or "return" }
+ local m = 1
+ local function fastserialize(t,outer) -- no mixes
+ local n = #t
+ m = m + 1
+ r[m] = "{"
+ if n > 0 then
+ local v = t[0]
+ if v then
+ local tv = type(v)
+ if tv == "string" then
+ m = m + 1 r[m] = f_indexed_string(0,v)
+ elseif tv == "number" then
+ m = m + 1 r[m] = f_indexed_number(0,v)
+ elseif tv == "table" then
+ m = m + 1 r[m] = f_indexed_table(0)
+ fastserialize(v)
+ m = m + 1 r[m] = f_indexed_table(0)
+ elseif tv == "boolean" then
+ m = m + 1 r[m] = f_indexed_boolean(0,v)
+ end
end
- end
- for i=1,n do
- local v = t[i]
- local tv = type(v)
- if tv == "string" then
- m = m + 1 r[m] = f_ordered_string(v)
- elseif tv == "number" then
- m = m + 1 r[m] = f_ordered_number(v)
- elseif tv == "table" then
- fastserialize(v)
- elseif tv == "boolean" then
- m = m + 1 r[m] = f_ordered_boolean(v)
+ for i=1,n do
+ local v = t[i]
+ local tv = type(v)
+ if tv == "string" then
+ m = m + 1 r[m] = f_ordered_string(v)
+ elseif tv == "number" then
+ m = m + 1 r[m] = f_ordered_number(v)
+ elseif tv == "table" then
+ fastserialize(v)
+ elseif tv == "boolean" then
+ m = m + 1 r[m] = f_ordered_boolean(v)
+ end
end
end
- end
- -- hm, can't we avoid this ... lua should have a way to check if there
- -- is a hash part
- for k, v in next, t do
- local tk = type(k)
- if tk == "number" then
- if k > n or k < 0 then
+ -- hm, can't we avoid this ... lua should have a way to check if there
+ -- is a hash part
+ for k, v in next, t do
+ local tk = type(k)
+ if tk == "number" then
+ if k > n or k < 0 then
+ local tv = type(v)
+ if tv == "string" then
+ m = m + 1 r[m] = f_indexed_string(k,v)
+ elseif tv == "number" then
+ m = m + 1 r[m] = f_indexed_number(k,v)
+ elseif tv == "table" then
+ m = m + 1 r[m] = f_indexed_table(k)
+ fastserialize(v)
+ elseif tv == "boolean" then
+ m = m + 1 r[m] = f_indexed_boolean(k,v)
+ end
+ end
+ else
local tv = type(v)
if tv == "string" then
- m = m + 1 r[m] = f_indexed_string(k,v)
+ m = m + 1 r[m] = f_hashed_string(k,v)
elseif tv == "number" then
- m = m + 1 r[m] = f_indexed_number(k,v)
+ m = m + 1 r[m] = f_hashed_number(k,v)
elseif tv == "table" then
- m = m + 1 r[m] = f_indexed_table(k)
+ m = m + 1 r[m] = f_hashed_table(k)
fastserialize(v)
elseif tv == "boolean" then
- m = m + 1 r[m] = f_indexed_boolean(k,v)
+ m = m + 1 r[m] = f_hashed_boolean(k,v)
end
end
+ end
+ m = m + 1
+ if outer then
+ r[m] = "}"
else
- local tv = type(v)
- if tv == "string" then
- m = m + 1 r[m] = f_hashed_string(k,v)
- elseif tv == "number" then
- m = m + 1 r[m] = f_hashed_number(k,v)
- elseif tv == "table" then
- m = m + 1 r[m] = f_hashed_table(k)
- fastserialize(v)
- elseif tv == "boolean" then
- m = m + 1 r[m] = f_hashed_boolean(k,v)
- end
+ r[m] = "},"
end
+ return r
end
- m = m + 1
- if outer then
- r[m] = "}"
- else
- r[m] = "},"
+ return concat(fastserialize(t,true))
+ end
+
+else
+
+ local f_v = formatters["[%q]=%q,"]
+ local f_t = formatters["[%q]="]
+ local f_q = formatters["%q,"]
+
+ function table.fastserialize(t,prefix) -- todo, move local function out
+ local r = { type(prefix) == "string" and prefix or "return" }
+ local m = 1
+ local function fastserialize(t,outer) -- no mixes
+ local n = #t
+ m = m + 1
+ r[m] = "{"
+ if n > 0 then
+ local v = t[0]
+ if v then
+ m = m + 1
+ r[m] = "[0]='"
+ if type(v) == "table" then
+ fastserialize(v)
+ else
+ r[m] = format("%q,",v)
+ end
+ end
+ for i=1,n do
+ local v = t[i]
+ m = m + 1
+ if type(v) == "table" then
+ r[m] = format("[%i]=",i)
+ fastserialize(v)
+ else
+ r[m] = format("[%i]=%q,",i,v)
+ end
+ end
+ end
+ -- hm, can't we avoid this ... lua should have a way to check if there
+ -- is a hash part
+ for k, v in next, t do
+ local tk = type(k)
+ if tk == "number" then
+ if k > n or k < 0 then
+ m = m + 1
+ if type(v) == "table" then
+ r[m] = format("[%i]=",k)
+ fastserialize(v)
+ else
+ r[m] = format("[%i]=%q,",k,v)
+ end
+ end
+ else
+ m = m + 1
+ if type(v) == "table" then
+ r[m] = format("[%q]=",k)
+ fastserialize(v)
+ else
+ r[m] = format("[%q]=%q,",k,v)
+ end
+ end
+ end
+ m = m + 1
+ if outer then
+ r[m] = "}"
+ else
+ r[m] = "},"
+ end
+ return r
end
- return r
+ return concat(fastserialize(t,true))
end
- return concat(fastserialize(t,true))
+
end
function table.deserialize(str)
@@ -533,34 +608,34 @@ end
-- husayni.tma : 0.28 -> 0.19
local f_start_key_idx = formatters["%w{"]
-local f_start_key_num = formatters["%w[%s]={"]
+local f_start_key_num = JITSUPPORTED and formatters["%w[%s]={"] or formatters["%w[%q]={"]
local f_start_key_str = formatters["%w[%q]={"]
local f_start_key_boo = formatters["%w[%l]={"]
local f_start_key_nop = formatters["%w{"]
local f_stop = formatters["%w},"]
-local f_key_num_value_num = formatters["%w[%s]=%s,"]
-local f_key_str_value_num = formatters["%w[%Q]=%s,"]
-local f_key_boo_value_num = formatters["%w[%l]=%s,"]
+local f_key_num_value_num = JITSUPPORTED and formatters["%w[%s]=%s,"] or formatters["%w[%s]=%q,"]
+local f_key_str_value_num = JITSUPPORTED and formatters["%w[%Q]=%s,"] or formatters["%w[%Q]=%q,"]
+local f_key_boo_value_num = JITSUPPORTED and formatters["%w[%l]=%s,"] or formatters["%w[%l]=%q,"]
-local f_key_num_value_str = formatters["%w[%s]=%Q,"]
+local f_key_num_value_str = JITSUPPORTED and formatters["%w[%s]=%Q,"] or formatters["%w[%q]=%Q,"]
local f_key_str_value_str = formatters["%w[%Q]=%Q,"]
local f_key_boo_value_str = formatters["%w[%l]=%Q,"]
-local f_key_num_value_boo = formatters["%w[%s]=%l,"]
+local f_key_num_value_boo = JITSUPPORTED and formatters["%w[%s]=%l,"] or formatters["%w[%q]=%l,"]
local f_key_str_value_boo = formatters["%w[%Q]=%l,"]
local f_key_boo_value_boo = formatters["%w[%l]=%l,"]
-local f_key_num_value_not = formatters["%w[%s]={},"]
+local f_key_num_value_not = JITSUPPORTED and formatters["%w[%s]={},"] or formatters["%w[%q]={},"]
local f_key_str_value_not = formatters["%w[%Q]={},"]
local f_key_boo_value_not = formatters["%w[%l]={},"]
-local f_key_num_value_seq = formatters["%w[%s]={ %, t },"]
+local f_key_num_value_seq = JITSUPPORTED and formatters["%w[%s]={ %, t },"] or formatters["%w[%q]={ %, t },"]
local f_key_str_value_seq = formatters["%w[%Q]={ %, t },"]
local f_key_boo_value_seq = formatters["%w[%l]={ %, t },"]
-local f_val_num = formatters["%w%s,"]
+local f_val_num = JITSUPPORTED and formatters["%w%s,"] or formatters["%w%q,"]
local f_val_str = formatters["%w%Q,"]
local f_val_boo = formatters["%w%l,"]
local f_val_not = formatters["%w{},"]
@@ -573,8 +648,6 @@ local f_table_direct = formatters["{"]
local f_table_entry = formatters["[%Q]={"]
local f_table_finish = formatters["}"]
------ f_string = formatters["%q"]
-
local spaces = utilities.strings.newrepeater(" ")
local original_serialize = table.serialize -- the extensive one, the one we started with
diff --git a/macros/luatex/generic/lualibs/lualibs.dtx b/macros/luatex/generic/lualibs/lualibs.dtx
index 579982e542..e93eaac5df 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 2020-02-02 v2.70 Lua additional functions.}
+\Msg{* Package: lualibs 2020-05-01 v2.71 Lua additional functions.}
\Msg{************************************************************************}
\keepsilent
@@ -107,7 +107,7 @@ and lualibs-extended.lua.
%<*driver>
\NeedsTeXFormat{LaTeX2e}
\ProvidesFile{lualibs.drv}
- [2020/02/02 v2.70 Lua Libraries.]
+ [2020/05/01 v2.71 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{2020/02/02 v2.70}
+% \date{2020/05/01 v2.71}
% \author{Élie Roux · \email{elie.roux@telecom-bretagne.eu}\\
% Philipp Gesang · \email{phg@phi-gamma.net}\\
% The \LaTeX3 Project · \email{https://github.com/latex3/lualibs/}\\
@@ -429,8 +429,8 @@ lualibs = lualibs or { }
lualibs.module_info = {
name = "lualibs",
- version = "2.70", --TAGVERSION
- date = "2020-02-02", --TAGDATE
+ version = "2.71", --TAGVERSION
+ date = "2020-05-01", --TAGDATE
description = "ConTeXt Lua standard libraries.",
author = "Hans Hagen, PRAGMA-ADE, Hasselt NL & Elie Roux & Philipp Gesang",
copyright = "PRAGMA ADE / ConTeXt Development Team",
@@ -583,8 +583,8 @@ local loadmodule = lualibs.loadmodule
local lualibs_basic_module = {
name = "lualibs-basic",
- version = "2.70", --TAGVERSION
- date = "2020-02-02", --TAGDATE
+ version = "2.71", --TAGVERSION
+ date = "2020-05-01", --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.70", --TAGVERSION
- date = "2020-02-02", --TAGDATE
+ version = "2.71", --TAGVERSION
+ date = "2020-05-01", --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 721f42266f..6c5ff03540 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 07855af501..501af67e47 100644
--- a/macros/luatex/generic/luaotfload/NEWS
+++ b/macros/luatex/generic/luaotfload/NEWS
@@ -1,5 +1,23 @@
Change History
--------------
+2020-05-01 luaotfload v3.13
+ * A problem with text fonts with minimal math table has been fixed (issue 148.)
+ In new luaotfload versions, math parameters will only be loaded for fonts with `script=math`.
+ If you do want to set math parameters for fonts with other scripts, add `-nomathparam`.
+ We strongly recommend against setting math parameters for text fonts because
+ these would overwrite parameters from actual math fonts.
+ * A bug in harf-mode that could lead to missing chars and freezing was corrected (issue 141).
+ * A font size problem in harf-mode has been fixed (issue 147).
+ * An error if the main function was called twice has been fixed (issue 145).
+ * Allow .ttf fonts to be loaded with a map file with luahbtex (issue 142) (issue 143).
+ * Fonts installed for a single user on windows are now found (issue 138).
+ * A problem with wrong \TeX-ligatures in harf mode has been fixed (issue 139).
+ * The debugging output has been changed (issue 131).
+ * a missing U+1E9E (Capital ß) in a font is replaced by
+ SS instead of giving a missing character.
+ * extended the color handling to be compatible with the luacolor package
+ * sync with context files from 2020-04-30
+
2020-02-02 luaotfload v3.12
* new experimental feature multiscript
* new experimental feature fallback
diff --git a/macros/luatex/generic/luaotfload/README.md b/macros/luatex/generic/luaotfload/README.md
index 94a315839b..91d1d45acf 100644
--- a/macros/luatex/generic/luaotfload/README.md
+++ b/macros/luatex/generic/luaotfload/README.md
@@ -1,8 +1,8 @@
# The Luaotfload Package
-VERSION: 3.12
+VERSION: 3.13
-DATE: 2020-02-02
+DATE: 2020-05-01
## Description
@@ -23,10 +23,9 @@ Please see the documentation luaotfload.pdf for more information.
## Maintenance
This package is currently maintained at
-<https://github.com/u-fischer/luaotfload>.
+<https://github.com/latex3/luaotfload>.
-Issues can be reported at the issue tracker or at the old issue tracker on
-<http://github.com/lualatex/luaotfload>.
+Issues can be reported at the issue tracker.
The development for LuaLaTeX is discussed on the lualatex-dev mailing list. See
<http://www.tug.org/mailman/listinfo/lualatex-dev> for details.
@@ -58,7 +57,7 @@ The following people have contributed to this package.
If you want to install manually: there is a tds-zip file which can be unpacked in a texmf tree.
2. If you want to try the development version download the texmf folder in the development branch.
- at <https://github.com/u-fischer/luaotfload>
+ at <https://github.com/latex3/luaotfload>
3. Manual installation:
* luaotfload-tool.lua belongs in scripts/luatex/luaotfload
diff --git a/macros/luatex/generic/luaotfload/filegraph.pdf b/macros/luatex/generic/luaotfload/filegraph.pdf
index d6202804f9..76c5754744 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-2020-01-26.lua b/macros/luatex/generic/luaotfload/fontloader-2020-04-30.lua
index be8fefacfe..721d246121 100644
--- a/macros/luatex/generic/luaotfload/fontloader-2020-01-26.lua
+++ b/macros/luatex/generic/luaotfload/fontloader-2020-04-30.lua
@@ -1,6 +1,6 @@
--[[info-----------------------------------------------------------------------
Luaotfload fontloader package
- build 2020-02-02 22:46:14
+ build 2020-05-01 16:08:24
-------------------------------------------------------------------------------
© 2020 PRAGMA ADE / ConTeXt Development Team
@@ -62,7 +62,7 @@
--info]]-----------------------------------------------------------------------
-do --- [luaotfload, fontloader-2020-02-02.lua scope for “data-con” de6ae0997b0e70a23bcc9afff5d8b072] ---
+do --- [luaotfload, fontloader-2020-05-01.lua scope for “data-con” de6ae0997b0e70a23bcc9afff5d8b072] ---
if not modules then modules={} end modules ['data-con']={
version=1.100,
@@ -183,10 +183,10 @@ function containers.cleanname(name)
return (gsub(lower(name),"[^%w\128-\255]+","-"))
end
-end --- [luaotfload, fontloader-2020-02-02.lua scope for “data-con”] ---
+end --- [luaotfload, fontloader-2020-05-01.lua scope for “data-con”] ---
-do --- [luaotfload, fontloader-2020-02-02.lua scope for “basics-nod” 4ce2f7c752fdc4c1d6d9f74e8cd50be8] ---
+do --- [luaotfload, fontloader-2020-05-01.lua scope for “basics-nod” 68226d7dadd241bca55171af9ce1f243] ---
if not modules then modules={} end modules ['luatex-fonts-nod']={
version=1.001,
@@ -253,7 +253,6 @@ nuts.tonut=tonut
nuts.getattr=direct.get_attribute
nuts.getboth=direct.getboth
nuts.getchar=direct.getchar
-nuts.getcomponents=direct.getcomponents
nuts.getdirection=direct.getdirection
nuts.getdisc=direct.getdisc
nuts.getreplace=direct.getreplace
@@ -291,7 +290,6 @@ nuts.isglyph=direct.is_glyph
nuts.copy=direct.copy
nuts.copy_list=direct.copy_list
nuts.copy_node=direct.copy
-nuts.delete=direct.delete
nuts.end_of_math=direct.end_of_math
nuts.flush=direct.flush
nuts.flush_list=direct.flush_list
@@ -339,45 +337,72 @@ local getnext=nuts.getnext
local setlink=nuts.setlink
local getfield=nuts.getfield
local setfield=nuts.setfield
-local getcomponents=nuts.getcomponents
-local setcomponents=nuts.setcomponents
+local getsubtype=nuts.getsubtype
+local isglyph=nuts.isglyph
local find_tail=nuts.tail
local flush_list=nuts.flush_list
local flush_node=nuts.flush_node
local traverse_id=nuts.traverse_id
local copy_node=nuts.copy_node
local glyph_code=nodes.nodecodes.glyph
-function nuts.copy_no_components(g,copyinjection)
- local components=getcomponents(g)
- if components then
- setcomponents(g)
- local n=copy_node(g)
- if copyinjection then
- copyinjection(n,g)
- end
- setcomponents(g,components)
- return n
- else
- local n=copy_node(g)
- if copyinjection then
- copyinjection(n,g)
+local ligature_code=nodes.glyphcodes.ligature
+do
+ local get_components=node.direct.getcomponents
+ local set_components=node.direct.setcomponents
+ local function copy_no_components(g,copyinjection)
+ local components=get_components(g)
+ if components then
+ set_components(g)
+ local n=copy_node(g)
+ if copyinjection then
+ copyinjection(n,g)
+ end
+ set_components(g,components)
+ return n
+ else
+ local n=copy_node(g)
+ if copyinjection then
+ copyinjection(n,g)
+ end
+ return n
end
- return n
end
-end
-function nuts.copy_only_glyphs(current)
- local head=nil
- local previous=nil
- for n in traverse_id(glyph_code,current) do
- n=copy_node(n)
- if head then
- setlink(previous,n)
- else
- head=n
+ local function copy_only_glyphs(current)
+ local head=nil
+ local previous=nil
+ for n in traverse_id(glyph_code,current) do
+ n=copy_node(n)
+ if head then
+ setlink(previous,n)
+ else
+ head=n
+ end
+ previous=n
end
- previous=n
+ return head
end
- return head
+ local function count_components(start,marks)
+ local char=isglyph(start)
+ if char then
+ if getsubtype(start)==ligature_code then
+ local n=0
+ local components=get_components(start)
+ while components do
+ n=n+count_components(components,marks)
+ components=getnext(components)
+ end
+ return n
+ elseif not marks[char] then
+ return 1
+ end
+ end
+ return 0
+ end
+ nuts.set_components=set_components
+ nuts.get_components=get_components
+ nuts.copy_only_glyphs=copy_only_glyphs
+ nuts.copy_no_components=copy_no_components
+ nuts.count_components=count_components
end
nuts.uses_font=direct.uses_font
do
@@ -410,10 +435,10 @@ do
end
end
-end --- [luaotfload, fontloader-2020-02-02.lua scope for “basics-nod”] ---
+end --- [luaotfload, fontloader-2020-05-01.lua scope for “basics-nod”] ---
-do --- [luaotfload, fontloader-2020-02-02.lua scope for “basics-chr” 58b7ef0c486e06090b362971b9f85e27] ---
+do --- [luaotfload, fontloader-2020-05-01.lua scope for “basics-chr” 58b7ef0c486e06090b362971b9f85e27] ---
characters=characters or {}
@@ -4023,10 +4048,10 @@ characters.indicgroups={
},
}
-end --- [luaotfload, fontloader-2020-02-02.lua scope for “basics-chr”] ---
+end --- [luaotfload, fontloader-2020-05-01.lua scope for “basics-chr”] ---
-do --- [luaotfload, fontloader-2020-02-02.lua scope for “font-ini” 4dee96e1e1474d324dd126bd5d375df8] ---
+do --- [luaotfload, fontloader-2020-05-01.lua scope for “font-ini” 4dee96e1e1474d324dd126bd5d375df8] ---
if not modules then modules={} end modules ['font-ini']={
version=1.001,
@@ -4067,10 +4092,10 @@ if node and not tex.getfontoffamily then
tex.getfontoffamily=node.family_font
end
-end --- [luaotfload, fontloader-2020-02-02.lua scope for “font-ini”] ---
+end --- [luaotfload, fontloader-2020-05-01.lua scope for “font-ini”] ---
-do --- [luaotfload, fontloader-2020-02-02.lua scope for “fonts-mis” bc9eb43c27f63ce9d0fff67e104fe1c6] ---
+do --- [luaotfload, fontloader-2020-05-01.lua scope for “fonts-mis” bc9eb43c27f63ce9d0fff67e104fe1c6] ---
if not modules then modules={} end modules ['luatex-font-mis']={
version=1.001,
@@ -4102,10 +4127,10 @@ function font.each()
return table.sortedhash(fonts.hashes.identifiers)
end
-end --- [luaotfload, fontloader-2020-02-02.lua scope for “fonts-mis”] ---
+end --- [luaotfload, fontloader-2020-05-01.lua scope for “fonts-mis”] ---
-do --- [luaotfload, fontloader-2020-02-02.lua scope for “font-con” b436bf6880a56216445779ac68fee877] ---
+do --- [luaotfload, fontloader-2020-05-01.lua scope for “font-con” 40e3a857b2f31be1959dc6d445aaa9c4] ---
if not modules then modules={} end modules ['font-con']={
version=1.001,
@@ -4999,6 +5024,7 @@ hashmethods.normal=function(list)
m=m+1
t[m]=k..'='..tostring(v)
end
+ sort(t)
s[n]=k..'={'..concat(t,",").."}"
else
s[n]=k..'='..tostring(v)
@@ -5447,10 +5473,10 @@ function constructors.addcoreunicodes(unicodes)
return unicodes
end
-end --- [luaotfload, fontloader-2020-02-02.lua scope for “font-con”] ---
+end --- [luaotfload, fontloader-2020-05-01.lua scope for “font-con”] ---
-do --- [luaotfload, fontloader-2020-02-02.lua scope for “fonts-enc” 3e71a54297e8f85a1ac438bb0f20dd79] ---
+do --- [luaotfload, fontloader-2020-05-01.lua scope for “fonts-enc” 3e71a54297e8f85a1ac438bb0f20dd79] ---
if not modules then modules={} end modules ['luatex-font-enc']={
version=1.001,
@@ -5519,10 +5545,10 @@ function encodings.load(filename)
return containers.write(encodings.cache,name,data)
end
-end --- [luaotfload, fontloader-2020-02-02.lua scope for “fonts-enc”] ---
+end --- [luaotfload, fontloader-2020-05-01.lua scope for “fonts-enc”] ---
-do --- [luaotfload, fontloader-2020-02-02.lua scope for “font-cid” 4d87988efa86020a14708ee03c23415f] ---
+do --- [luaotfload, fontloader-2020-05-01.lua scope for “font-cid” 4d87988efa86020a14708ee03c23415f] ---
if not modules then modules={} end modules ['font-cid']={
version=1.001,
@@ -5673,10 +5699,10 @@ function cid.getmap(specification)
return found
end
-end --- [luaotfload, fontloader-2020-02-02.lua scope for “font-cid”] ---
+end --- [luaotfload, fontloader-2020-05-01.lua scope for “font-cid”] ---
-do --- [luaotfload, fontloader-2020-02-02.lua scope for “font-map” f486746e90fe972de4b73e208ac7cbb2] ---
+do --- [luaotfload, fontloader-2020-05-01.lua scope for “font-map” 51d0362c19d2d0f621e5cb750410a809] ---
if not modules then modules={} end modules ['font-map']={
version=1.001,
@@ -5690,7 +5716,7 @@ local match,format,find,concat,gsub,lower=string.match,string.format,string.find
local P,R,S,C,Ct,Cc,lpegmatch=lpeg.P,lpeg.R,lpeg.S,lpeg.C,lpeg.Ct,lpeg.Cc,lpeg.match
local formatters=string.formatters
local sortedhash,sortedkeys=table.sortedhash,table.sortedkeys
-local rshift=bit32.rshift
+local idiv=number.idiv
local trace_loading=false trackers.register("fonts.loading",function(v) trace_loading=v end)
local trace_mapping=false trackers.register("fonts.mapping",function(v) trace_mapping=v end)
local report_fonts=logs.reporter("fonts","loading")
@@ -5723,12 +5749,21 @@ local function makenameparser(str)
end
local f_single=formatters["%04X"]
local f_double=formatters["%04X%04X"]
+local s_unknown="FFFD"
local function tounicode16(unicode)
if unicode<0xD7FF or (unicode>0xDFFF and unicode<=0xFFFF) then
return f_single(unicode)
+ elseif unicode>=0x00E000 and unicode<=0x00F8FF then
+ return s_unknown
+ elseif unicode>=0x0F0000 and unicode<=0x0FFFFF then
+ return s_unknown
+ elseif unicode>=0x100000 and unicode<=0x10FFFF then
+ return s_unknown
+ elseif unicode>=0x00D800 and unicode<=0x00DFFF then
+ return s_unknown
else
unicode=unicode-0x10000
- return f_double(rshift(unicode,10)+0xD800,unicode%1024+0xDC00)
+ return f_double(idiv(k,0x400)+0xD800,unicode%0x400+0xDC00)
end
end
local function tounicode16sequence(unicodes)
@@ -5737,14 +5772,21 @@ local function tounicode16sequence(unicodes)
local u=unicodes[l]
if u<0xD7FF or (u>0xDFFF and u<=0xFFFF) then
t[l]=f_single(u)
+ elseif unicode>=0x00E000 and unicode<=0x00F8FF then
+ t[l]=s_unknown
+ elseif unicode>=0x0F0000 and unicode<=0x0FFFFF then
+ t[l]=s_unknown
+ elseif unicode>=0x100000 and unicode<=0x10FFFF then
+ t[l]=s_unknown
+ elseif unicode>=0x00D7FF and unicode<=0x00DFFF then
+ t[l]=s_unknown
else
u=u-0x10000
- t[l]=f_double(rshift(u,10)+0xD800,u%1024+0xDC00)
+ t[l]=f_double(idiv(k,0x400)+0xD800,u%0x400+0xDC00)
end
end
return concat(t)
end
-local unknown=f_single(0xFFFD)
local hash={}
local conc={}
table.setmetatableindex(hash,function(t,k)
@@ -5752,7 +5794,7 @@ table.setmetatableindex(hash,function(t,k)
v=f_single(k)
else
local k=k-0x10000
- v=f_double(rshift(k,10)+0xD800,k%1024+0xDC00)
+ v=f_double(idiv(k,0x400)+0xD800,k%0x400+0xDC00)
end
t[k]=v
return v
@@ -5765,11 +5807,13 @@ local function tounicode(k)
end
return concat(conc,"",1,n)
elseif k>=0x00E000 and k<=0x00F8FF then
- return unknown
+ return s_unknown
elseif k>=0x0F0000 and k<=0x0FFFFF then
- return unknown
+ return s_unknown
elseif k>=0x100000 and k<=0x10FFFF then
- return unknown
+ return s_unknown
+ elseif k>=0x00D7FF and k<=0x00DFFF then
+ return s_unknown
else
return hash[k]
end
@@ -6064,10 +6108,10 @@ function mappings.addtounicode(data,filename,checklookups,forceligatures)
end
end
-end --- [luaotfload, fontloader-2020-02-02.lua scope for “font-map”] ---
+end --- [luaotfload, fontloader-2020-05-01.lua scope for “font-map”] ---
-do --- [luaotfload, fontloader-2020-02-02.lua scope for “font-vfc” 94937140f2c909e9c831ba021f1ab303] ---
+do --- [luaotfload, fontloader-2020-05-01.lua scope for “font-vfc” 94937140f2c909e9c831ba021f1ab303] ---
if not modules then modules={} end modules ['font-vfc']={
version=1.001,
@@ -6165,10 +6209,10 @@ helpers.commands=utilities.storage.allocate {
dummy=dummy,
}
-end --- [luaotfload, fontloader-2020-02-02.lua scope for “font-vfc”] ---
+end --- [luaotfload, fontloader-2020-05-01.lua scope for “font-vfc”] ---
-do --- [luaotfload, fontloader-2020-02-02.lua scope for “font-otr” d96724dcb40c673ac294df7044a39925] ---
+do --- [luaotfload, fontloader-2020-05-01.lua scope for “font-otr” d96724dcb40c673ac294df7044a39925] ---
if not modules then modules={} end modules ['font-otr']={
version=1.001,
@@ -8018,10 +8062,10 @@ function readers.extend(fontdata)
end
end
-end --- [luaotfload, fontloader-2020-02-02.lua scope for “font-otr”] ---
+end --- [luaotfload, fontloader-2020-05-01.lua scope for “font-otr”] ---
-do --- [luaotfload, fontloader-2020-02-02.lua scope for “font-oti” dbae7722baae24d917a17176553825cf] ---
+do --- [luaotfload, fontloader-2020-05-01.lua scope for “font-oti” dbae7722baae24d917a17176553825cf] ---
if not modules then modules={} end modules ['font-oti']={
version=1.001,
@@ -8164,10 +8208,10 @@ function otffeatures.checkeddefaultlanguage(featuretype,autolanguage,languages)
end
end
-end --- [luaotfload, fontloader-2020-02-02.lua scope for “font-oti”] ---
+end --- [luaotfload, fontloader-2020-05-01.lua scope for “font-oti”] ---
-do --- [luaotfload, fontloader-2020-02-02.lua scope for “font-ott” aba6d8335a5f38a5a62d3631492f3392] ---
+do --- [luaotfload, fontloader-2020-05-01.lua scope for “font-ott” aba6d8335a5f38a5a62d3631492f3392] ---
if not modules then modules={} end modules ["font-ott"]={
version=1.001,
@@ -9286,10 +9330,10 @@ function otffeatures.normalize(features,wrap)
end
end
-end --- [luaotfload, fontloader-2020-02-02.lua scope for “font-ott”] ---
+end --- [luaotfload, fontloader-2020-05-01.lua scope for “font-ott”] ---
-do --- [luaotfload, fontloader-2020-02-02.lua scope for “font-cff” c769020b41b39418f703347f3d328bc7] ---
+do --- [luaotfload, fontloader-2020-05-01.lua scope for “font-cff” 155821e11e84021437869ff973e75d93] ---
if not modules then modules={} end modules ['font-cff']={
version=1.001,
@@ -9443,6 +9487,14 @@ local cffreaders={
readuint,
readulong,
}
+directives.register("fonts.streamreader",function()
+ cffreaders={
+ readbyte,
+ readushort,
+ readuint,
+ readulong,
+ }
+end)
local function readheader(f)
local offset=getposition(f)
local major=readbyte(f)
@@ -11452,10 +11504,10 @@ function readers.cffcheck(filename)
end
end
-end --- [luaotfload, fontloader-2020-02-02.lua scope for “font-cff”] ---
+end --- [luaotfload, fontloader-2020-05-01.lua scope for “font-cff”] ---
-do --- [luaotfload, fontloader-2020-02-02.lua scope for “font-ttf” 44e61cef50dab9b1aaf48130f9367c34] ---
+do --- [luaotfload, fontloader-2020-05-01.lua scope for “font-ttf” 44e61cef50dab9b1aaf48130f9367c34] ---
if not modules then modules={} end modules ['font-ttf']={
version=1.001,
@@ -12625,10 +12677,10 @@ function readers.gvar(f,fontdata,specification,glyphdata,shapedata)
end
end
-end --- [luaotfload, fontloader-2020-02-02.lua scope for “font-ttf”] ---
+end --- [luaotfload, fontloader-2020-05-01.lua scope for “font-ttf”] ---
-do --- [luaotfload, fontloader-2020-02-02.lua scope for “font-dsp” 5d3db0184c903829b2c5bddcb8cdb14c] ---
+do --- [luaotfload, fontloader-2020-05-01.lua scope for “font-dsp” 618e5e760ec5dceb0c898a83816dbe61] ---
if not modules then modules={} end modules ['font-dsp']={
version=1.001,
@@ -15329,6 +15381,7 @@ function readers.sbix(f,fontdata,specification)
end
end)
local glyphs={}
+ local delayed=CONTEXTLMTXMODE and CONTEXTLMTXMODE>0 or fonts.handlers.typethree
for i=1,nofstrikes do
local strike=strikes[i]
local strikeppem=strike.ppem
@@ -15345,13 +15398,25 @@ function readers.sbix(f,fontdata,specification)
local datasize=nextoffset-glyphoffset
if datasize>0 then
setposition(f,strikeoffset+glyphoffset)
+ local x=readshort(f)
+ local y=readshort(f)
+ local tag=readtag(f)
+ local size=datasize-8
+ local data=nil
+ local offset=nil
+ if delayed then
+ offset=getposition(f)
+ data=nil
+ else
+ data=readstring(f,size)
+ size=nil
+ end
shapes[i]={
- x=readshort(f),
- y=readshort(f),
- tag=readtag(f),
- data=readstring(f,datasize-8),
- ppem=strikeppem,
- ppi=strikeppi,
+ x=x,
+ y=y,
+ o=offset,
+ s=size,
+ data=data,
}
done=done+1
if done==nofglyphs then
@@ -15530,29 +15595,46 @@ do
end
local default={ width=0,height=0 }
local glyphs=fontdata.glyphs
+ local delayed=CONTEXTLMTXMODE and CONTEXTLMTXMODE>0 or fonts.handlers.typethree
for index,subtable in sortedhash(shapes) do
if type(subtable)=="table" then
local data=nil
+ local size=nil
local metrics=default
local format=subtable.format
local offset=subtable.offsets[index]
setposition(f,offset)
if format==17 then
metrics=getsmallmetrics(f)
- data=readstring(f,readulong(f))
+ size=true
elseif format==18 then
metrics=getbigmetrics(f)
- data=readstring(f,readulong(f))
+ size=true
elseif format==19 then
metrics=subtable.metrics
- data=readstring(f,readulong(f))
+ size=true
else
end
+ if size then
+ size=readulong(f)
+ if delayed then
+ offset=getposition(f)
+ data=nil
+ else
+ offset=nil
+ data=readstring(f,size)
+ size=nil
+ end
+ else
+ offset=nil
+ end
local x=metrics.width
local y=metrics.height
shapes[index]={
x=x,
y=y,
+ o=offset,
+ s=size,
data=data,
}
local glyph=glyphs[index]
@@ -15875,10 +15957,10 @@ function readers.mvar(f,fontdata,specification)
end
end
-end --- [luaotfload, fontloader-2020-02-02.lua scope for “font-dsp”] ---
+end --- [luaotfload, fontloader-2020-05-01.lua scope for “font-dsp”] ---
-do --- [luaotfload, fontloader-2020-02-02.lua scope for “font-oup” 0cef35af01739f52fd09feb5401192ae] ---
+do --- [luaotfload, fontloader-2020-05-01.lua scope for “font-oup” 1700a2dac4f8b105c187d4e5b84cecdf] ---
if not modules then modules={} end modules ['font-oup']={
version=1.001,
@@ -18519,10 +18601,10 @@ function readers.expand(data)
expandlookups(sublookups)
end
-end --- [luaotfload, fontloader-2020-02-02.lua scope for “font-oup”] ---
+end --- [luaotfload, fontloader-2020-05-01.lua scope for “font-oup”] ---
-do --- [luaotfload, fontloader-2020-02-02.lua scope for “font-otl” ec0241b7465a7713e53c246e8e9fb2a8] ---
+do --- [luaotfload, fontloader-2020-05-01.lua scope for “font-otl” f111f9ac18d24049fadeb8883e4e8da5] ---
if not modules then modules={} end modules ['font-otl']={
version=1.001,
@@ -18550,7 +18632,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.110
+otf.version=3.111
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)
@@ -19226,10 +19308,10 @@ otf.coverup={
end
}
-end --- [luaotfload, fontloader-2020-02-02.lua scope for “font-otl”] ---
+end --- [luaotfload, fontloader-2020-05-01.lua scope for “font-otl”] ---
-do --- [luaotfload, fontloader-2020-02-02.lua scope for “font-oto” 24238a7c600d090a8ee88312321dd9b3] ---
+do --- [luaotfload, fontloader-2020-05-01.lua scope for “font-oto” 24238a7c600d090a8ee88312321dd9b3] ---
if not modules then modules={} end modules ['font-oto']={
version=1.001,
@@ -19687,10 +19769,10 @@ registerotffeature {
}
otf.basemodeinitializer=featuresinitializer
-end --- [luaotfload, fontloader-2020-02-02.lua scope for “font-oto”] ---
+end --- [luaotfload, fontloader-2020-05-01.lua scope for “font-oto”] ---
-do --- [luaotfload, fontloader-2020-02-02.lua scope for “font-otj” 66c7a910d95d4a52b81061de776898e1] ---
+do --- [luaotfload, fontloader-2020-05-01.lua scope for “font-otj” c9ded1d935bfa43020657e1f408fb820] ---
if not modules then modules={} end modules ['font-otj']={
version=1.001,
@@ -19753,14 +19835,14 @@ local insert_node_after=nuts.insert_after
local properties=nodes.properties.data
local fontkern=nuts.pool and nuts.pool.fontkern
local italickern=nuts.pool and nuts.pool.italickern
-local useitalickerns=false
+local useitalickerns=false
directives.register("fonts.injections.useitalics",function(v)
if v then
report_injections("using italics for space kerns (tracing only)")
end
useitalickerns=v
end)
-do if not fontkern then
+if not fontkern then
local thekern=nuts.new("kern",0)
local setkern=nuts.setkern
local copy_node=nuts.copy_node
@@ -19769,8 +19851,8 @@ do if not fontkern then
setkern(n,k)
return n
end
-end end
-do if not italickern then
+end
+if not italickern then
local thekern=nuts.new("kern",3)
local setkern=nuts.setkern
local copy_node=nuts.copy_node
@@ -19779,7 +19861,7 @@ do if not italickern then
setkern(n,k)
return n
end
-end end
+end
function injections.installnewkern() end
local nofregisteredkerns=0
local nofregisteredpositions=0
@@ -20232,7 +20314,15 @@ local function inject_kerns_only(head,where)
if i then
local leftkern=i.leftkern
if leftkern and leftkern~=0 then
- head=insert_node_before(head,current,fontkern(leftkern))
+ if prev and getid(prev)==glue_code then
+ if useitalickerns then
+ head=insert_node_before(head,current,italickern(leftkern))
+ else
+ setwidth(prev,getwidth(prev)+leftkern)
+ end
+ else
+ head=insert_node_before(head,current,fontkern(leftkern))
+ end
end
end
if prevdisc then
@@ -20375,12 +20465,26 @@ local function inject_positions_only(head,where)
if rightkern and leftkern==-rightkern then
setoffsets(current,leftkern,false)
rightkern=0
+ elseif prev and getid(prev)==glue_code then
+ if useitalickerns then
+ head=insert_node_before(head,current,italickern(leftkern))
+ else
+ setwidth(prev,getwidth(prev)+leftkern)
+ end
else
head=insert_node_before(head,current,fontkern(leftkern))
end
end
if rightkern and rightkern~=0 then
- insert_node_after(head,current,fontkern(rightkern))
+ if next and getid(next)==glue_code then
+ if useitalickerns then
+ insert_node_after(head,current,italickern(rightkern))
+ else
+ setwidth(next,getwidth(next)+rightkern)
+ end
+ else
+ insert_node_after(head,current,fontkern(rightkern))
+ end
end
else
local i=p.emptyinjections
@@ -20728,12 +20832,26 @@ local function inject_everything(head,where)
if rightkern and leftkern==-rightkern then
setoffsets(current,leftkern,false)
rightkern=0
+ elseif prev and getid(prev)==glue_code then
+ if useitalickerns then
+ head=insert_node_before(head,current,italickern(leftkern))
+ else
+ setwidth(prev,getwidth(prev)+leftkern)
+ end
else
head=insert_node_before(head,current,fontkern(leftkern))
end
end
if rightkern and rightkern~=0 then
- insert_node_after(head,current,fontkern(rightkern))
+ if next and getid(next)==glue_code then
+ if useitalickerns then
+ insert_node_after(head,current,italickern(rightkern))
+ else
+ setwidth(next,getwidth(next)+rightkern)
+ end
+ else
+ insert_node_after(head,current,fontkern(rightkern))
+ end
end
end
else
@@ -21106,16 +21224,17 @@ local function injectspaces(head)
if useitalickerns then
local new=rightkern*factor
if trace_spaces then
- report_spaces("%C [%p + %p]",nextchar,old,new)
+ report_spaces("[%p + %p] %C",old,new,nextchar)
end
insert_node_after(head,n,italickern(new))
else
local new=old+rightkern*factor
if trace_spaces then
- report_spaces("[%p -> %p] %C",nextchar,old,new)
+ report_spaces("[%p -> %p] %C",old,new,nextchar)
end
setwidth(n,new)
end
+ else
end
rightkern=false
end
@@ -21147,10 +21266,10 @@ function injections.handler(head,where)
end
end
-end --- [luaotfload, fontloader-2020-02-02.lua scope for “font-otj”] ---
+end --- [luaotfload, fontloader-2020-05-01.lua scope for “font-otj”] ---
-do --- [luaotfload, fontloader-2020-02-02.lua scope for “font-ota” d6dfb94563d6a52675e274b2e673e4a6] ---
+do --- [luaotfload, fontloader-2020-05-01.lua scope for “font-ota” dd5f1c8ba28abaf4505fd960d04a3a98] ---
if not modules then modules={} end modules ['font-ota']={
version=1.001,
@@ -21169,7 +21288,6 @@ local initializers=allocate()
local methods=allocate()
analyzers.initializers=initializers
analyzers.methods=methods
-local a_state=attributes.private('state')
local nuts=nodes.nuts
local tonut=nuts.tonut
local getnext=nuts.getnext
@@ -21189,6 +21307,23 @@ local categories=characters and characters.categories or {}
local chardata=characters and characters.data
local otffeatures=fonts.constructors.features.otf
local registerotffeature=otffeatures.register
+local setstate=nuts.setstate
+local getstate=nuts.getstate
+if not setstate or not getstate then
+ setstate=function(n,v)
+ setprop(n,"state",v)
+ end
+ getstate=function(n,v)
+ local s=getprop(n,"state")
+ if v then
+ return s==v
+ else
+ return s
+ end
+ end
+ nuts.setstate=setstate
+ nuts.getstate=getstate
+end
local s_init=1 local s_rphf=7
local s_medi=2 local s_half=8
local s_fina=3 local s_pref=9
@@ -21236,49 +21371,49 @@ function analyzers.setstate(head,font)
current=tonut(current)
while current do
local char,id=ischar(current,font)
- if char and not getprop(current,a_state) then
+ if char and not getstate(current) then
done=true
local d=descriptions[char]
if d then
if d.class=="mark" then
done=true
- setprop(current,a_state,s_mark)
+ setstate(current,s_mark)
elseif useunicodemarks and categories[char]=="mn" then
done=true
- setprop(current,a_state,s_mark)
+ setstate(current,s_mark)
elseif n==0 then
first,last,n=current,current,1
- setprop(current,a_state,s_init)
+ setstate(current,s_init)
else
last,n=current,n+1
- setprop(current,a_state,s_medi)
+ setstate(current,s_medi)
end
else
if first and first==last then
- setprop(last,a_state,s_isol)
+ setstate(last,s_isol)
elseif last then
- setprop(last,a_state,s_fina)
+ setstate(last,s_fina)
end
first,last,n=nil,nil,0
end
elseif char==false then
if first and first==last then
- setprop(last,a_state,s_isol)
+ setstate(last,s_isol)
elseif last then
- setprop(last,a_state,s_fina)
+ setstate(last,s_fina)
end
first,last,n=nil,nil,0
if id==math_code then
current=end_of_math(current)
end
elseif id==disc_code then
- setprop(current,a_state,s_medi)
+ setstate(current,s_medi)
last=current
else
if first and first==last then
- setprop(last,a_state,s_isol)
+ setstate(last,s_isol)
elseif last then
- setprop(last,a_state,s_fina)
+ setstate(last,s_fina)
end
first,last,n=nil,nil,0
if id==math_code then
@@ -21288,9 +21423,9 @@ function analyzers.setstate(head,font)
current=getnext(current)
end
if first and first==last then
- setprop(last,a_state,s_isol)
+ setstate(last,s_isol)
elseif last then
- setprop(last,a_state,s_fina)
+ setstate(last,s_fina)
end
return head,done
end
@@ -21394,87 +21529,87 @@ function methods.arab(head,font,attr)
current=tonut(current)
while current do
local char,id=ischar(current,font)
- if char and not getprop(current,a_state) then
+ if char and not getstate(current) then
done=true
local classifier=classifiers[char]
if not classifier then
if last then
if c_last==s_medi or c_last==s_fina then
- setprop(last,a_state,s_fina)
+ setstate(last,s_fina)
else
warning(last,"fina")
- setprop(last,a_state,s_error)
+ setstate(last,s_error)
end
first,last=nil,nil
elseif first then
if c_first==s_medi or c_first==s_fina then
- setprop(first,a_state,s_isol)
+ setstate(first,s_isol)
else
warning(first,"isol")
- setprop(first,a_state,s_error)
+ setstate(first,s_error)
end
first=nil
end
elseif classifier==s_mark then
- setprop(current,a_state,s_mark)
+ setstate(current,s_mark)
elseif classifier==s_isol then
if last then
if c_last==s_medi or c_last==s_fina then
- setprop(last,a_state,s_fina)
+ setstate(last,s_fina)
else
warning(last,"fina")
- setprop(last,a_state,s_error)
+ setstate(last,s_error)
end
first,last=nil,nil
elseif first then
if c_first==s_medi or c_first==s_fina then
- setprop(first,a_state,s_isol)
+ setstate(first,s_isol)
else
warning(first,"isol")
- setprop(first,a_state,s_error)
+ setstate(first,s_error)
end
first=nil
end
- setprop(current,a_state,s_isol)
+ setstate(current,s_isol)
elseif classifier==s_medi then
if first then
last=current
c_last=classifier
- setprop(current,a_state,s_medi)
+ setstate(current,s_medi)
else
- setprop(current,a_state,s_init)
+ setstate(current,s_init)
first=current
c_first=classifier
end
elseif classifier==s_fina then
if last then
- if getprop(last,a_state)~=s_init then
- setprop(last,a_state,s_medi)
+ if getstate(last)~=s_init then
+ setstate(last,s_medi)
end
- setprop(current,a_state,s_fina)
+ setstate(current,s_fina)
first,last=nil,nil
elseif first then
- setprop(current,a_state,s_fina)
+ setstate(current,s_fina)
first=nil
else
- setprop(current,a_state,s_isol)
+ setstate(current,s_isol)
end
else
- setprop(current,a_state,s_rest)
+ setstate(current,s_rest)
if last then
if c_last==s_medi or c_last==s_fina then
- setprop(last,a_state,s_fina)
+ setstate(last,s_fina)
else
warning(last,"fina")
- setprop(last,a_state,s_error)
+ setstate(last,s_error)
end
first,last=nil,nil
elseif first then
if c_first==s_medi or c_first==s_fina then
- setprop(first,a_state,s_isol)
+ setstate(first,s_isol)
else
warning(first,"isol")
- setprop(first,a_state,s_error)
+ setstate(first,s_error)
end
first=nil
end
@@ -21482,18 +21617,18 @@ function methods.arab(head,font,attr)
else
if last then
if c_last==s_medi or c_last==s_fina then
- setprop(last,a_state,s_fina)
+ setstate(last,s_fina)
else
warning(last,"fina")
- setprop(last,a_state,s_error)
+ setstate(last,s_error)
end
first,last=nil,nil
elseif first then
if c_first==s_medi or c_first==s_fina then
- setprop(first,a_state,s_isol)
+ setstate(first,s_isol)
else
warning(first,"isol")
- setprop(first,a_state,s_error)
+ setstate(first,s_error)
end
first=nil
end
@@ -21505,17 +21640,17 @@ function methods.arab(head,font,attr)
end
if last then
if c_last==s_medi or c_last==s_fina then
- setprop(last,a_state,s_fina)
+ setstate(last,s_fina)
else
warning(last,"fina")
- setprop(last,a_state,s_error)
+ setstate(last,s_error)
end
elseif first then
if c_first==s_medi or c_first==s_fina then
- setprop(first,a_state,s_isol)
+ setstate(first,s_isol)
else
warning(first,"isol")
- setprop(first,a_state,s_error)
+ setstate(first,s_error)
end
end
return head,done
@@ -21527,10 +21662,10 @@ directives.register("otf.analyze.useunicodemarks",function(v)
analyzers.useunicodemarks=v
end)
-end --- [luaotfload, fontloader-2020-02-02.lua scope for “font-ota”] ---
+end --- [luaotfload, fontloader-2020-05-01.lua scope for “font-ota”] ---
-do --- [luaotfload, fontloader-2020-02-02.lua scope for “font-ots” d0107799ec82da7f96dafe9626c5ee7f] ---
+do --- [luaotfload, fontloader-2020-05-01.lua scope for “font-ots” 113b7ad0c40d4786bb026706e479c3f3] ---
if not modules then modules={} end modules ['font-ots']={
version=1.001,
@@ -21596,8 +21731,7 @@ local setprev=nuts.setprev
local getboth=nuts.getboth
local setboth=nuts.setboth
local getid=nuts.getid
-local getprop=nuts.getprop
-local setprop=nuts.setprop
+local getstate=nuts.getstate
local getsubtype=nuts.getsubtype
local setsubtype=nuts.setsubtype
local getchar=nuts.getchar
@@ -21606,13 +21740,15 @@ local getdisc=nuts.getdisc
local setdisc=nuts.setdisc
local getreplace=nuts.getreplace
local setlink=nuts.setlink
-local getcomponents=nuts.getcomponents
-local setcomponents=nuts.setcomponents
local getwidth=nuts.getwidth
local getattr=nuts.getattr
local getglyphdata=nuts.getglyphdata
+local copy_no_components=nuts.copy_no_components
+local copy_only_glyphs=nuts.copy_only_glyphs
+local count_components=nuts.count_components
+local set_components=nuts.set_components
+local get_components=nuts.get_components
local ischar=nuts.ischar
-local isglyph=nuts.isglyph
local usesfont=nuts.uses_font
local insert_node_after=nuts.insert_after
local copy_node=nuts.copy
@@ -21637,7 +21773,6 @@ local dir_code=nodecodes.dir
local localpar_code=nodecodes.localpar
local discretionarydisc_code=disccodes.discretionary
local ligatureglyph_code=glyphcodes.ligature
-local a_state=attributes.private('state')
local a_noligature=attributes.private("noligature")
local injections=nodes.injections
local setmark=injections.setmark
@@ -21798,27 +21933,6 @@ local function appenddisc(disc,list)
end
setdisc(disc,pre,post,replace)
end
-local copy_no_components=nuts.copy_no_components
-local copy_only_glyphs=nuts.copy_only_glyphs
-local set_components=setcomponents
-local take_components=getcomponents
-local function count_components(start,marks)
- local char=isglyph(start)
- if char then
- if getsubtype(start)==ligatureglyph_code then
- local i=0
- local components=getcomponents(start)
- while components do
- i=i+count_components(components,marks)
- components=getnext(components)
- end
- return i
- elseif not marks[char] then
- return 1
- end
- end
- return 0
-end
local function markstoligature(head,start,stop,char)
if start==stop and getchar(start)==char then
return head,start
@@ -21864,7 +21978,7 @@ local function toligature(head,start,stop,char,dataset,sequence,skiphash,discfou
setlink(prev,base,next)
if not discfound then
local deletemarks=not skiphash or hasmarks
- local components=start
+ local components=start
local baseindex=0
local componentindex=0
local head=base
@@ -21877,13 +21991,13 @@ local function toligature(head,start,stop,char,dataset,sequence,skiphash,discfou
elseif not deletemarks then
setligaindex(start,baseindex+getligaindex(start,componentindex))
if trace_marks then
- logwarning("%s: keep mark %s, gets index %s",pref(dataset,sequence),gref(char),getligaindex(start))
+ logwarning("%s: keep ligature mark %s, gets index %s",pref(dataset,sequence),gref(char),getligaindex(start))
end
local n=copy_node(start)
copyinjection(n,start)
head,current=insert_node_after(head,current,n)
elseif trace_marks then
- logwarning("%s: delete mark %s",pref(dataset,sequence),gref(char))
+ logwarning("%s: delete ligature mark %s",pref(dataset,sequence),gref(char))
end
start=getnext(start)
end
@@ -21894,7 +22008,7 @@ local function toligature(head,start,stop,char,dataset,sequence,skiphash,discfou
if marks[char] then
setligaindex(start,baseindex+getligaindex(start,componentindex))
if trace_marks then
- logwarning("%s: set mark %s, gets index %s",pref(dataset,sequence),gref(char),getligaindex(start))
+ logwarning("%s: set ligature mark %s, gets index %s",pref(dataset,sequence),gref(char),getligaindex(start))
end
start=getnext(start)
else
@@ -21910,17 +22024,16 @@ local function toligature(head,start,stop,char,dataset,sequence,skiphash,discfou
local pre,post,replace,pretail,posttail,replacetail=getdisc(discfound,true)
if not replace then
local prev=getprev(base)
- local comp=take_components(base)
local copied=copy_only_glyphs(comp)
if pre then
setlink(discprev,pre)
else
setnext(discprev)
end
- pre=comp
+ pre=comp
if post then
setlink(posttail,discnext)
- setprev(post)
+ setprev(post)
else
post=discnext
setprev(discnext)
@@ -24104,7 +24217,7 @@ local function testrun(disc,t_run,c_run,...)
end
local pre,post,replace,pretail,posttail,replacetail=getdisc(disc,true)
local renewed=false
- if (post or replace) then
+ if post or replace then
if post then
setlink(posttail,next)
else
@@ -24204,6 +24317,7 @@ local nesting=0
local function c_run_single(head,font,attr,lookupcache,step,dataset,sequence,rlmode,skiphash,handler)
local done=false
local sweep=sweephead[head]
+ local start
if sweep then
start=sweep
sweephead[head]=false
@@ -24297,7 +24411,7 @@ local function t_run_single(start,stop,font,attr,lookupcache)
ss=nil
end
end
-lookupmatch=lg
+ lookupmatch=lg
else
break
end
@@ -24332,7 +24446,7 @@ local function k_run_single(sub,injection,last,font,attr,lookupcache,step,datase
if n==last then
break
end
- local char=ischar(n)
+ local char=ischar(n,font)
if char then
local lookupmatch=lookupcache[char]
if lookupmatch then
@@ -24348,6 +24462,7 @@ end
local function c_run_multiple(head,font,attr,steps,nofsteps,dataset,sequence,rlmode,skiphash,handler)
local done=false
local sweep=sweephead[head]
+ local start
if sweep then
start=sweep
sweephead[head]=false
@@ -24451,7 +24566,7 @@ local function t_run_multiple(start,stop,font,attr,steps,nofsteps)
ss=nil
end
end
-lookupmatch=lg
+ lookupmatch=lg
else
break
end
@@ -24674,10 +24789,10 @@ do
if lookupmatch then
local a
if attr then
- if getglyphdata(start)==attr and (not attribute or getprop(start,a_state)==attribute) then
+ if getglyphdata(start)==attr and (not attribute or getstate(start,attribute)) then
a=true
end
- elseif not attribute or getprop(start,a_state)==attribute then
+ elseif not attribute or getstate(start,attribute) then
a=true
end
if a then
@@ -24730,10 +24845,10 @@ do
if m then
local a
if attr then
- if getglyphdata(start)==attr and (not attribute or getprop(start,a_state)==attribute) then
+ if getglyphdata(start)==attr and (not attribute or getstate(start,attribute)) then
a=true
end
- elseif not attribute or getprop(start,a_state)==attribute then
+ elseif not attribute or getstate(start,attribute) then
a=true
end
if a then
@@ -25138,10 +25253,10 @@ registerotffeature {
},
}
-end --- [luaotfload, fontloader-2020-02-02.lua scope for “font-ots”] ---
+end --- [luaotfload, fontloader-2020-05-01.lua scope for “font-ots”] ---
-do --- [luaotfload, fontloader-2020-02-02.lua scope for “font-osd” 39e92f6e575741646d75ea79e3be87f3] ---
+do --- [luaotfload, fontloader-2020-05-01.lua scope for “font-osd” 61f05fcf91add1aa5dac9bc8b235adc9] ---
if not modules then modules={} end modules ['font-osd']={
version=1.001,
@@ -25175,6 +25290,8 @@ local setprev=nuts.setprev
local setchar=nuts.setchar
local getprop=nuts.getprop
local setprop=nuts.setprop
+local getstate=nuts.getstate
+local setstate=nuts.setstate
local ischar=nuts.ischar
local insert_node_after=nuts.insert_after
local copy_node=nuts.copy
@@ -25184,7 +25301,6 @@ local flush_node=nuts.flush_node
local copyinjection=nodes.injections.copy
local unsetvalue=attributes.unsetvalue
local fontdata=fonts.hashes.identifiers
-local a_state=attributes.private('state')
local a_syllabe=attributes.private('syllabe')
local dotted_circle=0x25CC
local c_nbsp=0x00A0
@@ -25922,7 +26038,7 @@ local function reorder_one(head,start,stop,font,attr,nbspaces)
current=start
else
current=getnext(n)
- setprop(start,a_state,s_rphf)
+ setstate(start,s_rphf)
end
end
if getchar(current)==c_nbsp then
@@ -25955,9 +26071,9 @@ local function reorder_one(head,start,stop,font,attr,nbspaces)
local nextcurrent=copy_node(current)
copyinjection(nextcurrent,current)
setlink(tempcurrent,nextcurrent)
- setprop(tempcurrent,a_state,s_blwf)
+ setstate(tempcurrent,s_blwf)
tempcurrent=processcharacters(tempcurrent,font)
- setprop(tempcurrent,a_state,unsetvalue)
+ setstate(tempcurrent,unsetvalue)
if getchar(next)==getchar(tempcurrent) then
flush_list(tempcurrent)
if show_syntax_errors then
@@ -25981,7 +26097,7 @@ local function reorder_one(head,start,stop,font,attr,nbspaces)
while not basefound do
local char=getchar(current)
if consonant[char] then
- setprop(current,a_state,s_half)
+ setstate(current,s_half)
if not firstcons then
firstcons=current
end
@@ -25989,9 +26105,9 @@ local function reorder_one(head,start,stop,font,attr,nbspaces)
if not base then
base=current
elseif blwfcache[char] then
- setprop(current,a_state,s_blwf)
+ setstate(current,s_blwf)
elseif pstfcache[char] then
- setprop(current,a_state,s_pstf)
+ setstate(current,s_pstf)
else
base=current
end
@@ -26056,14 +26172,14 @@ local function reorder_one(head,start,stop,font,attr,nbspaces)
while current~=stop do
local next=getnext(current)
if next~=stop and halant[getchar(next)] and getchar(getnext(next))==c_zwnj then
- setprop(current,a_state,unsetvalue)
+ setstate(current,unsetvalue)
end
current=next
end
- if base~=stop and getprop(base,a_state) then
+ if base~=stop and getstate(base) then
local next=getnext(base)
if halant[getchar(next)] and not (next~=stop and getchar(getnext(next))==c_zwj) then
- setprop(base,a_state,unsetvalue)
+ setstate(base,unsetvalue)
end
end
local current,allreordered,moved=start,false,{ [base]=true }
@@ -26200,7 +26316,7 @@ local function reorder_one(head,start,stop,font,attr,nbspaces)
end
bn=next
end
- if getprop(current,a_state)==s_rphf then
+ if getstate(current,s_rphf) then
if b~=current then
if current==start then
if head==start then
@@ -26351,7 +26467,7 @@ function handlers.devanagari_reorder_reph(head,start)
while current do
local char=ischar(current,startfont)
if char and getprop(current,a_syllabe)==startattr then
- if consonant[char] and not getprop(current,a_state)==s_pref then
+ if consonant[char] and not getstate(current,s_pref) then
startnext=getnext(start)
head=remove_node(head,start)
setlink(current,start)
@@ -26375,7 +26491,7 @@ function handlers.devanagari_reorder_reph(head,start)
while current do
local char=ischar(current,startfont)
if char and getprop(current,a_syllabe)==startattr then
- if getprop(current,a_state)==s_pstf then
+ if getstate(current,s_pstf) then
startnext=getnext(start)
head=remove_node(head,start)
setlink(getprev(current),start)
@@ -26408,7 +26524,7 @@ function handlers.devanagari_reorder_reph(head,start)
while current do
local char=ischar(current,startfont)
if char and getprop(current,a_syllabe)==startattr then
- local state=getprop(current,a_state)
+ local state=getstate(current)
if before_subscript[rephbase] and (state==s_blwf or state==s_pstf) then
c=current
elseif after_subscript[rephbase] and (state==s_pstf) then
@@ -26488,7 +26604,7 @@ function handlers.devanagari_reorder_pre_base_reordering_consonants(head,start)
local current=getprev(start)
while current and getprop(current,a_syllabe)==startattr do
local char=ischar(current)
- if (not dependent_vowel[char] and not getprop(current,a_state) or getprop(current,a_state)==s_init) then
+ if (not dependent_vowel[char] and (not getstate(current) or getstate(current,s_init))) then
startnext=getnext(start)
head=remove_node(head,start)
if current==head then
@@ -26568,7 +26684,7 @@ local function reorder_two(head,start,stop,font,attr,nbspaces)
if afternext and zw_char[getchar(afternext)] then
current=afternext
elseif current==start then
- setprop(current,a_state,s_rphf)
+ setstate(current,s_rphf)
current=next
else
current=next
@@ -26588,9 +26704,9 @@ local function reorder_two(head,start,stop,font,attr,nbspaces)
if found then
local next=getnext(current)
if found[getchar(next)] or contextchain(found,next) then
- if (not getprop(current,a_state) and not getprop(next,a_state)) then
- setprop(current,a_state,s_pref)
- setprop(next,a_state,s_pref)
+ if (not getstate(current) and not getstate(next)) then
+ setstate(current,s_pref)
+ setstate(next,s_pref)
current=next
end
end
@@ -26610,8 +26726,8 @@ local function reorder_two(head,start,stop,font,attr,nbspaces)
if found[getchar(next)] or contextchain(found,next) then
if next~=stop and getchar(getnext(next))==c_zwnj then
current=next
- elseif (not getprop(current,a_state)) then
- setprop(current,a_state,s_half)
+ elseif (not getstate(current)) then
+ setstate(current,s_half)
if not halfpos then
halfpos=current
end
@@ -26632,9 +26748,9 @@ local function reorder_two(head,start,stop,font,attr,nbspaces)
if found then
local next=getnext(current)
if found[getchar(next)] or contextchain(found,next) then
- if (not getprop(current,a_state) and not getprop(next,a_state)) then
- setprop(current,a_state,s_blwf)
- setprop(next,a_state,s_blwf)
+ if (not getstate(current) and not getstate(next)) then
+ setstate(current,s_blwf)
+ setstate(next,s_blwf)
current=next
subpos=current
end
@@ -26653,9 +26769,9 @@ local function reorder_two(head,start,stop,font,attr,nbspaces)
if found then
local next=getnext(current)
if found[getchar(next)] or contextchain(found,next) then
- if (not getprop(current,a_state) and not getprop(next,a_state)) then
- setprop(current,a_state,s_pstf)
- setprop(next,a_state,s_pstf)
+ if (not getstate(current) and not getstate(next)) then
+ setstate(current,s_pstf)
+ setstate(next,s_pstf)
current=next
postpos=current
end
@@ -26667,7 +26783,7 @@ local function reorder_two(head,start,stop,font,attr,nbspaces)
end
end
local current,base,firstcons=start,nil,nil
- if getprop(start,a_state)==s_rphf then
+ if getstate(start,s_rphf) then
current=getnext(getnext(start))
end
if current~=getnext(stop) and getchar(current)==c_nbsp then
@@ -26694,13 +26810,13 @@ local function reorder_two(head,start,stop,font,attr,nbspaces)
local tmp=getnext(next)
local changestop=next==stop
setnext(next)
- setprop(current,a_state,s_pref)
+ setstate(current,s_pref)
current=processcharacters(current,font)
- setprop(current,a_state,s_blwf)
+ setstate(current,s_blwf)
current=processcharacters(current,font)
- setprop(current,a_state,s_pstf)
+ setstate(current,s_pstf)
current=processcharacters(current,font)
- setprop(current,a_state,unsetvalue)
+ setstate(current,unsetvalue)
if halant[getchar(current)] then
setnext(getnext(current),tmp)
if show_syntax_errors then
@@ -26725,7 +26841,7 @@ local function reorder_two(head,start,stop,font,attr,nbspaces)
if not firstcons then
firstcons=current
end
- local a=getprop(current,a_state)
+ 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
end
@@ -26738,13 +26854,13 @@ local function reorder_two(head,start,stop,font,attr,nbspaces)
end
end
if not base then
- if getprop(start,a_state)==s_rphf then
- setprop(start,a_state,unsetvalue)
+ if getstate(start,s_rphf) then
+ setstate(start,unsetvalue)
end
return head,stop,nbspaces
else
- if getprop(base,a_state) then
- setprop(base,a_state,unsetvalue)
+ if getstate(base) then
+ setstate(base,unsetvalue)
end
basepos=base
end
@@ -26790,7 +26906,7 @@ local function reorder_two(head,start,stop,font,attr,nbspaces)
end
local ppos=getprev(pos)
while ppos and getprop(ppos,a_syllabe)==getprop(pos,a_syllabe) do
- if getprop(ppos,a_state)==s_pref then
+ if getstate(ppos,s_pref) then
pos=ppos
end
ppos=getprev(ppos)
@@ -26862,7 +26978,7 @@ local function reorder_two(head,start,stop,font,attr,nbspaces)
while current~=last do
local char=getchar(current)
local cn=getnext(current)
- if halant[char] and ra[ischar(cn)] and getprop(cn,a_state)~=s_rphf and getprop(cn,a_state)~=s_blwf then
+ if halant[char] and ra[ischar(cn)] and (not getstate(cn,s_rphf)) and (not getstate(cn,s_blwf)) then
if after_main[ischar(cn)] then
local prev=getprev(current)
local next=getnext(cn)
@@ -27462,8 +27578,8 @@ local function method_one(head,font,attr)
while current do
local char=ischar(current,font)
if char then
- if n==0 and not getprop(current,a_state) then
- setprop(current,a_state,s_init)
+ if n==0 and not getstate(current) then
+ setstate(current,s_init)
end
n=n+1
else
@@ -27539,7 +27655,7 @@ local function method_two(head,font,attr)
end
if not syllableend and show_syntax_errors then
local char=ischar(current,font)
- if char and not getprop(current,a_state) then
+ if char and not getstate(current) then
local mark=mark_four[char]
if mark then
head,current=inject_syntax_error(head,current,char)
@@ -27557,8 +27673,8 @@ local function method_two(head,font,attr)
while current do
local char=ischar(current,font)
if char then
- if n==0 and not getprop(current,a_state) then
- setprop(current,a_state,s_init)
+ if n==0 and not getstate(current) then
+ setstate(current,s_init)
end
n=n+1
else
@@ -27573,10 +27689,10 @@ for i=1,nofscripts do
methods[scripts_two[i]]=method_two
end
-end --- [luaotfload, fontloader-2020-02-02.lua scope for “font-osd”] ---
+end --- [luaotfload, fontloader-2020-05-01.lua scope for “font-osd”] ---
-do --- [luaotfload, fontloader-2020-02-02.lua scope for “font-ocl” c1f4cbea3c4ec5002a04fc637b135711] ---
+do --- [luaotfload, fontloader-2020-05-01.lua scope for “font-ocl” e6b45379971219a6227e8655cda14aff] ---
if not modules then modules={} end modules ['font-ocl']={
version=1.001,
@@ -28113,10 +28229,10 @@ if context then
}
end
-end --- [luaotfload, fontloader-2020-02-02.lua scope for “font-ocl”] ---
+end --- [luaotfload, fontloader-2020-05-01.lua scope for “font-ocl”] ---
-do --- [luaotfload, fontloader-2020-02-02.lua scope for “font-otc” 1204a2fdc436e644127c0aa38ab69607] ---
+do --- [luaotfload, fontloader-2020-05-01.lua scope for “font-otc” 1204a2fdc436e644127c0aa38ab69607] ---
if not modules then modules={} end modules ['font-otc']={
version=1.001,
@@ -28873,10 +28989,10 @@ end
otf.enhancers.enhance=enhance
otf.enhancers.register("check extra features",enhance)
-end --- [luaotfload, fontloader-2020-02-02.lua scope for “font-otc”] ---
+end --- [luaotfload, fontloader-2020-05-01.lua scope for “font-otc”] ---
-do --- [luaotfload, fontloader-2020-02-02.lua scope for “font-onr” 22572ec0f86f53631e14b6d1ed43ee51] ---
+do --- [luaotfload, fontloader-2020-05-01.lua scope for “font-onr” 22572ec0f86f53631e14b6d1ed43ee51] ---
if not modules then modules={} end modules ['font-onr']={
version=1.001,
@@ -29248,10 +29364,10 @@ function readers.getinfo(filename)
end
end
-end --- [luaotfload, fontloader-2020-02-02.lua scope for “font-onr”] ---
+end --- [luaotfload, fontloader-2020-05-01.lua scope for “font-onr”] ---
-do --- [luaotfload, fontloader-2020-02-02.lua scope for “font-one” 987c5c5ed3754ad2feab80985067d59e] ---
+do --- [luaotfload, fontloader-2020-05-01.lua scope for “font-one” 987c5c5ed3754ad2feab80985067d59e] ---
if not modules then modules={} end modules ['font-one']={
version=1.001,
@@ -29962,10 +30078,10 @@ registerafmenhancer("normalize features",enhance_normalize_features)
registerafmenhancer("check extra features",otfenhancers.enhance)
registerafmenhancer("fix names",enhance_fix_names)
-end --- [luaotfload, fontloader-2020-02-02.lua scope for “font-one”] ---
+end --- [luaotfload, fontloader-2020-05-01.lua scope for “font-one”] ---
-do --- [luaotfload, fontloader-2020-02-02.lua scope for “font-afk” 54d554530e75c57c56ee76234724e26d] ---
+do --- [luaotfload, fontloader-2020-05-01.lua scope for “font-afk” 54d554530e75c57c56ee76234724e26d] ---
if not modules then modules={} end modules ['font-afk']={
version=1.001,
@@ -30132,10 +30248,10 @@ fonts.handlers.afm.helpdata={
}
}
-end --- [luaotfload, fontloader-2020-02-02.lua scope for “font-afk”] ---
+end --- [luaotfload, fontloader-2020-05-01.lua scope for “font-afk”] ---
-do --- [luaotfload, fontloader-2020-02-02.lua scope for “fonts-tfm” 3bbba3214fd0b8c6f35ad85592fc2917] ---
+do --- [luaotfload, fontloader-2020-05-01.lua scope for “fonts-tfm” 3bbba3214fd0b8c6f35ad85592fc2917] ---
if not modules then modules={} end modules ['luatex-fonts-tfm']={
version=1.001,
@@ -30650,10 +30766,10 @@ registertfmfeature {
}
}
-end --- [luaotfload, fontloader-2020-02-02.lua scope for “fonts-tfm”] ---
+end --- [luaotfload, fontloader-2020-05-01.lua scope for “fonts-tfm”] ---
-do --- [luaotfload, fontloader-2020-02-02.lua scope for “font-lua” 55b281fb98f7bd848fc19928f376f647] ---
+do --- [luaotfload, fontloader-2020-05-01.lua scope for “font-lua” 55b281fb98f7bd848fc19928f376f647] ---
if not modules then modules={} end modules ['font-lua']={
version=1.001,
@@ -30693,10 +30809,10 @@ function readers.lua(specification)
return check_lua(specification,fullname)
end
-end --- [luaotfload, fontloader-2020-02-02.lua scope for “font-lua”] ---
+end --- [luaotfload, fontloader-2020-05-01.lua scope for “font-lua”] ---
-do --- [luaotfload, fontloader-2020-02-02.lua scope for “font-def” c525b9f55da1c736a1f6939c0a6f8f00] ---
+do --- [luaotfload, fontloader-2020-05-01.lua scope for “font-def” c525b9f55da1c736a1f6939c0a6f8f00] ---
if not modules then modules={} end modules ['font-def']={
version=1.001,
@@ -31095,10 +31211,10 @@ if not context then
callbacks.register('define_font',definers.read,"definition of fonts (tfmdata preparation)")
end
-end --- [luaotfload, fontloader-2020-02-02.lua scope for “font-def”] ---
+end --- [luaotfload, fontloader-2020-05-01.lua scope for “font-def”] ---
-do --- [luaotfload, fontloader-2020-02-02.lua scope for “fonts-def” 5ad79120ebc5e60f4d322fb3ee13bffe] ---
+do --- [luaotfload, fontloader-2020-05-01.lua scope for “fonts-def” 5ad79120ebc5e60f4d322fb3ee13bffe] ---
if not modules then modules={} end modules ['luatex-fonts-def']={
version=1.001,
@@ -31179,10 +31295,10 @@ function fonts.definers.applypostprocessors(tfmdata)
return tfmdata
end
-end --- [luaotfload, fontloader-2020-02-02.lua scope for “fonts-def”] ---
+end --- [luaotfload, fontloader-2020-05-01.lua scope for “fonts-def”] ---
-do --- [luaotfload, fontloader-2020-02-02.lua scope for “fonts-ext” 01015ab3758cdc2af29394e6d502a91a] ---
+do --- [luaotfload, fontloader-2020-05-01.lua scope for “fonts-ext” 01015ab3758cdc2af29394e6d502a91a] ---
if not modules then modules={} end modules ['luatex-fonts-ext']={
version=1.001,
@@ -31368,10 +31484,10 @@ registerotffeature {
}
}
-end --- [luaotfload, fontloader-2020-02-02.lua scope for “fonts-ext”] ---
+end --- [luaotfload, fontloader-2020-05-01.lua scope for “fonts-ext”] ---
-do --- [luaotfload, fontloader-2020-02-02.lua scope for “font-imp-tex” 77c374b0ef00c2fb12188ec42beb4257] ---
+do --- [luaotfload, fontloader-2020-05-01.lua scope for “font-imp-tex” 77c374b0ef00c2fb12188ec42beb4257] ---
if not modules then modules={} end modules ['font-imp-tex']={
version=1.001,
@@ -31470,10 +31586,10 @@ registerotffeature {
description="arabic digits",
}
-end --- [luaotfload, fontloader-2020-02-02.lua scope for “font-imp-tex”] ---
+end --- [luaotfload, fontloader-2020-05-01.lua scope for “font-imp-tex”] ---
-do --- [luaotfload, fontloader-2020-02-02.lua scope for “font-imp-ligatures” 043daa4fcccf2560868da359d71d3a4a] ---
+do --- [luaotfload, fontloader-2020-05-01.lua scope for “font-imp-ligatures” 043daa4fcccf2560868da359d71d3a4a] ---
if not modules then modules={} end modules ['font-imp-ligatures']={
version=1.001,
@@ -31587,10 +31703,10 @@ if context then
}
end
-end --- [luaotfload, fontloader-2020-02-02.lua scope for “font-imp-ligatures”] ---
+end --- [luaotfload, fontloader-2020-05-01.lua scope for “font-imp-ligatures”] ---
-do --- [luaotfload, fontloader-2020-02-02.lua scope for “font-imp-italics” fe1ca80fb5ea4a2f8d2d5c484e7ba913] ---
+do --- [luaotfload, fontloader-2020-05-01.lua scope for “font-imp-italics” fe1ca80fb5ea4a2f8d2d5c484e7ba913] ---
if not modules then modules={} end modules ['font-imp-italics']={
version=1.001,
@@ -31696,10 +31812,10 @@ if context then
registerafmfeature(dimensions_specification)
end
-end --- [luaotfload, fontloader-2020-02-02.lua scope for “font-imp-italics”] ---
+end --- [luaotfload, fontloader-2020-05-01.lua scope for “font-imp-italics”] ---
-do --- [luaotfload, fontloader-2020-02-02.lua scope for “font-imp-effects” 73a660359a0ec71e44cc2b7225a715ac] ---
+do --- [luaotfload, fontloader-2020-05-01.lua scope for “font-imp-effects” 73a660359a0ec71e44cc2b7225a715ac] ---
if not modules then modules={} end modules ['font-imp-effects']={
version=1.001,
@@ -32056,10 +32172,10 @@ local specification={
registerotffeature(specification)
registerafmfeature(specification)
-end --- [luaotfload, fontloader-2020-02-02.lua scope for “font-imp-effects”] ---
+end --- [luaotfload, fontloader-2020-05-01.lua scope for “font-imp-effects”] ---
-do --- [luaotfload, fontloader-2020-02-02.lua scope for “fonts-lig” b9dbe77ce747d4c35bb2a20ffbe5aa51] ---
+do --- [luaotfload, fontloader-2020-05-01.lua scope for “fonts-lig” b9dbe77ce747d4c35bb2a20ffbe5aa51] ---
fonts.handlers.otf.addfeature {
@@ -34128,10 +34244,10 @@ fonts.handlers.otf.addfeature {
["type"]="ligature",
}
-end --- [luaotfload, fontloader-2020-02-02.lua scope for “fonts-lig”] ---
+end --- [luaotfload, fontloader-2020-05-01.lua scope for “fonts-lig”] ---
-do --- [luaotfload, fontloader-2020-02-02.lua scope for “fonts-gbn” d25472d54c4841db43a745764a63533e] ---
+do --- [luaotfload, fontloader-2020-05-01.lua scope for “fonts-gbn” d25472d54c4841db43a745764a63533e] ---
if not modules then modules={} end modules ['luatex-fonts-gbn']={
version=1.001,
@@ -34396,7 +34512,7 @@ function nodes.simple_font_handler(head,groupcode,size,packtype,direction)
return head
end
-end --- [luaotfload, fontloader-2020-02-02.lua scope for “fonts-gbn”] ---
+end --- [luaotfload, fontloader-2020-05-01.lua scope for “fonts-gbn”] ---
--- vim:ft=lua:sw=2:ts=8:et:tw=79
diff --git a/macros/luatex/generic/luaotfload/fontloader-basics-gen.lua b/macros/luatex/generic/luaotfload/fontloader-basics-gen.lua
index f52fec6967..3959ca0222 100644
--- a/macros/luatex/generic/luaotfload/fontloader-basics-gen.lua
+++ b/macros/luatex/generic/luaotfload/fontloader-basics-gen.lua
@@ -189,7 +189,7 @@ local readables = { }
local usingjit = jit
if not caches.namespace or caches.namespace == "" or caches.namespace == "context" then
- caches.namespace = 'generic-dev'
+ caches.namespace = 'generic'
end
do
diff --git a/macros/luatex/generic/luaotfload/fontloader-basics-nod.lua b/macros/luatex/generic/luaotfload/fontloader-basics-nod.lua
index be82277bd4..0fb768cf83 100644
--- a/macros/luatex/generic/luaotfload/fontloader-basics-nod.lua
+++ b/macros/luatex/generic/luaotfload/fontloader-basics-nod.lua
@@ -96,7 +96,6 @@ nuts.tonut = tonut
nuts.getattr = direct.get_attribute
nuts.getboth = direct.getboth
nuts.getchar = direct.getchar
-nuts.getcomponents = direct.getcomponents
nuts.getdirection = direct.getdirection
nuts.getdisc = direct.getdisc
nuts.getreplace = direct.getreplace
@@ -137,7 +136,6 @@ nuts.isglyph = direct.is_glyph
nuts.copy = direct.copy
nuts.copy_list = direct.copy_list
nuts.copy_node = direct.copy
-nuts.delete = direct.delete
nuts.end_of_math = direct.end_of_math
nuts.flush = direct.flush
nuts.flush_list = direct.flush_list
@@ -196,9 +194,8 @@ local getnext = nuts.getnext
local setlink = nuts.setlink
local getfield = nuts.getfield
local setfield = nuts.setfield
-local getcomponents = nuts.getcomponents
-local setcomponents = nuts.setcomponents
-
+local getsubtype = nuts.getsubtype
+local isglyph = nuts.isglyph
local find_tail = nuts.tail
local flush_list = nuts.flush_list
local flush_node = nuts.flush_node
@@ -206,40 +203,72 @@ local traverse_id = nuts.traverse_id
local copy_node = nuts.copy_node
local glyph_code = nodes.nodecodes.glyph
+local ligature_code = nodes.glyphcodes.ligature
+
+do
-function nuts.copy_no_components(g,copyinjection)
- local components = getcomponents(g)
- if components then
- setcomponents(g)
- local n = copy_node(g)
- if copyinjection then
- copyinjection(n,g)
+ local get_components = node.direct.getcomponents
+ local set_components = node.direct.setcomponents
+
+ local function copy_no_components(g,copyinjection)
+ local components = get_components(g)
+ if components then
+ set_components(g)
+ local n = copy_node(g)
+ if copyinjection then
+ copyinjection(n,g)
+ end
+ set_components(g,components)
+ -- maybe also upgrade the subtype but we don't use it anyway
+ return n
+ else
+ local n = copy_node(g)
+ if copyinjection then
+ copyinjection(n,g)
+ end
+ return n
end
- setcomponents(g,components)
- -- maybe also upgrade the subtype but we don't use it anyway
- return n
- else
- local n = copy_node(g)
- if copyinjection then
- copyinjection(n,g)
+ end
+
+ local function copy_only_glyphs(current)
+ local head = nil
+ local previous = nil
+ for n in traverse_id(glyph_code,current) do
+ n = copy_node(n)
+ if head then
+ setlink(previous,n)
+ else
+ head = n
+ end
+ previous = n
end
- return n
+ return head
end
-end
-function nuts.copy_only_glyphs(current)
- local head = nil
- local previous = nil
- for n in traverse_id(glyph_code,current) do
- n = copy_node(n)
- if head then
- setlink(previous,n)
- else
- head = n
+ local function count_components(start,marks)
+ local char = isglyph(start)
+ if char then
+ if getsubtype(start) == ligature_code then
+ local n = 0
+ local components = get_components(start)
+ while components do
+ n = n + count_components(components,marks)
+ components = getnext(components)
+ end
+ return n
+ elseif not marks[char] then
+ return 1
+ end
end
- previous = n
+ return 0
end
- return head
+
+ nuts.set_components = set_components
+ nuts.get_components = get_components
+ nuts.copy_only_glyphs = copy_only_glyphs
+ nuts.copy_no_components = copy_no_components
+ nuts.count_components = count_components
+
end
nuts.uses_font = direct.uses_font
diff --git a/macros/luatex/generic/luaotfload/fontloader-font-cff.lua b/macros/luatex/generic/luaotfload/fontloader-font-cff.lua
index 5f79ba7a33..72b0a038f1 100644
--- a/macros/luatex/generic/luaotfload/fontloader-font-cff.lua
+++ b/macros/luatex/generic/luaotfload/fontloader-font-cff.lua
@@ -184,6 +184,15 @@ local cffreaders = {
readulong,
}
+directives.register("fonts.streamreader",function()
+ cffreaders = {
+ readbyte,
+ readushort,
+ readuint,
+ readulong,
+ }
+end)
+
-- The header contains information about its own size.
local function readheader(f)
diff --git a/macros/luatex/generic/luaotfload/fontloader-font-con.lua b/macros/luatex/generic/luaotfload/fontloader-font-con.lua
index e42d20d4e1..1bb63aa519 100644
--- a/macros/luatex/generic/luaotfload/fontloader-font-con.lua
+++ b/macros/luatex/generic/luaotfload/fontloader-font-con.lua
@@ -1139,6 +1139,7 @@ hashmethods.normal = function(list)
m = m + 1
t[m] = k .. '=' .. tostring(v)
end
+ sort(t)
s[n] = k .. '={' .. concat(t,",") .. "}"
else
s[n] = k .. '=' .. tostring(v)
diff --git a/macros/luatex/generic/luaotfload/fontloader-font-dsp.lua b/macros/luatex/generic/luaotfload/fontloader-font-dsp.lua
index 7777f9c6ad..3058be37b9 100644
--- a/macros/luatex/generic/luaotfload/fontloader-font-dsp.lua
+++ b/macros/luatex/generic/luaotfload/fontloader-font-dsp.lua
@@ -3237,7 +3237,8 @@ function readers.sbix(f,fontdata,specification)
return b.ppem < a.ppem
end
end)
- local glyphs = { }
+ local glyphs = { }
+ local delayed = CONTEXTLMTXMODE and CONTEXTLMTXMODE > 0 or fonts.handlers.typethree
for i=1,nofstrikes do
local strike = strikes[i]
local strikeppem = strike.ppem
@@ -3254,13 +3255,28 @@ function readers.sbix(f,fontdata,specification)
local datasize = nextoffset - glyphoffset
if datasize > 0 then
setposition(f,strikeoffset + glyphoffset)
+ local x = readshort(f)
+ local y = readshort(f)
+ local tag = readtag(f) -- or just skip, we never needed it till now
+ local size = datasize - 8
+ local data = nil
+ local offset = nil
+ if delayed then
+ offset = getposition(f)
+ data = nil
+ else
+ data = readstring(f,size)
+ size = nil
+ end
shapes[i] = {
- x = readshort(f),
- y = readshort(f),
- tag = readtag(f), -- maybe for tracing
- data = readstring(f,datasize-8),
- ppem = strikeppem, -- not used, for tracing
- ppi = strikeppi, -- not used, for tracing
+ x = x,
+ y = y,
+ o = offset,
+ s = size,
+ data = data,
+ -- tag = tag, -- maybe for tracing
+ -- ppem = strikeppem, -- not used, for tracing
+ -- ppi = strikeppi, -- not used, for tracing
}
done = done + 1
if done == nofglyphs then
@@ -3462,32 +3478,48 @@ do
local default = { width = 0, height = 0 }
local glyphs = fontdata.glyphs
+ local delayed = CONTEXTLMTXMODE and CONTEXTLMTXMODE > 0 or fonts.handlers.typethree
for index, subtable in sortedhash(shapes) do
if type(subtable) == "table" then
local data = nil
+ local size = nil
local metrics = default
local format = subtable.format
local offset = subtable.offsets[index]
setposition(f,offset)
if format == 17 then
metrics = getsmallmetrics(f)
- data = readstring(f,readulong(f))
+ size = true
elseif format == 18 then
metrics = getbigmetrics(f)
- data = readstring(f,readulong(f))
+ size = true
elseif format == 19 then
metrics = subtable.metrics
- data = readstring(f,readulong(f))
+ size = true
else
-- forget about it
end
+ if size then
+ size = readulong(f)
+ if delayed then
+ offset = getposition(f)
+ data = nil
+ else
+ offset = nil
+ data = readstring(f,size)
+ size = nil
+ end
+ else
+ offset = nil
+ end
local x = metrics.width
local y = metrics.height
shapes[index] = {
- -- maybe some metrics
x = x,
y = y,
+ o = offset,
+ s = size,
data = data,
}
-- I'll look into this in more details when needed
@@ -3498,12 +3530,11 @@ do
local height = width * y/x
glyph.boundingbox = { 0, 0, width, height }
end
-
else
shapes[index] = {
x = 0,
y = 0,
- data = "",
+ data = "", -- or just nil
}
end
end
diff --git a/macros/luatex/generic/luaotfload/fontloader-font-map.lua b/macros/luatex/generic/luaotfload/fontloader-font-map.lua
index d931b822e5..84a28a8b7e 100644
--- a/macros/luatex/generic/luaotfload/fontloader-font-map.lua
+++ b/macros/luatex/generic/luaotfload/fontloader-font-map.lua
@@ -12,7 +12,7 @@ local match, format, find, concat, gsub, lower = string.match, string.format, st
local P, R, S, C, Ct, Cc, lpegmatch = lpeg.P, lpeg.R, lpeg.S, lpeg.C, lpeg.Ct, lpeg.Cc, lpeg.match
local formatters = string.formatters
local sortedhash, sortedkeys = table.sortedhash, table.sortedkeys
-local rshift = bit32.rshift
+local idiv = number.idiv
local trace_loading = false trackers.register("fonts.loading", function(v) trace_loading = v end)
local trace_mapping = false trackers.register("fonts.mapping", function(v) trace_mapping = v end)
@@ -23,44 +23,23 @@ local report_fonts = logs.reporter("fonts","loading") -- not otf only
local force_ligatures = false directives.register("fonts.mapping.forceligatures",function(v) force_ligatures = v end)
-local fonts = fonts or { }
-local mappings = fonts.mappings or { }
-fonts.mappings = mappings
-
-local allocate = utilities.storage.allocate
-
---[[ldx--
-<p>Eventually this code will disappear because map files are kind
-of obsolete. Some code may move to runtime or auxiliary modules.</p>
-<p>The name to unciode related code will stay of course.</p>
---ldx]]--
-
--- local function loadlumtable(filename) -- will move to font goodies
--- local lumname = file.replacesuffix(file.basename(filename),"lum")
--- local lumfile = resolvers.findfile(lumname,"map") or ""
--- if lumfile ~= "" and lfs.isfile(lumfile) then
--- if trace_loading or trace_mapping then
--- report_fonts("loading map table %a",lumfile)
--- end
--- lumunic = dofile(lumfile)
--- return lumunic, lumfile
--- end
--- end
+local fonts = fonts or { }
+local mappings = fonts.mappings or { }
+fonts.mappings = mappings
-local hex = R("AF","af","09")
------ hexfour = (hex*hex*hex*hex) / function(s) return tonumber(s,16) end
------ hexsix = (hex*hex*hex*hex*hex*hex) / function(s) return tonumber(s,16) end
-local hexfour = (hex*hex*hex^-2) / function(s) return tonumber(s,16) end
-local hexsix = (hex*hex*hex^-4) / function(s) return tonumber(s,16) end
-local dec = (R("09")^1) / tonumber
-local period = P(".")
-local unicode = (P("uni") + P("UNI")) * (hexfour * (period + P(-1)) * Cc(false) + Ct(hexfour^1) * Cc(true)) -- base planes
-local ucode = (P("u") + P("U") ) * (hexsix * (period + P(-1)) * Cc(false) + Ct(hexsix ^1) * Cc(true)) -- extended
-local index = P("index") * dec * Cc(false)
+local allocate = utilities.storage.allocate
-local parser = unicode + ucode + index
+local hex = R("AF","af","09")
+local hexfour = (hex*hex*hex^-2) / function(s) return tonumber(s,16) end
+local hexsix = (hex*hex*hex^-4) / function(s) return tonumber(s,16) end
+local dec = (R("09")^1) / tonumber
+local period = P(".")
+local unicode = (P("uni") + P("UNI")) * (hexfour * (period + P(-1)) * Cc(false) + Ct(hexfour^1) * Cc(true)) -- base planes
+local ucode = (P("u") + P("U") ) * (hexsix * (period + P(-1)) * Cc(false) + Ct(hexsix ^1) * Cc(true)) -- extended
+local index = P("index") * dec * Cc(false)
-local parsers = { }
+local parser = unicode + ucode + index
+local parsers = { }
local function makenameparser(str)
if not str or str == "" then
@@ -75,82 +54,24 @@ local function makenameparser(str)
end
end
-local f_single = formatters["%04X"]
-local f_double = formatters["%04X%04X"]
-
--- floor(x/256) => rshift(x, 8)
--- floor(x/1024) => rshift(x,10)
-
--- 0.684 0.661 0,672 0.650 : cache at lua end (more mem)
--- 0.682 0,672 0.698 0.657 : no cache (moderate mem i.e. lua strings)
--- 0.644 0.647 0.655 0.645 : convert in c (less mem in theory)
-
--- local tounicodes = table.setmetatableindex(function(t,unicode)
--- local s
--- if unicode < 0xD7FF or (unicode > 0xDFFF and unicode <= 0xFFFF) then
--- s = f_single(unicode)
--- else
--- unicode = unicode - 0x10000
--- s = f_double(rshift(unicode,10)+0xD800,unicode%1024+0xDC00)
--- end
--- t[unicode] = s
--- return s
--- end)
---
--- local function tounicode16(unicode,name)
--- local s = tounicodes[unicode]
--- if s then
--- return s
--- else
--- report_fonts("can't convert %a in %a into tounicode",unicode,name)
--- end
--- end
---
--- local function tounicode16sequence(unicodes,name)
--- local t = { }
--- for l=1,#unicodes do
--- local u = unicodes[l]
--- local s = tounicodes[u]
--- if s then
--- t[l] = s
--- else
--- report_fonts ("can't convert %a in %a into tounicode",u,name)
--- return
--- end
--- end
--- return concat(t)
--- end
---
--- local function tounicode(unicode,name)
--- if type(unicode) == "table" then
--- local t = { }
--- for l=1,#unicode do
--- local u = unicode[l]
--- local s = tounicodes[u]
--- if s then
--- t[l] = s
--- else
--- report_fonts ("can't convert %a in %a into tounicode",u,name)
--- return
--- end
--- end
--- return concat(t)
--- else
--- local s = tounicodes[unicode]
--- if s then
--- return s
--- else
--- report_fonts("can't convert %a in %a into tounicode",unicode,name)
--- end
--- end
--- end
+local f_single = formatters["%04X"]
+local f_double = formatters["%04X%04X"]
+local s_unknown = "FFFD"
local function tounicode16(unicode)
if unicode < 0xD7FF or (unicode > 0xDFFF and unicode <= 0xFFFF) then
return f_single(unicode)
+ elseif unicode >= 0x00E000 and unicode <= 0x00F8FF then
+ return s_unknown
+ elseif unicode >= 0x0F0000 and unicode <= 0x0FFFFF then
+ return s_unknown
+ elseif unicode >= 0x100000 and unicode <= 0x10FFFF then
+ return s_unknown
+ elseif unicode >= 0x00D800 and unicode <= 0x00DFFF then
+ return s_unknown
else
unicode = unicode - 0x10000
- return f_double(rshift(unicode,10)+0xD800,unicode%1024+0xDC00)
+ return f_double(idiv(k,0x400)+0xD800,unicode%0x400+0xDC00)
end
end
@@ -160,132 +81,33 @@ local function tounicode16sequence(unicodes)
local u = unicodes[l]
if u < 0xD7FF or (u > 0xDFFF and u <= 0xFFFF) then
t[l] = f_single(u)
+ elseif unicode >= 0x00E000 and unicode <= 0x00F8FF then
+ t[l] = s_unknown
+ elseif unicode >= 0x0F0000 and unicode <= 0x0FFFFF then
+ t[l] = s_unknown
+ elseif unicode >= 0x100000 and unicode <= 0x10FFFF then
+ t[l] = s_unknown
+ -- elseif unicode >= 0x00D800 and unicode <= 0x00DFFF then
+ elseif unicode >= 0x00D7FF and unicode <= 0x00DFFF then
+ t[l] = s_unknown
else
u = u - 0x10000
- t[l] = f_double(rshift(u,10)+0xD800,u%1024+0xDC00)
+ t[l] = f_double(idiv(k,0x400)+0xD800,u%0x400+0xDC00)
end
end
return concat(t)
end
--- local function tounicode(unicode)
--- if type(unicode) == "table" then
--- local t = { }
--- for l=1,#unicode do
--- local u = unicode[l]
--- if u < 0xD7FF or (u > 0xDFFF and u <= 0xFFFF) then
--- t[l] = f_single(u)
--- else
--- u = u - 0x10000
--- t[l] = f_double(rshift(u,10)+0xD800,u%1024+0xDC00)
--- end
--- end
--- return concat(t)
--- else
--- if unicode < 0xD7FF or (unicode > 0xDFFF and unicode <= 0xFFFF) then
--- return f_single(unicode)
--- else
--- unicode = unicode - 0x10000
--- return f_double(rshift(unicode,10)+0xD800,unicode%1024+0xDC00)
--- end
--- end
--- end
-
-local unknown = f_single(0xFFFD)
-
--- local function tounicode(unicode)
--- if type(unicode) == "table" then
--- local t = { }
--- for l=1,#unicode do
--- t[l] = tounicode(unicode[l])
--- end
--- return concat(t)
--- elseif unicode >= 0x00E000 and unicode <= 0x00F8FF then
--- return unknown
--- elseif unicode >= 0x0F0000 and unicode <= 0x0FFFFF then
--- return unknown
--- elseif unicode >= 0x100000 and unicode <= 0x10FFFF then
--- return unknown
--- elseif unicode < 0xD7FF or (unicode > 0xDFFF and unicode <= 0xFFFF) then
--- return f_single(unicode)
--- else
--- unicode = unicode - 0x10000
--- return f_double(rshift(unicode,10)+0xD800,unicode%1024+0xDC00)
--- end
--- end
-
--- local hash = table.setmetatableindex(function(t,k)
--- local v
--- if k >= 0x00E000 and k <= 0x00F8FF then
--- v = unknown
--- elseif k >= 0x0F0000 and k <= 0x0FFFFF then
--- v = unknown
--- elseif k >= 0x100000 and k <= 0x10FFFF then
--- v = unknown
--- elseif k < 0xD7FF or (k > 0xDFFF and k <= 0xFFFF) then
--- v = f_single(k)
--- else
--- local k = k - 0x10000
--- v = f_double(rshift(k,10)+0xD800,k%1024+0xDC00)
--- end
--- t[k] = v
--- return v
--- end)
---
--- table.makeweak(hash)
---
--- local function tounicode(unicode)
--- if type(unicode) == "table" then
--- local t = { }
--- for l=1,#unicode do
--- t[l] = hash[unicode[l]]
--- end
--- return concat(t)
--- else
--- return hash[unicode]
--- end
--- end
local hash = { }
local conc = { }
--- table.makeweak(hash)
-
--- table.setmetatableindex(hash,function(t,k)
--- if type(k) == "table" then
--- local n = #k
--- for l=1,n do
--- conc[l] = hash[k[l]]
--- end
--- return concat(conc,"",1,n)
--- end
--- local v
--- if k >= 0x00E000 and k <= 0x00F8FF then
--- v = unknown
--- elseif k >= 0x0F0000 and k <= 0x0FFFFF then
--- v = unknown
--- elseif k >= 0x100000 and k <= 0x10FFFF then
--- v = unknown
--- elseif k < 0xD7FF or (k > 0xDFFF and k <= 0xFFFF) then
--- v = f_single(k)
--- else
--- local k = k - 0x10000
--- v = f_double(rshift(k,10)+0xD800,k%1024+0xDC00)
--- end
--- t[k] = v
--- return v
--- end)
---
--- local function tounicode(unicode)
--- return hash[unicode]
--- end
-
table.setmetatableindex(hash,function(t,k)
if k < 0xD7FF or (k > 0xDFFF and k <= 0xFFFF) then
v = f_single(k)
else
local k = k - 0x10000
- v = f_double(rshift(k,10)+0xD800,k%1024+0xDC00)
+ v = f_double(idiv(k,0x400)+0xD800,k%0x400+0xDC00)
end
t[k] = v
return v
@@ -299,11 +121,14 @@ local function tounicode(k)
end
return concat(conc,"",1,n)
elseif k >= 0x00E000 and k <= 0x00F8FF then
- return unknown
+ return s_unknown
elseif k >= 0x0F0000 and k <= 0x0FFFFF then
- return unknown
+ return s_unknown
elseif k >= 0x100000 and k <= 0x10FFFF then
- return unknown
+ return s_unknown
+ -- elseif k >= 0x00D800 and k <= 0x00DFFF then
+ elseif k >= 0x00D7FF and k <= 0x00DFFF then
+ return s_unknown
else
return hash[k]
end
@@ -314,7 +139,6 @@ local function fromunicode16(str)
return tonumber(str,16)
else
local l, r = match(str,"(....)(....)")
- -- return (tonumber(l,16))*0x400 + tonumber(r,16) - 0xDC00
return 0x10000 + (tonumber(l,16)-0xD800)*0x400 + tonumber(r,16) - 0xDC00
end
end
diff --git a/macros/luatex/generic/luaotfload/fontloader-font-ocl.lua b/macros/luatex/generic/luaotfload/fontloader-font-ocl.lua
index 77e1538f94..1890e5ec54 100644
--- a/macros/luatex/generic/luaotfload/fontloader-font-ocl.lua
+++ b/macros/luatex/generic/luaotfload/fontloader-font-ocl.lua
@@ -49,6 +49,10 @@ if context then
else
+ -- Actually we don't need a generic branch at all because (according the the
+ -- internet) other macro packages rely on hb for emoji etc and never used this
+ -- feature of the font loader. So maybe I should just remove this from generic.
+
local tounicode = fonts.mappings.tounicode16
function otf.getactualtext(s)
@@ -401,7 +405,7 @@ local function pdftovirtual(tfmdata,pdfshapes,kind) -- kind = png|svg
-- The down and right will change too (we can move that elsewhere). We have
-- a different treatment in lmtx but the next kind of works. These images are
-- a mess anyway as in svg the bbox can be messed up absent). A png image
- -- needs the x/y. I might normalize this once we moev to lmtx exlusively.
+ -- needs the x/y. I might normalize this once we move to lmtx exlusively.
character.commands = {
not unicode and actualb or { "pdf", "page", (getactualtext(unicode)) },
-- lmtx (when we deal with depth in vfimage, currently disabled):
diff --git a/macros/luatex/generic/luaotfload/fontloader-font-osd.lua b/macros/luatex/generic/luaotfload/fontloader-font-osd.lua
index b97ac9c6f5..87453d9e2d 100644
--- a/macros/luatex/generic/luaotfload/fontloader-font-osd.lua
+++ b/macros/luatex/generic/luaotfload/fontloader-font-osd.lua
@@ -113,6 +113,8 @@ local setprev = nuts.setprev
local setchar = nuts.setchar
local getprop = nuts.getprop
local setprop = nuts.setprop
+local getstate = nuts.getstate
+local setstate = nuts.setstate
local ischar = nuts.ischar
@@ -128,7 +130,6 @@ local unsetvalue = attributes.unsetvalue
local fontdata = fonts.hashes.identifiers
-local a_state = attributes.private('state')
local a_syllabe = attributes.private('syllabe')
local dotted_circle = 0x25CC
@@ -958,7 +959,7 @@ local function reorder_one(head,start,stop,font,attr,nbspaces)
current = start
else
current = getnext(n)
- setprop(start,a_state,s_rphf)
+ setstate(start,s_rphf)
end
end
@@ -993,9 +994,9 @@ local function reorder_one(head,start,stop,font,attr,nbspaces)
local nextcurrent = copy_node(current)
copyinjection(nextcurrent,current) -- KE: necessary? HH: probably not as positioning comes later and we rawget/set
setlink(tempcurrent,nextcurrent)
- setprop(tempcurrent,a_state,s_blwf)
+ setstate(tempcurrent,s_blwf)
tempcurrent = processcharacters(tempcurrent,font)
- setprop(tempcurrent,a_state,unsetvalue)
+ setstate(tempcurrent,unsetvalue)
if getchar(next) == getchar(tempcurrent) then
flush_list(tempcurrent)
if show_syntax_errors then
@@ -1021,7 +1022,7 @@ local function reorder_one(head,start,stop,font,attr,nbspaces)
-- find base consonant
local char = getchar(current)
if consonant[char] then
- setprop(current,a_state,s_half)
+ setstate(current,s_half)
if not firstcons then
firstcons = current
end
@@ -1030,10 +1031,10 @@ local function reorder_one(head,start,stop,font,attr,nbspaces)
base = current
elseif blwfcache[char] then
-- consonant has below-base form
- setprop(current,a_state,s_blwf)
+ setstate(current,s_blwf)
elseif pstfcache[char] then
-- consonant has post-base form
- setprop(current,a_state,s_pstf)
+ setstate(current,s_pstf)
else
base = current
end
@@ -1107,15 +1108,15 @@ local function reorder_one(head,start,stop,font,attr,nbspaces)
while current ~= stop do
local next = getnext(current)
if next ~= stop and halant[getchar(next)] and getchar(getnext(next)) == c_zwnj then
- setprop(current,a_state,unsetvalue)
+ setstate(current,unsetvalue)
end
current = next
end
- if base ~= stop and getprop(base,a_state) then -- a_state can also be init
+ if base ~= stop and getstate(base) then -- state can also be init
local next = getnext(base)
if halant[getchar(next)] and not (next ~= stop and getchar(getnext(next)) == c_zwj) then
- setprop(base,a_state,unsetvalue)
+ setstate(base,unsetvalue)
end
end
@@ -1261,7 +1262,7 @@ local function reorder_one(head,start,stop,font,attr,nbspaces)
end
bn = next
end
- if getprop(current,a_state) == s_rphf then
+ 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
if b ~= current then
@@ -1357,7 +1358,7 @@ function handlers.devanagari_reorder_matras(head,start) -- no leak
local char = ischar(current,startfont)
local next = getnext(current)
if char and getprop(current,a_syllabe) == startattr then
- if halant[char] then -- a_state can also be init
+ if halant[char] then -- state can also be init
if next then
local char = ischar(next,startfont)
if char and zw_char[char] and getprop(next,a_syllabe) == startattr then
@@ -1373,7 +1374,7 @@ function handlers.devanagari_reorder_matras(head,start) -- no leak
-- setlink(current,start,next) -- maybe
start = startnext
break
- -- elseif consonant[char] and ( not getprop(current,a_state) or getprop(current,a_state) == s_init) then
+ -- elseif consonant[char] and (not getstate(current) or getstate(current,s_init) then
-- startnext = getnext(start)
-- head = remove_node(head,start)
-- if current == head then
@@ -1473,7 +1474,7 @@ function handlers.devanagari_reorder_reph(head,start)
while current do
local char = ischar(current,startfont)
if char and getprop(current,a_syllabe) == startattr then
- if consonant[char] and not getprop(current,a_state) == s_pref then
+ if consonant[char] and not getstate(current,s_pref) then
startnext = getnext(start)
head = remove_node(head,start)
setlink(current,start)
@@ -1504,7 +1505,7 @@ function handlers.devanagari_reorder_reph(head,start)
while current do
local char = ischar(current,startfont)
if char and getprop(current,a_syllabe) == startattr then
- if getprop(current,a_state) == s_pstf then -- post-base
+ if getstate(current,s_pstf) then -- post-base
startnext = getnext(start)
head = remove_node(head,start)
setlink(getprev(current),start)
@@ -1547,7 +1548,7 @@ function handlers.devanagari_reorder_reph(head,start)
while current do
local char = ischar(current,startfont)
if char and getprop(current,a_syllabe) == startattr then
- local state = getprop(current,a_state)
+ local state = getstate(current)
if before_subscript[rephbase] and (state == s_blwf or state == s_pstf) then
c = current
elseif after_subscript[rephbase] and (state == s_pstf) then
@@ -1628,7 +1629,7 @@ function handlers.devanagari_reorder_pre_base_reordering_consonants(head,start)
local char = ischar(current,startfont)
local next = getnext(current)
if char and getprop(current,a_syllabe) == startattr then
- if halant[char] then -- a_state can also be init
+ if halant[char] then -- state can also be init
if next then
local char = ischar(next,startfont)
if char and zw_char[char] and getprop(next,a_syllabe) == startattr then
@@ -1645,7 +1646,7 @@ function handlers.devanagari_reorder_pre_base_reordering_consonants(head,start)
reordered_pre_base_reordering_consonants[start] = true
start = startnext
return head, start, true
- -- elseif consonant[char] and ( not getprop(current,a_state) or getprop(current,a_state) == s_init) then
+ -- elseif consonant[char] and (not getstate(current) or getstate(current,s_init)) then
-- startnext = getnext(start)
-- head = remove_node(head,start)
-- if current == head then
@@ -1668,7 +1669,7 @@ function handlers.devanagari_reorder_pre_base_reordering_consonants(head,start)
local current = getprev(start)
while current and getprop(current,a_syllabe) == startattr do
local char = ischar(current)
- if ( not dependent_vowel[char] and not getprop(current,a_state) or getprop(current,a_state) == s_init) then
+ if (not dependent_vowel[char] and (not getstate(current) or getstate(current,s_init))) then
startnext = getnext(start)
head = remove_node(head,start)
if current == head then
@@ -1764,7 +1765,7 @@ local function reorder_two(head,start,stop,font,attr,nbspaces) -- maybe do a pas
if afternext and zw_char[getchar(afternext)] then -- ZWJ and ZWNJ prevent creation of reph
current = afternext -- getnext(next)
elseif current == start then
- setprop(current,a_state,s_rphf)
+ setstate(current,s_rphf)
current = next
else
current = next
@@ -1784,9 +1785,9 @@ local function reorder_two(head,start,stop,font,attr,nbspaces) -- maybe do a pas
if found then -- pre-base: pref Halant + Consonant
local next = getnext(current)
if found[getchar(next)] or contextchain(found, next) then
- if (not getprop(current,a_state) and not getprop(next,a_state)) then --KE: a_state can also be init...
- setprop(current,a_state,s_pref)
- setprop(next,a_state,s_pref)
+ if (not getstate(current) and not getstate(next)) then --KE: state can also be init...
+ setstate(current,s_pref)
+ setstate(next,s_pref)
current = next
end
end
@@ -1806,8 +1807,8 @@ local function reorder_two(head,start,stop,font,attr,nbspaces) -- maybe do a pas
if found[getchar(next)] or contextchain(found, next) then
if next ~= stop and getchar(getnext(next)) == c_zwnj then -- zwnj prevent creation of half
current = next
- elseif (not getprop(current,a_state)) then --KE: a_state can also be init...
- setprop(current,a_state,s_half)
+ elseif (not getstate(current)) then --KE: state can also be init...
+ setstate(current,s_half)
if not halfpos then
halfpos = current
end
@@ -1828,9 +1829,9 @@ local function reorder_two(head,start,stop,font,attr,nbspaces) -- maybe do a pas
if found then
local next = getnext(current)
if found[getchar(next)] or contextchain(found, next) then
- if (not getprop(current,a_state) and not getprop(next,a_state)) then --KE: a_state can also be init...
- setprop(current,a_state,s_blwf)
- setprop(next,a_state,s_blwf)
+ if (not getstate(current) and not getstate(next)) then --KE: state can also be init...
+ setstate(current,s_blwf)
+ setstate(next,s_blwf)
current = next
subpos = current
end
@@ -1849,9 +1850,9 @@ local function reorder_two(head,start,stop,font,attr,nbspaces) -- maybe do a pas
if found then
local next = getnext(current)
if found[getchar(next)] or contextchain(found, next) then
- if (not getprop(current,a_state) and not getprop(next,a_state)) then --KE: a_state can also be init...
- setprop(current,a_state,s_pstf)
- setprop(next,a_state,s_pstf)
+ if (not getstate(current) and not getstate(next)) then -- KE: state can also be init...
+ setstate(current,s_pstf)
+ setstate(next,s_pstf)
current = next
postpos = current
end
@@ -1865,7 +1866,7 @@ local function reorder_two(head,start,stop,font,attr,nbspaces) -- maybe do a pas
local current, base, firstcons = start, nil, nil
- if getprop(start,a_state) == s_rphf then
+ if getstate(start,s_rphf) then
-- if syllable starts with Ra + H and script has 'Reph' then exclude Reph from candidates for base consonants
current = getnext(getnext(start))
end
@@ -1895,13 +1896,13 @@ local function reorder_two(head,start,stop,font,attr,nbspaces) -- maybe do a pas
local tmp = getnext(next)
local changestop = next == stop
setnext(next)
- setprop(current,a_state,s_pref)
+ setstate(current,s_pref)
current = processcharacters(current,font)
- setprop(current,a_state,s_blwf)
+ setstate(current,s_blwf)
current = processcharacters(current,font)
- setprop(current,a_state,s_pstf)
+ setstate(current,s_pstf)
current = processcharacters(current,font)
- setprop(current,a_state,unsetvalue)
+ setstate(current,unsetvalue)
if halant[getchar(current)] then
setnext(getnext(current),tmp)
if show_syntax_errors then
@@ -1927,7 +1928,7 @@ local function reorder_two(head,start,stop,font,attr,nbspaces) -- maybe do a pas
firstcons = current
end
-- check whether consonant has below-base or post-base form or is pre-base reordering Ra
- local a = getprop(current,a_state)
+ 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
end
@@ -1941,13 +1942,13 @@ local function reorder_two(head,start,stop,font,attr,nbspaces) -- maybe do a pas
end
if not base then
- if getprop(start,a_state) == s_rphf then
- setprop(start,a_state,unsetvalue)
+ if getstate(start,s_rphf) then
+ setstate(start,unsetvalue)
end
return head, stop, nbspaces
else
- if getprop(base,a_state) then -- a_state can also be init
- setprop(base,a_state,unsetvalue)
+ if getstate(base) then -- state can also be init
+ setstate(base,unsetvalue)
end
basepos = base
end
@@ -2004,7 +2005,7 @@ local function reorder_two(head,start,stop,font,attr,nbspaces) -- maybe do a pas
local ppos = getprev(pos) -- necessary?
while ppos and getprop(ppos,a_syllabe) == getprop(pos,a_syllabe) do
- if getprop(ppos,a_state) == s_pref then
+ if getstate(ppos,s_pref) then
pos = ppos
end
ppos = getprev(ppos)
@@ -2086,7 +2087,7 @@ local function reorder_two(head,start,stop,font,attr,nbspaces) -- maybe do a pas
while current ~= last do
local char = getchar(current)
local cn = getnext(current)
- if halant[char] and ra[ischar(cn)] and getprop(cn,a_state) ~= s_rphf and getprop(cn,a_state) ~= s_blwf then
+ if halant[char] and ra[ischar(cn)] and (not getstate(cn,s_rphf)) and (not getstate(cn,s_blwf)) then
if after_main[ischar(cn)] then
local prev = getprev(current)
local next = getnext(cn)
@@ -2730,8 +2731,8 @@ local function method_one(head,font,attr)
while current do
local char = ischar(current,font)
if char then
- if n == 0 and not getprop(current,a_state) then
- setprop(current,a_state,s_init)
+ if n == 0 and not getstate(current) then
+ setstate(current,s_init)
end
n = n + 1
else
@@ -2820,7 +2821,7 @@ local function method_two(head,font,attr)
end
if not syllableend and show_syntax_errors then
local char = ischar(current,font)
- if char and not getprop(current,a_state) then -- a_state can also be init
+ if char and not getstate(current) then -- state can also be init
local mark = mark_four[char]
if mark then
head, current = inject_syntax_error(head,current,char)
@@ -2840,8 +2841,8 @@ local function method_two(head,font,attr)
while current do
local char = ischar(current,font)
if char then
- if n == 0 and not getprop(current,a_state) then -- a_state can also be init
- setprop(current,a_state,s_init)
+ if n == 0 and not getstate(current) then -- state can also be init
+ setstate(current,s_init)
end
n = n + 1
else
diff --git a/macros/luatex/generic/luaotfload/fontloader-font-ota.lua b/macros/luatex/generic/luaotfload/fontloader-font-ota.lua
index 3d217b3f4d..6cbf4bb86f 100644
--- a/macros/luatex/generic/luaotfload/fontloader-font-ota.lua
+++ b/macros/luatex/generic/luaotfload/fontloader-font-ota.lua
@@ -27,8 +27,6 @@ local methods = allocate()
analyzers.initializers = initializers
analyzers.methods = methods
-local a_state = attributes.private('state')
-
local nuts = nodes.nuts
local tonut = nuts.tonut
@@ -60,6 +58,26 @@ local registerotffeature = otffeatures.register
process features right.</p>
--ldx]]--
+local setstate = nuts.setstate
+local getstate = nuts.getstate
+
+if not setstate or not getstate then
+ -- generic (might move to the nod lib)
+ setstate = function(n,v)
+ setprop(n,"state",v)
+ end
+ getstate = function(n,v)
+ local s = getprop(n,"state")
+ if v then
+ return s == v
+ else
+ return s
+ end
+ end
+ nuts.setstate = setstate
+ nuts.getstate = getstate
+end
+
-- never use these numbers directly
local s_init = 1 local s_rphf = 7
@@ -120,37 +138,37 @@ function analyzers.setstate(head,font)
current = tonut(current)
while current do
local char, id = ischar(current,font)
- if char and not getprop(current,a_state) then
+ if char and not getstate(current) then
done = true
local d = descriptions[char]
if d then
if d.class == "mark" then
done = true
- setprop(current,a_state,s_mark)
+ setstate(current,s_mark)
elseif useunicodemarks and categories[char] == "mn" then
done = true
- setprop(current,a_state,s_mark)
+ setstate(current,s_mark)
elseif n == 0 then
first, last, n = current, current, 1
- setprop(current,a_state,s_init)
+ setstate(current,s_init)
else
last, n = current, n+1
- setprop(current,a_state,s_medi)
+ setstate(current,s_medi)
end
else -- finish
if first and first == last then
- setprop(last,a_state,s_isol)
+ setstate(last,s_isol)
elseif last then
- setprop(last,a_state,s_fina)
+ setstate(last,s_fina)
end
first, last, n = nil, nil, 0
end
elseif char == false then
-- other font
if first and first == last then
- setprop(last,a_state,s_isol)
+ setstate(last,s_isol)
elseif last then
- setprop(last,a_state,s_fina)
+ setstate(last,s_fina)
end
first, last, n = nil, nil, 0
if id == math_code then
@@ -160,13 +178,13 @@ function analyzers.setstate(head,font)
-- always in the middle .. it doesn't make much sense to assign a property
-- here ... we might at some point decide to flag the components when present
-- but even then it's kind of bogus
- setprop(current,a_state,s_medi)
+ setstate(current,s_medi)
last = current
else -- finish
if first and first == last then
- setprop(last,a_state,s_isol)
+ setstate(last,s_isol)
elseif last then
- setprop(last,a_state,s_fina)
+ setstate(last,s_fina)
end
first, last, n = nil, nil, 0
if id == math_code then
@@ -176,9 +194,9 @@ function analyzers.setstate(head,font)
current = getnext(current)
end
if first and first == last then
- setprop(last,a_state,s_isol)
+ setstate(last,s_isol)
elseif last then
- setprop(last,a_state,s_fina)
+ setstate(last,s_fina)
end
return head, done
end
@@ -308,91 +326,91 @@ function methods.arab(head,font,attr)
current = tonut(current)
while current do
local char, id = ischar(current,font)
- if char and not getprop(current,a_state) then
+ if char and not getstate(current) then
done = true
local classifier = classifiers[char]
if not classifier then
if last then
if c_last == s_medi or c_last == s_fina then
- setprop(last,a_state,s_fina)
+ setstate(last,s_fina)
else
warning(last,"fina")
- setprop(last,a_state,s_error)
+ setstate(last,s_error)
end
first, last = nil, nil
elseif first then
if c_first == s_medi or c_first == s_fina then
- setprop(first,a_state,s_isol)
+ setstate(first,s_isol)
else
warning(first,"isol")
- setprop(first,a_state,s_error)
+ setstate(first,s_error)
end
first = nil
end
elseif classifier == s_mark then
- setprop(current,a_state,s_mark)
+ setstate(current,s_mark)
elseif classifier == s_isol then
if last then
if c_last == s_medi or c_last == s_fina then
- setprop(last,a_state,s_fina)
+ setstate(last,s_fina)
else
warning(last,"fina")
- setprop(last,a_state,s_error)
+ setstate(last,s_error)
end
first, last = nil, nil
elseif first then
if c_first == s_medi or c_first == s_fina then
- setprop(first,a_state,s_isol)
+ setstate(first,s_isol)
else
warning(first,"isol")
- setprop(first,a_state,s_error)
+ setstate(first,s_error)
end
first = nil
end
- setprop(current,a_state,s_isol)
+ setstate(current,s_isol)
elseif classifier == s_medi then
if first then
last = current
c_last = classifier
- setprop(current,a_state,s_medi)
+ setstate(current,s_medi)
else
- setprop(current,a_state,s_init)
+ setstate(current,s_init)
first = current
c_first = classifier
end
elseif classifier == s_fina then
if last then
- if getprop(last,a_state) ~= s_init then
- setprop(last,a_state,s_medi)
+ if getstate(last) ~= s_init then
+ setstate(last,s_medi)
end
- setprop(current,a_state,s_fina)
+ setstate(current,s_fina)
first, last = nil, nil
elseif first then
- -- if getprop(first,a_state) ~= s_init then
+ -- if getstate(first) ~= s_init then
-- -- needs checking
- -- setprop(first,a_state,s_medi)
+ -- setstate(first,s_medi)
-- end
- setprop(current,a_state,s_fina)
+ setstate(current,s_fina)
first = nil
else
- setprop(current,a_state,s_isol)
+ setstate(current,s_isol)
end
else -- classifier == s_rest
- setprop(current,a_state,s_rest)
+ setstate(current,s_rest)
if last then
if c_last == s_medi or c_last == s_fina then
- setprop(last,a_state,s_fina)
+ setstate(last,s_fina)
else
warning(last,"fina")
- setprop(last,a_state,s_error)
+ setstate(last,s_error)
end
first, last = nil, nil
elseif first then
if c_first == s_medi or c_first == s_fina then
- setprop(first,a_state,s_isol)
+ setstate(first,s_isol)
else
warning(first,"isol")
- setprop(first,a_state,s_error)
+ setstate(first,s_error)
end
first = nil
end
@@ -400,18 +418,18 @@ function methods.arab(head,font,attr)
else
if last then
if c_last == s_medi or c_last == s_fina then
- setprop(last,a_state,s_fina)
+ setstate(last,s_fina)
else
warning(last,"fina")
- setprop(last,a_state,s_error)
+ setstate(last,s_error)
end
first, last = nil, nil
elseif first then
if c_first == s_medi or c_first == s_fina then
- setprop(first,a_state,s_isol)
+ setstate(first,s_isol)
else
warning(first,"isol")
- setprop(first,a_state,s_error)
+ setstate(first,s_error)
end
first = nil
end
@@ -423,17 +441,17 @@ function methods.arab(head,font,attr)
end
if last then
if c_last == s_medi or c_last == s_fina then
- setprop(last,a_state,s_fina)
+ setstate(last,s_fina)
else
warning(last,"fina")
- setprop(last,a_state,s_error)
+ setstate(last,s_error)
end
elseif first then
if c_first == s_medi or c_first == s_fina then
- setprop(first,a_state,s_isol)
+ setstate(first,s_isol)
else
warning(first,"isol")
- setprop(first,a_state,s_error)
+ setstate(first,s_error)
end
end
return head, done
diff --git a/macros/luatex/generic/luaotfload/fontloader-font-otj.lua b/macros/luatex/generic/luaotfload/fontloader-font-otj.lua
index 2e7878d3df..bec52d813f 100644
--- a/macros/luatex/generic/luaotfload/fontloader-font-otj.lua
+++ b/macros/luatex/generic/luaotfload/fontloader-font-otj.lua
@@ -110,7 +110,7 @@ local properties = nodes.properties.data
local fontkern = nuts.pool and nuts.pool.fontkern -- context
local italickern = nuts.pool and nuts.pool.italickern -- context
-local useitalickerns = false
+local useitalickerns = false -- context only
directives.register("fonts.injections.useitalics", function(v)
if v then
@@ -119,7 +119,7 @@ directives.register("fonts.injections.useitalics", function(v)
useitalickerns = v
end)
-do if not fontkern then -- generic
+if not fontkern then -- generic
local thekern = nuts.new("kern",0) -- fontkern
local setkern = nuts.setkern
@@ -131,9 +131,9 @@ do if not fontkern then -- generic
return n
end
-end end
+end
-do if not italickern then -- generic
+if not italickern then -- generic
local thekern = nuts.new("kern",3) -- italiccorrection
local setkern = nuts.setkern
@@ -145,7 +145,7 @@ do if not italickern then -- generic
return n
end
-end end
+end
function injections.installnewkern() end -- obsolete
@@ -664,7 +664,15 @@ local function inject_kerns_only(head,where)
-- left|glyph|right
local leftkern = i.leftkern
if leftkern and leftkern ~= 0 then
- head = insert_node_before(head,current,fontkern(leftkern))
+ if prev and getid(prev) == glue_code then
+ if useitalickerns then
+ head = insert_node_before(head,current,italickern(leftkern))
+ else
+ setwidth(prev, getwidth(prev) + leftkern)
+ end
+ else
+ head = insert_node_before(head,current,fontkern(leftkern))
+ end
end
end
if prevdisc then
@@ -819,12 +827,26 @@ local function inject_positions_only(head,where)
if rightkern and leftkern == -rightkern then
setoffsets(current,leftkern,false)
rightkern = 0
+ elseif prev and getid(prev) == glue_code then
+ if useitalickerns then
+ head = insert_node_before(head,current,italickern(leftkern))
+ else
+ setwidth(prev, getwidth(prev) + leftkern)
+ end
else
head = insert_node_before(head,current,fontkern(leftkern))
end
end
if rightkern and rightkern ~= 0 then
- insert_node_after(head,current,fontkern(rightkern))
+ if next and getid(next) == glue_code then
+ if useitalickerns then
+ insert_node_after(head,current,italickern(rightkern))
+ else
+ setwidth(next, getwidth(next) + rightkern)
+ end
+ else
+ insert_node_after(head,current,fontkern(rightkern))
+ end
end
else
local i = p.emptyinjections
@@ -1270,12 +1292,26 @@ local function inject_everything(head,where)
if rightkern and leftkern == -rightkern then
setoffsets(current,leftkern,false)
rightkern = 0
+ elseif prev and getid(prev) == glue_code then
+ if useitalickerns then
+ head = insert_node_before(head,current,italickern(leftkern))
+ else
+ setwidth(prev, getwidth(prev) + leftkern)
+ end
else
head = insert_node_before(head,current,fontkern(leftkern))
end
end
if rightkern and rightkern ~= 0 then
- insert_node_after(head,current,fontkern(rightkern))
+ if next and getid(next) == glue_code then
+ if useitalickerns then
+ insert_node_after(head,current,italickern(rightkern))
+ else
+ setwidth(next, getwidth(next) + rightkern)
+ end
+ else
+ insert_node_after(head,current,fontkern(rightkern))
+ end
end
end
else
@@ -1518,7 +1554,7 @@ local function inject_everything(head,where)
end
--
if keepregisteredcounts then
- keepregisteredcounts = false
+ keepregisteredcounts = false
else
nofregisteredkerns = 0
nofregisteredpositions = 0
@@ -1707,16 +1743,18 @@ local function injectspaces(head)
if useitalickerns then
local new = rightkern * factor
if trace_spaces then
- report_spaces("%C [%p + %p]",nextchar,old,new)
+ report_spaces("[%p + %p] %C",old,new,nextchar)
end
insert_node_after(head,n,italickern(new))
else
local new = old + rightkern * factor
if trace_spaces then
- report_spaces("[%p -> %p] %C",nextchar,old,new)
+ report_spaces("[%p -> %p] %C",old,new,nextchar)
end
setwidth(n,new)
end
+ else
+ -- message
end
rightkern = false
end
@@ -1753,3 +1791,4 @@ function injections.handler(head,where)
return head
end
end
+
diff --git a/macros/luatex/generic/luaotfload/fontloader-font-otl.lua b/macros/luatex/generic/luaotfload/fontloader-font-otl.lua
index 5d3bd4230c..aff4cc8c8d 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.110 -- beware: also sync font-mis.lua and in mtx-fonts
+otf.version = 3.111 -- 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)
@@ -534,6 +534,9 @@ local converters = {
}
}
+-- We can get differences between daylight saving etc ... but it makes no sense to
+-- mess with trickery .. so be it when you use a different binary.
+
local function checkconversion(specification)
local filename = specification.filename
local converter = converters[lower(file.suffix(filename))]
diff --git a/macros/luatex/generic/luaotfload/fontloader-font-ots.lua b/macros/luatex/generic/luaotfload/fontloader-font-ots.lua
index c4f89c156b..3b6ea6a726 100644
--- a/macros/luatex/generic/luaotfload/fontloader-font-ots.lua
+++ b/macros/luatex/generic/luaotfload/fontloader-font-ots.lua
@@ -114,6 +114,14 @@ mechanisms. Both put some constraints on the code here.</p>
--
-- Todo: just (0=l2r and 1=r2l) or maybe (r2l = true)
+-- Experiments with returning the data with the ischar are positive for lmtx but
+-- have a performance hit on mkiv because there we need to wrap ischardata (pending
+-- extensions to luatex which is unlikely to happen for such an experiment because
+-- we then can't remove it). Actually it might make generic slightly faster. Also,
+-- there are some corner cases where a data check comes before a char fetch and
+-- we're talking of millions of calls there. At some point I might make a version
+-- for lmtx that does it slightly different anyway.
+
local type, next, tonumber = type, next, tonumber
local random = math.random
local formatters = string.formatters
@@ -184,8 +192,7 @@ local setprev = nuts.setprev
local getboth = nuts.getboth
local setboth = nuts.setboth
local getid = nuts.getid
-local getprop = nuts.getprop
-local setprop = nuts.setprop
+local getstate = nuts.getstate
local getsubtype = nuts.getsubtype
local setsubtype = nuts.setsubtype
local getchar = nuts.getchar
@@ -194,15 +201,26 @@ local getdisc = nuts.getdisc
local setdisc = nuts.setdisc
local getreplace = nuts.getreplace
local setlink = nuts.setlink
-local getcomponents = nuts.getcomponents -- the original one, not yet node-aux
-local setcomponents = nuts.setcomponents -- the original one, not yet node-aux
local getwidth = nuts.getwidth
local getattr = nuts.getattr
local getglyphdata = nuts.getglyphdata
+---------------------------------------------------------------------------------------
+
+-- Beware: In ConTeXt components no longer are real components. We only keep track of
+-- their positions because some complex ligatures might need that. For the moment we
+-- use an x_ prefix because for now generic follows the other approach.
+
+local copy_no_components = nuts.copy_no_components
+local copy_only_glyphs = nuts.copy_only_glyphs
+local count_components = nuts.count_components
+local set_components = nuts.set_components
+local get_components = nuts.get_components
+
+---------------------------------------------------------------------------------------
+
local ischar = nuts.ischar
-local isglyph = nuts.isglyph
local usesfont = nuts.uses_font
local insert_node_after = nuts.insert_after
@@ -237,7 +255,6 @@ local localpar_code = nodecodes.localpar
local discretionarydisc_code = disccodes.discretionary
local ligatureglyph_code = glyphcodes.ligature
-local a_state = attributes.private('state')
local a_noligature = attributes.private("noligature")
local injections = nodes.injections
@@ -450,32 +467,6 @@ local function appenddisc(disc,list)
setdisc(disc,pre,post,replace)
end
--- start is a mark and we need to keep that one
-
-local copy_no_components = nuts.copy_no_components
-local copy_only_glyphs = nuts.copy_only_glyphs
-
-local set_components = setcomponents
-local take_components = getcomponents
-
-local function count_components(start,marks)
- local char = isglyph(start)
- if char then
- if getsubtype(start) == ligatureglyph_code then
- local i = 0
- local components = getcomponents(start)
- while components do
- i = i + count_components(components,marks)
- components = getnext(components)
- end
- return i
- elseif not marks[char] then
- return 1
- end
- end
- return 0
-end
-
local function markstoligature(head,start,stop,char)
if start == stop and getchar(start) == char then
return head, start
@@ -531,7 +522,7 @@ local function toligature(head,start,stop,char,dataset,sequence,skiphash,discfou
setlink(prev,base,next)
if not discfound then
local deletemarks = not skiphash or hasmarks
- local components = start
+ local components = start -- not used
local baseindex = 0
local componentindex = 0
local head = base
@@ -542,19 +533,19 @@ local function toligature(head,start,stop,char,dataset,sequence,skiphash,discfou
if not marks[char] then
baseindex = baseindex + componentindex
componentindex = count_components(start,marks)
- -- we can be more clever here: "not deletemarks or (skiphash and not skiphash[char])"
- -- and such:
+ -- we can be more clever here: "not deletemarks or (skiphash and not skiphash[char])"
+ -- and such:
elseif not deletemarks then
-- we can get a loop when the font expects otherwise (i.e. unexpected deletemarks)
setligaindex(start,baseindex + getligaindex(start,componentindex))
if trace_marks then
- logwarning("%s: keep mark %s, gets index %s",pref(dataset,sequence),gref(char),getligaindex(start))
+ logwarning("%s: keep ligature mark %s, gets index %s",pref(dataset,sequence),gref(char),getligaindex(start))
end
local n = copy_node(start)
copyinjection(n,start) -- is this ok ? we position later anyway
head, current = insert_node_after(head,current,n) -- unlikely that mark has components
elseif trace_marks then
- logwarning("%s: delete mark %s",pref(dataset,sequence),gref(char))
+ logwarning("%s: delete ligature mark %s",pref(dataset,sequence),gref(char))
end
start = getnext(start)
end
@@ -567,7 +558,7 @@ local function toligature(head,start,stop,char,dataset,sequence,skiphash,discfou
if marks[char] then
setligaindex(start,baseindex + getligaindex(start,componentindex))
if trace_marks then
- logwarning("%s: set mark %s, gets index %s",pref(dataset,sequence),gref(char),getligaindex(start))
+ logwarning("%s: set ligature mark %s, gets index %s",pref(dataset,sequence),gref(char),getligaindex(start))
end
start = getnext(start)
else
@@ -586,18 +577,19 @@ local function toligature(head,start,stop,char,dataset,sequence,skiphash,discfou
-- anyway
local pre, post, replace, pretail, posttail, replacetail = getdisc(discfound,true)
if not replace then
+ -- looks like we never come here as it's not okay
local prev = getprev(base)
- local comp = take_components(base)
+ -- local comp = get_components(base) -- already set
local copied = copy_only_glyphs(comp)
if pre then
setlink(discprev,pre)
else
setnext(discprev) -- also blocks funny assignments
end
- pre = comp
+ pre = comp -- is start
if post then
setlink(posttail,discnext)
- setprev(post)
+ setprev(post) -- nil anyway
else
post = discnext
setprev(discnext) -- also blocks funny assignments
@@ -3179,7 +3171,7 @@ local function testrun(disc,t_run,c_run,...)
end
local pre, post, replace, pretail, posttail, replacetail = getdisc(disc,true)
local renewed = false
- if (post or replace) then -- and prev then -- hm, we can start with a disc
+ if post or replace then -- and prev then -- hm, we can start with a disc
if post then
setlink(posttail,next)
else
@@ -3287,28 +3279,6 @@ local function testrun(disc,t_run,c_run,...)
return getnext(disc), renewed
end
--- We can make some assumptions with respect to discretionaries. First of all it is very
--- unlikely that some of the analysis related attributes applies. Then we can also assume
--- that the ConTeXt specific dynamic attribute is different, although we do use explicit
--- discretionaries (maybe we need to tag those some day). So, at least for now, we don't
--- have the following test in the sub runs:
---
--- -- local a = getglyhpdata(start)
--- -- if a then
--- -- a = (a == attr) and (not attribute or getprop(start,a_state) == attribute)
--- -- else
--- -- a = not attribute or getprop(start,a_state) == attribute
--- -- end
--- -- if a then
---
--- but use this instead:
---
--- -- local a = getglyphdata(start)
--- -- if not a or (a == attr) then
---
--- and even that one is probably not needed. However, we can handle interesting
--- cases now:
---
-- 1{2{\oldstyle\discretionary{3}{4}{5}}6}7\par
-- 1{2\discretionary{3{\oldstyle3}}{{\oldstyle4}4}{5{\oldstyle5}5}6}7\par
@@ -3317,6 +3287,7 @@ local nesting = 0
local function c_run_single(head,font,attr,lookupcache,step,dataset,sequence,rlmode,skiphash,handler)
local done = false
local sweep = sweephead[head]
+ local start
if sweep then
start = sweep
-- sweephead[head] = nil
@@ -3420,7 +3391,7 @@ local function t_run_single(start,stop,font,attr,lookupcache)
ss = nil
end
end
-lookupmatch = lg
+ lookupmatch = lg
else
break
end
@@ -3431,14 +3402,14 @@ lookupmatch = lg
if l and l.ligature then -- so we test for ligature
lastd = d
end
--- why not: if not l then break elseif l.ligature then return d end
+ -- why not: if not l then break elseif l.ligature then return d end
else
--- why not: break
+ -- why not: break
-- no match (yet)
end
else
-- go on can be a mixed one
--- why not: break
+ -- why not: break
end
if lastd then
return lastd
@@ -3461,7 +3432,7 @@ local function k_run_single(sub,injection,last,font,attr,lookupcache,step,datase
if n == last then
break
end
- local char = ischar(n)
+ local char = ischar(n,font)
if char then
local lookupmatch = lookupcache[char]
if lookupmatch then
@@ -3478,6 +3449,7 @@ end
local function c_run_multiple(head,font,attr,steps,nofsteps,dataset,sequence,rlmode,skiphash,handler)
local done = false
local sweep = sweephead[head]
+ local start
if sweep then
start = sweep
-- sweephead[head] = nil
@@ -3590,7 +3562,7 @@ local function t_run_multiple(start,stop,font,attr,steps,nofsteps)
ss = nil
end
end
-lookupmatch = lg
+ lookupmatch = lg
else
break
end
@@ -3711,26 +3683,6 @@ otf.helpers.pardirstate = pardirstate
do
- -- reference:
- --
- -- local a = attr and getglyphdata(start)
- -- if a then
- -- a = (a == attr) and (not attribute or getprop(start,a_state) == attribute)
- -- else
- -- a = not attribute or getprop(start,a_state) == attribute
- -- end
- --
- -- used:
- --
- -- local a -- happens often so no assignment is faster
- -- if attr then
- -- if getglyphdata(start) == attr and (not attribute or getprop(start,a_state) == attribute) then
- -- a = true
- -- end
- -- elseif not attribute or getprop(start,a_state) == attribute then
- -- a = true
- -- end
-
-- This is a measurable experimental speedup (only with hyphenated text and multiple
-- fonts per processor call), especially for fonts with lots of contextual lookups.
@@ -3911,10 +3863,10 @@ do
if lookupmatch then
local a -- happens often so no assignment is faster
if attr then
- if getglyphdata(start) == attr and (not attribute or getprop(start,a_state) == attribute) then
+ if getglyphdata(start) == attr and (not attribute or getstate(start,attribute)) then
a = true
end
- elseif not attribute or getprop(start,a_state) == attribute then
+ elseif not attribute or getstate(start,attribute) then
a = true
end
if a then
@@ -3978,10 +3930,10 @@ do
if m then
local a -- happens often so no assignment is faster
if attr then
- if getglyphdata(start) == attr and (not attribute or getprop(start,a_state) == attribute) then
+ if getglyphdata(start) == attr and (not attribute or getstate(start,attribute)) then
a = true
end
- elseif not attribute or getprop(start,a_state) == attribute then
+ elseif not attribute or getstate(start,attribute) then
a = true
end
if a then
diff --git a/macros/luatex/generic/luaotfload/fontloader-font-oup.lua b/macros/luatex/generic/luaotfload/fontloader-font-oup.lua
index 0e7e25808c..2c49bc993f 100644
--- a/macros/luatex/generic/luaotfload/fontloader-font-oup.lua
+++ b/macros/luatex/generic/luaotfload/fontloader-font-oup.lua
@@ -1368,65 +1368,6 @@ function readers.pack(data)
end
end
- -- -- This was an experiment to see if we can bypass the luajit limits but loading is
- -- -- still an issue due to other limits so we don't use this ... actually it can
- -- -- prevent a luajittex crash but i don't care too much about that as we can't use
- -- -- that engine anyway then.
- --
- -- local function check(t)
- -- if type(t) == "table" then
- -- local s = sortedkeys(t)
- -- local n = #s
- -- if n <= 10 then
- -- return
- -- end
- -- local ranges = { }
- -- local first, last
- -- for i=1,#s do
- -- local ti = s[i]
- -- if not first then
- -- first = ti
- -- last = ti
- -- elseif ti == last + 1 then
- -- last = ti
- -- elseif last - first < 10 then
- -- -- we could permits a few exceptions
- -- return
- -- else
- -- ranges[#ranges+1] = { first, last }
- -- first, last = nil, nil
- -- end
- -- end
- -- if #ranges > 0 then
- -- return {
- -- ranges = ranges
- -- }
- -- end
- -- end
- -- end
- --
- -- local function pack_boolean(v)
- -- local tag
- -- local r = check(v)
- -- if r then
- -- v = r
- -- tag = tabstr_normal(v)
- -- else
- -- tag = tabstr_boolean(v)
- -- end
- -- local ht = h[tag]
- -- if ht then
- -- c[ht] = c[ht] + 1
- -- return ht
- -- else
- -- nt = nt + 1
- -- t[nt] = v
- -- h[tag] = nt
- -- c[nt] = 1
- -- return nt
- -- end
- -- end
-
local function pack_final(v)
-- v == number
if c[v] <= criterium then
diff --git a/macros/luatex/generic/luaotfload/fontloader-l-table.lua b/macros/luatex/generic/luaotfload/fontloader-l-table.lua
index 98b377bdc1..c20bd4733c 100644
--- a/macros/luatex/generic/luaotfload/fontloader-l-table.lua
+++ b/macros/luatex/generic/luaotfload/fontloader-l-table.lua
@@ -525,84 +525,15 @@ function table.fromhash(t)
return hsh
end
-local noquotes, hexify, handle, compact, inline, functions, metacheck
+local noquotes, hexify, handle, compact, inline, functions, metacheck, accurate
local reserved = table.tohash { -- intercept a language inconvenience: no reserved words as key
'and', 'break', 'do', 'else', 'elseif', 'end', 'false', 'for', 'function', 'if',
'in', 'local', 'nil', 'not', 'or', 'repeat', 'return', 'then', 'true', 'until', 'while',
- 'NaN', 'goto',
+ 'NaN', 'goto', 'const',
}
--- local function is_simple_table(t)
--- if #t > 0 then
--- local n = 0
--- for _,v in next, t do
--- n = n + 1
--- end
--- if n == #t then
--- local tt, nt = { }, 0
--- for i=1,#t do
--- local v = t[i]
--- local tv = type(v)
--- if tv == "number" then
--- nt = nt + 1
--- if hexify then
--- tt[nt] = format("0x%X",v)
--- else
--- tt[nt] = tostring(v) -- tostring not needed
--- end
--- elseif tv == "string" then
--- nt = nt + 1
--- tt[nt] = format("%q",v)
--- elseif tv == "boolean" then
--- nt = nt + 1
--- tt[nt] = v and "true" or "false"
--- else
--- return nil
--- end
--- end
--- return tt
--- end
--- end
--- return nil
--- end
-
--- local function is_simple_table(t)
--- local nt = #t
--- if nt > 0 then
--- local n = 0
--- for _,v in next, t do
--- n = n + 1
--- -- if type(v) == "table" then
--- -- return nil
--- -- end
--- end
--- if n == nt then
--- local tt = { }
--- for i=1,nt do
--- local v = t[i]
--- local tv = type(v)
--- if tv == "number" then
--- if hexify then
--- tt[i] = format("0x%X",v)
--- else
--- tt[i] = tostring(v) -- tostring not needed
--- end
--- elseif tv == "string" then
--- tt[i] = format("%q",v)
--- elseif tv == "boolean" then
--- tt[i] = v and "true" or "false"
--- else
--- return nil
--- end
--- end
--- return tt
--- end
--- end
--- return nil
--- end
-
-local function is_simple_table(t,hexify) -- also used in util-tab so maybe public
+local function is_simple_table(t,hexify,accurate) -- also used in util-tab so maybe public
local nt = #t
if nt > 0 then
local n = 0
@@ -623,6 +554,8 @@ local function is_simple_table(t,hexify) -- also used in util-tab so maybe publi
-- tt[i] = v -- not needed tostring(v)
if hexify then
tt[i] = format("0x%X",v)
+ elseif accurate then
+ tt[i] = format("%q",v)
else
tt[i] = v -- not needed tostring(v)
end
@@ -644,6 +577,8 @@ local function is_simple_table(t,hexify) -- also used in util-tab so maybe publi
-- tt[i+1] = v -- not needed tostring(v)
if hexify then
tt[i+1] = format("0x%X",v)
+ elseif accurate then
+ tt[i+1] = format("%q",v)
else
tt[i+1] = v -- not needed tostring(v)
end
@@ -738,6 +673,8 @@ local function do_serialize(root,name,depth,level,indexed)
if tv == "number" then
if hexify then
handle(format("%s 0x%X,",depth,v))
+ elseif accurate then
+ handle(format("%s %q,",depth,v))
else
handle(format("%s %s,",depth,v)) -- %.99g
end
@@ -747,7 +684,7 @@ local function do_serialize(root,name,depth,level,indexed)
if next(v) == nil then
handle(format("%s {},",depth))
elseif inline then -- and #t > 0
- local st = is_simple_table(v,hexify)
+ local st = is_simple_table(v,hexify,accurate)
if st then
handle(format("%s { %s },",depth,concat(st,", ")))
else
@@ -775,12 +712,16 @@ local function do_serialize(root,name,depth,level,indexed)
if tk == "number" then
if hexify then
handle(format("%s [0x%X]=0x%X,",depth,k,v))
+ elseif accurate then
+ handle(format("%s [%s]=%q,",depth,k,v))
else
handle(format("%s [%s]=%s,",depth,k,v)) -- %.99g
end
elseif tk == "boolean" then
if hexify then
handle(format("%s [%s]=0x%X,",depth,k and "true" or "false",v))
+ elseif 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)) -- %.99g
end
@@ -789,12 +730,16 @@ local function do_serialize(root,name,depth,level,indexed)
elseif noquotes and not reserved[k] and lpegmatch(propername,k) then
if hexify then
handle(format("%s %s=0x%X,",depth,k,v))
+ elseif accurate then
+ handle(format("%s %s=%q,",depth,k,v))
else
handle(format("%s %s=%s,",depth,k,v)) -- %.99g
end
else
if hexify then
handle(format("%s [%q]=0x%X,",depth,k,v))
+ elseif accurate then
+ handle(format("%s [%q]=%q,",depth,k,v))
else
handle(format("%s [%q]=%s,",depth,k,v)) -- %.99g
end
@@ -803,6 +748,8 @@ local function do_serialize(root,name,depth,level,indexed)
if tk == "number" then
if hexify then
handle(format("%s [0x%X]=%q,",depth,k,v))
+ elseif accurate then
+ handle(format("%s [%q]=%q,",depth,k,v))
else
handle(format("%s [%s]=%q,",depth,k,v))
end
@@ -820,6 +767,8 @@ local function do_serialize(root,name,depth,level,indexed)
if tk == "number" then
if hexify then
handle(format("%s [0x%X]={},",depth,k))
+ elseif accurate then
+ handle(format("%s [%q]={},",depth,k))
else
handle(format("%s [%s]={},",depth,k))
end
@@ -833,11 +782,13 @@ local function do_serialize(root,name,depth,level,indexed)
handle(format("%s [%q]={},",depth,k))
end
elseif inline then
- local st = is_simple_table(v,hexify)
+ local st = is_simple_table(v,hexify,accurate)
if st then
if tk == "number" then
if hexify then
handle(format("%s [0x%X]={ %s },",depth,k,concat(st,", ")))
+ elseif accurate then
+ handle(format("%s [%q]={ %s },",depth,k,concat(st,", ")))
else
handle(format("%s [%s]={ %s },",depth,k,concat(st,", ")))
end
@@ -860,6 +811,8 @@ local function do_serialize(root,name,depth,level,indexed)
if tk == "number" then
if hexify then
handle(format("%s [0x%X]=%s,",depth,k,v and "true" or "false"))
+ elseif accurate then
+ handle(format("%s [%q]=%s,",depth,k,v and "true" or "false"))
else
handle(format("%s [%s]=%s,",depth,k,v and "true" or "false"))
end
@@ -881,6 +834,8 @@ local function do_serialize(root,name,depth,level,indexed)
if tk == "number" then
if hexify then
handle(format("%s [0x%X]=load(%q),",depth,k,f))
+ elseif accurate then
+ handle(format("%s [%q]=load(%q),",depth,k,f))
else
handle(format("%s [%s]=load(%q),",depth,k,f))
end
@@ -899,6 +854,8 @@ local function do_serialize(root,name,depth,level,indexed)
if tk == "number" then
if hexify then
handle(format("%s [0x%X]=%q,",depth,k,tostring(v)))
+ elseif accurate then
+ handle(format("%s [%q]=%q,",depth,k,tostring(v)))
else
handle(format("%s [%s]=%q,",depth,k,tostring(v)))
end
@@ -927,6 +884,7 @@ local function serialize(_handle,root,name,specification) -- handle wins
if type(specification) == "table" then
noquotes = specification.noquotes
hexify = specification.hexify
+ accurate = specification.accurate
handle = _handle or specification.handle or print
functions = specification.functions
compact = specification.compact
diff --git a/macros/luatex/generic/luaotfload/fontloader-reference-load-order.lua b/macros/luatex/generic/luaotfload/fontloader-reference-load-order.lua
index 85fe1ae975..9f45408b1b 100644
--- a/macros/luatex/generic/luaotfload/fontloader-reference-load-order.lua
+++ b/macros/luatex/generic/luaotfload/fontloader-reference-load-order.lua
@@ -257,7 +257,9 @@ if non_generic_context.luatex_fonts.skip_loading ~= true then
loadmodule('font-vfc.lua')
- -- This is the bulk of opentype code.
+ -- This is the bulk of opentype code. The color and variable font support (as for
+ -- emoji) can (and might) actually go away here because it has never been used
+ -- outside context so in retrospect there was no need for it being generic.
loadmodule('font-otr.lua')
loadmodule('font-oti.lua')
diff --git a/macros/luatex/generic/luaotfload/fontloader-reference.lua b/macros/luatex/generic/luaotfload/fontloader-reference.lua
index ce2794cf36..32f25b931e 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 : 01/26/20 18:34:44
+-- merge date : 2020-04-30 11:10
do -- begin closure to overcome local limits and interference
@@ -1383,13 +1383,13 @@ function table.fromhash(t)
end
return hsh
end
-local noquotes,hexify,handle,compact,inline,functions,metacheck
+local noquotes,hexify,handle,compact,inline,functions,metacheck,accurate
local reserved=table.tohash {
'and','break','do','else','elseif','end','false','for','function','if',
'in','local','nil','not','or','repeat','return','then','true','until','while',
- 'NaN','goto',
+ 'NaN','goto','const',
}
-local function is_simple_table(t,hexify)
+local function is_simple_table(t,hexify,accurate)
local nt=#t
if nt>0 then
local n=0
@@ -1408,6 +1408,8 @@ local function is_simple_table(t,hexify)
if tv=="number" then
if hexify then
tt[i]=format("0x%X",v)
+ elseif accurate then
+ tt[i]=format("%q",v)
else
tt[i]=v
end
@@ -1428,6 +1430,8 @@ local function is_simple_table(t,hexify)
if tv=="number" then
if hexify then
tt[i+1]=format("0x%X",v)
+ elseif accurate then
+ tt[i+1]=format("%q",v)
else
tt[i+1]=v
end
@@ -1499,6 +1503,8 @@ local function do_serialize(root,name,depth,level,indexed)
if tv=="number" then
if hexify then
handle(format("%s 0x%X,",depth,v))
+ elseif accurate then
+ handle(format("%s %q,",depth,v))
else
handle(format("%s %s,",depth,v))
end
@@ -1508,7 +1514,7 @@ local function do_serialize(root,name,depth,level,indexed)
if next(v)==nil then
handle(format("%s {},",depth))
elseif inline then
- local st=is_simple_table(v,hexify)
+ local st=is_simple_table(v,hexify,accurate)
if st then
handle(format("%s { %s },",depth,concat(st,", ")))
else
@@ -1536,12 +1542,16 @@ local function do_serialize(root,name,depth,level,indexed)
if tk=="number" then
if hexify then
handle(format("%s [0x%X]=0x%X,",depth,k,v))
+ elseif accurate then
+ handle(format("%s [%s]=%q,",depth,k,v))
else
handle(format("%s [%s]=%s,",depth,k,v))
end
elseif tk=="boolean" then
if hexify then
handle(format("%s [%s]=0x%X,",depth,k and "true" or "false",v))
+ elseif 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
@@ -1549,12 +1559,16 @@ local function do_serialize(root,name,depth,level,indexed)
elseif noquotes and not reserved[k] and lpegmatch(propername,k) then
if hexify then
handle(format("%s %s=0x%X,",depth,k,v))
+ elseif accurate then
+ handle(format("%s %s=%q,",depth,k,v))
else
handle(format("%s %s=%s,",depth,k,v))
end
else
if hexify then
handle(format("%s [%q]=0x%X,",depth,k,v))
+ elseif accurate then
+ handle(format("%s [%q]=%q,",depth,k,v))
else
handle(format("%s [%q]=%s,",depth,k,v))
end
@@ -1563,6 +1577,8 @@ local function do_serialize(root,name,depth,level,indexed)
if tk=="number" then
if hexify then
handle(format("%s [0x%X]=%q,",depth,k,v))
+ elseif accurate then
+ handle(format("%s [%q]=%q,",depth,k,v))
else
handle(format("%s [%s]=%q,",depth,k,v))
end
@@ -1579,6 +1595,8 @@ local function do_serialize(root,name,depth,level,indexed)
if tk=="number" then
if hexify then
handle(format("%s [0x%X]={},",depth,k))
+ elseif accurate then
+ handle(format("%s [%q]={},",depth,k))
else
handle(format("%s [%s]={},",depth,k))
end
@@ -1591,11 +1609,13 @@ local function do_serialize(root,name,depth,level,indexed)
handle(format("%s [%q]={},",depth,k))
end
elseif inline then
- local st=is_simple_table(v,hexify)
+ local st=is_simple_table(v,hexify,accurate)
if st then
if tk=="number" then
if hexify then
handle(format("%s [0x%X]={ %s },",depth,k,concat(st,", ")))
+ elseif accurate then
+ handle(format("%s [%q]={ %s },",depth,k,concat(st,", ")))
else
handle(format("%s [%s]={ %s },",depth,k,concat(st,", ")))
end
@@ -1617,6 +1637,8 @@ local function do_serialize(root,name,depth,level,indexed)
if tk=="number" then
if hexify then
handle(format("%s [0x%X]=%s,",depth,k,v and "true" or "false"))
+ elseif accurate then
+ handle(format("%s [%q]=%s,",depth,k,v and "true" or "false"))
else
handle(format("%s [%s]=%s,",depth,k,v and "true" or "false"))
end
@@ -1636,6 +1658,8 @@ local function do_serialize(root,name,depth,level,indexed)
if tk=="number" then
if hexify then
handle(format("%s [0x%X]=load(%q),",depth,k,f))
+ elseif accurate then
+ handle(format("%s [%q]=load(%q),",depth,k,f))
else
handle(format("%s [%s]=load(%q),",depth,k,f))
end
@@ -1653,6 +1677,8 @@ local function do_serialize(root,name,depth,level,indexed)
if tk=="number" then
if hexify then
handle(format("%s [0x%X]=%q,",depth,k,tostring(v)))
+ elseif accurate then
+ handle(format("%s [%q]=%q,",depth,k,tostring(v)))
else
handle(format("%s [%s]=%q,",depth,k,tostring(v)))
end
@@ -1676,6 +1702,7 @@ local function serialize(_handle,root,name,specification)
if type(specification)=="table" then
noquotes=specification.noquotes
hexify=specification.hexify
+ accurate=specification.accurate
handle=_handle or specification.handle or print
functions=specification.functions
compact=specification.compact
@@ -3493,9 +3520,12 @@ local format_left=function(f)
return format("a%s..utfpadding(a%s,%i)",n,n,-f)
end
end
-local format_q=function()
+local format_q=JITSUPPORTED and function()
n=n+1
return format("(a%s ~= nil and format('%%q',tostring(a%s)) or '')",n,n)
+end or function()
+ n=n+1
+ return format("(a%s ~= nil and format('%%q',a%s) or '')",n,n)
end
local format_Q=function()
n=n+1
@@ -4893,7 +4923,6 @@ nuts.tonut=tonut
nuts.getattr=direct.get_attribute
nuts.getboth=direct.getboth
nuts.getchar=direct.getchar
-nuts.getcomponents=direct.getcomponents
nuts.getdirection=direct.getdirection
nuts.getdisc=direct.getdisc
nuts.getreplace=direct.getreplace
@@ -4931,7 +4960,6 @@ nuts.isglyph=direct.is_glyph
nuts.copy=direct.copy
nuts.copy_list=direct.copy_list
nuts.copy_node=direct.copy
-nuts.delete=direct.delete
nuts.end_of_math=direct.end_of_math
nuts.flush=direct.flush
nuts.flush_list=direct.flush_list
@@ -4979,45 +5007,72 @@ local getnext=nuts.getnext
local setlink=nuts.setlink
local getfield=nuts.getfield
local setfield=nuts.setfield
-local getcomponents=nuts.getcomponents
-local setcomponents=nuts.setcomponents
+local getsubtype=nuts.getsubtype
+local isglyph=nuts.isglyph
local find_tail=nuts.tail
local flush_list=nuts.flush_list
local flush_node=nuts.flush_node
local traverse_id=nuts.traverse_id
local copy_node=nuts.copy_node
local glyph_code=nodes.nodecodes.glyph
-function nuts.copy_no_components(g,copyinjection)
- local components=getcomponents(g)
- if components then
- setcomponents(g)
- local n=copy_node(g)
- if copyinjection then
- copyinjection(n,g)
- end
- setcomponents(g,components)
- return n
- else
- local n=copy_node(g)
- if copyinjection then
- copyinjection(n,g)
+local ligature_code=nodes.glyphcodes.ligature
+do
+ local get_components=node.direct.getcomponents
+ local set_components=node.direct.setcomponents
+ local function copy_no_components(g,copyinjection)
+ local components=get_components(g)
+ if components then
+ set_components(g)
+ local n=copy_node(g)
+ if copyinjection then
+ copyinjection(n,g)
+ end
+ set_components(g,components)
+ return n
+ else
+ local n=copy_node(g)
+ if copyinjection then
+ copyinjection(n,g)
+ end
+ return n
end
- return n
end
-end
-function nuts.copy_only_glyphs(current)
- local head=nil
- local previous=nil
- for n in traverse_id(glyph_code,current) do
- n=copy_node(n)
- if head then
- setlink(previous,n)
- else
- head=n
+ local function copy_only_glyphs(current)
+ local head=nil
+ local previous=nil
+ for n in traverse_id(glyph_code,current) do
+ n=copy_node(n)
+ if head then
+ setlink(previous,n)
+ else
+ head=n
+ end
+ previous=n
end
- previous=n
+ return head
end
- return head
+ local function count_components(start,marks)
+ local char=isglyph(start)
+ if char then
+ if getsubtype(start)==ligature_code then
+ local n=0
+ local components=get_components(start)
+ while components do
+ n=n+count_components(components,marks)
+ components=getnext(components)
+ end
+ return n
+ elseif not marks[char] then
+ return 1
+ end
+ end
+ return 0
+ end
+ nuts.set_components=set_components
+ nuts.get_components=get_components
+ nuts.copy_only_glyphs=copy_only_glyphs
+ nuts.copy_no_components=copy_no_components
+ nuts.count_components=count_components
end
nuts.uses_font=direct.uses_font
do
@@ -9634,6 +9689,7 @@ hashmethods.normal=function(list)
m=m+1
t[m]=k..'='..tostring(v)
end
+ sort(t)
s[n]=k..'={'..concat(t,",").."}"
else
s[n]=k..'='..tostring(v)
@@ -10323,7 +10379,7 @@ local match,format,find,concat,gsub,lower=string.match,string.format,string.find
local P,R,S,C,Ct,Cc,lpegmatch=lpeg.P,lpeg.R,lpeg.S,lpeg.C,lpeg.Ct,lpeg.Cc,lpeg.match
local formatters=string.formatters
local sortedhash,sortedkeys=table.sortedhash,table.sortedkeys
-local rshift=bit32.rshift
+local idiv=number.idiv
local trace_loading=false trackers.register("fonts.loading",function(v) trace_loading=v end)
local trace_mapping=false trackers.register("fonts.mapping",function(v) trace_mapping=v end)
local report_fonts=logs.reporter("fonts","loading")
@@ -10356,12 +10412,21 @@ local function makenameparser(str)
end
local f_single=formatters["%04X"]
local f_double=formatters["%04X%04X"]
+local s_unknown="FFFD"
local function tounicode16(unicode)
if unicode<0xD7FF or (unicode>0xDFFF and unicode<=0xFFFF) then
return f_single(unicode)
+ elseif unicode>=0x00E000 and unicode<=0x00F8FF then
+ return s_unknown
+ elseif unicode>=0x0F0000 and unicode<=0x0FFFFF then
+ return s_unknown
+ elseif unicode>=0x100000 and unicode<=0x10FFFF then
+ return s_unknown
+ elseif unicode>=0x00D800 and unicode<=0x00DFFF then
+ return s_unknown
else
unicode=unicode-0x10000
- return f_double(rshift(unicode,10)+0xD800,unicode%1024+0xDC00)
+ return f_double(idiv(k,0x400)+0xD800,unicode%0x400+0xDC00)
end
end
local function tounicode16sequence(unicodes)
@@ -10370,14 +10435,21 @@ local function tounicode16sequence(unicodes)
local u=unicodes[l]
if u<0xD7FF or (u>0xDFFF and u<=0xFFFF) then
t[l]=f_single(u)
+ elseif unicode>=0x00E000 and unicode<=0x00F8FF then
+ t[l]=s_unknown
+ elseif unicode>=0x0F0000 and unicode<=0x0FFFFF then
+ t[l]=s_unknown
+ elseif unicode>=0x100000 and unicode<=0x10FFFF then
+ t[l]=s_unknown
+ elseif unicode>=0x00D7FF and unicode<=0x00DFFF then
+ t[l]=s_unknown
else
u=u-0x10000
- t[l]=f_double(rshift(u,10)+0xD800,u%1024+0xDC00)
+ t[l]=f_double(idiv(k,0x400)+0xD800,u%0x400+0xDC00)
end
end
return concat(t)
end
-local unknown=f_single(0xFFFD)
local hash={}
local conc={}
table.setmetatableindex(hash,function(t,k)
@@ -10385,7 +10457,7 @@ table.setmetatableindex(hash,function(t,k)
v=f_single(k)
else
local k=k-0x10000
- v=f_double(rshift(k,10)+0xD800,k%1024+0xDC00)
+ v=f_double(idiv(k,0x400)+0xD800,k%0x400+0xDC00)
end
t[k]=v
return v
@@ -10398,11 +10470,13 @@ local function tounicode(k)
end
return concat(conc,"",1,n)
elseif k>=0x00E000 and k<=0x00F8FF then
- return unknown
+ return s_unknown
elseif k>=0x0F0000 and k<=0x0FFFFF then
- return unknown
+ return s_unknown
elseif k>=0x100000 and k<=0x10FFFF then
- return unknown
+ return s_unknown
+ elseif k>=0x00D7FF and k<=0x00DFFF then
+ return s_unknown
else
return hash[k]
end
@@ -14148,6 +14222,14 @@ local cffreaders={
readuint,
readulong,
}
+directives.register("fonts.streamreader",function()
+ cffreaders={
+ readbyte,
+ readushort,
+ readuint,
+ readulong,
+ }
+end)
local function readheader(f)
local offset=getposition(f)
local major=readbyte(f)
@@ -20032,6 +20114,7 @@ function readers.sbix(f,fontdata,specification)
end
end)
local glyphs={}
+ local delayed=CONTEXTLMTXMODE and CONTEXTLMTXMODE>0 or fonts.handlers.typethree
for i=1,nofstrikes do
local strike=strikes[i]
local strikeppem=strike.ppem
@@ -20048,13 +20131,25 @@ function readers.sbix(f,fontdata,specification)
local datasize=nextoffset-glyphoffset
if datasize>0 then
setposition(f,strikeoffset+glyphoffset)
+ local x=readshort(f)
+ local y=readshort(f)
+ local tag=readtag(f)
+ local size=datasize-8
+ local data=nil
+ local offset=nil
+ if delayed then
+ offset=getposition(f)
+ data=nil
+ else
+ data=readstring(f,size)
+ size=nil
+ end
shapes[i]={
- x=readshort(f),
- y=readshort(f),
- tag=readtag(f),
- data=readstring(f,datasize-8),
- ppem=strikeppem,
- ppi=strikeppi,
+ x=x,
+ y=y,
+ o=offset,
+ s=size,
+ data=data,
}
done=done+1
if done==nofglyphs then
@@ -20233,29 +20328,46 @@ do
end
local default={ width=0,height=0 }
local glyphs=fontdata.glyphs
+ local delayed=CONTEXTLMTXMODE and CONTEXTLMTXMODE>0 or fonts.handlers.typethree
for index,subtable in sortedhash(shapes) do
if type(subtable)=="table" then
local data=nil
+ local size=nil
local metrics=default
local format=subtable.format
local offset=subtable.offsets[index]
setposition(f,offset)
if format==17 then
metrics=getsmallmetrics(f)
- data=readstring(f,readulong(f))
+ size=true
elseif format==18 then
metrics=getbigmetrics(f)
- data=readstring(f,readulong(f))
+ size=true
elseif format==19 then
metrics=subtable.metrics
- data=readstring(f,readulong(f))
+ size=true
+ else
+ end
+ if size then
+ size=readulong(f)
+ if delayed then
+ offset=getposition(f)
+ data=nil
+ else
+ offset=nil
+ data=readstring(f,size)
+ size=nil
+ end
else
+ offset=nil
end
local x=metrics.width
local y=metrics.height
shapes[index]={
x=x,
y=y,
+ o=offset,
+ s=size,
data=data,
}
local glyph=glyphs[index]
@@ -23251,7 +23363,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.110
+otf.version=3.111
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)
@@ -24452,14 +24564,14 @@ local insert_node_after=nuts.insert_after
local properties=nodes.properties.data
local fontkern=nuts.pool and nuts.pool.fontkern
local italickern=nuts.pool and nuts.pool.italickern
-local useitalickerns=false
+local useitalickerns=false
directives.register("fonts.injections.useitalics",function(v)
if v then
report_injections("using italics for space kerns (tracing only)")
end
useitalickerns=v
end)
-do if not fontkern then
+if not fontkern then
local thekern=nuts.new("kern",0)
local setkern=nuts.setkern
local copy_node=nuts.copy_node
@@ -24468,8 +24580,8 @@ do if not fontkern then
setkern(n,k)
return n
end
-end end
-do if not italickern then
+end
+if not italickern then
local thekern=nuts.new("kern",3)
local setkern=nuts.setkern
local copy_node=nuts.copy_node
@@ -24478,7 +24590,7 @@ do if not italickern then
setkern(n,k)
return n
end
-end end
+end
function injections.installnewkern() end
local nofregisteredkerns=0
local nofregisteredpositions=0
@@ -24931,7 +25043,15 @@ local function inject_kerns_only(head,where)
if i then
local leftkern=i.leftkern
if leftkern and leftkern~=0 then
- head=insert_node_before(head,current,fontkern(leftkern))
+ if prev and getid(prev)==glue_code then
+ if useitalickerns then
+ head=insert_node_before(head,current,italickern(leftkern))
+ else
+ setwidth(prev,getwidth(prev)+leftkern)
+ end
+ else
+ head=insert_node_before(head,current,fontkern(leftkern))
+ end
end
end
if prevdisc then
@@ -25074,12 +25194,26 @@ local function inject_positions_only(head,where)
if rightkern and leftkern==-rightkern then
setoffsets(current,leftkern,false)
rightkern=0
+ elseif prev and getid(prev)==glue_code then
+ if useitalickerns then
+ head=insert_node_before(head,current,italickern(leftkern))
+ else
+ setwidth(prev,getwidth(prev)+leftkern)
+ end
else
head=insert_node_before(head,current,fontkern(leftkern))
end
end
if rightkern and rightkern~=0 then
- insert_node_after(head,current,fontkern(rightkern))
+ if next and getid(next)==glue_code then
+ if useitalickerns then
+ insert_node_after(head,current,italickern(rightkern))
+ else
+ setwidth(next,getwidth(next)+rightkern)
+ end
+ else
+ insert_node_after(head,current,fontkern(rightkern))
+ end
end
else
local i=p.emptyinjections
@@ -25427,12 +25561,26 @@ local function inject_everything(head,where)
if rightkern and leftkern==-rightkern then
setoffsets(current,leftkern,false)
rightkern=0
+ elseif prev and getid(prev)==glue_code then
+ if useitalickerns then
+ head=insert_node_before(head,current,italickern(leftkern))
+ else
+ setwidth(prev,getwidth(prev)+leftkern)
+ end
else
head=insert_node_before(head,current,fontkern(leftkern))
end
end
if rightkern and rightkern~=0 then
- insert_node_after(head,current,fontkern(rightkern))
+ if next and getid(next)==glue_code then
+ if useitalickerns then
+ insert_node_after(head,current,italickern(rightkern))
+ else
+ setwidth(next,getwidth(next)+rightkern)
+ end
+ else
+ insert_node_after(head,current,fontkern(rightkern))
+ end
end
end
else
@@ -25798,16 +25946,17 @@ local function injectspaces(head)
if useitalickerns then
local new=rightkern*factor
if trace_spaces then
- report_spaces("%C [%p + %p]",nextchar,old,new)
+ report_spaces("[%p + %p] %C",old,new,nextchar)
end
insert_node_after(head,n,italickern(new))
else
local new=old+rightkern*factor
if trace_spaces then
- report_spaces("[%p -> %p] %C",nextchar,old,new)
+ report_spaces("[%p -> %p] %C",old,new,nextchar)
end
setwidth(n,new)
end
+ else
end
rightkern=false
end
@@ -25860,7 +26009,6 @@ local initializers=allocate()
local methods=allocate()
analyzers.initializers=initializers
analyzers.methods=methods
-local a_state=attributes.private('state')
local nuts=nodes.nuts
local tonut=nuts.tonut
local getnext=nuts.getnext
@@ -25880,6 +26028,23 @@ local categories=characters and characters.categories or {}
local chardata=characters and characters.data
local otffeatures=fonts.constructors.features.otf
local registerotffeature=otffeatures.register
+local setstate=nuts.setstate
+local getstate=nuts.getstate
+if not setstate or not getstate then
+ setstate=function(n,v)
+ setprop(n,"state",v)
+ end
+ getstate=function(n,v)
+ local s=getprop(n,"state")
+ if v then
+ return s==v
+ else
+ return s
+ end
+ end
+ nuts.setstate=setstate
+ nuts.getstate=getstate
+end
local s_init=1 local s_rphf=7
local s_medi=2 local s_half=8
local s_fina=3 local s_pref=9
@@ -25927,49 +26092,49 @@ function analyzers.setstate(head,font)
current=tonut(current)
while current do
local char,id=ischar(current,font)
- if char and not getprop(current,a_state) then
+ if char and not getstate(current) then
done=true
local d=descriptions[char]
if d then
if d.class=="mark" then
done=true
- setprop(current,a_state,s_mark)
+ setstate(current,s_mark)
elseif useunicodemarks and categories[char]=="mn" then
done=true
- setprop(current,a_state,s_mark)
+ setstate(current,s_mark)
elseif n==0 then
first,last,n=current,current,1
- setprop(current,a_state,s_init)
+ setstate(current,s_init)
else
last,n=current,n+1
- setprop(current,a_state,s_medi)
+ setstate(current,s_medi)
end
else
if first and first==last then
- setprop(last,a_state,s_isol)
+ setstate(last,s_isol)
elseif last then
- setprop(last,a_state,s_fina)
+ setstate(last,s_fina)
end
first,last,n=nil,nil,0
end
elseif char==false then
if first and first==last then
- setprop(last,a_state,s_isol)
+ setstate(last,s_isol)
elseif last then
- setprop(last,a_state,s_fina)
+ setstate(last,s_fina)
end
first,last,n=nil,nil,0
if id==math_code then
current=end_of_math(current)
end
elseif id==disc_code then
- setprop(current,a_state,s_medi)
+ setstate(current,s_medi)
last=current
else
if first and first==last then
- setprop(last,a_state,s_isol)
+ setstate(last,s_isol)
elseif last then
- setprop(last,a_state,s_fina)
+ setstate(last,s_fina)
end
first,last,n=nil,nil,0
if id==math_code then
@@ -25979,9 +26144,9 @@ function analyzers.setstate(head,font)
current=getnext(current)
end
if first and first==last then
- setprop(last,a_state,s_isol)
+ setstate(last,s_isol)
elseif last then
- setprop(last,a_state,s_fina)
+ setstate(last,s_fina)
end
return head,done
end
@@ -26085,87 +26250,87 @@ function methods.arab(head,font,attr)
current=tonut(current)
while current do
local char,id=ischar(current,font)
- if char and not getprop(current,a_state) then
+ if char and not getstate(current) then
done=true
local classifier=classifiers[char]
if not classifier then
if last then
if c_last==s_medi or c_last==s_fina then
- setprop(last,a_state,s_fina)
+ setstate(last,s_fina)
else
warning(last,"fina")
- setprop(last,a_state,s_error)
+ setstate(last,s_error)
end
first,last=nil,nil
elseif first then
if c_first==s_medi or c_first==s_fina then
- setprop(first,a_state,s_isol)
+ setstate(first,s_isol)
else
warning(first,"isol")
- setprop(first,a_state,s_error)
+ setstate(first,s_error)
end
first=nil
end
elseif classifier==s_mark then
- setprop(current,a_state,s_mark)
+ setstate(current,s_mark)
elseif classifier==s_isol then
if last then
if c_last==s_medi or c_last==s_fina then
- setprop(last,a_state,s_fina)
+ setstate(last,s_fina)
else
warning(last,"fina")
- setprop(last,a_state,s_error)
+ setstate(last,s_error)
end
first,last=nil,nil
elseif first then
if c_first==s_medi or c_first==s_fina then
- setprop(first,a_state,s_isol)
+ setstate(first,s_isol)
else
warning(first,"isol")
- setprop(first,a_state,s_error)
+ setstate(first,s_error)
end
first=nil
end
- setprop(current,a_state,s_isol)
+ setstate(current,s_isol)
elseif classifier==s_medi then
if first then
last=current
c_last=classifier
- setprop(current,a_state,s_medi)
+ setstate(current,s_medi)
else
- setprop(current,a_state,s_init)
+ setstate(current,s_init)
first=current
c_first=classifier
end
elseif classifier==s_fina then
if last then
- if getprop(last,a_state)~=s_init then
- setprop(last,a_state,s_medi)
+ if getstate(last)~=s_init then
+ setstate(last,s_medi)
end
- setprop(current,a_state,s_fina)
+ setstate(current,s_fina)
first,last=nil,nil
elseif first then
- setprop(current,a_state,s_fina)
+ setstate(current,s_fina)
first=nil
else
- setprop(current,a_state,s_isol)
+ setstate(current,s_isol)
end
else
- setprop(current,a_state,s_rest)
+ setstate(current,s_rest)
if last then
if c_last==s_medi or c_last==s_fina then
- setprop(last,a_state,s_fina)
+ setstate(last,s_fina)
else
warning(last,"fina")
- setprop(last,a_state,s_error)
+ setstate(last,s_error)
end
first,last=nil,nil
elseif first then
if c_first==s_medi or c_first==s_fina then
- setprop(first,a_state,s_isol)
+ setstate(first,s_isol)
else
warning(first,"isol")
- setprop(first,a_state,s_error)
+ setstate(first,s_error)
end
first=nil
end
@@ -26173,18 +26338,18 @@ function methods.arab(head,font,attr)
else
if last then
if c_last==s_medi or c_last==s_fina then
- setprop(last,a_state,s_fina)
+ setstate(last,s_fina)
else
warning(last,"fina")
- setprop(last,a_state,s_error)
+ setstate(last,s_error)
end
first,last=nil,nil
elseif first then
if c_first==s_medi or c_first==s_fina then
- setprop(first,a_state,s_isol)
+ setstate(first,s_isol)
else
warning(first,"isol")
- setprop(first,a_state,s_error)
+ setstate(first,s_error)
end
first=nil
end
@@ -26196,17 +26361,17 @@ function methods.arab(head,font,attr)
end
if last then
if c_last==s_medi or c_last==s_fina then
- setprop(last,a_state,s_fina)
+ setstate(last,s_fina)
else
warning(last,"fina")
- setprop(last,a_state,s_error)
+ setstate(last,s_error)
end
elseif first then
if c_first==s_medi or c_first==s_fina then
- setprop(first,a_state,s_isol)
+ setstate(first,s_isol)
else
warning(first,"isol")
- setprop(first,a_state,s_error)
+ setstate(first,s_error)
end
end
return head,done
@@ -26286,8 +26451,7 @@ local setprev=nuts.setprev
local getboth=nuts.getboth
local setboth=nuts.setboth
local getid=nuts.getid
-local getprop=nuts.getprop
-local setprop=nuts.setprop
+local getstate=nuts.getstate
local getsubtype=nuts.getsubtype
local setsubtype=nuts.setsubtype
local getchar=nuts.getchar
@@ -26296,13 +26460,15 @@ local getdisc=nuts.getdisc
local setdisc=nuts.setdisc
local getreplace=nuts.getreplace
local setlink=nuts.setlink
-local getcomponents=nuts.getcomponents
-local setcomponents=nuts.setcomponents
local getwidth=nuts.getwidth
local getattr=nuts.getattr
local getglyphdata=nuts.getglyphdata
+local copy_no_components=nuts.copy_no_components
+local copy_only_glyphs=nuts.copy_only_glyphs
+local count_components=nuts.count_components
+local set_components=nuts.set_components
+local get_components=nuts.get_components
local ischar=nuts.ischar
-local isglyph=nuts.isglyph
local usesfont=nuts.uses_font
local insert_node_after=nuts.insert_after
local copy_node=nuts.copy
@@ -26327,7 +26493,6 @@ local dir_code=nodecodes.dir
local localpar_code=nodecodes.localpar
local discretionarydisc_code=disccodes.discretionary
local ligatureglyph_code=glyphcodes.ligature
-local a_state=attributes.private('state')
local a_noligature=attributes.private("noligature")
local injections=nodes.injections
local setmark=injections.setmark
@@ -26488,27 +26653,6 @@ local function appenddisc(disc,list)
end
setdisc(disc,pre,post,replace)
end
-local copy_no_components=nuts.copy_no_components
-local copy_only_glyphs=nuts.copy_only_glyphs
-local set_components=setcomponents
-local take_components=getcomponents
-local function count_components(start,marks)
- local char=isglyph(start)
- if char then
- if getsubtype(start)==ligatureglyph_code then
- local i=0
- local components=getcomponents(start)
- while components do
- i=i+count_components(components,marks)
- components=getnext(components)
- end
- return i
- elseif not marks[char] then
- return 1
- end
- end
- return 0
-end
local function markstoligature(head,start,stop,char)
if start==stop and getchar(start)==char then
return head,start
@@ -26554,7 +26698,7 @@ local function toligature(head,start,stop,char,dataset,sequence,skiphash,discfou
setlink(prev,base,next)
if not discfound then
local deletemarks=not skiphash or hasmarks
- local components=start
+ local components=start
local baseindex=0
local componentindex=0
local head=base
@@ -26567,13 +26711,13 @@ local function toligature(head,start,stop,char,dataset,sequence,skiphash,discfou
elseif not deletemarks then
setligaindex(start,baseindex+getligaindex(start,componentindex))
if trace_marks then
- logwarning("%s: keep mark %s, gets index %s",pref(dataset,sequence),gref(char),getligaindex(start))
+ logwarning("%s: keep ligature mark %s, gets index %s",pref(dataset,sequence),gref(char),getligaindex(start))
end
local n=copy_node(start)
copyinjection(n,start)
head,current=insert_node_after(head,current,n)
elseif trace_marks then
- logwarning("%s: delete mark %s",pref(dataset,sequence),gref(char))
+ logwarning("%s: delete ligature mark %s",pref(dataset,sequence),gref(char))
end
start=getnext(start)
end
@@ -26584,7 +26728,7 @@ local function toligature(head,start,stop,char,dataset,sequence,skiphash,discfou
if marks[char] then
setligaindex(start,baseindex+getligaindex(start,componentindex))
if trace_marks then
- logwarning("%s: set mark %s, gets index %s",pref(dataset,sequence),gref(char),getligaindex(start))
+ logwarning("%s: set ligature mark %s, gets index %s",pref(dataset,sequence),gref(char),getligaindex(start))
end
start=getnext(start)
else
@@ -26600,17 +26744,16 @@ local function toligature(head,start,stop,char,dataset,sequence,skiphash,discfou
local pre,post,replace,pretail,posttail,replacetail=getdisc(discfound,true)
if not replace then
local prev=getprev(base)
- local comp=take_components(base)
local copied=copy_only_glyphs(comp)
if pre then
setlink(discprev,pre)
else
setnext(discprev)
end
- pre=comp
+ pre=comp
if post then
setlink(posttail,discnext)
- setprev(post)
+ setprev(post)
else
post=discnext
setprev(discnext)
@@ -28794,7 +28937,7 @@ local function testrun(disc,t_run,c_run,...)
end
local pre,post,replace,pretail,posttail,replacetail=getdisc(disc,true)
local renewed=false
- if (post or replace) then
+ if post or replace then
if post then
setlink(posttail,next)
else
@@ -28894,6 +29037,7 @@ local nesting=0
local function c_run_single(head,font,attr,lookupcache,step,dataset,sequence,rlmode,skiphash,handler)
local done=false
local sweep=sweephead[head]
+ local start
if sweep then
start=sweep
sweephead[head]=false
@@ -28987,7 +29131,7 @@ local function t_run_single(start,stop,font,attr,lookupcache)
ss=nil
end
end
-lookupmatch=lg
+ lookupmatch=lg
else
break
end
@@ -29022,7 +29166,7 @@ local function k_run_single(sub,injection,last,font,attr,lookupcache,step,datase
if n==last then
break
end
- local char=ischar(n)
+ local char=ischar(n,font)
if char then
local lookupmatch=lookupcache[char]
if lookupmatch then
@@ -29038,6 +29182,7 @@ end
local function c_run_multiple(head,font,attr,steps,nofsteps,dataset,sequence,rlmode,skiphash,handler)
local done=false
local sweep=sweephead[head]
+ local start
if sweep then
start=sweep
sweephead[head]=false
@@ -29141,7 +29286,7 @@ local function t_run_multiple(start,stop,font,attr,steps,nofsteps)
ss=nil
end
end
-lookupmatch=lg
+ lookupmatch=lg
else
break
end
@@ -29364,10 +29509,10 @@ do
if lookupmatch then
local a
if attr then
- if getglyphdata(start)==attr and (not attribute or getprop(start,a_state)==attribute) then
+ if getglyphdata(start)==attr and (not attribute or getstate(start,attribute)) then
a=true
end
- elseif not attribute or getprop(start,a_state)==attribute then
+ elseif not attribute or getstate(start,attribute) then
a=true
end
if a then
@@ -29420,10 +29565,10 @@ do
if m then
local a
if attr then
- if getglyphdata(start)==attr and (not attribute or getprop(start,a_state)==attribute) then
+ if getglyphdata(start)==attr and (not attribute or getstate(start,attribute)) then
a=true
end
- elseif not attribute or getprop(start,a_state)==attribute then
+ elseif not attribute or getstate(start,attribute) then
a=true
end
if a then
@@ -29866,6 +30011,8 @@ local setprev=nuts.setprev
local setchar=nuts.setchar
local getprop=nuts.getprop
local setprop=nuts.setprop
+local getstate=nuts.getstate
+local setstate=nuts.setstate
local ischar=nuts.ischar
local insert_node_after=nuts.insert_after
local copy_node=nuts.copy
@@ -29875,7 +30022,6 @@ local flush_node=nuts.flush_node
local copyinjection=nodes.injections.copy
local unsetvalue=attributes.unsetvalue
local fontdata=fonts.hashes.identifiers
-local a_state=attributes.private('state')
local a_syllabe=attributes.private('syllabe')
local dotted_circle=0x25CC
local c_nbsp=0x00A0
@@ -30608,7 +30754,7 @@ local function reorder_one(head,start,stop,font,attr,nbspaces)
current=start
else
current=getnext(n)
- setprop(start,a_state,s_rphf)
+ setstate(start,s_rphf)
end
end
if getchar(current)==c_nbsp then
@@ -30641,9 +30787,9 @@ local function reorder_one(head,start,stop,font,attr,nbspaces)
local nextcurrent=copy_node(current)
copyinjection(nextcurrent,current)
setlink(tempcurrent,nextcurrent)
- setprop(tempcurrent,a_state,s_blwf)
+ setstate(tempcurrent,s_blwf)
tempcurrent=processcharacters(tempcurrent,font)
- setprop(tempcurrent,a_state,unsetvalue)
+ setstate(tempcurrent,unsetvalue)
if getchar(next)==getchar(tempcurrent) then
flush_list(tempcurrent)
if show_syntax_errors then
@@ -30667,7 +30813,7 @@ local function reorder_one(head,start,stop,font,attr,nbspaces)
while not basefound do
local char=getchar(current)
if consonant[char] then
- setprop(current,a_state,s_half)
+ setstate(current,s_half)
if not firstcons then
firstcons=current
end
@@ -30675,9 +30821,9 @@ local function reorder_one(head,start,stop,font,attr,nbspaces)
if not base then
base=current
elseif blwfcache[char] then
- setprop(current,a_state,s_blwf)
+ setstate(current,s_blwf)
elseif pstfcache[char] then
- setprop(current,a_state,s_pstf)
+ setstate(current,s_pstf)
else
base=current
end
@@ -30742,14 +30888,14 @@ local function reorder_one(head,start,stop,font,attr,nbspaces)
while current~=stop do
local next=getnext(current)
if next~=stop and halant[getchar(next)] and getchar(getnext(next))==c_zwnj then
- setprop(current,a_state,unsetvalue)
+ setstate(current,unsetvalue)
end
current=next
end
- if base~=stop and getprop(base,a_state) then
+ if base~=stop and getstate(base) then
local next=getnext(base)
if halant[getchar(next)] and not (next~=stop and getchar(getnext(next))==c_zwj) then
- setprop(base,a_state,unsetvalue)
+ setstate(base,unsetvalue)
end
end
local current,allreordered,moved=start,false,{ [base]=true }
@@ -30886,7 +31032,7 @@ local function reorder_one(head,start,stop,font,attr,nbspaces)
end
bn=next
end
- if getprop(current,a_state)==s_rphf then
+ if getstate(current,s_rphf) then
if b~=current then
if current==start then
if head==start then
@@ -31037,7 +31183,7 @@ function handlers.devanagari_reorder_reph(head,start)
while current do
local char=ischar(current,startfont)
if char and getprop(current,a_syllabe)==startattr then
- if consonant[char] and not getprop(current,a_state)==s_pref then
+ if consonant[char] and not getstate(current,s_pref) then
startnext=getnext(start)
head=remove_node(head,start)
setlink(current,start)
@@ -31061,7 +31207,7 @@ function handlers.devanagari_reorder_reph(head,start)
while current do
local char=ischar(current,startfont)
if char and getprop(current,a_syllabe)==startattr then
- if getprop(current,a_state)==s_pstf then
+ if getstate(current,s_pstf) then
startnext=getnext(start)
head=remove_node(head,start)
setlink(getprev(current),start)
@@ -31094,7 +31240,7 @@ function handlers.devanagari_reorder_reph(head,start)
while current do
local char=ischar(current,startfont)
if char and getprop(current,a_syllabe)==startattr then
- local state=getprop(current,a_state)
+ local state=getstate(current)
if before_subscript[rephbase] and (state==s_blwf or state==s_pstf) then
c=current
elseif after_subscript[rephbase] and (state==s_pstf) then
@@ -31174,7 +31320,7 @@ function handlers.devanagari_reorder_pre_base_reordering_consonants(head,start)
local current=getprev(start)
while current and getprop(current,a_syllabe)==startattr do
local char=ischar(current)
- if (not dependent_vowel[char] and not getprop(current,a_state) or getprop(current,a_state)==s_init) then
+ if (not dependent_vowel[char] and (not getstate(current) or getstate(current,s_init))) then
startnext=getnext(start)
head=remove_node(head,start)
if current==head then
@@ -31254,7 +31400,7 @@ local function reorder_two(head,start,stop,font,attr,nbspaces)
if afternext and zw_char[getchar(afternext)] then
current=afternext
elseif current==start then
- setprop(current,a_state,s_rphf)
+ setstate(current,s_rphf)
current=next
else
current=next
@@ -31274,9 +31420,9 @@ local function reorder_two(head,start,stop,font,attr,nbspaces)
if found then
local next=getnext(current)
if found[getchar(next)] or contextchain(found,next) then
- if (not getprop(current,a_state) and not getprop(next,a_state)) then
- setprop(current,a_state,s_pref)
- setprop(next,a_state,s_pref)
+ if (not getstate(current) and not getstate(next)) then
+ setstate(current,s_pref)
+ setstate(next,s_pref)
current=next
end
end
@@ -31296,8 +31442,8 @@ local function reorder_two(head,start,stop,font,attr,nbspaces)
if found[getchar(next)] or contextchain(found,next) then
if next~=stop and getchar(getnext(next))==c_zwnj then
current=next
- elseif (not getprop(current,a_state)) then
- setprop(current,a_state,s_half)
+ elseif (not getstate(current)) then
+ setstate(current,s_half)
if not halfpos then
halfpos=current
end
@@ -31318,9 +31464,9 @@ local function reorder_two(head,start,stop,font,attr,nbspaces)
if found then
local next=getnext(current)
if found[getchar(next)] or contextchain(found,next) then
- if (not getprop(current,a_state) and not getprop(next,a_state)) then
- setprop(current,a_state,s_blwf)
- setprop(next,a_state,s_blwf)
+ if (not getstate(current) and not getstate(next)) then
+ setstate(current,s_blwf)
+ setstate(next,s_blwf)
current=next
subpos=current
end
@@ -31339,9 +31485,9 @@ local function reorder_two(head,start,stop,font,attr,nbspaces)
if found then
local next=getnext(current)
if found[getchar(next)] or contextchain(found,next) then
- if (not getprop(current,a_state) and not getprop(next,a_state)) then
- setprop(current,a_state,s_pstf)
- setprop(next,a_state,s_pstf)
+ if (not getstate(current) and not getstate(next)) then
+ setstate(current,s_pstf)
+ setstate(next,s_pstf)
current=next
postpos=current
end
@@ -31353,7 +31499,7 @@ local function reorder_two(head,start,stop,font,attr,nbspaces)
end
end
local current,base,firstcons=start,nil,nil
- if getprop(start,a_state)==s_rphf then
+ if getstate(start,s_rphf) then
current=getnext(getnext(start))
end
if current~=getnext(stop) and getchar(current)==c_nbsp then
@@ -31380,13 +31526,13 @@ local function reorder_two(head,start,stop,font,attr,nbspaces)
local tmp=getnext(next)
local changestop=next==stop
setnext(next)
- setprop(current,a_state,s_pref)
+ setstate(current,s_pref)
current=processcharacters(current,font)
- setprop(current,a_state,s_blwf)
+ setstate(current,s_blwf)
current=processcharacters(current,font)
- setprop(current,a_state,s_pstf)
+ setstate(current,s_pstf)
current=processcharacters(current,font)
- setprop(current,a_state,unsetvalue)
+ setstate(current,unsetvalue)
if halant[getchar(current)] then
setnext(getnext(current),tmp)
if show_syntax_errors then
@@ -31411,7 +31557,7 @@ local function reorder_two(head,start,stop,font,attr,nbspaces)
if not firstcons then
firstcons=current
end
- local a=getprop(current,a_state)
+ 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
end
@@ -31424,13 +31570,13 @@ local function reorder_two(head,start,stop,font,attr,nbspaces)
end
end
if not base then
- if getprop(start,a_state)==s_rphf then
- setprop(start,a_state,unsetvalue)
+ if getstate(start,s_rphf) then
+ setstate(start,unsetvalue)
end
return head,stop,nbspaces
else
- if getprop(base,a_state) then
- setprop(base,a_state,unsetvalue)
+ if getstate(base) then
+ setstate(base,unsetvalue)
end
basepos=base
end
@@ -31476,7 +31622,7 @@ local function reorder_two(head,start,stop,font,attr,nbspaces)
end
local ppos=getprev(pos)
while ppos and getprop(ppos,a_syllabe)==getprop(pos,a_syllabe) do
- if getprop(ppos,a_state)==s_pref then
+ if getstate(ppos,s_pref) then
pos=ppos
end
ppos=getprev(ppos)
@@ -31548,7 +31694,7 @@ local function reorder_two(head,start,stop,font,attr,nbspaces)
while current~=last do
local char=getchar(current)
local cn=getnext(current)
- if halant[char] and ra[ischar(cn)] and getprop(cn,a_state)~=s_rphf and getprop(cn,a_state)~=s_blwf then
+ if halant[char] and ra[ischar(cn)] and (not getstate(cn,s_rphf)) and (not getstate(cn,s_blwf)) then
if after_main[ischar(cn)] then
local prev=getprev(current)
local next=getnext(cn)
@@ -32148,8 +32294,8 @@ local function method_one(head,font,attr)
while current do
local char=ischar(current,font)
if char then
- if n==0 and not getprop(current,a_state) then
- setprop(current,a_state,s_init)
+ if n==0 and not getstate(current) then
+ setstate(current,s_init)
end
n=n+1
else
@@ -32225,7 +32371,7 @@ local function method_two(head,font,attr)
end
if not syllableend and show_syntax_errors then
local char=ischar(current,font)
- if char and not getprop(current,a_state) then
+ if char and not getstate(current) then
local mark=mark_four[char]
if mark then
head,current=inject_syntax_error(head,current,char)
@@ -32243,8 +32389,8 @@ local function method_two(head,font,attr)
while current do
local char=ischar(current,font)
if char then
- if n==0 and not getprop(current,a_state) then
- setprop(current,a_state,s_init)
+ if n==0 and not getstate(current) then
+ setstate(current,s_init)
end
n=n+1
else
diff --git a/macros/luatex/generic/luaotfload/fontloader-util-str.lua b/macros/luatex/generic/luaotfload/fontloader-util-str.lua
index 68c9be5860..aba7859c31 100644
--- a/macros/luatex/generic/luaotfload/fontloader-util-str.lua
+++ b/macros/luatex/generic/luaotfload/fontloader-util-str.lua
@@ -701,14 +701,18 @@ local format_left = function(f)
end
end
-local format_q = function()
+local format_q = JITSUPPORTED and function()
n = n + 1
-- lua 5.3 has a different q than lua 5.2 (which does a tostring on numbers)
-- return format("(a%s ~= nil and format('%%q',a%s) or '')",n,n)
return format("(a%s ~= nil and format('%%q',tostring(a%s)) or '')",n,n)
-- return format("(a%s ~= nil and escapedquotes(tostring(a%s)) or '')",n,n)
+end or function()
+ n = n + 1
+ return format("(a%s ~= nil and format('%%q',a%s) or '')",n,n)
end
+
local format_Q = function() -- fast escaping
n = n + 1
-- return format("format('%%q',tostring(a%s))",n)
@@ -1269,7 +1273,6 @@ local function make(t,str)
f = function() return str end
end
end
- -- if jit then jit.on(f,true) end
t[str] = f
return f
end
diff --git a/macros/luatex/generic/luaotfload/luaotfload-auxiliary.lua b/macros/luatex/generic/luaotfload/luaotfload-auxiliary.lua
index f6539dca8d..02f52f59bd 100644
--- a/macros/luatex/generic/luaotfload/luaotfload-auxiliary.lua
+++ b/macros/luatex/generic/luaotfload/luaotfload-auxiliary.lua
@@ -6,8 +6,8 @@
local ProvidesLuaModule = {
name = "luaotfload-auxiliary",
- version = "3.12", --TAGVERSION
- date = "2020-02-02", --TAGDATE
+ version = "3.13", --TAGVERSION
+ date = "2020-05-01", --TAGDATE
description = "luaotfload submodule / auxiliary functions",
license = "GPL v2.0"
}
@@ -215,7 +215,7 @@ local function determine_capheight(fontdata)
local refchar = characters [refcp]
if refchar then
logreport ("both", 4, "aux",
- "picked height of character ‘%s’ (U+%d) as \\fontdimen8 \z
+ "picked height of character '%s' (U+%04X) as \\fontdimen8 \z
candidate",
capheight_reference_chars [i], refcp)
return refchar.height
@@ -729,7 +729,7 @@ end
--- https://github.com/lualatex/luaotfload/pull/61#issuecomment-17776975
--- string -> (int * int)
-local scan_external_dir = function (dir)
+local function scan_external_dir (dir)
local old_names, new_names = names.data()
if not old_names then
old_names = load_names()
@@ -918,7 +918,7 @@ end
local function inject_callbacks (lst)
if not lst and next (lst) then return false end
- local inject = function (def)
+ local function inject (def)
local cb, fn, id = unpack (def)
cb = tostring (cb)
id = tostring (id)
diff --git a/macros/luatex/generic/luaotfload/luaotfload-characters.lua b/macros/luatex/generic/luaotfload/luaotfload-characters.lua
index ded3b3eaf0..94ea5f035a 100644
--- a/macros/luatex/generic/luaotfload/luaotfload-characters.lua
+++ b/macros/luatex/generic/luaotfload/luaotfload-characters.lua
@@ -13153,6 +13153,66 @@ return {
linebreak="al",
unicodeslot=0x8BD,
},
+ [0x8BE]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x8BE,
+ },
+ [0x8BF]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x8BF,
+ },
+ [0x8C0]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x8C0,
+ },
+ [0x8C1]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x8C1,
+ },
+ [0x8C2]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x8C2,
+ },
+ [0x8C3]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x8C3,
+ },
+ [0x8C4]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x8C4,
+ },
+ [0x8C5]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x8C5,
+ },
+ [0x8C6]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x8C6,
+ },
+ [0x8C7]={
+ category="lo",
+ direction="al",
+ linebreak="al",
+ unicodeslot=0x8C7,
+ },
[0x8D3]={
category="mn",
direction="nsm",
@@ -16830,6 +16890,12 @@ return {
linebreak="cm",
unicodeslot=0xB4D,
},
+ [0xB55]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0xB55,
+ },
[0xB56]={
category="mn",
direction="nsm",
@@ -18964,6 +19030,12 @@ return {
linebreak="cm",
unicodeslot=0xD03,
},
+ [0xD04]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xD04,
+ },
[0xD05]={
category="lo",
direction="l",
@@ -19788,6 +19860,12 @@ return {
linebreak="al",
unicodeslot=0xD7F,
},
+ [0xD81]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0xD81,
+ },
[0xD82]={
category="mc",
direction="l",
@@ -38161,6 +38239,18 @@ return {
linebreak="cm",
unicodeslot=0x1ABE,
},
+ [0x1ABF]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x1ABF,
+ },
+ [0x1AC0]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x1AC0,
+ },
[0x1B00]={
category="mn",
direction="nsm",
@@ -64006,6 +64096,12 @@ return {
linebreak="al",
unicodeslot=0x2B95,
},
+ [0x2B97]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2B97,
+ },
[0x2B98]={
category="so",
direction="on",
@@ -67888,6 +67984,24 @@ return {
linebreak="ba",
unicodeslot=0x2E4F,
},
+ [0x2E50]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2E50,
+ },
+ [0x2E51]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2E51,
+ },
+ [0x2E52]={
+ category="po",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x2E52,
+ },
[0x2E80]={
category="so",
direction="on",
@@ -72941,6 +73055,36 @@ return {
linebreak="id",
unicodeslot=0x31BA,
},
+ [0x31BB]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x31BB,
+ },
+ [0x31BC]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x31BC,
+ },
+ [0x31BD]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x31BD,
+ },
+ [0x31BE]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x31BE,
+ },
+ [0x31BF]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x31BF,
+ },
[0x31C0]={
category="so",
direction="on",
@@ -88902,6 +89046,42 @@ return {
linebreak="al",
unicodeslot=0xA7C6,
},
+ [0xA7C7]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA7C7,
+ },
+ [0xA7C8]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA7C8,
+ },
+ [0xA7C9]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA7C9,
+ },
+ [0xA7CA]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA7CA,
+ },
+ [0xA7F5]={
+ category="lu",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA7F5,
+ },
+ [0xA7F6]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xA7F6,
+ },
[0xA7F7]={
category="lo",
direction="l",
@@ -89222,6 +89402,12 @@ return {
linebreak="al",
unicodeslot=0xA82B,
},
+ [0xA82C]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0xA82C,
+ },
[0xA830]={
category="no",
direction="l",
@@ -93612,6 +93798,31 @@ return {
linebreak="al",
unicodeslot=0xAB67,
},
+ [0xAB68]={
+ category="ll",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0xAB68,
+ },
+ [0xAB69]={
+ category="lm",
+ direction="l",
+ linebreak="al",
+ specials={ "super", 0x28D },
+ unicodeslot=0xAB69,
+ },
+ [0xAB6A]={
+ category="sk",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0xAB6A,
+ },
+ [0xAB6B]={
+ category="sk",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0xAB6B,
+ },
[0xAB70]={
category="ll",
direction="l",
@@ -108218,6 +108429,12 @@ return {
linebreak="al",
unicodeslot=0x1019B,
},
+ [0x1019C]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1019C,
+ },
[0x101A0]={
category="so",
direction="on",
@@ -120044,6 +120261,288 @@ return {
linebreak="al",
unicodeslot=0x10E7E,
},
+ [0x10E80]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10E80,
+ },
+ [0x10E81]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10E81,
+ },
+ [0x10E82]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10E82,
+ },
+ [0x10E83]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10E83,
+ },
+ [0x10E84]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10E84,
+ },
+ [0x10E85]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10E85,
+ },
+ [0x10E86]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10E86,
+ },
+ [0x10E87]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10E87,
+ },
+ [0x10E88]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10E88,
+ },
+ [0x10E89]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10E89,
+ },
+ [0x10E8A]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10E8A,
+ },
+ [0x10E8B]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10E8B,
+ },
+ [0x10E8C]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10E8C,
+ },
+ [0x10E8D]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10E8D,
+ },
+ [0x10E8E]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10E8E,
+ },
+ [0x10E8F]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10E8F,
+ },
+ [0x10E90]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10E90,
+ },
+ [0x10E91]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10E91,
+ },
+ [0x10E92]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10E92,
+ },
+ [0x10E93]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10E93,
+ },
+ [0x10E94]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10E94,
+ },
+ [0x10E95]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10E95,
+ },
+ [0x10E96]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10E96,
+ },
+ [0x10E97]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10E97,
+ },
+ [0x10E98]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10E98,
+ },
+ [0x10E99]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10E99,
+ },
+ [0x10E9A]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10E9A,
+ },
+ [0x10E9B]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10E9B,
+ },
+ [0x10E9C]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10E9C,
+ },
+ [0x10E9D]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10E9D,
+ },
+ [0x10E9E]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10E9E,
+ },
+ [0x10E9F]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10E9F,
+ },
+ [0x10EA0]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10EA0,
+ },
+ [0x10EA1]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10EA1,
+ },
+ [0x10EA2]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10EA2,
+ },
+ [0x10EA3]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10EA3,
+ },
+ [0x10EA4]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10EA4,
+ },
+ [0x10EA5]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10EA5,
+ },
+ [0x10EA6]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10EA6,
+ },
+ [0x10EA7]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10EA7,
+ },
+ [0x10EA8]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10EA8,
+ },
+ [0x10EA9]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10EA9,
+ },
+ [0x10EAB]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x10EAB,
+ },
+ [0x10EAC]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x10EAC,
+ },
+ [0x10EAD]={
+ category="pd",
+ direction="r",
+ linebreak="ba",
+ unicodeslot=0x10EAD,
+ },
+ [0x10EB0]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10EB0,
+ },
+ [0x10EB1]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10EB1,
+ },
[0x10F00]={
category="lo",
direction="r",
@@ -120536,6 +121035,174 @@ return {
linebreak="al",
unicodeslot=0x10F59,
},
+ [0x10FB0]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10FB0,
+ },
+ [0x10FB1]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10FB1,
+ },
+ [0x10FB2]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10FB2,
+ },
+ [0x10FB3]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10FB3,
+ },
+ [0x10FB4]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10FB4,
+ },
+ [0x10FB5]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10FB5,
+ },
+ [0x10FB6]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10FB6,
+ },
+ [0x10FB7]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10FB7,
+ },
+ [0x10FB8]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10FB8,
+ },
+ [0x10FB9]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10FB9,
+ },
+ [0x10FBA]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10FBA,
+ },
+ [0x10FBB]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10FBB,
+ },
+ [0x10FBC]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10FBC,
+ },
+ [0x10FBD]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10FBD,
+ },
+ [0x10FBE]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10FBE,
+ },
+ [0x10FBF]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10FBF,
+ },
+ [0x10FC0]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10FC0,
+ },
+ [0x10FC1]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10FC1,
+ },
+ [0x10FC2]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10FC2,
+ },
+ [0x10FC3]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10FC3,
+ },
+ [0x10FC4]={
+ category="lo",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10FC4,
+ },
+ [0x10FC5]={
+ category="no",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10FC5,
+ },
+ [0x10FC6]={
+ category="no",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10FC6,
+ },
+ [0x10FC7]={
+ category="no",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10FC7,
+ },
+ [0x10FC8]={
+ category="no",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10FC8,
+ },
+ [0x10FC9]={
+ category="no",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10FC9,
+ },
+ [0x10FCA]={
+ category="no",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10FCA,
+ },
+ [0x10FCB]={
+ category="no",
+ direction="r",
+ linebreak="al",
+ unicodeslot=0x10FCB,
+ },
[0x10FE0]={
category="lo",
direction="r",
@@ -122365,6 +123032,12 @@ return {
linebreak="cm",
unicodeslot=0x11146,
},
+ [0x11147]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11147,
+ },
[0x11150]={
category="lo",
direction="l",
@@ -123067,6 +123740,18 @@ return {
linebreak="al",
unicodeslot=0x111CD,
},
+ [0x111CE]={
+ category="mc",
+ direction="l",
+ linebreak="cm",
+ unicodeslot=0x111CE,
+ },
+ [0x111CF]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x111CF,
+ },
[0x111D0]={
category="nd",
direction="l",
@@ -125355,6 +126040,12 @@ return {
linebreak="nu",
unicodeslot=0x11459,
},
+ [0x1145A]={
+ category="po",
+ direction="l",
+ linebreak="ba",
+ unicodeslot=0x1145A,
+ },
[0x1145B]={
category="po",
direction="l",
@@ -125379,6 +126070,18 @@ return {
linebreak="al",
unicodeslot=0x1145F,
},
+ [0x11460]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11460,
+ },
+ [0x11461]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11461,
+ },
[0x11480]={
category="lo",
direction="l",
@@ -128594,6 +129297,439 @@ return {
linebreak="al",
unicodeslot=0x118FF,
},
+ [0x11900]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11900,
+ },
+ [0x11901]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11901,
+ },
+ [0x11902]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11902,
+ },
+ [0x11903]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11903,
+ },
+ [0x11904]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11904,
+ },
+ [0x11905]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11905,
+ },
+ [0x11906]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11906,
+ },
+ [0x11909]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11909,
+ },
+ [0x1190C]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1190C,
+ },
+ [0x1190D]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1190D,
+ },
+ [0x1190E]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1190E,
+ },
+ [0x1190F]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1190F,
+ },
+ [0x11910]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11910,
+ },
+ [0x11911]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11911,
+ },
+ [0x11912]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11912,
+ },
+ [0x11913]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11913,
+ },
+ [0x11915]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11915,
+ },
+ [0x11916]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11916,
+ },
+ [0x11918]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11918,
+ },
+ [0x11919]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11919,
+ },
+ [0x1191A]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1191A,
+ },
+ [0x1191B]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1191B,
+ },
+ [0x1191C]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1191C,
+ },
+ [0x1191D]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1191D,
+ },
+ [0x1191E]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1191E,
+ },
+ [0x1191F]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1191F,
+ },
+ [0x11920]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11920,
+ },
+ [0x11921]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11921,
+ },
+ [0x11922]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11922,
+ },
+ [0x11923]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11923,
+ },
+ [0x11924]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11924,
+ },
+ [0x11925]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11925,
+ },
+ [0x11926]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11926,
+ },
+ [0x11927]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11927,
+ },
+ [0x11928]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11928,
+ },
+ [0x11929]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11929,
+ },
+ [0x1192A]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1192A,
+ },
+ [0x1192B]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1192B,
+ },
+ [0x1192C]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1192C,
+ },
+ [0x1192D]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1192D,
+ },
+ [0x1192E]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1192E,
+ },
+ [0x1192F]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1192F,
+ },
+ [0x11930]={
+ category="mc",
+ direction="l",
+ linebreak="cm",
+ unicodeslot=0x11930,
+ },
+ [0x11931]={
+ category="mc",
+ direction="l",
+ linebreak="cm",
+ unicodeslot=0x11931,
+ },
+ [0x11932]={
+ category="mc",
+ direction="l",
+ linebreak="cm",
+ unicodeslot=0x11932,
+ },
+ [0x11933]={
+ category="mc",
+ direction="l",
+ linebreak="cm",
+ unicodeslot=0x11933,
+ },
+ [0x11934]={
+ category="mc",
+ direction="l",
+ linebreak="cm",
+ unicodeslot=0x11934,
+ },
+ [0x11935]={
+ category="mc",
+ direction="l",
+ linebreak="cm",
+ unicodeslot=0x11935,
+ },
+ [0x11937]={
+ category="mc",
+ direction="l",
+ linebreak="cm",
+ unicodeslot=0x11937,
+ },
+ [0x11938]={
+ category="mc",
+ direction="l",
+ linebreak="cm",
+ specials={ "char", 0x11935, 0x11930 },
+ unicodeslot=0x11938,
+ },
+ [0x1193B]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x1193B,
+ },
+ [0x1193C]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x1193C,
+ },
+ [0x1193D]={
+ category="mc",
+ direction="l",
+ linebreak="cm",
+ unicodeslot=0x1193D,
+ },
+ [0x1193E]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x1193E,
+ },
+ [0x1193F]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x1193F,
+ },
+ [0x11940]={
+ category="mc",
+ direction="l",
+ linebreak="cm",
+ unicodeslot=0x11940,
+ },
+ [0x11941]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11941,
+ },
+ [0x11942]={
+ category="mc",
+ direction="l",
+ linebreak="cm",
+ unicodeslot=0x11942,
+ },
+ [0x11943]={
+ category="mn",
+ direction="nsm",
+ linebreak="cm",
+ unicodeslot=0x11943,
+ },
+ [0x11944]={
+ category="po",
+ direction="l",
+ linebreak="ba",
+ unicodeslot=0x11944,
+ },
+ [0x11945]={
+ category="po",
+ direction="l",
+ linebreak="ba",
+ unicodeslot=0x11945,
+ },
+ [0x11946]={
+ category="po",
+ direction="l",
+ linebreak="ba",
+ unicodeslot=0x11946,
+ },
+ [0x11950]={
+ category="nd",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0x11950,
+ },
+ [0x11951]={
+ category="nd",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0x11951,
+ },
+ [0x11952]={
+ category="nd",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0x11952,
+ },
+ [0x11953]={
+ category="nd",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0x11953,
+ },
+ [0x11954]={
+ category="nd",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0x11954,
+ },
+ [0x11955]={
+ category="nd",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0x11955,
+ },
+ [0x11956]={
+ category="nd",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0x11956,
+ },
+ [0x11957]={
+ category="nd",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0x11957,
+ },
+ [0x11958]={
+ category="nd",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0x11958,
+ },
+ [0x11959]={
+ category="nd",
+ direction="l",
+ linebreak="nu",
+ unicodeslot=0x11959,
+ },
[0x119A0]={
category="lo",
direction="l",
@@ -132224,6 +133360,12 @@ return {
linebreak="al",
unicodeslot=0x11EF8,
},
+ [0x11FB0]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x11FB0,
+ },
[0x11FC0]={
category="no",
direction="l",
@@ -156026,6 +157168,24 @@ return {
linebreak="ns",
unicodeslot=0x16FE3,
},
+ [0x16FE4]={
+ category="mn",
+ direction="nsm",
+ linebreak="gl",
+ unicodeslot=0x16FE4,
+ },
+ [0x16FF0]={
+ category="mc",
+ direction="l",
+ linebreak="cm",
+ unicodeslot=0x16FF0,
+ },
+ [0x16FF1]={
+ category="mc",
+ direction="l",
+ linebreak="cm",
+ unicodeslot=0x16FF1,
+ },
[0x18800]={
category="lo",
direction="l",
@@ -160556,6 +161716,2904 @@ return {
linebreak="id",
unicodeslot=0x18AF2,
},
+ [0x18AF3]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x18AF3,
+ },
+ [0x18AF4]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x18AF4,
+ },
+ [0x18AF5]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x18AF5,
+ },
+ [0x18AF6]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x18AF6,
+ },
+ [0x18AF7]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x18AF7,
+ },
+ [0x18AF8]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x18AF8,
+ },
+ [0x18AF9]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x18AF9,
+ },
+ [0x18AFA]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x18AFA,
+ },
+ [0x18AFB]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x18AFB,
+ },
+ [0x18AFC]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x18AFC,
+ },
+ [0x18AFD]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x18AFD,
+ },
+ [0x18AFE]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x18AFE,
+ },
+ [0x18AFF]={
+ category="lo",
+ direction="l",
+ linebreak="id",
+ unicodeslot=0x18AFF,
+ },
+ [0x18B00]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x18B00,
+ },
+ [0x18B01]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x18B01,
+ },
+ [0x18B02]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x18B02,
+ },
+ [0x18B03]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x18B03,
+ },
+ [0x18B04]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x18B04,
+ },
+ [0x18B05]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x18B05,
+ },
+ [0x18B06]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x18B06,
+ },
+ [0x18B07]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x18B07,
+ },
+ [0x18B08]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x18B08,
+ },
+ [0x18B09]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x18B09,
+ },
+ [0x18B0A]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x18B0A,
+ },
+ [0x18B0B]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x18B0B,
+ },
+ [0x18B0C]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x18B0C,
+ },
+ [0x18B0D]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x18B0D,
+ },
+ [0x18B0E]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x18B0E,
+ },
+ [0x18B0F]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x18B0F,
+ },
+ [0x18B10]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x18B10,
+ },
+ [0x18B11]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x18B11,
+ },
+ [0x18B12]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x18B12,
+ },
+ [0x18B13]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x18B13,
+ },
+ [0x18B14]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x18B14,
+ },
+ [0x18B15]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x18B15,
+ },
+ [0x18B16]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x18B16,
+ },
+ [0x18B17]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x18B17,
+ },
+ [0x18B18]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x18B18,
+ },
+ [0x18B19]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x18B19,
+ },
+ [0x18B1A]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x18B1A,
+ },
+ [0x18B1B]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x18B1B,
+ },
+ [0x18B1C]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x18B1C,
+ },
+ [0x18B1D]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x18B1D,
+ },
+ [0x18B1E]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x18B1E,
+ },
+ [0x18B1F]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x18B1F,
+ },
+ [0x18B20]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x18B20,
+ },
+ [0x18B21]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x18B21,
+ },
+ [0x18B22]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x18B22,
+ },
+ [0x18B23]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x18B23,
+ },
+ [0x18B24]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x18B24,
+ },
+ [0x18B25]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x18B25,
+ },
+ [0x18B26]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x18B26,
+ },
+ [0x18B27]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x18B27,
+ },
+ [0x18B28]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x18B28,
+ },
+ [0x18B29]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x18B29,
+ },
+ [0x18B2A]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x18B2A,
+ },
+ [0x18B2B]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x18B2B,
+ },
+ [0x18B2C]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x18B2C,
+ },
+ [0x18B2D]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x18B2D,
+ },
+ [0x18B2E]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x18B2E,
+ },
+ [0x18B2F]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x18B2F,
+ },
+ [0x18B30]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x18B30,
+ },
+ [0x18B31]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x18B31,
+ },
+ [0x18B32]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x18B32,
+ },
+ [0x18B33]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x18B33,
+ },
+ [0x18B34]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x18B34,
+ },
+ [0x18B35]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x18B35,
+ },
+ [0x18B36]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x18B36,
+ },
+ [0x18B37]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x18B37,
+ },
+ [0x18B38]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x18B38,
+ },
+ [0x18B39]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x18B39,
+ },
+ [0x18B3A]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x18B3A,
+ },
+ [0x18B3B]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x18B3B,
+ },
+ [0x18B3C]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x18B3C,
+ },
+ [0x18B3D]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x18B3D,
+ },
+ [0x18B3E]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x18B3E,
+ },
+ [0x18B3F]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x18B3F,
+ },
+ [0x18B40]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x18B40,
+ },
+ [0x18B41]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x18B41,
+ },
+ [0x18B42]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x18B42,
+ },
+ [0x18B43]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x18B43,
+ },
+ [0x18B44]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x18B44,
+ },
+ [0x18B45]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x18B45,
+ },
+ [0x18B46]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x18B46,
+ },
+ [0x18B47]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x18B47,
+ },
+ [0x18B48]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x18B48,
+ },
+ [0x18B49]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x18B49,
+ },
+ [0x18B4A]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x18B4A,
+ },
+ [0x18B4B]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x18B4B,
+ },
+ [0x18B4C]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x18B4C,
+ },
+ [0x18B4D]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x18B4D,
+ },
+ [0x18B4E]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x18B4E,
+ },
+ [0x18B4F]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x18B4F,
+ },
+ [0x18B50]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x18B50,
+ },
+ [0x18B51]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x18B51,
+ },
+ [0x18B52]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x18B52,
+ },
+ [0x18B53]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x18B53,
+ },
+ [0x18B54]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x18B54,
+ },
+ [0x18B55]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x18B55,
+ },
+ [0x18B56]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x18B56,
+ },
+ [0x18B57]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x18B57,
+ },
+ [0x18B58]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x18B58,
+ },
+ [0x18B59]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x18B59,
+ },
+ [0x18B5A]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x18B5A,
+ },
+ [0x18B5B]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x18B5B,
+ },
+ [0x18B5C]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x18B5C,
+ },
+ [0x18B5D]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x18B5D,
+ },
+ [0x18B5E]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x18B5E,
+ },
+ [0x18B5F]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x18B5F,
+ },
+ [0x18B60]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x18B60,
+ },
+ [0x18B61]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x18B61,
+ },
+ [0x18B62]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x18B62,
+ },
+ [0x18B63]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x18B63,
+ },
+ [0x18B64]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x18B64,
+ },
+ [0x18B65]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x18B65,
+ },
+ [0x18B66]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x18B66,
+ },
+ [0x18B67]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x18B67,
+ },
+ [0x18B68]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x18B68,
+ },
+ [0x18B69]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x18B69,
+ },
+ [0x18B6A]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x18B6A,
+ },
+ [0x18B6B]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x18B6B,
+ },
+ [0x18B6C]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x18B6C,
+ },
+ [0x18B6D]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x18B6D,
+ },
+ [0x18B6E]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x18B6E,
+ },
+ [0x18B6F]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x18B6F,
+ },
+ [0x18B70]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x18B70,
+ },
+ [0x18B71]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x18B71,
+ },
+ [0x18B72]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x18B72,
+ },
+ [0x18B73]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x18B73,
+ },
+ [0x18B74]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x18B74,
+ },
+ [0x18B75]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x18B75,
+ },
+ [0x18B76]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x18B76,
+ },
+ [0x18B77]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x18B77,
+ },
+ [0x18B78]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x18B78,
+ },
+ [0x18B79]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x18B79,
+ },
+ [0x18B7A]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x18B7A,
+ },
+ [0x18B7B]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x18B7B,
+ },
+ [0x18B7C]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x18B7C,
+ },
+ [0x18B7D]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x18B7D,
+ },
+ [0x18B7E]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x18B7E,
+ },
+ [0x18B7F]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x18B7F,
+ },
+ [0x18B80]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x18B80,
+ },
+ [0x18B81]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x18B81,
+ },
+ [0x18B82]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x18B82,
+ },
+ [0x18B83]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x18B83,
+ },
+ [0x18B84]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x18B84,
+ },
+ [0x18B85]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x18B85,
+ },
+ [0x18B86]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x18B86,
+ },
+ [0x18B87]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x18B87,
+ },
+ [0x18B88]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x18B88,
+ },
+ [0x18B89]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x18B89,
+ },
+ [0x18B8A]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x18B8A,
+ },
+ [0x18B8B]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x18B8B,
+ },
+ [0x18B8C]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x18B8C,
+ },
+ [0x18B8D]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x18B8D,
+ },
+ [0x18B8E]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x18B8E,
+ },
+ [0x18B8F]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x18B8F,
+ },
+ [0x18B90]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x18B90,
+ },
+ [0x18B91]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x18B91,
+ },
+ [0x18B92]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x18B92,
+ },
+ [0x18B93]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x18B93,
+ },
+ [0x18B94]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x18B94,
+ },
+ [0x18B95]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x18B95,
+ },
+ [0x18B96]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x18B96,
+ },
+ [0x18B97]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x18B97,
+ },
+ [0x18B98]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x18B98,
+ },
+ [0x18B99]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x18B99,
+ },
+ [0x18B9A]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x18B9A,
+ },
+ [0x18B9B]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x18B9B,
+ },
+ [0x18B9C]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x18B9C,
+ },
+ [0x18B9D]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x18B9D,
+ },
+ [0x18B9E]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x18B9E,
+ },
+ [0x18B9F]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x18B9F,
+ },
+ [0x18BA0]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x18BA0,
+ },
+ [0x18BA1]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x18BA1,
+ },
+ [0x18BA2]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x18BA2,
+ },
+ [0x18BA3]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x18BA3,
+ },
+ [0x18BA4]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x18BA4,
+ },
+ [0x18BA5]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x18BA5,
+ },
+ [0x18BA6]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x18BA6,
+ },
+ [0x18BA7]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x18BA7,
+ },
+ [0x18BA8]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x18BA8,
+ },
+ [0x18BA9]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x18BA9,
+ },
+ [0x18BAA]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x18BAA,
+ },
+ [0x18BAB]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x18BAB,
+ },
+ [0x18BAC]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x18BAC,
+ },
+ [0x18BAD]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x18BAD,
+ },
+ [0x18BAE]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x18BAE,
+ },
+ [0x18BAF]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x18BAF,
+ },
+ [0x18BB0]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x18BB0,
+ },
+ [0x18BB1]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x18BB1,
+ },
+ [0x18BB2]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x18BB2,
+ },
+ [0x18BB3]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x18BB3,
+ },
+ [0x18BB4]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x18BB4,
+ },
+ [0x18BB5]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x18BB5,
+ },
+ [0x18BB6]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x18BB6,
+ },
+ [0x18BB7]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x18BB7,
+ },
+ [0x18BB8]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x18BB8,
+ },
+ [0x18BB9]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x18BB9,
+ },
+ [0x18BBA]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x18BBA,
+ },
+ [0x18BBB]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x18BBB,
+ },
+ [0x18BBC]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x18BBC,
+ },
+ [0x18BBD]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x18BBD,
+ },
+ [0x18BBE]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x18BBE,
+ },
+ [0x18BBF]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x18BBF,
+ },
+ [0x18BC0]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x18BC0,
+ },
+ [0x18BC1]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x18BC1,
+ },
+ [0x18BC2]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x18BC2,
+ },
+ [0x18BC3]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x18BC3,
+ },
+ [0x18BC4]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x18BC4,
+ },
+ [0x18BC5]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x18BC5,
+ },
+ [0x18BC6]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x18BC6,
+ },
+ [0x18BC7]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x18BC7,
+ },
+ [0x18BC8]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x18BC8,
+ },
+ [0x18BC9]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x18BC9,
+ },
+ [0x18BCA]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x18BCA,
+ },
+ [0x18BCB]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x18BCB,
+ },
+ [0x18BCC]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x18BCC,
+ },
+ [0x18BCD]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x18BCD,
+ },
+ [0x18BCE]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x18BCE,
+ },
+ [0x18BCF]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x18BCF,
+ },
+ [0x18BD0]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x18BD0,
+ },
+ [0x18BD1]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x18BD1,
+ },
+ [0x18BD2]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x18BD2,
+ },
+ [0x18BD3]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x18BD3,
+ },
+ [0x18BD4]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x18BD4,
+ },
+ [0x18BD5]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x18BD5,
+ },
+ [0x18BD6]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x18BD6,
+ },
+ [0x18BD7]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x18BD7,
+ },
+ [0x18BD8]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x18BD8,
+ },
+ [0x18BD9]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x18BD9,
+ },
+ [0x18BDA]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x18BDA,
+ },
+ [0x18BDB]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x18BDB,
+ },
+ [0x18BDC]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x18BDC,
+ },
+ [0x18BDD]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x18BDD,
+ },
+ [0x18BDE]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x18BDE,
+ },
+ [0x18BDF]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x18BDF,
+ },
+ [0x18BE0]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x18BE0,
+ },
+ [0x18BE1]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x18BE1,
+ },
+ [0x18BE2]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x18BE2,
+ },
+ [0x18BE3]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x18BE3,
+ },
+ [0x18BE4]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x18BE4,
+ },
+ [0x18BE5]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x18BE5,
+ },
+ [0x18BE6]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x18BE6,
+ },
+ [0x18BE7]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x18BE7,
+ },
+ [0x18BE8]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x18BE8,
+ },
+ [0x18BE9]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x18BE9,
+ },
+ [0x18BEA]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x18BEA,
+ },
+ [0x18BEB]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x18BEB,
+ },
+ [0x18BEC]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x18BEC,
+ },
+ [0x18BED]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x18BED,
+ },
+ [0x18BEE]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x18BEE,
+ },
+ [0x18BEF]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x18BEF,
+ },
+ [0x18BF0]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x18BF0,
+ },
+ [0x18BF1]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x18BF1,
+ },
+ [0x18BF2]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x18BF2,
+ },
+ [0x18BF3]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x18BF3,
+ },
+ [0x18BF4]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x18BF4,
+ },
+ [0x18BF5]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x18BF5,
+ },
+ [0x18BF6]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x18BF6,
+ },
+ [0x18BF7]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x18BF7,
+ },
+ [0x18BF8]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x18BF8,
+ },
+ [0x18BF9]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x18BF9,
+ },
+ [0x18BFA]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x18BFA,
+ },
+ [0x18BFB]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x18BFB,
+ },
+ [0x18BFC]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x18BFC,
+ },
+ [0x18BFD]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x18BFD,
+ },
+ [0x18BFE]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x18BFE,
+ },
+ [0x18BFF]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x18BFF,
+ },
+ [0x18C00]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x18C00,
+ },
+ [0x18C01]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x18C01,
+ },
+ [0x18C02]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x18C02,
+ },
+ [0x18C03]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x18C03,
+ },
+ [0x18C04]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x18C04,
+ },
+ [0x18C05]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x18C05,
+ },
+ [0x18C06]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x18C06,
+ },
+ [0x18C07]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x18C07,
+ },
+ [0x18C08]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x18C08,
+ },
+ [0x18C09]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x18C09,
+ },
+ [0x18C0A]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x18C0A,
+ },
+ [0x18C0B]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x18C0B,
+ },
+ [0x18C0C]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x18C0C,
+ },
+ [0x18C0D]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x18C0D,
+ },
+ [0x18C0E]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x18C0E,
+ },
+ [0x18C0F]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x18C0F,
+ },
+ [0x18C10]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x18C10,
+ },
+ [0x18C11]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x18C11,
+ },
+ [0x18C12]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x18C12,
+ },
+ [0x18C13]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x18C13,
+ },
+ [0x18C14]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x18C14,
+ },
+ [0x18C15]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x18C15,
+ },
+ [0x18C16]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x18C16,
+ },
+ [0x18C17]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x18C17,
+ },
+ [0x18C18]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x18C18,
+ },
+ [0x18C19]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x18C19,
+ },
+ [0x18C1A]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x18C1A,
+ },
+ [0x18C1B]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x18C1B,
+ },
+ [0x18C1C]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x18C1C,
+ },
+ [0x18C1D]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x18C1D,
+ },
+ [0x18C1E]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x18C1E,
+ },
+ [0x18C1F]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x18C1F,
+ },
+ [0x18C20]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x18C20,
+ },
+ [0x18C21]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x18C21,
+ },
+ [0x18C22]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x18C22,
+ },
+ [0x18C23]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x18C23,
+ },
+ [0x18C24]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x18C24,
+ },
+ [0x18C25]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x18C25,
+ },
+ [0x18C26]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x18C26,
+ },
+ [0x18C27]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x18C27,
+ },
+ [0x18C28]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x18C28,
+ },
+ [0x18C29]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x18C29,
+ },
+ [0x18C2A]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x18C2A,
+ },
+ [0x18C2B]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x18C2B,
+ },
+ [0x18C2C]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x18C2C,
+ },
+ [0x18C2D]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x18C2D,
+ },
+ [0x18C2E]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x18C2E,
+ },
+ [0x18C2F]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x18C2F,
+ },
+ [0x18C30]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x18C30,
+ },
+ [0x18C31]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x18C31,
+ },
+ [0x18C32]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x18C32,
+ },
+ [0x18C33]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x18C33,
+ },
+ [0x18C34]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x18C34,
+ },
+ [0x18C35]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x18C35,
+ },
+ [0x18C36]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x18C36,
+ },
+ [0x18C37]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x18C37,
+ },
+ [0x18C38]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x18C38,
+ },
+ [0x18C39]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x18C39,
+ },
+ [0x18C3A]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x18C3A,
+ },
+ [0x18C3B]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x18C3B,
+ },
+ [0x18C3C]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x18C3C,
+ },
+ [0x18C3D]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x18C3D,
+ },
+ [0x18C3E]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x18C3E,
+ },
+ [0x18C3F]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x18C3F,
+ },
+ [0x18C40]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x18C40,
+ },
+ [0x18C41]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x18C41,
+ },
+ [0x18C42]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x18C42,
+ },
+ [0x18C43]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x18C43,
+ },
+ [0x18C44]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x18C44,
+ },
+ [0x18C45]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x18C45,
+ },
+ [0x18C46]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x18C46,
+ },
+ [0x18C47]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x18C47,
+ },
+ [0x18C48]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x18C48,
+ },
+ [0x18C49]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x18C49,
+ },
+ [0x18C4A]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x18C4A,
+ },
+ [0x18C4B]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x18C4B,
+ },
+ [0x18C4C]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x18C4C,
+ },
+ [0x18C4D]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x18C4D,
+ },
+ [0x18C4E]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x18C4E,
+ },
+ [0x18C4F]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x18C4F,
+ },
+ [0x18C50]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x18C50,
+ },
+ [0x18C51]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x18C51,
+ },
+ [0x18C52]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x18C52,
+ },
+ [0x18C53]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x18C53,
+ },
+ [0x18C54]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x18C54,
+ },
+ [0x18C55]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x18C55,
+ },
+ [0x18C56]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x18C56,
+ },
+ [0x18C57]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x18C57,
+ },
+ [0x18C58]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x18C58,
+ },
+ [0x18C59]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x18C59,
+ },
+ [0x18C5A]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x18C5A,
+ },
+ [0x18C5B]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x18C5B,
+ },
+ [0x18C5C]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x18C5C,
+ },
+ [0x18C5D]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x18C5D,
+ },
+ [0x18C5E]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x18C5E,
+ },
+ [0x18C5F]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x18C5F,
+ },
+ [0x18C60]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x18C60,
+ },
+ [0x18C61]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x18C61,
+ },
+ [0x18C62]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x18C62,
+ },
+ [0x18C63]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x18C63,
+ },
+ [0x18C64]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x18C64,
+ },
+ [0x18C65]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x18C65,
+ },
+ [0x18C66]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x18C66,
+ },
+ [0x18C67]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x18C67,
+ },
+ [0x18C68]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x18C68,
+ },
+ [0x18C69]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x18C69,
+ },
+ [0x18C6A]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x18C6A,
+ },
+ [0x18C6B]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x18C6B,
+ },
+ [0x18C6C]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x18C6C,
+ },
+ [0x18C6D]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x18C6D,
+ },
+ [0x18C6E]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x18C6E,
+ },
+ [0x18C6F]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x18C6F,
+ },
+ [0x18C70]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x18C70,
+ },
+ [0x18C71]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x18C71,
+ },
+ [0x18C72]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x18C72,
+ },
+ [0x18C73]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x18C73,
+ },
+ [0x18C74]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x18C74,
+ },
+ [0x18C75]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x18C75,
+ },
+ [0x18C76]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x18C76,
+ },
+ [0x18C77]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x18C77,
+ },
+ [0x18C78]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x18C78,
+ },
+ [0x18C79]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x18C79,
+ },
+ [0x18C7A]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x18C7A,
+ },
+ [0x18C7B]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x18C7B,
+ },
+ [0x18C7C]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x18C7C,
+ },
+ [0x18C7D]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x18C7D,
+ },
+ [0x18C7E]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x18C7E,
+ },
+ [0x18C7F]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x18C7F,
+ },
+ [0x18C80]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x18C80,
+ },
+ [0x18C81]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x18C81,
+ },
+ [0x18C82]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x18C82,
+ },
+ [0x18C83]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x18C83,
+ },
+ [0x18C84]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x18C84,
+ },
+ [0x18C85]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x18C85,
+ },
+ [0x18C86]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x18C86,
+ },
+ [0x18C87]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x18C87,
+ },
+ [0x18C88]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x18C88,
+ },
+ [0x18C89]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x18C89,
+ },
+ [0x18C8A]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x18C8A,
+ },
+ [0x18C8B]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x18C8B,
+ },
+ [0x18C8C]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x18C8C,
+ },
+ [0x18C8D]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x18C8D,
+ },
+ [0x18C8E]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x18C8E,
+ },
+ [0x18C8F]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x18C8F,
+ },
+ [0x18C90]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x18C90,
+ },
+ [0x18C91]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x18C91,
+ },
+ [0x18C92]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x18C92,
+ },
+ [0x18C93]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x18C93,
+ },
+ [0x18C94]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x18C94,
+ },
+ [0x18C95]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x18C95,
+ },
+ [0x18C96]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x18C96,
+ },
+ [0x18C97]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x18C97,
+ },
+ [0x18C98]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x18C98,
+ },
+ [0x18C99]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x18C99,
+ },
+ [0x18C9A]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x18C9A,
+ },
+ [0x18C9B]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x18C9B,
+ },
+ [0x18C9C]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x18C9C,
+ },
+ [0x18C9D]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x18C9D,
+ },
+ [0x18C9E]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x18C9E,
+ },
+ [0x18C9F]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x18C9F,
+ },
+ [0x18CA0]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x18CA0,
+ },
+ [0x18CA1]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x18CA1,
+ },
+ [0x18CA2]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x18CA2,
+ },
+ [0x18CA3]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x18CA3,
+ },
+ [0x18CA4]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x18CA4,
+ },
+ [0x18CA5]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x18CA5,
+ },
+ [0x18CA6]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x18CA6,
+ },
+ [0x18CA7]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x18CA7,
+ },
+ [0x18CA8]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x18CA8,
+ },
+ [0x18CA9]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x18CA9,
+ },
+ [0x18CAA]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x18CAA,
+ },
+ [0x18CAB]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x18CAB,
+ },
+ [0x18CAC]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x18CAC,
+ },
+ [0x18CAD]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x18CAD,
+ },
+ [0x18CAE]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x18CAE,
+ },
+ [0x18CAF]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x18CAF,
+ },
+ [0x18CB0]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x18CB0,
+ },
+ [0x18CB1]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x18CB1,
+ },
+ [0x18CB2]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x18CB2,
+ },
+ [0x18CB3]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x18CB3,
+ },
+ [0x18CB4]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x18CB4,
+ },
+ [0x18CB5]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x18CB5,
+ },
+ [0x18CB6]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x18CB6,
+ },
+ [0x18CB7]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x18CB7,
+ },
+ [0x18CB8]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x18CB8,
+ },
+ [0x18CB9]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x18CB9,
+ },
+ [0x18CBA]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x18CBA,
+ },
+ [0x18CBB]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x18CBB,
+ },
+ [0x18CBC]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x18CBC,
+ },
+ [0x18CBD]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x18CBD,
+ },
+ [0x18CBE]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x18CBE,
+ },
+ [0x18CBF]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x18CBF,
+ },
+ [0x18CC0]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x18CC0,
+ },
+ [0x18CC1]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x18CC1,
+ },
+ [0x18CC2]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x18CC2,
+ },
+ [0x18CC3]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x18CC3,
+ },
+ [0x18CC4]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x18CC4,
+ },
+ [0x18CC5]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x18CC5,
+ },
+ [0x18CC6]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x18CC6,
+ },
+ [0x18CC7]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x18CC7,
+ },
+ [0x18CC8]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x18CC8,
+ },
+ [0x18CC9]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x18CC9,
+ },
+ [0x18CCA]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x18CCA,
+ },
+ [0x18CCB]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x18CCB,
+ },
+ [0x18CCC]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x18CCC,
+ },
+ [0x18CCD]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x18CCD,
+ },
+ [0x18CCE]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x18CCE,
+ },
+ [0x18CCF]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x18CCF,
+ },
+ [0x18CD0]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x18CD0,
+ },
+ [0x18CD1]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x18CD1,
+ },
+ [0x18CD2]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x18CD2,
+ },
+ [0x18CD3]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x18CD3,
+ },
+ [0x18CD4]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x18CD4,
+ },
+ [0x18CD5]={
+ category="lo",
+ direction="l",
+ linebreak="al",
+ unicodeslot=0x18CD5,
+ },
[0x1B000]={
category="lo",
direction="l",
@@ -186701,6 +190759,24 @@ return {
linebreak="ai",
unicodeslot=0x1F10C,
},
+ [0x1F10D]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F10D,
+ },
+ [0x1F10E]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F10E,
+ },
+ [0x1F10F]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F10F,
+ },
[0x1F110]={
category="so",
direction="l",
@@ -187325,6 +191401,24 @@ return {
specials={ "super", 0x4D, 0x52 },
unicodeslot=0x1F16C,
},
+ [0x1F16D]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F16D,
+ },
+ [0x1F16E]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F16E,
+ },
+ [0x1F16F]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F16F,
+ },
[0x1F170]={
category="so",
direction="l",
@@ -187692,6 +191786,12 @@ return {
linebreak="ai",
unicodeslot=0x1F1AC,
},
+ [0x1F1AD]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F1AD,
+ },
[0x1F1E6]={
category="so",
direction="l",
@@ -194182,6 +198282,18 @@ return {
linebreak="id",
unicodeslot=0x1F6D5,
},
+ [0x1F6D6]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F6D6,
+ },
+ [0x1F6D7]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F6D7,
+ },
[0x1F6E0]={
category="so",
direction="on",
@@ -194326,6 +198438,18 @@ return {
linebreak="id",
unicodeslot=0x1F6FA,
},
+ [0x1F6FB]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F6FB,
+ },
+ [0x1F6FC]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F6FC,
+ },
[0x1F700]={
category="so",
direction="on",
@@ -196516,6 +200640,18 @@ return {
linebreak="al",
unicodeslot=0x1F8AD,
},
+ [0x1F8B0]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F8B0,
+ },
+ [0x1F8B1]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F8B1,
+ },
[0x1F900]={
category="so",
direction="on",
@@ -196588,6 +200724,12 @@ return {
linebreak="al",
unicodeslot=0x1F90B,
},
+ [0x1F90C]={
+ category="so",
+ direction="on",
+ linebreak="eb",
+ unicodeslot=0x1F90C,
+ },
[0x1F90D]={
category="so",
direction="on",
@@ -197194,6 +201336,12 @@ return {
linebreak="id",
unicodeslot=0x1F971,
},
+ [0x1F972]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F972,
+ },
[0x1F973]={
category="so",
direction="on",
@@ -197218,6 +201366,18 @@ return {
linebreak="id",
unicodeslot=0x1F976,
},
+ [0x1F977]={
+ category="so",
+ direction="on",
+ linebreak="eb",
+ unicodeslot=0x1F977,
+ },
+ [0x1F978]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F978,
+ },
[0x1F97A]={
category="so",
direction="on",
@@ -197464,6 +201624,18 @@ return {
linebreak="id",
unicodeslot=0x1F9A2,
},
+ [0x1F9A3]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F9A3,
+ },
+ [0x1F9A4]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F9A4,
+ },
[0x1F9A5]={
category="so",
direction="on",
@@ -197500,6 +201672,24 @@ return {
linebreak="id",
unicodeslot=0x1F9AA,
},
+ [0x1F9AB]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F9AB,
+ },
+ [0x1F9AC]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F9AC,
+ },
+ [0x1F9AD]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F9AD,
+ },
[0x1F9AE]={
category="so",
direction="on",
@@ -197674,6 +201864,12 @@ return {
linebreak="id",
unicodeslot=0x1F9CA,
},
+ [0x1F9CB]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1F9CB,
+ },
[0x1F9CD]={
category="so",
direction="on",
@@ -198592,6 +202788,12 @@ return {
linebreak="id",
unicodeslot=0x1FA73,
},
+ [0x1FA74]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1FA74,
+ },
[0x1FA78]={
category="so",
direction="on",
@@ -198628,6 +202830,30 @@ return {
linebreak="id",
unicodeslot=0x1FA82,
},
+ [0x1FA83]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1FA83,
+ },
+ [0x1FA84]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1FA84,
+ },
+ [0x1FA85]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1FA85,
+ },
+ [0x1FA86]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1FA86,
+ },
[0x1FA90]={
category="so",
direction="on",
@@ -198664,6 +202890,1504 @@ return {
linebreak="id",
unicodeslot=0x1FA95,
},
+ [0x1FA96]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1FA96,
+ },
+ [0x1FA97]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1FA97,
+ },
+ [0x1FA98]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1FA98,
+ },
+ [0x1FA99]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1FA99,
+ },
+ [0x1FA9A]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1FA9A,
+ },
+ [0x1FA9B]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1FA9B,
+ },
+ [0x1FA9C]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1FA9C,
+ },
+ [0x1FA9D]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1FA9D,
+ },
+ [0x1FA9E]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1FA9E,
+ },
+ [0x1FA9F]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1FA9F,
+ },
+ [0x1FAA0]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1FAA0,
+ },
+ [0x1FAA1]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1FAA1,
+ },
+ [0x1FAA2]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1FAA2,
+ },
+ [0x1FAA3]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1FAA3,
+ },
+ [0x1FAA4]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1FAA4,
+ },
+ [0x1FAA5]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1FAA5,
+ },
+ [0x1FAA6]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1FAA6,
+ },
+ [0x1FAA7]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1FAA7,
+ },
+ [0x1FAA8]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1FAA8,
+ },
+ [0x1FAB0]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1FAB0,
+ },
+ [0x1FAB1]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1FAB1,
+ },
+ [0x1FAB2]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1FAB2,
+ },
+ [0x1FAB3]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1FAB3,
+ },
+ [0x1FAB4]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1FAB4,
+ },
+ [0x1FAB5]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1FAB5,
+ },
+ [0x1FAB6]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1FAB6,
+ },
+ [0x1FAC0]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1FAC0,
+ },
+ [0x1FAC1]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1FAC1,
+ },
+ [0x1FAC2]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1FAC2,
+ },
+ [0x1FAD0]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1FAD0,
+ },
+ [0x1FAD1]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1FAD1,
+ },
+ [0x1FAD2]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1FAD2,
+ },
+ [0x1FAD3]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1FAD3,
+ },
+ [0x1FAD4]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1FAD4,
+ },
+ [0x1FAD5]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1FAD5,
+ },
+ [0x1FAD6]={
+ category="so",
+ direction="on",
+ linebreak="id",
+ unicodeslot=0x1FAD6,
+ },
+ [0x1FB00]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1FB00,
+ },
+ [0x1FB01]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1FB01,
+ },
+ [0x1FB02]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1FB02,
+ },
+ [0x1FB03]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1FB03,
+ },
+ [0x1FB04]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1FB04,
+ },
+ [0x1FB05]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1FB05,
+ },
+ [0x1FB06]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1FB06,
+ },
+ [0x1FB07]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1FB07,
+ },
+ [0x1FB08]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1FB08,
+ },
+ [0x1FB09]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1FB09,
+ },
+ [0x1FB0A]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1FB0A,
+ },
+ [0x1FB0B]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1FB0B,
+ },
+ [0x1FB0C]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1FB0C,
+ },
+ [0x1FB0D]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1FB0D,
+ },
+ [0x1FB0E]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1FB0E,
+ },
+ [0x1FB0F]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1FB0F,
+ },
+ [0x1FB10]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1FB10,
+ },
+ [0x1FB11]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1FB11,
+ },
+ [0x1FB12]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1FB12,
+ },
+ [0x1FB13]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1FB13,
+ },
+ [0x1FB14]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1FB14,
+ },
+ [0x1FB15]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1FB15,
+ },
+ [0x1FB16]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1FB16,
+ },
+ [0x1FB17]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1FB17,
+ },
+ [0x1FB18]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1FB18,
+ },
+ [0x1FB19]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1FB19,
+ },
+ [0x1FB1A]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1FB1A,
+ },
+ [0x1FB1B]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1FB1B,
+ },
+ [0x1FB1C]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1FB1C,
+ },
+ [0x1FB1D]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1FB1D,
+ },
+ [0x1FB1E]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1FB1E,
+ },
+ [0x1FB1F]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1FB1F,
+ },
+ [0x1FB20]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1FB20,
+ },
+ [0x1FB21]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1FB21,
+ },
+ [0x1FB22]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1FB22,
+ },
+ [0x1FB23]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1FB23,
+ },
+ [0x1FB24]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1FB24,
+ },
+ [0x1FB25]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1FB25,
+ },
+ [0x1FB26]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1FB26,
+ },
+ [0x1FB27]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1FB27,
+ },
+ [0x1FB28]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1FB28,
+ },
+ [0x1FB29]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1FB29,
+ },
+ [0x1FB2A]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1FB2A,
+ },
+ [0x1FB2B]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1FB2B,
+ },
+ [0x1FB2C]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1FB2C,
+ },
+ [0x1FB2D]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1FB2D,
+ },
+ [0x1FB2E]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1FB2E,
+ },
+ [0x1FB2F]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1FB2F,
+ },
+ [0x1FB30]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1FB30,
+ },
+ [0x1FB31]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1FB31,
+ },
+ [0x1FB32]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1FB32,
+ },
+ [0x1FB33]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1FB33,
+ },
+ [0x1FB34]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1FB34,
+ },
+ [0x1FB35]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1FB35,
+ },
+ [0x1FB36]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1FB36,
+ },
+ [0x1FB37]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1FB37,
+ },
+ [0x1FB38]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1FB38,
+ },
+ [0x1FB39]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1FB39,
+ },
+ [0x1FB3A]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1FB3A,
+ },
+ [0x1FB3B]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1FB3B,
+ },
+ [0x1FB3C]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1FB3C,
+ },
+ [0x1FB3D]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1FB3D,
+ },
+ [0x1FB3E]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1FB3E,
+ },
+ [0x1FB3F]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1FB3F,
+ },
+ [0x1FB40]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1FB40,
+ },
+ [0x1FB41]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1FB41,
+ },
+ [0x1FB42]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1FB42,
+ },
+ [0x1FB43]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1FB43,
+ },
+ [0x1FB44]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1FB44,
+ },
+ [0x1FB45]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1FB45,
+ },
+ [0x1FB46]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1FB46,
+ },
+ [0x1FB47]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1FB47,
+ },
+ [0x1FB48]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1FB48,
+ },
+ [0x1FB49]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1FB49,
+ },
+ [0x1FB4A]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1FB4A,
+ },
+ [0x1FB4B]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1FB4B,
+ },
+ [0x1FB4C]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1FB4C,
+ },
+ [0x1FB4D]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1FB4D,
+ },
+ [0x1FB4E]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1FB4E,
+ },
+ [0x1FB4F]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1FB4F,
+ },
+ [0x1FB50]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1FB50,
+ },
+ [0x1FB51]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1FB51,
+ },
+ [0x1FB52]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1FB52,
+ },
+ [0x1FB53]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1FB53,
+ },
+ [0x1FB54]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1FB54,
+ },
+ [0x1FB55]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1FB55,
+ },
+ [0x1FB56]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1FB56,
+ },
+ [0x1FB57]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1FB57,
+ },
+ [0x1FB58]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1FB58,
+ },
+ [0x1FB59]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1FB59,
+ },
+ [0x1FB5A]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1FB5A,
+ },
+ [0x1FB5B]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1FB5B,
+ },
+ [0x1FB5C]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1FB5C,
+ },
+ [0x1FB5D]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1FB5D,
+ },
+ [0x1FB5E]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1FB5E,
+ },
+ [0x1FB5F]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1FB5F,
+ },
+ [0x1FB60]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1FB60,
+ },
+ [0x1FB61]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1FB61,
+ },
+ [0x1FB62]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1FB62,
+ },
+ [0x1FB63]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1FB63,
+ },
+ [0x1FB64]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1FB64,
+ },
+ [0x1FB65]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1FB65,
+ },
+ [0x1FB66]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1FB66,
+ },
+ [0x1FB67]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1FB67,
+ },
+ [0x1FB68]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1FB68,
+ },
+ [0x1FB69]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1FB69,
+ },
+ [0x1FB6A]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1FB6A,
+ },
+ [0x1FB6B]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1FB6B,
+ },
+ [0x1FB6C]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1FB6C,
+ },
+ [0x1FB6D]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1FB6D,
+ },
+ [0x1FB6E]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1FB6E,
+ },
+ [0x1FB6F]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1FB6F,
+ },
+ [0x1FB70]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1FB70,
+ },
+ [0x1FB71]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1FB71,
+ },
+ [0x1FB72]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1FB72,
+ },
+ [0x1FB73]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1FB73,
+ },
+ [0x1FB74]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1FB74,
+ },
+ [0x1FB75]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1FB75,
+ },
+ [0x1FB76]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1FB76,
+ },
+ [0x1FB77]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1FB77,
+ },
+ [0x1FB78]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1FB78,
+ },
+ [0x1FB79]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1FB79,
+ },
+ [0x1FB7A]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1FB7A,
+ },
+ [0x1FB7B]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1FB7B,
+ },
+ [0x1FB7C]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1FB7C,
+ },
+ [0x1FB7D]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1FB7D,
+ },
+ [0x1FB7E]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1FB7E,
+ },
+ [0x1FB7F]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1FB7F,
+ },
+ [0x1FB80]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1FB80,
+ },
+ [0x1FB81]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1FB81,
+ },
+ [0x1FB82]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1FB82,
+ },
+ [0x1FB83]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1FB83,
+ },
+ [0x1FB84]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1FB84,
+ },
+ [0x1FB85]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1FB85,
+ },
+ [0x1FB86]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1FB86,
+ },
+ [0x1FB87]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1FB87,
+ },
+ [0x1FB88]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1FB88,
+ },
+ [0x1FB89]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1FB89,
+ },
+ [0x1FB8A]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1FB8A,
+ },
+ [0x1FB8B]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1FB8B,
+ },
+ [0x1FB8C]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1FB8C,
+ },
+ [0x1FB8D]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1FB8D,
+ },
+ [0x1FB8E]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1FB8E,
+ },
+ [0x1FB8F]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1FB8F,
+ },
+ [0x1FB90]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1FB90,
+ },
+ [0x1FB91]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1FB91,
+ },
+ [0x1FB92]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1FB92,
+ },
+ [0x1FB94]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1FB94,
+ },
+ [0x1FB95]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1FB95,
+ },
+ [0x1FB96]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1FB96,
+ },
+ [0x1FB97]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1FB97,
+ },
+ [0x1FB98]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1FB98,
+ },
+ [0x1FB99]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1FB99,
+ },
+ [0x1FB9A]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1FB9A,
+ },
+ [0x1FB9B]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1FB9B,
+ },
+ [0x1FB9C]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1FB9C,
+ },
+ [0x1FB9D]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1FB9D,
+ },
+ [0x1FB9E]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1FB9E,
+ },
+ [0x1FB9F]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1FB9F,
+ },
+ [0x1FBA0]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1FBA0,
+ },
+ [0x1FBA1]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1FBA1,
+ },
+ [0x1FBA2]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1FBA2,
+ },
+ [0x1FBA3]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1FBA3,
+ },
+ [0x1FBA4]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1FBA4,
+ },
+ [0x1FBA5]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1FBA5,
+ },
+ [0x1FBA6]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1FBA6,
+ },
+ [0x1FBA7]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1FBA7,
+ },
+ [0x1FBA8]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1FBA8,
+ },
+ [0x1FBA9]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1FBA9,
+ },
+ [0x1FBAA]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1FBAA,
+ },
+ [0x1FBAB]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1FBAB,
+ },
+ [0x1FBAC]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1FBAC,
+ },
+ [0x1FBAD]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1FBAD,
+ },
+ [0x1FBAE]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1FBAE,
+ },
+ [0x1FBAF]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1FBAF,
+ },
+ [0x1FBB0]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1FBB0,
+ },
+ [0x1FBB1]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1FBB1,
+ },
+ [0x1FBB2]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1FBB2,
+ },
+ [0x1FBB3]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1FBB3,
+ },
+ [0x1FBB4]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1FBB4,
+ },
+ [0x1FBB5]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1FBB5,
+ },
+ [0x1FBB6]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1FBB6,
+ },
+ [0x1FBB7]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1FBB7,
+ },
+ [0x1FBB8]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1FBB8,
+ },
+ [0x1FBB9]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1FBB9,
+ },
+ [0x1FBBA]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1FBBA,
+ },
+ [0x1FBBB]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1FBBB,
+ },
+ [0x1FBBC]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1FBBC,
+ },
+ [0x1FBBD]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1FBBD,
+ },
+ [0x1FBBE]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1FBBE,
+ },
+ [0x1FBBF]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1FBBF,
+ },
+ [0x1FBC0]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1FBC0,
+ },
+ [0x1FBC1]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1FBC1,
+ },
+ [0x1FBC2]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1FBC2,
+ },
+ [0x1FBC3]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1FBC3,
+ },
+ [0x1FBC4]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1FBC4,
+ },
+ [0x1FBC5]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1FBC5,
+ },
+ [0x1FBC6]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1FBC6,
+ },
+ [0x1FBC7]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1FBC7,
+ },
+ [0x1FBC8]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1FBC8,
+ },
+ [0x1FBC9]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1FBC9,
+ },
+ [0x1FBCA]={
+ category="so",
+ direction="on",
+ linebreak="al",
+ unicodeslot=0x1FBCA,
+ },
+ [0x1FBF0]={
+ category="nd",
+ direction="en",
+ linebreak="nu",
+ specials={ "font", 0x30 },
+ unicodeslot=0x1FBF0,
+ },
+ [0x1FBF1]={
+ category="nd",
+ direction="en",
+ linebreak="nu",
+ specials={ "font", 0x31 },
+ unicodeslot=0x1FBF1,
+ },
+ [0x1FBF2]={
+ category="nd",
+ direction="en",
+ linebreak="nu",
+ specials={ "font", 0x32 },
+ unicodeslot=0x1FBF2,
+ },
+ [0x1FBF3]={
+ category="nd",
+ direction="en",
+ linebreak="nu",
+ specials={ "font", 0x33 },
+ unicodeslot=0x1FBF3,
+ },
+ [0x1FBF4]={
+ category="nd",
+ direction="en",
+ linebreak="nu",
+ specials={ "font", 0x34 },
+ unicodeslot=0x1FBF4,
+ },
+ [0x1FBF5]={
+ category="nd",
+ direction="en",
+ linebreak="nu",
+ specials={ "font", 0x35 },
+ unicodeslot=0x1FBF5,
+ },
+ [0x1FBF6]={
+ category="nd",
+ direction="en",
+ linebreak="nu",
+ specials={ "font", 0x36 },
+ unicodeslot=0x1FBF6,
+ },
+ [0x1FBF7]={
+ category="nd",
+ direction="en",
+ linebreak="nu",
+ specials={ "font", 0x37 },
+ unicodeslot=0x1FBF7,
+ },
+ [0x1FBF8]={
+ category="nd",
+ direction="en",
+ linebreak="nu",
+ specials={ "font", 0x38 },
+ unicodeslot=0x1FBF8,
+ },
+ [0x1FBF9]={
+ category="nd",
+ direction="en",
+ linebreak="nu",
+ specials={ "font", 0x39 },
+ unicodeslot=0x1FBF9,
+ },
[0x2F800]={
category="lo",
direction="l",
@@ -203508,9 +209232,9 @@ return {
[0x853]=0x2,
[0x854]=0x3,
[0x855]=0x2,
- [0x856]=0x4,
- [0x857]=0x4,
- [0x858]=0x4,
+ [0x856]=0x3,
+ [0x857]=0x3,
+ [0x858]=0x3,
[0x860]=0x2,
[0x861]=0x4,
[0x862]=0x2,
@@ -203551,6 +209275,16 @@ return {
[0x8BB]=0x2,
[0x8BC]=0x2,
[0x8BD]=0x2,
+ [0x8BE]=0x2,
+ [0x8BF]=0x2,
+ [0x8C0]=0x2,
+ [0x8C1]=0x2,
+ [0x8C2]=0x2,
+ [0x8C3]=0x2,
+ [0x8C4]=0x2,
+ [0x8C5]=0x2,
+ [0x8C6]=0x2,
+ [0x8C7]=0x2,
[0x8E2]=0x4,
[0x1806]=0x4,
[0x1807]=0x2,
@@ -203873,6 +209607,34 @@ return {
[0x10F52]=0x2,
[0x10F53]=0x2,
[0x10F54]=0x3,
+ [0x10FB0]=0x2,
+ [0x10FB1]=0x4,
+ [0x10FB2]=0x2,
+ [0x10FB3]=0x2,
+ [0x10FB4]=0x3,
+ [0x10FB5]=0x3,
+ [0x10FB6]=0x3,
+ [0x10FB7]=0x4,
+ [0x10FB8]=0x2,
+ [0x10FB9]=0x3,
+ [0x10FBA]=0x3,
+ [0x10FBB]=0x2,
+ [0x10FBC]=0x2,
+ [0x10FBD]=0x3,
+ [0x10FBE]=0x2,
+ [0x10FBF]=0x2,
+ [0x10FC0]=0x4,
+ [0x10FC1]=0x2,
+ [0x10FC2]=0x3,
+ [0x10FC3]=0x3,
+ [0x10FC4]=0x2,
+ [0x10FC5]=0x4,
+ [0x10FC6]=0x4,
+ [0x10FC7]=0x4,
+ [0x10FC8]=0x4,
+ [0x10FC9]=0x3,
+ [0x10FCA]=0x2,
+ [0x10FCB]=0x1,
[0x110BD]=0x4,
[0x110CD]=0x4,
[0x1E900]=0x2,
diff --git a/macros/luatex/generic/luaotfload/luaotfload-colors.lua b/macros/luatex/generic/luaotfload/luaotfload-colors.lua
index 2569eb1b48..52d38a7eec 100644
--- a/macros/luatex/generic/luaotfload/luaotfload-colors.lua
+++ b/macros/luatex/generic/luaotfload/luaotfload-colors.lua
@@ -5,8 +5,8 @@
local ProvidesLuaModule = {
name = "luaotfload-colors",
- version = "3.12", --TAGVERSION
- date = "2020-02-02", --TAGDATE
+ version = "3.13", --TAGVERSION
+ date = "2020-05-01", --TAGDATE
description = "luaotfload submodule / color",
license = "GPL v2.0",
author = "Khaled Hosny, Elie Roux, Philipp Gesang, Dohyun Kim, David Carlisle",
@@ -59,55 +59,24 @@ local identifiers = fonts.hashes.identifiers
local add_color_callback --[[ this used to be a global‽ ]]
--[[doc--
-This converts a single octet into a decimal with three digits of
-precision. The optional second argument limits precision to a single
-digit.
---doc]]--
-
---- string -> bool? -> string
-local hex_to_dec = function (hex,one) --- one isn’t actually used anywhere ...
- if one then
- return stringformat("%.1g", tonumber(hex, 16)/255)
- else
- return stringformat("%.3g", tonumber(hex, 16)/255)
- end
-end
-
---[[doc--
-Color string validator / parser.
+Color string parser.
--doc]]--
local lpeg = require"lpeg"
local lpegmatch = lpeg.match
local C, Cg, Ct, P, R, S = lpeg.C, lpeg.Cg, lpeg.Ct, lpeg.P, lpeg.R, lpeg.S
+local spaces = S"\t "^0
local digit16 = R("09", "af", "AF")
local opaque = S("fF") * S("fF")
-local octet = C(digit16 * digit16)
-
-local p_rgb = octet * octet * octet
-local p_rgba = p_rgb * (octet - opaque)
-local valid_digits = C(p_rgba + p_rgb) -- matches eight or six hex digits
-
-local p_Crgb = Cg(octet/hex_to_dec, "red") --- for captures
- * Cg(octet/hex_to_dec, "green")
- * Cg(octet/hex_to_dec, "blue")
-local p_Crgba = p_Crgb * Cg(octet/hex_to_dec, "alpha")
-local extract_color = Ct(p_Crgba + p_Crgb)
-
---- string -> (string | nil)
-local sanitize_color_expression = function (digits)
- digits = tostring(digits)
- local sanitized = lpegmatch(valid_digits, digits)
- if not sanitized then
- logreport("both", 0, "color",
- "%q is not a valid rgb[a] color expression",
- digits)
- return nil
- end
- return sanitized
+local octet = digit16 * digit16 / function(s)
+ return tonumber(s, 16) / 255
end
+local extract_color = spaces * octet * octet * octet / function(r,g,b)
+ return stringformat("%.3g %.3g %.3g rg", r, g, b)
+ end * (opaque + octet)^-1 * spaces * -1
+
--- something is carried around in ``res``
--- for later use by color_handler() --- but what?
@@ -115,48 +84,37 @@ local res = nil
--- float -> unit
local function pageresources(alpha)
- res = res or {}
- res[alpha] = true
+ res = res or {true} -- Initialize with /TransGs1
+ local f = res[alpha]
+ or stringformat("/TransGs%.3g gs", alpha, alpha)
+ res[alpha] = f
+ return f
end
---- we store results of below color handler as tuples of
---- push/pop strings
-local color_cache = { } --- (string, (string * string)) hash_t
-
---- string -> (string * string)
-local hex_to_rgba = function (digits)
- if not digits then
+--- string -> (string | nil)
+local function sanitize_color_expression (digits)
+ digits = tostring(digits)
+ local rgb, a = lpegmatch(extract_color, digits)
+ if not rgb then
+ logreport("both", 0, "color",
+ "%q is not a valid rgb[a] color expression",
+ digits)
return
end
+ return rgb, (a and pageresources(a))
+end
- --- this is called like a thousand times, so some
- --- memoizing is in order.
- local cached = color_cache[digits]
- if not cached then
- local push, pop
- local rgb = lpegmatch(extract_color, digits)
- if rgb.alpha then
- pageresources(rgb.alpha)
- push = stringformat(
- "/TransGs%g gs %s %s %s rg",
- rgb.alpha,
- rgb.red,
- rgb.green,
- rgb.blue)
- pop = "0 g /TransGs1 gs"
- else
- push = stringformat(
- "%s %s %s rg",
- rgb.red,
- rgb.green,
- rgb.blue)
- pop = "0 g"
- end
- color_cache[digits] = { push, pop }
- return push, pop
- end
-
- return cached[1], cached[2]
+local color_stack = 0
+-- Beside maybe allowing {transpareny} package compatibility at some
+-- point, this ensures that the stack is only created if it is actually
+-- needed. Especially important because it adds /TransGs1 gs to every page
+local function transparent_stack()
+ -- if token.is_defined'TRP@colorstack' then -- transparency
+ -- transparent_stack = tonumber(token.get_macro'TRP@colorstack')
+ -- else
+ transparent_stack = pdf.newcolorstack("/TransGs1 gs","direct",true)
+ -- end
+ return transparent_stack
end
--- Luatex internal types
@@ -167,50 +125,44 @@ local hlist_t = nodetype("hlist")
local vlist_t = nodetype("vlist")
local whatsit_t = nodetype("whatsit")
local disc_t = nodetype("disc")
-local pdfliteral_t = node.subtype("pdf_literal")
local colorstack_t = node.subtype("pdf_colorstack")
-local mlist_to_hlist = node.mlist_to_hlist
local color_callback
local color_attr = luatexbase.new_attribute("luaotfload_color_attribute")
--- (node * node * string * bool * (bool | nil)) -> (node * node * (string | nil))
-local color_whatsit
-color_whatsit = function (head, curr, color, push, tail)
- local pushdata = hex_to_rgba(color)
+local custom_setcolor
+
+-- Pass nil for new_color or old_color to indicate no color
+-- If color is nil, pass tail to decide where to add whatsit
+local function color_whatsit (head, curr, stack, old_color, new_color, tail)
+ if new_color == old_color then
+ return head, curr, old_color
+ end
local colornode = newnode(whatsit_t, colorstack_t)
- setfield(colornode, "stack", 0)
- setfield(colornode, "command", push and 1 or 2) -- 1: push, 2: pop
- setfield(colornode, "data", push and pushdata or nil)
+ setfield(colornode, "stack", tonumber(stack) or stack())
+ setfield(colornode, "command", new_color and (old_color and 0 or 1) or 2) -- 1: push, 2: pop
+ setfield(colornode, "data", new_color) -- Is nil for pop
if tail then
head, curr = insert_node_after (head, curr, colornode)
else
head = insert_node_before(head, curr, colornode)
end
- if not push and color:len() > 6 then
- local colornode = newnode(whatsit_t, pdfliteral_t)
- setfield(colornode, "mode", 2)
- setfield(colornode, "data", "/TransGs1 gs")
- if tail then
- head, curr = insert_node_after (head, curr, colornode)
- else
- head = insert_node_before(head, curr, colornode)
- end
- end
- color = push and color or nil
- return head, curr, color
+ return head, curr, new_color
end
-- number -> string | nil
-local get_glyph_color = function (font_id, char)
+local function get_glyph_color (font_id, char)
local tfmdata = identifiers[font_id]
- local font_color = tfmdata and tfmdata.properties and tfmdata.properties.color
+ local properties = tfmdata and tfmdata.properties
+ local font_color = properties and properties.color_rgb
+ local font_transparent = properties and properties.color_a
if type(font_color) == "table" then
local char_tbl = tfmdata.characters[char]
char = char_tbl and (char_tbl.index or char)
- return char and font_color[char] or font_color.default
+ font_color = char and font_color[char] or font_color.default
+ font_transparent = font_transparent and (char and font_transparent[char] or font_transparent.default)
end
- return font_color
+ return font_color, font_transparent
end
--[[doc--
@@ -220,8 +172,7 @@ values during the node list traversal.
--doc]]--
--- (node * (string | nil)) -> (node * (string | nil))
-local node_colorize
-node_colorize = function (head, toplevel, current_color)
+local function node_colorize (head, toplevel, current_color, current_transparent)
local n = head
while n do
local n_id = getid(n)
@@ -229,70 +180,60 @@ node_colorize = function (head, toplevel, current_color)
if n_id == hlist_t or n_id == vlist_t then
local n_list = getlist(n)
if getattribute(n_list, color_attr) then
- if current_color then
- head, n, current_color = color_whatsit(head, n, current_color, false)
- end
+ head, n, current_color = color_whatsit(head, n, color_stack, current_color, nil)
+ head, n, current_transparent = color_whatsit(head, n, transparent_stack, current_transparent, nil)
else
- n_list, current_color = node_colorize(n_list, false, current_color)
- if current_color and getsubtype(n) == 1 then -- created by linebreak
- n_list, _, current_color = color_whatsit(n_list, nodetail(n_list), current_color, false, true)
+ n_list, current_color, current_transparent = node_colorize(n_list, false, current_color, current_transparent)
+ if getsubtype(n) == 1 then -- created by linebreak
+ local nn = nodetail(n_list)
+ n_list, nn, current_color = color_whatsit(n_list, nn, color_stack, current_color, nil, true)
+ n_list, nn, current_transparent = color_whatsit(n_list, nn, transparent_stack, current_transparent, nil, true)
end
setfield(n, "head", n_list)
end
elseif n_id == disc_t then
local n_pre, n_post, n_replace = getdisc(n)
- n_replace, current_color = node_colorize(n_replace, false, current_color)
+ n_replace, current_color, current_transparent = node_colorize(n_replace, false, current_color, current_transparent)
setdisc(n, n_pre, n_post, n_replace)
elseif n_id == glyph_t then
--- colorization is restricted to those fonts
--- that received the “color” property upon
--- loading (see ``setcolor()`` above)
- local glyph_color = get_glyph_color(getfont(n), getchar(n))
- if glyph_color ~= current_color then
- if current_color then
- head, n, current_color = color_whatsit(head, n, current_color, false)
- end
+ local glyph_color, glyph_transparent = get_glyph_color(getfont(n), getchar(n))
+ if custom_setcolor then
if glyph_color then
- head, n, current_color = color_whatsit(head, n, glyph_color, true)
+ head, n = custom_setcolor(head, n, glyph_color) -- Don't change current_color to transform all other color_whatsit calls into noops
end
+ else
+ head, n, current_color = color_whatsit(head, n, color_stack, current_color, glyph_color)
end
-
- if current_color and color_callback == "pre_linebreak_filter" then
- local nn = getnext(n)
- while nn and getid(nn) == glyph_t do
- local glyph_color = get_glyph_color(getfont(nn), getchar(nn))
- if glyph_color == current_color then
- n = nn
- else
- break
- end
- nn = getnext(nn)
- end
- if getid(nn) == disc_t then
- head, n, current_color = color_whatsit(head, nn, current_color, false, true)
- else
- head, n, current_color = color_whatsit(head, n, current_color, false, true)
+ if custom_settransparent then
+ if glyph_transparent then
+ head, n = custom_settransparent(head, n, glyph_transparent) -- Don't change current_transparent to transform all other color_whatsit calls into noops
end
+ else
+ head, n, current_transparent = color_whatsit(head, n, transparent_stack, current_transparent, glyph_transparent)
end
elseif n_id == whatsit_t then
- if current_color then
- head, n, current_color = color_whatsit(head, n, current_color, false)
- end
+ head, n, current_color = color_whatsit(head, n, color_stack, current_color, nil)
+ head, n, current_transparent = color_whatsit(head, n, transparent_stack, current_transparent, nil)
end
n = getnext(n)
end
- if toplevel and current_color then
- head, _, current_color = color_whatsit(head, nodetail(head), current_color, false, true)
+ if toplevel then
+ local nn = nodetail(head)
+ head, nn, current_color = color_whatsit(head, nn, color_stack, current_color, nil, true)
+ head, nn, current_transparent = color_whatsit(head, nn, transparent_stack, current_transparent, nil, true)
end
setattribute(head, color_attr, 1)
- return head, current_color
+ return head, current_color, current_transparent
end
local getpageres = pdf.getpageresources or function() return pdf.pageresources end
@@ -302,23 +243,23 @@ local gettoks, scantoks = tex.gettoks, tex.scantoks
local pgf = { bye = "pgfutil@everybye", extgs = "\\pgf@sys@addpdfresource@extgs@plain" }
--- node -> node
-local color_handler = function (head)
+local function color_handler (head)
head = todirect(head)
head = node_colorize(head, true)
head = tonode(head)
-- now append our page resources
- if res then
- res["1"] = true
- if scantoks and pgf.bye and not pgf.loaded then
+ if res and tonumber(transparent_stack) then
+ if scantoks and nil == pgf.loaded then
pgf.loaded = token.create(pgf.bye).cmdname == "assign_toks"
- pgf.bye = pgf.loaded and pgf.bye
end
- local tpr = pgf.loaded and gettoks(pgf.bye) or getpageres() or ""
+ local tpr = pgf.loaded and gettoks(pgf.bye) or -- PGF
+ -- token.is_defined'TRP@list' and token.get_macro'TRP@list' or -- transparency
+ getpageres() or ""
local t = ""
for k in pairs(res) do
- local str = stringformat("/TransGs%s<</ca %s>>", k, k) -- don't touch stroking elements
+ local str = stringformat("/TransGs%.3g<</ca %.3g>>", k, k) -- don't touch stroking elements
if not tpr:find(str) then
t = t .. str
end
@@ -326,6 +267,8 @@ local color_handler = function (head)
if t ~= "" then
if pgf.loaded then
scantoks("global", pgf.bye, catat11, stringformat("%s{%s}%s", pgf.extgs, t, tpr))
+ -- elseif token.is_defined'TRP@list' then
+ -- token.set_macro('TRP@list', t .. tpr, 'global')
else
local tpr, n = tpr:gsub("/ExtGState<<", "%1"..t)
if n == 0 then
@@ -343,12 +286,6 @@ local color_callback_name = "luaotfload.color_handler"
local color_callback_activated = 0
local add_to_callback = luatexbase.add_to_callback
---- unit -> bool
-local mlist_to_hlist_initial = function ()
- local cdesc = luatexbase.callback_descriptions "mlist_to_hlist"
- return cdesc and cdesc[1] == color_callback_name
-end
-
--- unit -> unit
add_color_callback = function ( )
color_callback = config.luaotfload.run.color_callback
@@ -370,11 +307,8 @@ add_color_callback = function ( )
return head
end,
color_callback_name)
- add_to_callback("mlist_to_hlist",
- function (head, display_type, need_penalties)
- if mlist_to_hlist_initial () then
- head = mlist_to_hlist(head, display_type, need_penalties)
- end
+ add_to_callback("post_mlist_to_hlist_filter",
+ function (head, display_type)
if display_type == "text" then
return head
end
@@ -403,10 +337,10 @@ local glyph_color_tables = { }
-- and node and difficulties with getting the mapped unicode value for
-- a GID.
local function setcolor (tfmdata, value)
- local sanitized
+ local sanitized_rgb, sanitized_a
local color_table = glyph_color_tables[tonumber(value) or value]
if color_table then
- sanitized = {}
+ sanitized_rgb = {}
local unicodes = tfmdata.resources.unicodes
local gid_mapping = {}
local descriptions = tfmdata.descriptions or tfmdata.characters
@@ -419,7 +353,13 @@ local function setcolor (tfmdata, value)
gid = desc and (desc.index or unicode)
end
if gid then
- sanitized[gid] = sanitize_color_expression(color)
+ local a
+ sanitized_rgb[gid], a
+ = sanitize_color_expression(color)
+ if a then
+ sanitized_a = sanitized_a or {}
+ sanitized_a[gid] = a
+ end
else
-- TODO: ??? Error out, warn or just ignore? Ignore
-- makes sense because we have to ignore for GIDs
@@ -428,12 +368,12 @@ local function setcolor (tfmdata, value)
end
end
else
- sanitized = sanitize_color_expression(value)
+ sanitized_rgb, sanitized_a = sanitize_color_expression(value)
end
local properties = tfmdata.properties
- if sanitized then
- properties.color = sanitized
+ if sanitized_rgb then
+ properties.color_rgb, properties.color_a = sanitized_rgb, sanitized_a
add_color_callback()
end
end
@@ -449,6 +389,14 @@ function luaotfload.add_colorscheme(name, colortable)
return name
end
+-- cb must have the signature
+-- head, n = cb(head, n, color)
+-- and apply the PDF color operators in color to the node n.
+-- Call with nil to disable.
+function luaotfload.set_colorhandler(cb)
+ custom_setcolor = cb
+end
+
return function ()
logreport = luaotfload.log.report
if not fonts then
diff --git a/macros/luatex/generic/luaotfload/luaotfload-conf.pdf b/macros/luatex/generic/luaotfload/luaotfload-conf.pdf
index 0bc208e735..1e112f413f 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 b6b214c249..736b9c64d3 100644
--- a/macros/luatex/generic/luaotfload/luaotfload-configuration.lua
+++ b/macros/luatex/generic/luaotfload/luaotfload-configuration.lua
@@ -7,8 +7,8 @@
local ProvidesLuaModule = {
name = "luaotfload-configuration",
- version = "3.12", --TAGVERSION
- date = "2020-02-02", --TAGDATE
+ version = "3.13", --TAGVERSION
+ date = "2020-05-01", --TAGDATE
description = "luaotfload submodule / config file reader",
license = "GPL v2.0"
}
@@ -137,7 +137,7 @@ local feature_presets = {
--doc]]--
-local default_fontloader = function ()
+local function default_fontloader ()
return luaotfloadstatus and luaotfloadstatus.notes.loader or "reference"
end
@@ -148,10 +148,10 @@ local registered_loaders = {
context = "context",
}
-local pick_fontloader = function (s)
+local function pick_fontloader (s)
local ldr = registered_loaders[s]
if ldr ~= nil and type (ldr) == "string" then
- logreport ("log", 2, "conf", "Using predefined fontloader \"%s\".", ldr)
+ logreport ("log", 2, "conf", "Using predefined fontloader %q.", ldr)
return ldr
end
local idx = stringfind (s, ":")
@@ -159,17 +159,17 @@ local pick_fontloader = function (s)
if stringsub (s, 1, idx - 1) == "context" then
local pth = stringsub (s, idx + 1)
pth = stringstrip (pth)
- logreport ("log", 2, "conf", "Context base path specified at \"%s\".", pth)
+ logreport ("log", 2, "conf", "Context base path specified at %q.", pth)
if lfsisdir (pth) then
- logreport ("log", 5, "conf", "Context base path exists at \"%s\".", pth)
+ logreport ("log", 5, "conf", "Context base path exists at %q.", pth)
return pth
end
pth = kpseexpand_path (pth)
if lfsisdir (pth) then
- logreport ("log", 5, "conf", "Context base path exists at \"%s\".", pth)
+ logreport ("log", 5, "conf", "Context base path exists at %q.", pth)
return pth
end
- logreport ("both", 0, "conf", "Context base path not found at \"%s\".", pth)
+ logreport ("both", 0, "conf", "Context base path not found at %q.", pth)
end
end
return nil
@@ -281,7 +281,7 @@ local min_terminal_width = 40
--- The “termwidth” value is only considered when printing
--- short status messages, e.g. when building the database
--- online.
-local check_termwidth = function ()
+local function check_termwidth ()
if config.luaotfload.misc.termwidth == nil then
local tw = 79
if not ( os.type == "windows" --- Assume broken terminal.
@@ -306,7 +306,7 @@ local check_termwidth = function ()
return true
end
-local set_font_filter = function ()
+local function set_font_filter ()
local names = fonts.names
if names and names.set_font_filter then
local formats = config.luaotfload.db.formats
@@ -318,7 +318,7 @@ local set_font_filter = function ()
return true
end
-local set_size_dimension = function ()
+local function set_size_dimension ()
local names = fonts.names
if names and names.set_size_dimension then
local dim = config.luaotfload.db.designsize_dimen
@@ -330,7 +330,7 @@ local set_size_dimension = function ()
return true
end
-local set_name_resolver = function ()
+local function set_name_resolver ()
local names = fonts.names
if names and names.resolve_cached then
--- replace the resolver from luatex-fonts
@@ -344,7 +344,7 @@ local set_name_resolver = function ()
return true
end
-local set_loglevel = function ()
+local function set_loglevel ()
if luaotfload then
luaotfload.log.set_loglevel (config.luaotfload.run.log_level)
return true
@@ -352,7 +352,7 @@ local set_loglevel = function ()
return false
end
-local build_cache_paths = function ()
+local function build_cache_paths ()
local paths = config.luaotfload.paths
local prefix = getwritablepath (paths.names_dir, "")
@@ -362,7 +362,7 @@ local build_cache_paths = function ()
end
prefix = lpegmatch (stripslashes, prefix)
- logreport ("log", 0, "conf", "Root cache directory is %s.", prefix)
+ logreport ("log", 0, "conf", "Root cache directory is %q.", prefix)
local index_file = filejoin (prefix, paths.index_file)
local lookups_file = filejoin (prefix, paths.lookups_file)
@@ -376,7 +376,7 @@ local build_cache_paths = function ()
end
-local set_default_features = function ()
+local function set_default_features ()
local default_features = config.luaotfload.default_features
luaotfload.features = luaotfload.features or {
global = { },
@@ -413,14 +413,14 @@ local number_t = "number"
local boolean_t = "boolean"
local function_t = "function"
-local tointeger = function (n)
+local function tointeger (n)
n = tonumber (n)
if n then
return mathfloor (n + 0.5)
end
end
-local toarray = function (s)
+local function toarray (s)
local fields = { lpegmatch (commasplitter, s) }
local ret = { }
for i = 1, #fields do
@@ -432,7 +432,7 @@ local toarray = function (s)
return ret
end
-local tohash = function (s)
+local function tohash (s)
local result = { }
local fields = toarray (s)
for _, field in next, fields do
@@ -571,7 +571,7 @@ local option_spec = {
return ldr
end
logreport ("log", 0, "conf",
- "Requested fontloader \"%s\" not defined, "
+ "Requested fontloader %q not defined, "
.. "use at your own risk.",
id)
return id
@@ -590,12 +590,12 @@ local option_spec = {
local cb = permissible_color_callbacks[cb_spec]
if cb then
logreport ("log", 3, "conf",
- "Using callback \"%s\" for font colorization.",
+ "Using callback %q for font colorization.",
cb)
return cb
end
logreport ("log", 0, "conf",
- "Requested callback identifier \"%s\" invalid, "
+ "Requested callback identifier %q invalid, "
.. "falling back to default.",
cb_spec)
return permissible_color_callbacks.default
@@ -637,32 +637,32 @@ local option_spec = {
--- FORMATTERS
-------------------------------------------------------------------------------
-local commented = function (str)
+local function commented (str)
return ";" .. str
end
local underscore_replacer = lpeg.replacer ("_", "-", true)
-local dashed = function (var)
+local function dashed (var)
--- INI spec dictates that dashes are valid in variable names, not
--- underscores.
return underscore_replacer (var) or var
end
local indent = " "
-local format_string = function (var, val)
+local function format_string (var, val)
return stringformat (indent .. "%s = %s", var, val)
end
-local format_integer = function (var, val)
+local function format_integer (var, val)
return stringformat (indent .. "%s = %d", var, val)
end
-local format_boolean = function (var, val)
+local function format_boolean (var, val)
return stringformat (indent .. "%s = %s", var, val == true and "true" or "false")
end
-local format_keyval = function (var, val)
+local function format_keyval (var, val)
local list = { }
local keys = table.sortedkeys (val)
for i = 1, #keys do
@@ -681,7 +681,7 @@ local format_keyval = function (var, val)
end
end
-local format_list = function (var, val)
+local function format_list (var, val)
local elts = { }
for i = 1, #val do elts [i] = val [i] end
if next (elts) then
@@ -690,7 +690,7 @@ local format_list = function (var, val)
end
end
-local format_section = function (title)
+local function format_section (title)
return stringformat ("[%s]", dashed (title))
end
@@ -764,7 +764,7 @@ local formatters = {
--doc]]--
-local tilde_expand = function (p)
+local function tilde_expand (p)
if #p > 2 then
if stringsub (p, 1, 2) == "~/" then
local homedir = osgetenv "HOME"
@@ -776,7 +776,7 @@ local tilde_expand = function (p)
return p
end
-local resolve_config_path = function ()
+local function resolve_config_path ()
for i = 1, #config_paths do
local t, p = unpack (config_paths[i])
local fullname
@@ -799,7 +799,7 @@ local resolve_config_path = function ()
return false
end
-local add_config_paths = function (t)
+local function add_config_paths (t)
if not next (t) then
return
end
@@ -887,8 +887,7 @@ local process_options = function (opts)
return new
end
-local apply
-apply = function (old, new)
+local function apply (old, new)
if not new then
if not old then
return false
@@ -916,7 +915,7 @@ apply = function (old, new)
return result
end
-local reconfigure = function ()
+local function reconfigure()
for i = 1, #reconf_tasks do
local name, task = unpack (reconf_tasks[i])
logreport ("both", 3, "conf", "Launch post-configuration task %q.", name)
@@ -928,7 +927,7 @@ local reconfigure = function ()
return true
end
-local read = function (extra)
+local function read (extra)
if extra then
add_config_paths (extra)
end
@@ -960,7 +959,7 @@ local read = function (extra)
return ret
end
-local apply_defaults = function ()
+local function apply_defaults ()
local defaults = default_config
local vars = read ()
--- Side-effects galore ...
@@ -968,7 +967,7 @@ local apply_defaults = function ()
return reconfigure ()
end
-local dump = function ()
+local function dump ()
local sections = table.sortedkeys (config.luaotfload)
local confdata = { }
for i = 1, #sections do
diff --git a/macros/luatex/generic/luaotfload/luaotfload-database.lua b/macros/luatex/generic/luaotfload/luaotfload-database.lua
index f4bace8b44..11f3d91142 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
local ProvidesLuaModule = {
name = "luaotfload-database",
- version = "3.12", --TAGVERSION
- date = "2020-02-02", --TAGDATE
+ version = "3.13", --TAGVERSION
+ date = "2020-05-01", --TAGDATE
description = "luaotfload submodule / database",
license = "GPL v2.0",
author = "Khaled Hosny, Elie Roux, Philipp Gesang, Marcel Krüger",
@@ -211,7 +211,7 @@ local name_index = nil --> upvalue for names.data
local lookup_cache = nil --> for names.lookups
--- string -> (string * string)
-local make_luanames = function (path)
+local function make_luanames (path)
return filereplacesuffix(path, "lua"),
filereplacesuffix(path, "luc")
end
@@ -224,7 +224,7 @@ local location_precedence = {
"local", "system", "texmf",
}
-local set_location_precedence = function (precedence)
+local function set_location_precedence (precedence)
location_precedence = precedence
end
@@ -282,7 +282,7 @@ local macroman2utf8 do
return utf8.char(table.unpack(bytes))
end
end
-local sanitize_fontname = function (str)
+local function sanitize_fontname (str)
if str ~= nil then
str = utf8len(str) and str or macroman2utf8(str)
str = alphnum_only(casefold(str, true))
@@ -291,7 +291,7 @@ local sanitize_fontname = function (str)
return nil
end
-local sanitize_fontnames = function (rawnames)
+local function sanitize_fontnames (rawnames)
local result = { }
for category, namedata in next, rawnames do
@@ -310,8 +310,7 @@ local sanitize_fontnames = function (rawnames)
return result
end
-local find_files_indeed
-find_files_indeed = function (acc, dirs, filter)
+local function find_files_indeed (acc, dirs, filter)
if not next (dirs) then --- done
return acc
end
@@ -343,14 +342,14 @@ find_files_indeed = function (acc, dirs, filter)
return find_files_indeed (acc, dirs, filter)
end
-local dummyfilter = function () return true end
+local function dummyfilter () return true end
--- the optional filter function receives the full path of a file
--- system entity. a filter applies if the first argument it returns is
--- true.
--- string -> function? -> string list
-local find_files = function (root, filter)
+local function find_files (root, filter)
if lfsisdir (root) then
return find_files_indeed ({}, { root }, filter or dummyfilter)
end
@@ -467,7 +466,7 @@ mtx-fonts has in names.tma:
--- string list -> string option -> dbobj
-local initialize_namedata = function (formats, created)
+local function initialize_namedata (formats, created)
local now = os.date "%Y-%m-%d %H:%M:%S" --- i. e. "%F %T" on POSIX systems
return {
status = { }, -- was: status; map abspath -> mapping
@@ -489,7 +488,7 @@ end
--- .luc.
--- string -> (string * table)
-local load_lua_file = function (path)
+local function load_lua_file (path)
local foundname = filereplacesuffix (path, "luc")
local code = nil
@@ -632,8 +631,7 @@ getmetadata = function ()
end
--- unit -> unit
-local load_lookups
-load_lookups = function ( )
+local function load_lookups ( )
local foundname, data = load_lua_file(config.luaotfload.paths.lookup_path_lua)
if data then
logreport ("log", 0, "cache", "Lookup cache loaded from %s.", foundname)
@@ -671,7 +669,7 @@ local casefold_search =
[(kpse.var_value'texmf_casefold_search' or '1'):sub(1,1)]
-- /MK
-local lookup_filename = function (filename)
+local function lookup_filename (filename)
if not name_index then name_index = load_names () end
local files = name_index.files
local basedata = files.base
@@ -778,7 +776,7 @@ end
--doc]]--
--- int -> bool * (string * int) option
-local get_font_file = function (index)
+local function get_font_file (index)
local entry = name_index.mappings [index]
if not entry then
return false
@@ -804,7 +802,7 @@ the texmf or filesystem. Again, due to the schizoprenic nature of the
font managment we have to check both the system path and the texmf.
--doc]]--
-local verify_font_file = function (basename)
+local function verify_font_file (basename)
local path = lookup_fullpath (basename)
if path and lfsisfile(path) then
return true
@@ -855,7 +853,7 @@ local hash_fields = {
local n_hash_fields = #hash_fields
--- spec -> string
-local hash_request = function (specification)
+local function hash_request (specification)
local key = { } --- segments of the hash
for i=1, n_hash_fields do
local field = specification[hash_fields[i]]
@@ -867,8 +865,7 @@ local hash_request = function (specification)
end
--- 'a -> 'a -> table -> (string * int|boolean * boolean)
-local lookup_font_name_cached
-lookup_font_name_cached = function (specification)
+local function lookup_font_name_cached (specification)
if not lookup_cache then load_lookups () end
local request = hash_request(specification)
logreport ("both", 4, "cache", "Looking for %q in cache ...",
@@ -916,7 +913,7 @@ end
--- this used to be inlined; with the lookup cache we don’t
--- have to be parsimonious wrt function calls anymore
--- “found” is the match accumulator
-local add_to_match = function (found, size, face)
+local function add_to_match (found, size, face)
local continue = true
@@ -944,7 +941,7 @@ local add_to_match = function (found, size, face)
return found, continue
end
-local choose_closest = function (distances)
+local function choose_closest (distances)
local closest = 2^51
local match
for i = 1, #distances do
@@ -1042,7 +1039,7 @@ end
--doc]]--
--- spec -> string -> string -> int -> string * int * bool
-local lookup_familyname = function (specification, name, style, askedsize)
+local function lookup_familyname (specification, name, style, askedsize)
local families = name_index.families
local mappings = name_index.mappings
local candidates = nil
@@ -1083,7 +1080,7 @@ local lookup_familyname = function (specification, name, style, askedsize)
return resolved, subfont, fallback
end
-local lookup_fontname = function (specification, name)
+local function lookup_fontname (specification, name)
local mappings = name_index.mappings
local fallback = nil
local lastresort = nil
@@ -1142,7 +1139,7 @@ do
design_size_dimension = dimens.bp
- set_size_dimension = function (dim)
+ function set_size_dimension (dim)
local conv = dimens [dim]
if conv ~= nil then
logreport ("both", 4, "db",
@@ -1306,7 +1303,7 @@ reload_db = function (why, caller, ...)
end
--- string -> string -> int
-local iterative_levenshtein = function (s1, s2)
+local function iterative_levenshtein (s1, s2)
local costs = { }
local len1, len2 = #s1, #s2
@@ -1334,7 +1331,7 @@ local iterative_levenshtein = function (s1, s2)
end
--- string list -> string list
-local delete_dupes = function (lst)
+local function delete_dupes (lst)
local n0 = #lst
if n0 == 0 then return lst end
tablesort (lst)
@@ -1413,7 +1410,7 @@ find_closest = function (name, limit)
local dist = distances[i]
local namelst = delete_dupes (by_distance[dist])
logreport (false, 0, "query",
- "Distance from \"%s\": %s\n "
+ "Distance from %q: %s\n "
.. tableconcat (namelst, "\n "),
name, dist)
end
@@ -1424,7 +1421,7 @@ find_closest = function (name, limit)
end --- find_closest()
--- string -> uint -> bool * (string | rawdata)
-local read_font_file = function (filename, subfont)
+local function read_font_file (filename, subfont)
local fontdata = otfhandler.readers.getinfo (filename,
{ subfont = subfont
, platformnames = true
@@ -1437,7 +1434,7 @@ local read_font_file = function (filename, subfont)
return true, fontdata
end
-local load_font_file = function (filename, subfont)
+local function load_font_file (filename, subfont)
local err, ret = read_font_file (filename, subfont)
if err == false then
logreport ("both", 1, "db", "ERROR: failed to open %q: %q.",
@@ -1457,7 +1454,7 @@ local get_size_info do --- too many upvalues :/
local sp = 2^16 -- pt
local bp = 7227 / 7200 -- pt
- get_size_info = function (rawinfo)
+ function get_size_info (rawinfo)
local design_size = rawinfo.design_size
local design_range_top = rawinfo.design_range_top
local design_range_bottom = rawinfo.design_range_bottom
@@ -1491,7 +1488,7 @@ end ---[local get_size_info]
stick to that part.
--doc]]--
-local get_english_names = function (metadata)
+local function get_english_names (metadata)
local namesource
local platformnames = metadata.platformnames
--[[--
@@ -1538,7 +1535,7 @@ end
For this reason we copy what is necessary whilst keeping the table
structure the same as in the tfmdata.
--]]--
-local get_raw_info = function (metadata, basename)
+local function get_raw_info (metadata, basename)
local fontname = metadata.fontname
local fullname = metadata.fullname
@@ -1569,10 +1566,10 @@ local get_raw_info = function (metadata, basename)
}
end
-local organize_namedata = function (rawinfo,
- nametable,
- basename,
- info)
+local function organize_namedata (rawinfo,
+ nametable,
+ basename,
+ info)
local default_name = nametable.compatiblefullname
or nametable.fullname
or nametable.postscriptname
@@ -1639,7 +1636,7 @@ end
local dashsplitter = lpegsplitat "-"
-local split_fontname = function (fontname)
+local function split_fontname (fontname)
--- sometimes the style hides in the latter part of the
--- fontname, separated by a dash, e.g. “Iwona-Regular”,
--- “GFSSolomos-Regular”
@@ -1649,7 +1646,7 @@ local split_fontname = function (fontname)
end
end
-local organize_styledata = function (metadata, rawinfo, info)
+local function organize_styledata (metadata, rawinfo, info)
local pfminfo = metadata.pfminfo
local names = rawinfo.names
return {
@@ -1777,13 +1774,13 @@ local loaders = {
--- not side-effect free!
-local compare_timestamps = function (fullname,
- currentstatus,
- currententrystatus,
- currentmappings,
- targetstatus,
- targetentrystatus,
- targetmappings)
+local function compare_timestamps (fullname,
+ currentstatus,
+ currententrystatus,
+ currentmappings,
+ targetstatus,
+ targetentrystatus,
+ targetmappings)
local currenttimestamp = currententrystatus
and currententrystatus.timestamp
@@ -1821,15 +1818,15 @@ local compare_timestamps = function (fullname,
return true
end
-local insert_fullinfo = function (fullname,
- basename,
- n_font,
- loader,
- format,
- location,
- targetmappings,
- targetentrystatus,
- info)
+local function insert_fullinfo (fullname,
+ basename,
+ n_font,
+ loader,
+ format,
+ location,
+ targetmappings,
+ targetentrystatus,
+ info)
local fullinfo = loader (fullname, n_font,
location, basename,
@@ -1856,10 +1853,10 @@ end
--- we return true if the font is new or re-indexed
--- string -> dbobj -> dbobj -> bool
-local read_font_names = function (fullname,
- currentnames,
- targetnames,
- location)
+local function read_font_names (fullname,
+ currentnames,
+ targetnames,
+ location)
local targetmappings = targetnames.mappings
local targetstatus = targetnames.status --- by full path
@@ -1963,7 +1960,7 @@ do
--- windows and dos
if os_type == "windows" or os_type == "msdos" then
--- ms platfom specific stuff
- path_normalize = function (path)
+ function path_normalize (path)
path = stringgsub(path, '\\', '/')
path = stringlower(path)
path = filecollapsepath(path)
@@ -1976,7 +1973,7 @@ do
--doc]]--
else -- posix
- path_normalize = function (path)
+ function path_normalize (path)
local dest = lfsreadlink(path)
if dest then
if kpsereadable_file(dest) then
@@ -1997,7 +1994,7 @@ local blacklist = { }
local p_blacklist --- prefixes of dirs
--- string list -> string list
-local collapse_prefixes = function (lst)
+local function collapse_prefixes (lst)
--- avoid redundancies in blacklist
if #lst < 2 then
return lst
@@ -2018,7 +2015,7 @@ local collapse_prefixes = function (lst)
end
--- string list -> string list -> (string, bool) hash_t
-local create_blacklist = function (blacklist, whitelist)
+local function create_blacklist (blacklist, whitelist)
local result = { }
local dirs = { }
@@ -2099,7 +2096,7 @@ end
local p_font_filter
do
- local extension_pattern = function (list)
+ local function extension_pattern (list)
if type (list) ~= "table" or #list == 0 then return P(-1) end
local pat
for i=#list, 1, -1 do
@@ -2119,7 +2116,7 @@ do
local current_formats = { }
- set_font_filter = function (formats)
+ function set_font_filter (formats)
if not formats or type (formats) ~= "string" then
return
@@ -2160,12 +2157,12 @@ do
p_font_filter = extension_pattern (current_formats)
end
- get_font_filter = function (formats)
+ function get_font_filter (formats)
return tablefastcopy (current_formats)
end
end
-local locate_matching_pfb = function (afmfile, dir)
+local function locate_matching_pfb (afmfile, dir)
local pfbname = filereplacesuffix (afmfile, "pfb")
local pfbpath = dir .. "/" .. pfbname
if lfsisfile (pfbpath) then
@@ -2175,8 +2172,7 @@ local locate_matching_pfb = function (afmfile, dir)
return kpsefind_file (pfbname, "type1 fonts")
end
-local process_dir_tree
-process_dir_tree = function (acc, dirs, done)
+local function process_dir_tree (acc, dirs, done)
if not next (dirs) then --- done
return acc
end
@@ -2229,7 +2225,7 @@ process_dir_tree = function (acc, dirs, done)
return process_dir_tree (tableappend (acc, newfiles), dirs, done)
end
-local process_dir = function (dir)
+local function process_dir (dir)
local pwd = lfscurrentdir ()
if lfschdir (dir) then
dir = lfscurrentdir () --- resolve symlinks
@@ -2262,7 +2258,7 @@ local process_dir = function (dir)
end
--- string -> bool -> string list
-local find_font_files = function (root, recurse)
+local function find_font_files (root, recurse)
if lfsisdir (root) then
if recurse == true then
return process_dir_tree ({}, { root }, {})
@@ -2276,7 +2272,7 @@ end
--- into a given terminal width. The parameter “restrict” (int)
--- indicates the number of characters already consumed on the
--- line.
-local truncate_string = function (str, restrict)
+local function truncate_string (str, restrict)
local tw = config.luaotfload.misc.termwidth
local wd = tw - restrict
local len = utf8len (str)
@@ -2304,7 +2300,7 @@ end
--doc]]--
--- string -> string -> string * string list
-local collect_font_filenames_dir = function (dirname, location)
+local function collect_font_filenames_dir (dirname, location)
if lpegmatch (p_blacklist, dirname) then
logreport ("both", 4, "db",
"Skipping blacklisted directory %s.", dirname)
@@ -2332,7 +2328,7 @@ local collect_font_filenames_dir = function (dirname, location)
end
--- string list -> string list
-local filter_out_pwd = function (dirs)
+local function filter_out_pwd (dirs)
local result = { }
if stripslashes == nil then
stripslashes = luaotfload.parsers and luaotfload.parsers.stripslashes
@@ -2344,7 +2340,7 @@ local filter_out_pwd = function (dirs)
local dir = path_normalize (lpegmatch (stripslashes, dirs[i]))
if dir == "." or dir == pwd then
logreport ("both", 3, "db",
- "Path “%s” matches $PWD (“%s”), skipping.",
+ "Path %q matches $PWD (%q), skipping.",
dir, pwd)
else
result[#result+1] = dir
@@ -2368,7 +2364,7 @@ local path_separator = os.type == "windows" and ";" or ":"
--doc]]--
--- unit -> string * string list
-local collect_font_filenames_texmf = function ()
+local function collect_font_filenames_texmf ()
local osfontdir = kpseexpand_path "$OSFONTDIR"
@@ -2417,7 +2413,8 @@ local function get_os_dirs ()
}
elseif os.type == "windows" or os.type == "msdos" then
local windir = osgetenv("WINDIR")
- return { filejoin(windir, 'Fonts') }
+ local appdata = osgetenv("LOCALAPPDATA")
+ return { filejoin(windir, 'Fonts'), filejoin(appdata, 'Microsoft/Windows/Fonts') }
else
local fonts_conves = { --- plural, much?
"/usr/local/etc/fonts/fonts.conf",
@@ -2439,7 +2436,7 @@ end
--doc]]--
--- string list -> size_t
-local count_removed = function (files)
+local function count_removed (files)
if not files or not files.full then
logreport ("log", 4, "db", "Empty file store; no data to work with.")
return 0
@@ -2452,7 +2449,7 @@ local count_removed = function (files)
local f = old[i]
if not kpsereadable_file (f) then
logreport ("log", 2, "db",
- "File %s does not exist in file system.")
+ "File %q does not exist in file system.")
nrem = nrem + 1
end
end
@@ -2474,7 +2471,7 @@ end
--doc]]--
--- string * string list -> dbobj -> dbobj -> bool? -> int * int
-local retrieve_namedata = function (files, currentnames, targetnames, dry_run)
+local function retrieve_namedata (files, currentnames, targetnames, dry_run)
local nfiles = #files
local nnew = 0
@@ -2516,7 +2513,7 @@ local retrieve_namedata = function (files, currentnames, targetnames, dry_run)
end
--- unit -> string * string list
-local collect_font_filenames_system = function ()
+local function collect_font_filenames_system ()
local n_scanned, n_new = 0, 0
logreport ("info", 1, "db", "Scanning system fonts...")
@@ -2551,7 +2548,7 @@ end
--doc]]--
--- unit -> string * string list
-local collect_font_filenames_local = function ()
+local function collect_font_filenames_local ()
local pwd = lfscurrentdir ()
logreport ("both", 1, "db", "Scanning for fonts in $PWD (%q) ...", pwd)
@@ -2757,11 +2754,11 @@ local pick_fallback_style
local check_regular
do
- pick_style = function (typographicsubfamily, subfamily)
+ function pick_style (typographicsubfamily, subfamily)
return style_synonym [typographicsubfamily or subfamily or ""]
end
- pick_fallback_style = function (italicangle, pfmweight, width)
+ function pick_fallback_style (italicangle, pfmweight, width)
--[[--
More aggressive, but only to determine bold faces.
Note: Before you make this test more inclusive, ensure
@@ -2792,12 +2789,12 @@ do
--- we use only exact matches here since there are constructs
--- like “regularitalic” (Cabin, Bodoni Old Fashion)
- check_regular = function (typographicsubfamily,
- subfamily,
- italicangle,
- weight,
- width,
- pfmweight)
+ function check_regular (typographicsubfamily,
+ subfamily,
+ italicangle,
+ weight,
+ width,
+ pfmweight)
local plausible_weight = false
--[[--
This filters out undesirable candidates that specify their
@@ -2838,7 +2835,7 @@ do
end
end
-local pull_values = function (entry)
+local function pull_values (entry)
local file = entry.file
local names = entry.names
local style = entry.style
@@ -2876,7 +2873,7 @@ local pull_values = function (entry)
end
end
-local add_family = function (name, subtable, modifier, entry)
+local function add_family (name, subtable, modifier, entry)
if not name then --- probably borked font
return
end
@@ -2892,7 +2889,7 @@ local add_family = function (name, subtable, modifier, entry)
}
end
-local add_lastresort_regular = function (name, subtable, entry)
+local function add_lastresort_regular (name, subtable, entry)
if not name then --- probably borked font
return
end
@@ -2904,7 +2901,7 @@ local add_lastresort_regular = function (name, subtable, entry)
familytable.fallback = entry.index
end
-local get_subtable = function (families, entry)
+local function get_subtable (families, entry)
local location = entry.location
local format = entry.format
local subtable = families [location] [format]
@@ -2915,7 +2912,7 @@ local get_subtable = function (families, entry)
return subtable
end
-local collect_families = function (mappings)
+local function collect_families (mappings)
logreport ("info", 2, "db", "Analyzing families.")
@@ -3081,7 +3078,7 @@ group_modifiers = function (mappings, families)
return families
end
-local cmp_sizes = function (a, b)
+local function cmp_sizes (a, b)
return a [1] < b [1]
end
@@ -3143,7 +3140,7 @@ end
--doc]]--
--- unit -> string * string list
-local collect_font_filenames = function ()
+local function collect_font_filenames ()
logreport ("info", 4, "db", "Scanning the filesystem for font files.")
@@ -3180,7 +3177,7 @@ end
--doc]]--
--- int -> string
-local nth_font_filename = function (n)
+local function nth_font_filename (n)
logreport ("info", 4, "db", "Picking font file no. %d.", n)
if not p_blacklist then
read_blacklist ()
@@ -3195,7 +3192,7 @@ end
--doc]]--
-local font_slice = function (lo, hi)
+local function font_slice (lo, hi)
logreport ("info", 4, "db", "Retrieving font files nos. %d--%d.", lo, hi)
if not p_blacklist then
read_blacklist ()
@@ -3217,7 +3214,7 @@ end
--doc]]--
--- unit -> int
-local count_font_files = function ()
+local function count_font_files ()
logreport ("info", 4, "db", "Counting font files.")
if not p_blacklist then
read_blacklist ()
@@ -3227,13 +3224,13 @@ end
--- dbobj -> stats
-local collect_statistics = function (mappings)
+local function collect_statistics (mappings)
local sum_dsnsize, n_dsnsize = 0, 0
local fullname, family, families = { }, { }, { }
local subfamily, typographicsubfamily = { }, { }
- local addtohash = function (hash, item)
+ local function addtohash (hash, item)
if item then
local times = hash [item]
if times then
@@ -3244,7 +3241,7 @@ local collect_statistics = function (mappings)
end
end
- local appendtohash = function (hash, key, value)
+ local function appendtohash (hash, key, value)
if key and value then
local entry = hash [key]
if entry then
@@ -3255,7 +3252,7 @@ local collect_statistics = function (mappings)
end
end
- local addtoset = function (hash, key, value)
+ local function addtoset (hash, key, value)
if key and value then
local set = hash [key]
if set then
@@ -3266,7 +3263,7 @@ local collect_statistics = function (mappings)
end
end
- local setsize = function (set)
+ local function setsize (set)
local n = 0
for _, _ in next, set do
n = n + 1
@@ -3274,7 +3271,7 @@ local collect_statistics = function (mappings)
return n
end
- local hashsum = function (hash)
+ local function hashsum (hash)
local n = 0
for _, m in next, hash do
n = n + m
@@ -3307,7 +3304,7 @@ local collect_statistics = function (mappings)
local n_family = setsize (family)
if log.get_loglevel () > 1 then
- local pprint_top = function (hash, n, set)
+ local function pprint_top (hash, n, set)
local freqs = { }
local items = { }
@@ -3356,12 +3353,12 @@ local collect_statistics = function (mappings)
pprint_top (families, 4, true)
logreport ("both", 0, "db",
- " · %d different “subfamily” kinds.",
+ " · %d different \"subfamily\" kinds.",
setsize (subfamily))
pprint_top (subfamily, 4)
logreport ("both", 0, "db",
- " · %d different “typographicsubfamily” kinds.",
+ " · %d different \"typographicsubfamily\" kinds.",
setsize (typographicsubfamily))
pprint_top (typographicsubfamily, 4)
@@ -3599,8 +3596,8 @@ end
--doc]]--
--- string -> string -> string list -> string list -> string list -> unit
-local print_cache = function (category, path, luanames, lucnames, rest)
- local report_indeed = function (...)
+local function print_cache (category, path, luanames, lucnames, rest)
+ local function report_indeed (...)
logreport ("info", 0, "cache", ...)
end
report_indeed("Luaotfload cache: %s", category)
@@ -3612,7 +3609,7 @@ local print_cache = function (category, path, luanames, lucnames, rest)
end
--- string -> string -> string list -> bool -> bool
-local purge_from_cache = function (category, path, list, all)
+local function purge_from_cache (category, path, list, all)
logreport ("info", 1, "cache", "Luaotfload cache: %s %s",
(all and "erase" or "purge"), category)
logreport ("info", 1, "cache", "location: %s", path)
@@ -3644,8 +3641,7 @@ end
--- string -> string list -> int -> string list -> string list -> string list ->
--- (string list * string list * string list * string list)
-local collect_cache collect_cache = function (path, all, n, luanames,
- lucnames, rest)
+local function collect_cache (path, all, n, luanames, lucnames, rest)
if not all then
local all = find_files (path)
@@ -3668,7 +3664,7 @@ local collect_cache collect_cache = function (path, all, n, luanames,
return luanames, lucnames, rest, all
end
-local getwritablecachepath = function ( )
+local function getwritablecachepath ( )
--- fonts.handlers.otf doesn’t exist outside a Luatex run,
--- so we have to improvise
local writable = getwritablepath (config.luaotfload.paths.cache_dir, "")
@@ -3677,7 +3673,7 @@ local getwritablecachepath = function ( )
end
end
-local getreadablecachepaths = function ( )
+local function getreadablecachepaths ( )
local readables = caches.getreadablepaths
(config.luaotfload.paths.cache_dir)
local result = { }
@@ -3693,7 +3689,7 @@ local getreadablecachepaths = function ( )
end
--- unit -> unit
-local purge_cache = function ( )
+local function purge_cache ( )
local writable_path = getwritablecachepath ()
local luanames, lucnames, rest = collect_cache(writable_path)
if log.get_loglevel() > 1 then
@@ -3704,7 +3700,7 @@ local purge_cache = function ( )
end
--- unit -> unit
-local erase_cache = function ( )
+local function erase_cache ( )
local writable_path = getwritablecachepath ()
local luanames, lucnames, rest, all = collect_cache(writable_path)
if log.get_loglevel() > 1 then
@@ -3714,12 +3710,12 @@ local erase_cache = function ( )
return success
end
-local separator = function ( )
+local function separator ( )
logreport ("info", 0, string.rep("-", 67))
end
--- unit -> unit
-local show_cache = function ( )
+local function show_cache ( )
local readable_paths = getreadablecachepaths ()
local writable_path = getwritablecachepath ()
local luanames, lucnames, rest = collect_cache(writable_path)
@@ -3746,27 +3742,27 @@ end
--- PHG: we need to investigate these, maybe they’re useful as early
--- hooks
-local reportmissingbase = function ()
+local function reportmissingbase ()
logreport ("info", 0, "db", --> bug‽
"Font name database not found but expected by fontloader.")
fonts.names.reportmissingbase = nil
end
-local reportmissingname = function ()
+local function reportmissingname ()
logreport ("info", 0, "db", --> bug‽
"Fontloader attempted to lookup name before Luaotfload \z
was initialized.")
fonts.names.reportmissingname = nil
end
-local getfilename = function (a1, a2)
+local function getfilename (a1, a2)
logreport ("info", 6, "db", --> bug‽
"Fontloader looked up font file (%s, %s) before Luaotfload \z
was initialized.", tostring(a1), tostring(a2))
return lookup_fullpath (a1, a2)
end
-local resolve = function (name, subfont)
+local function resolve (name, subfont)
logreport ("info", 6, "db", --> bug‽
"Fontloader attempted to resolve name (%s, %s) before \z
Luaotfload was initialized.", tostring(name), tostring(subfont))
diff --git a/macros/luatex/generic/luaotfload/luaotfload-diagnostics.lua b/macros/luatex/generic/luaotfload/luaotfload-diagnostics.lua
index c6bb5c9371..956e24e747 100644
--- a/macros/luatex/generic/luaotfload/luaotfload-diagnostics.lua
+++ b/macros/luatex/generic/luaotfload/luaotfload-diagnostics.lua
@@ -7,8 +7,8 @@
local ProvidesLuaModule = {
name = "luaotfload-diagnostics",
- version = "3.12", --TAGVERSION
- date = "2020-02-02", --TAGDATE
+ version = "3.13", --TAGVERSION
+ date = "2020-05-01", --TAGDATE
description = "luaotfload-tool submodule / diagnostics",
license = "GPL v2.0"
}
@@ -58,7 +58,7 @@ local C, Cg, Ct = lpeg.C, lpeg.Cg, lpeg.Ct
local lpegmatch = lpeg.match
local report = luaotfload.log.report
-local out = function (...)
+local function out (...)
report (false, 0, "diagnose", ...)
end
@@ -66,7 +66,7 @@ local parsers = luaotfload.parsers
local stripslashes = parsers.stripslashes
local splitcomma = parsers.splitcomma
-local check_index = function (errcnt)
+local function check_index (errcnt)
out "================= font names =================="
local namedata = names.data()
@@ -107,7 +107,7 @@ local check_index = function (errcnt)
return errcnt
end
-local verify_files = function (errcnt)
+local function verify_files (errcnt)
out "================ verify files ================="
local status = config.luaotfload.status
local hashes = status.hashes
@@ -157,7 +157,7 @@ local verify_files = function (errcnt)
return errcnt
end
-local get_tentative_attributes = function (file)
+local function get_tentative_attributes (file)
if not lfsisfile (file) then
local chan = ioopen (file, "w")
if chan then
@@ -173,11 +173,11 @@ local p_permissions = Ct(Cg(Ct(C(1) * C(1) * C(1)), "u")
* Cg(Ct(C(1) * C(1) * C(1)), "g")
* Cg(Ct(C(1) * C(1) * C(1)), "o"))
-local analyze_permissions = function (raw)
+local function analyze_permissions (raw)
return lpegmatch (p_permissions, raw)
end
-local get_permissions = function (t, location)
+local function get_permissions (t, location)
if stringsub (location, #location) == "/" then
--- strip trailing slashes (lfs idiosyncrasy on Win)
location = lpegmatch (stripslashes, location)
@@ -219,7 +219,7 @@ local get_permissions = function (t, location)
}
end
-local check_conformance = function (spec, permissions, errcnt)
+local function check_conformance (spec, permissions, errcnt)
local uid = permissions.attributes.uid
local gid = permissions.attributes.gid
local raw = permissions.attributes.permissions
@@ -255,7 +255,7 @@ local check_conformance = function (spec, permissions, errcnt)
return errcnt
end
-local init_desired_permissions = function ()
+local function init_desired_permissions ()
local paths = config.luaotfload.paths
return {
{ "d", {"r","w"}, function () return caches.getwritablepath ("", "") end },
@@ -267,7 +267,7 @@ local init_desired_permissions = function ()
}
end
-local check_permissions = function (errcnt)
+local function check_permissions (errcnt)
out [[=============== file permissions ==============]]
local desired_permissions = init_desired_permissions ()
for i = 1, #desired_permissions do
@@ -294,7 +294,7 @@ end
local check_upstream
if kpsefind_file ("https.lua", "lua") == nil then
- check_upstream = function (errcnt)
+ function check_upstream (errcnt)
out [[============= upstream repository =============
WARNING: Cannot retrieve repository data.
Github API access requires the luasec library.
@@ -307,16 +307,16 @@ else
local https = require "ssl.https"
local gh_api_root = [[https://api.github.com]]
- local release_url = [[https://github.com/lualatex/luaotfload/releases]]
- local luaotfload_repo = [[lualatex/luaotfload]]
- local user_agent = [[lualatex/luaotfload integrity check]]
+ local release_url = [[https://github.com/latex3/luaotfload/releases]]
+ local luaotfload_repo = [[latex3/luaotfload]]
+ local user_agent = [[latex3/luaotfload integrity check]]
local shortbytes = 8
- local gh_shortrevision = function (rev)
+ local function gh_shortrevision (rev)
return stringsub (rev, 1, shortbytes)
end
- local gh_encode_parameters = function (parameters)
+ local function gh_encode_parameters (parameters)
local acc = {}
for field, value in next, parameters do
--- unsafe, non-urlencoded coz it’s all ascii chars
@@ -325,7 +325,7 @@ else
return "?" .. tableconcat (acc, "&")
end
- local gh_make_url = function (components, parameters)
+ local function gh_make_url (components, parameters)
local url = tableconcat ({ gh_api_root,
unpack (components) },
"/")
@@ -337,7 +337,7 @@ else
local alright = [[HTTP/1.1 200 OK]]
- local gh_api_request = function (...)
+ local function gh_api_request (...)
local args = {...}
local nargs = #args
local final = args[nargs]
@@ -361,7 +361,7 @@ else
return response
end
- local gh_api_checklimit = function (headers)
+ local function gh_api_checklimit (headers)
local rawlimit = gh_api_request "rate_limit"
local limitdata = lua_of_json (rawlimit)
if not limitdata and limitdata.rate then
@@ -387,7 +387,7 @@ else
return true
end
- local gh_tags = function ()
+ local function gh_tags ()
out "Fetching tags from repository, please stand by."
local rawtags = gh_api_request ("repos",
luaotfload_repo,
@@ -407,7 +407,7 @@ else
return latest
end
- local gh_compare = function (head, base)
+ local function gh_compare (head, base)
if base == nil then
base = "HEAD"
end
@@ -428,7 +428,7 @@ else
return status
end
- local gh_news = function (since)
+ local function gh_news (since)
local compared = gh_compare (since)
if not compared then
return false
@@ -452,7 +452,7 @@ else
return false
end
- local gh_catchup = function (current, latest)
+ local function gh_catchup (current, latest)
local compared = gh_compare (latest, current)
local ahead_by = tonumber (compared.ahead_by)
if ahead_by > 0 then
@@ -472,7 +472,7 @@ else
return false
end
- check_upstream = function (current)
+ function check_upstream (current)
out "============= upstream repository ============="
local _succ = gh_api_checklimit ()
local behind = gh_news (current)
@@ -491,7 +491,7 @@ else
end
--- github api stuff end
-local print_envvar = function (var)
+local function print_envvar (var)
local val = osgetenv (var)
if val then
out ("%20s: %q", stringformat ("$%s", var), val)
@@ -501,7 +501,7 @@ local print_envvar = function (var)
end
end
-local print_path = function (var)
+local function print_path (var)
local val = osgetenv (var)
if val then
local paths = filesplitpath (val)
@@ -523,7 +523,7 @@ local print_path = function (var)
end
end
-local print_kpsevar = function (var)
+local function print_kpsevar (var)
var = "$" .. var
local val = kpseexpand_var (var)
if val and val ~= var then
@@ -534,7 +534,7 @@ local print_kpsevar = function (var)
end
end
-local print_kpsepath = function (var)
+local function print_kpsepath (var)
var = "$" .. var
local val = kpseexpand_path (var)
if val and val ~= "" then
@@ -562,7 +562,7 @@ end
--- return the empty string both if the variable is unset and if
--- the directory does not exist
-local print_kpsepathvar = function (var)
+local function print_kpsepathvar (var)
local vvar = "$" .. var
local val = kpseexpand_var (vvar)
if val and val ~= vvar then
@@ -573,7 +573,7 @@ local print_kpsepathvar = function (var)
end
end
-local check_environment = function (errcnt)
+local function check_environment (errcnt)
out "============ environment settings ============="
out ("system: %s/%s", ostype, osname)
if ostype == "unix" and io.popen then
@@ -623,7 +623,7 @@ local anamneses = {
"permissions"
}
-local diagnose = function (job)
+local function diagnose (job)
local errcnt = 0
local asked = job.asked_diagnostics
if asked == "all" or asked == "thorough" then
@@ -681,7 +681,7 @@ local diagnose = function (job)
github:
× http://www.ctan.org/pkg/luaotfload
- × https://github.com/lualatex/luaotfload/releases
+ × https://github.com/latex3/luaotfload/releases
If you are uncertain as to how to proceed, then
ask on the lualatex mailing list:
diff --git a/macros/luatex/generic/luaotfload/luaotfload-embolden.lua b/macros/luatex/generic/luaotfload/luaotfload-embolden.lua
index eec5ffde15..9d36071c03 100644
--- a/macros/luatex/generic/luaotfload/luaotfload-embolden.lua
+++ b/macros/luatex/generic/luaotfload/luaotfload-embolden.lua
@@ -5,8 +5,8 @@
local ProvidesLuaModule = {
name = "luaotfload-embolden",
- version = "3.12", --TAGVERSION
- date = "2020-02-02", --TAGDATE
+ version = "3.13", --TAGVERSION
+ date = "2020-05-01", --TAGDATE
description = "luaotfload submodule / color",
license = "GPL v2.0",
author = "Marcel Krüger"
@@ -18,24 +18,17 @@ end
local otffeatures = fonts.constructors.newfeatures "otf"
-local function setembolden(tfmdata, factor)
- tfmdata.embolden = factor
-end
-
-local function enableembolden(tfmdata)
- tfmdata.mode, tfmdata.width = 2, tfmdata.size*tfmdata.unscaled.embolden/6578.176
+local function enableembolden(tfmdata, _, embolden)
+ tfmdata.mode, tfmdata.width = 2, tfmdata.size*embolden/6578.176
end
otffeatures.register {
name = "embolden",
description = "embolden",
- initializers = {
- base = setembolden,
- node = setembolden,
- },
manipulators = {
base = enableembolden,
node = enableembolden,
+ plug = enableembolden,
}
}
diff --git a/macros/luatex/generic/luaotfload/luaotfload-fallback.lua b/macros/luatex/generic/luaotfload/luaotfload-fallback.lua
index e07b3c726a..9b790ae854 100644
--- a/macros/luatex/generic/luaotfload/luaotfload-fallback.lua
+++ b/macros/luatex/generic/luaotfload/luaotfload-fallback.lua
@@ -5,8 +5,8 @@
local ProvidesLuaModule = {
name = "luaotfload-fallback",
- version = "3.12", --TAGVERSION
- date = "2020-02-02", --TAGDATE
+ version = "3.13", --TAGVERSION
+ date = "2020-05-01", --TAGDATE
description = "luaotfload submodule / fallback",
license = "GPL v2.0",
author = "Marcel Krüger"
@@ -26,7 +26,7 @@ local protect_glyph = node.direct.protect_glyph
local otffeatures = fonts.constructors.newfeatures "otf"
-- local normalize = fonts.handlers.otf.features.normalize
local definers = fonts.definers
-local define_font = luaotfload.define_font
+local define_font -- = luaotfload.define_font % This is set when the first font is loaded.
local fallback_table_fontnames = {}
@@ -89,8 +89,8 @@ local function makefallbackfont(tfmdata, _, fallback)
end
local glyph_id = node.id'glyph'
--- TODO: unset last_script, matching parentheses etc
-function dofallback(head, _, _, _, direction)
+-- TODO: inherited fonts (combining accents etc.)
+local function dofallback(head, _, _, _, direction)
head = node.direct.todirect(head)
local last_fid, last_fallbacks
for cur, cid, fid in traverse_char(head) do
@@ -107,6 +107,7 @@ function dofallback(head, _, _, _, direction)
end
function luaotfload.add_fallback(name, fonts)
+ define_font = define_font or luaotfload.define_font -- Lazy loading because this file get's loaded before define_font is defined
if fonts == nil then
fonts = name
name = #fallback_table_fontnames + 1
@@ -131,4 +132,7 @@ otffeatures.register {
-- }
}
+return {
+ process = dofallback,
+}
--- vim:sw=2:ts=2:expandtab:tw=71
diff --git a/macros/luatex/generic/luaotfload/luaotfload-features.lua b/macros/luatex/generic/luaotfload/luaotfload-features.lua
index 0fe8a281c6..a54ef20e9d 100644
--- a/macros/luatex/generic/luaotfload/luaotfload-features.lua
+++ b/macros/luatex/generic/luaotfload/luaotfload-features.lua
@@ -5,8 +5,8 @@
local ProvidesLuaModule = {
name = "luaotfload-features",
- version = "3.12", --TAGVERSION
- date = "2020-02-02", --TAGDATE
+ version = "3.13", --TAGVERSION
+ date = "2020-05-01", --TAGDATE
description = "luaotfload submodule / features",
license = "GPL v2.0",
author = "Hans Hagen, Khaled Hosny, Elie Roux, Philipp Gesang, Marcel Krüger",
@@ -69,11 +69,11 @@ local stringgsub = string.gsub
local stringformat = string.format
local stringis_empty = string.is_empty
-local cmp_by_idx = function (a, b) return a.idx < b.idx end
+local function cmp_by_idx (a, b) return a.idx < b.idx end
local defined_combos = 0
-local handle_combination = function (combo, spec)
+local function handle_combination (combo, spec)
defined_combos = defined_combos + 1
if not combo [1] then
report ("both", 0, "features",
@@ -151,7 +151,7 @@ local handle_combination = function (combo, spec)
local src = fnt.characters
local cnt = 0
- local pickchr = function (uc, unavailable)
+ local function pickchr (uc, unavailable)
local chr = src [uc]
if unavailable == true and basechar [uc] then
--- fallback mode: already known
@@ -202,7 +202,7 @@ end
---[[ begin excerpt from font-ott.lua ]]
-local swapped = function (h)
+local function swapped (h)
local r = { }
for k, v in next, h do
r[stringgsub(v,"[^a-z0-9]","")] = k -- is already lower
@@ -242,7 +242,7 @@ local support_incomplete = tabletohash({
--doc]]--
--- (string, string) dict -> (string, string) dict
-local apply_default_features = function (rawlist)
+local function apply_default_features (rawlist)
local speclist = {}
for k, v in pairs(rawlist) do
if type(v) == 'string' then
@@ -327,7 +327,7 @@ local supported = {
}
--- (string | (string * string) | bool) list -> (string * number)
-local handle_slashed = function (modifiers)
+local function handle_slashed (modifiers)
local style, optsize
for i=1, #modifiers do
local mod = modifiers[i]
@@ -356,7 +356,7 @@ do
end
--- spec -> spec
-local handle_request = function (specification)
+local function handle_request (specification)
local request = lpegmatch(luaotfload.parsers.font_request,
specification.specification)
----inspect(request)
@@ -569,7 +569,7 @@ local autofeatures = {
{ "!!??", interrolig_specification, "interrobang substitutions" },
}
-local add_auto_features = function ()
+local function add_auto_features ()
local nfeats = #autofeatures
report ("both", 5, "features",
"auto-installing %d feature definitions", nfeats)
@@ -582,6 +582,26 @@ end
luaotfload.apply_default_features = apply_default_features
+do
+ local function mathparaminitializer(tfmdata, value, features)
+ if not next(tfmdata.mathparameters) then return end
+ if value == 'auto' then
+ if features.script == 'math' then return end
+ end
+ tfmdata.mathparameters = {}
+ end
+ fonts.constructors.features.otf.register {
+ name = 'nomathparam',
+ description = 'Set Math parameters based on this font',
+ default = 'auto',
+ initializers = {
+ base = mathparaminitializer,
+ node = mathparaminitializer,
+ -- plug = mathparaminitializer,
+ },
+ }
+end
+
return function ()
if not fonts and fonts.handlers then
report ("log", 0, "features",
diff --git a/macros/luatex/generic/luaotfload/luaotfload-filelist.lua b/macros/luatex/generic/luaotfload/luaotfload-filelist.lua
index 11bc525547..35b74f6fa3 100644
--- a/macros/luatex/generic/luaotfload/luaotfload-filelist.lua
+++ b/macros/luatex/generic/luaotfload/luaotfload-filelist.lua
@@ -6,8 +6,8 @@
local ProvidesLuaModule = {
name = "luaotfload-filelist",
- version = "3.12", --TAGVERSION
- date = "2020-02-02", --TAGDATE
+ version = "3.13", --TAGVERSION
+ date = "2020-05-01", --TAGDATE
description = "luaotfload submodule / filelist",
license = "GPL v2.0"
}
@@ -252,6 +252,8 @@ luaotfload.filelist.data =
{ name = "harf-plug" ,kind = kind_library, ext =".lua", gitdir=gitdirsrc, texdir=texdirtex, gitpref = "luaotfload-" },
{ name = "loaders" ,kind = kind_library, ext =".lua", gitdir=gitdirsrc, texdir=texdirtex, gitpref = "luaotfload-" },
{ name = "multiscript" ,kind = kind_library, ext =".lua", gitdir=gitdirsrc, texdir=texdirtex, gitpref = "luaotfload-" },
+ { name = "scripts" ,kind = kind_library, ext =".lua", gitdir=gitdirsrc, texdir=texdirtex, gitpref = "luaotfload-" },
+ { name = "szss" ,kind = kind_library, ext =".lua", gitdir=gitdirsrc, texdir=texdirtex, gitpref = "luaotfload-" },
{ name = "fallback" ,kind = kind_library, ext =".lua", gitdir=gitdirsrc, texdir=texdirtex, gitpref = "luaotfload-" },
{ name = "parsers" ,kind = kind_library, ext =".lua", gitdir=gitdirsrc, texdir=texdirtex, gitpref = "luaotfload-" },
{ name = "resolvers" ,kind = kind_library, ext =".lua", gitdir=gitdirsrc, texdir=texdirtex, gitpref = "luaotfload-" },
diff --git a/macros/luatex/generic/luaotfload/luaotfload-glyphlist.lua b/macros/luatex/generic/luaotfload/luaotfload-glyphlist.lua
index 50f1b4d590..ca74e47257 100644
--- a/macros/luatex/generic/luaotfload/luaotfload-glyphlist.lua
+++ b/macros/luatex/generic/luaotfload/luaotfload-glyphlist.lua
@@ -1,7 +1,7 @@
local ProvidesLuaModule = {
name = "luaotfload-glyphlist",
- version = "3.12", --TAGVERSION
- date = "2020-02-02", --TAGDATE
+ version = "3.13", --TAGVERSION
+ date = "2020-05-01", --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 555180435a..80895d0f4f 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
local ProvidesLuaModule = {
name = "luaotfload-harf-define",
- version = "3.12", --TAGVERSION
- date = "2020-02-02", --TAGDATE
+ version = "3.13", --TAGVERSION
+ date = "2020-05-01", --TAGDATE
description = "luaotfload submodule / database",
license = "GPL v2.0",
author = "Khaled Hosny, Marcel Krüger",
@@ -18,6 +18,7 @@ do -- block to avoid to many local variables error
end
end
+local unpack = string.unpack
local stringlower = string.lower
local stringupper = string.upper
local gsub = string.gsub
@@ -25,6 +26,11 @@ local gsub = string.gsub
local hb = luaotfload.harfbuzz
local scriptlang_to_harfbuzz = require'luaotfload-scripts'.to_harfbuzz
+local harf_settings = luaotfload.harf or {}
+luaotfload.harf = harf_settings
+
+harf_settings.default_buf_flags = hb.Buffer.FLAGS_DEFAULT or 0
+
local hbfonts = {}
local cfftag = hb.Tag.new("CFF ")
@@ -32,12 +38,44 @@ local cff2tag = hb.Tag.new("CFF2")
local os2tag = hb.Tag.new("OS/2")
local posttag = hb.Tag.new("post")
local glyftag = hb.Tag.new("glyf")
+local gpostag = hb.Tag.new("GPOS")
local invalid_l = hb.Language.new()
local invalid_s = hb.Script.new()
+local floor = math.floor
+local function round(x)
+ return floor(x + 0.5)
+end
+
+local get_designsize do
+ -- local lpeg = lpeg or require'lpeg'
+ -- local size_patt = 'size' * lpeg.C(2)/function(s)
+ -- local first, second = string.byte(s)
+ -- return (first << 8) | second
+ -- end
+ local factor = 6578.176 -- =803/125*2^10=7227/7200/10*2^16
+ function get_designsize(face)
+ local buf = face:get_table(gpostag):get_data()
+ if #buf == 0 then return 655360 end
+ local major, feature_off = unpack(">HxxxxH", buf)
+ assert(major == 1, "Unsupported major version of GPOS table")
+ local feature_count = unpack(">H", buf, feature_off + 1)
+ for off = feature_off + 3, feature_off + 6*feature_count, 6 do
+ local tag = buf:sub(off, off + 3)
+ if tag == 'size' then
+ local off = feature_off + 1 + unpack(">H", buf, off + 4)
+ local off = off + unpack(">H", buf, off)
+ local design_size = unpack(">H", buf, off) -- unpack(">HHHHH", buf, off))
+ return round(design_size * factor)
+ end
+ end
+ return 655360
+ end
+end
+
local containers = luaotfload.fontloader.containers
-local hbcacheversion = 1.0
+local hbcacheversion = 1.1
local facecache = containers.define("fonts", "hb", hbcacheversion, true)
local function loadfont(spec)
@@ -92,8 +130,8 @@ local function loadfont(spec)
local post = hbface:get_table(posttag)
local length = post:get_length()
local data = post:get_data()
- if length >= 32 and string.unpack(">i4", data) <= 0x00030000 then
- local italicangle = string.unpack(">i4", data, 5) / 2^16
+ if length >= 32 and unpack(">i4", data) <= 0x00030000 then
+ local italicangle = unpack(">i4", data, 5) / 2^16
if italicangle ~= 0 then
slant = -math.tan(italicangle * math.pi / 180) * 65536.0
end
@@ -111,6 +149,7 @@ local function loadfont(spec)
-- too slow.
local glyphcount = hbface:get_glyph_count()
local glyphs = {}
+ local autoitalic = slant ~= 0 and 20 or nil -- the magic 20 is taken from ConTeXt where it came from Dohyun Kim. We keep it to be metric compatible as far as possible
for gid = 0, glyphcount - 1 do
local width = hbfont:get_glyph_h_advance(gid)
local height, depth, italic = nil, nil, nil
@@ -118,8 +157,9 @@ local function loadfont(spec)
if extents then
height = extents.y_bearing
depth = extents.y_bearing + extents.height
- if extents.x_bearing < 0 then
- italic = -extents.x_bearing
+ local right_bearing = extents.x_bearing + extents.width - width
+ if autoitalic and right_bearing > -autoitalic then
+ italic = right_bearing + autoitalic
end
end
glyphs[gid] = {
@@ -146,10 +186,10 @@ local function loadfont(spec)
local os2 = hbface:get_table(os2tag)
local length = os2:get_length()
local data = os2:get_data()
- if length >= 96 and string.unpack(">H", data) > 1 then
+ if length >= 96 and unpack(">H", data) > 1 then
-- We don’t need much of the table, so we read from hard-coded offsets.
- xheight = string.unpack(">H", data, 87)
- capheight = string.unpack(">H", data, 89)
+ xheight = unpack(">H", data, 87)
+ capheight = unpack(">H", data, 89)
end
end
@@ -174,6 +214,7 @@ local function loadfont(spec)
cached = {
date = date,
size = size,
+ designsize = get_designsize(hbface),
gid_offset = 0x120000,
upem = upem,
fonttype = fonttype,
@@ -214,20 +255,6 @@ local function sanitize(psname)
return psname:gsub('[][\0-\32\127-\255(){}<>/%%]', '-')
end
--- Ligatures. The value is a character "ligature" table as described in the
--- manual.
-local tlig ={
- [0x2013] = { [0x002D] = { char = 0x2014 } }, -- [---]
- [0x002D] = { [0x002D] = { char = 0x2013 } }, -- [--]
- [0x0060] = { [0x0060] = { char = 0x201C } }, -- [``]
- [0x0027] = { [0x0027] = { char = 0x201D } }, -- ['']
- [0x0021] = { [0x0060] = { char = 0x00A1 } }, -- [!`]
- [0x003F] = { [0x0060] = { char = 0x00BF } }, -- [?`]
- [0x002C] = { [0x002C] = { char = 0x201E } }, -- [,,]
- [0x003C] = { [0x003C] = { char = 0x00AB } }, -- [<<]
- [0x003E] = { [0x003E] = { char = 0x00BB } }, -- [>>]
-}
-
local function scalefont(data, spec)
if not data then return data, spec end
local size = spec.size
@@ -241,7 +268,7 @@ local function scalefont(data, spec)
local gid_offset = data.gid_offset
if size < 0 then
- size = -655.36 * size
+ size = round(size * data.designsize / -1000)
end
-- We shape in font units (at UPEM) and then scale output with the desired
@@ -280,57 +307,11 @@ local function scalefont(data, spec)
end
end
- local letterspace = 0
- if features.letterspace then
- letterspace = tonumber(features.letterspace) / 100 * upem
- elseif features.kernfactor then
- letterspace = tonumber(features.kernfactor) * upem
- end
- space = space + letterspace
-
- local slantfactor = nil
- if features.slant then
- slantfactor = tonumber(features.slant) * 1000
- end
-
- local mode = nil
- local width = nil
- if features.embolden then
- mode = 2
- -- The multiplication by 7200.0/7227 is to undo the opposite conversion
- -- the engine is doing and make the final number written in the PDF file
- -- match XeTeX’s.
- width = (size * tonumber(features.embolden) / 6553.6) * (7200.0/7227)
- end
-
- local hscale = upem
- local extendfactor = nil
- if features.extend then
- extendfactor = tonumber(features.extend) * 1000
- hscale = hscale * tonumber(features.extend)
- end
-
- local vscale = upem
- local squeezefactor = nil
- if features.squeeze then
- squeezefactor = tonumber(features.squeeze) * 1000
- vscale = vscale * tonumber(features.squeeze)
- end
-
- if features.tlig then
- for char in next, characters do
- local ligatures = tlig[char]
- if ligatures then
- characters[char].ligatures = ligatures
- end
- end
- end
-
local tfmdata = {
name = spec.specification,
filename = 'harfloaded:' .. spec.resolved,
subfont = spec.sub or 1,
- designsize = size,
+ designsize = data.designsize,
psname = sanitize(data.psname),
fullname = data.fullname,
index = spec.index,
@@ -340,10 +321,6 @@ local function scalefont(data, spec)
tounicode = 1,
nomath = true,
format = data.fonttype,
- slant = slantfactor,
- mode = mode,
- width = width,
- extend = extendfactor,
squeeze = squeezefactor,
characters = characters,
parameters = {
@@ -358,15 +335,16 @@ local function scalefont(data, spec)
},
hb = {
scale = scale,
- spec = spec,
palette = palette,
shared = data,
- letterspace = letterspace,
- hscale = hscale,
- vscale = vscale,
+ hscale = upem,
+ vscale = upem,
+ buf_flags = harf_settings.default_buf_flags,
},
specification = spec,
- shared = {},
+ shared = {
+ features = features,
+ },
properties = {},
resources = {
unicodes = data.name_to_char,
@@ -421,10 +399,13 @@ fonts.readers.harf = function(spec)
return scalefont(loadfont(spec), spec)
end
+local find_file = kpse.find_file
luatexbase.add_to_callback('find_opentype_file', function(name)
- return name:gsub('^harfloaded:', '')
+ return find_file(name, 'opentype fonts')
+ or name:gsub('^harfloaded:', '')
end, 'luaotfload.harf.strip_prefix')
luatexbase.add_to_callback('find_truetype_file', function(name)
- return name:gsub('^harfloaded:', '')
+ return find_file(name, 'truetype fonts')
+ or name:gsub('^harfloaded:', '')
end, 'luaotfload.harf.strip_prefix')
diff --git a/macros/luatex/generic/luaotfload/luaotfload-harf-plug.lua b/macros/luatex/generic/luaotfload/luaotfload-harf-plug.lua
index c1d87de312..726aaaea7e 100644
--- a/macros/luatex/generic/luaotfload/luaotfload-harf-plug.lua
+++ b/macros/luatex/generic/luaotfload/luaotfload-harf-plug.lua
@@ -5,8 +5,8 @@
do -- block to avoid to many local variables error
local ProvidesLuaModule = {
name = "luaotfload-harf-plug",
- version = "3.12", --TAGVERSION
- date = "2020-02-02", --TAGDATE
+ version = "3.13", --TAGVERSION
+ date = "2020-05-01", --TAGDATE
description = "luaotfload submodule / database",
license = "GPL v2.0",
author = "Khaled Hosny, Marcel Krüger",
@@ -105,6 +105,8 @@ local fl_unsafe = hb.Buffer.GLYPH_FLAG_UNSAFE_TO_BREAK
local startactual_p = "luaotfload_startactualtext"
local endactual_p = "luaotfload_endactualtext"
+local empty_table = {}
+
-- "Copy" properties as done by LuaTeX: Make old properties metatable
local function copytable(old)
local new = {}
@@ -164,22 +166,11 @@ end
local process
--- Legacy TeX Input Method Disguised as Font Ligatures hack.
---
--- Single replacements, keyed by character to replace. Handled separately
--- because TeX ligaturing mechanism does not support one-to-one replacements.
-local trep = {
- [0x0022] = 0x201D, -- ["]
- [0x0027] = 0x2019, -- [']
- [0x0060] = 0x2018, -- [`]
-}
-
local function itemize(head, fontid, direction)
local fontdata = font.getfont(fontid)
local hbdata = fontdata and fontdata.hb
local spec = fontdata and fontdata.specification
local options = spec and spec.features.raw
- local texlig = options and options.tlig
local runs, codes = {}, {}
local dirstack = {}
@@ -189,20 +180,25 @@ local function itemize(head, fontid, direction)
for n, id, subtype in direct.traverse(head) do
local code = 0xFFFC -- OBJECT REPLACEMENT CHARACTER
- local skip = false
+ local skip = lastskip
+ local props = properties[n]
- if id == glyph_t then
+ if props and props.zwnj then
+ code = 0x200C
+ -- skip = false -- Not sure about this, but lastskip should be a bit faster
+ elseif id == glyph_t then
if is_char(n) and getfont(n) == fontid then
code = getchar(n)
+ skip = false
else
skip = true
end
elseif id == glue_t and subtype == spaceskip_t then
code = 0x0020 -- SPACE
- skip = lastskip
elseif id == disc_t then
if uses_font(n, fontid) then
code = 0x00AD -- SOFT HYPHEN
+ skip = false
else
skip = true
end
@@ -217,17 +213,8 @@ local function itemize(head, fontid, direction)
-- Pop the last direction from the stack.
currdir = tableremove(dirstack)
end
- skip = lastskip
elseif id == localpar_t then
currdir = getdir(n)
- skip = lastskip
- end
-
- if not skip and texlig then
- local replacement = trep[code]
- if replacement then
- code = replacement
- end
end
codes[#codes + 1] = code
@@ -277,7 +264,7 @@ local function makesub(run, codes, nodelist)
if nodelist == 0 then -- FIXME: This shouldn't happen
nodelist = nil
end
- nodelist, glyphs = shape(nodelist, nodelist, subrun)
+ nodelist, nodelist, glyphs = shape(nodelist, nodelist, subrun)
return { glyphs = glyphs, run = subrun, head = nodelist }
end
@@ -300,7 +287,8 @@ local function printnodes(label, head, after)
end
-- Main shaping function that calls HarfBuzz, and does some post-processing of
-- the output.
-function shape(head, node, run)
+function shape(head, firstnode, run)
+ local node = firstnode
local codes = run.codes
local offset = run.start
local nodeindex = offset
@@ -313,7 +301,7 @@ function shape(head, node, run)
local fontdata = font.getfont(fontid)
local hbdata = fontdata.hb
- local spec = hbdata.spec
+ local spec = fontdata.specification
local features = spec.hb_features
local options = spec.features.raw
local hbshared = hbdata.shared
@@ -324,6 +312,9 @@ function shape(head, node, run)
local shapers = options.shaper and { options.shaper } or {}
local buf = hb.Buffer.new()
+ if buf.set_flags then
+ buf:set_flags(hbdata.buf_flags)
+ end
buf:set_direction(dir)
buf:set_script(script)
buf:set_language(lang)
@@ -334,6 +325,41 @@ function shape(head, node, run)
local vscale = hbdata.vscale
hbfont:set_scale(hscale, vscale)
+ do
+ features = table.merged(features) -- We don't want to modify the global features
+ local current_features = {}
+ local n = node
+ for i = offset-1, offset+len-2 do
+ local props = properties[n] or empty_table
+ if props then
+ local local_feat = props.glyph_features or empty_table
+ if local_feat then
+ for tag, value in next, current_features do
+ local loc = local_feat[tag]
+ loc = loc ~= nil and (tonumber(loc) or (loc and 1 or 0)) or nil
+ if value.value ~= loc then -- This includes loc == nil
+ value._end = i
+ features[#features + 1] = value
+ current_features[tag] = nil
+ end
+ end
+ for tag, value in next, local_feat do
+ if not current_features[tag] then
+ local feat = hb.Feature.new(tag)
+ feat.value = tonumber(value) or (value and 1 or 0)
+ feat.start = i
+ current_features[tag] = feat
+ end
+ end
+ end
+ end
+ n = getnext(n)
+ end
+ for _, feat in next, current_features do
+ features[#features + 1] = feat
+ end
+ end
+
if hb.shape_full(hbfont, buf, features, shapers) then
-- The engine wants the glyphs in logical order, but HarfBuzz outputs them
-- in visual order, so we reverse RTL buffers.
@@ -372,7 +398,7 @@ function shape(head, node, run)
local node = node
for j = cluster,nextcluster-1 do
local id = getid(node)
- if id == glyph_t or id == glue_t then
+ if id == glyph_t or (id == glue_t and getsubtype(node) == spaceskip_t) then
local code = codes[j + 1]
hex = hex..to_utf16_hex(code)
str = str..utf8.char(code)
@@ -385,7 +411,8 @@ function shape(head, node, run)
local discindex = nil
local disc = node
for j = cluster + 1, nextcluster do
- if codes[j] == 0x00AD then
+ local props = properties[disc]
+ if (not (props and props.zwnj)) and getid(disc) == disc_t then
discindex = j
break
end
@@ -489,6 +516,9 @@ function shape(head, node, run)
local predisc = getprev(disc)
setnext(predisc, rep)
setprev(rep, predisc)
+ if firstnode == startnode then
+ firstnode = disc
+ end
if startnode == head then
head = disc
else
@@ -519,10 +549,10 @@ function shape(head, node, run)
end
end
end
- return head, glyphs, run.len - len
+ return head, firstnode, glyphs, run.len - len
end
- return head, {}, 0
+ return head, firstnode, {}, 0
end
local function color_to_rgba(color)
@@ -583,8 +613,10 @@ local function tonodes(head, node, run, glyphs)
local dir = run.dir
local fontid = run.font
local fontdata = font.getfont(fontid)
+ local space = fontdata.parameters.space
local characters = fontdata.characters
local hbdata = fontdata.hb
+ local hfactor = (fontdata.extend or 1000) / 1000
local palette = hbdata.palette
local hbshared = hbdata.shared
local hbface = hbshared.face
@@ -596,7 +628,6 @@ local function tonodes(head, node, run, glyphs)
local lastprops
local scale = hbdata.scale
- local letterspace = hbdata.letterspace
local haspng = hbshared.haspng
local fonttype = hbshared.fonttype
@@ -640,7 +671,8 @@ local function tonodes(head, node, run, glyphs)
freenode(oldnode)
nodeindex = nodeindex + 1
else
- if id == glyph_t then
+ if lastprops and lastprops.zwnj and nodeindex == glyph.cluster + 1 then
+ elseif id == glyph_t then
local done
local fontglyph = fontglyphs[gid]
local character = characters[char]
@@ -749,8 +781,14 @@ local function tonodes(head, node, run, glyphs)
-- glyph, keep the node char unchanged. Helps with primitives that
-- take characters as input but actually work on glyphs, like
-- `\rpcode`.
- if character.commands or not oldcharacter
- or character.index ~= oldcharacter.index then
+ if not oldcharacter then
+ if gid == 0 then
+ local new = copynode(node)
+ head, node = insertafter(head, node, new)
+ end
+ setchar(node, char)
+ elseif character.commands
+ or character.index ~= oldcharacter.index then
setchar(node, char)
end
local xoffset = (rtl and -glyph.x_offset or glyph.x_offset) * scale
@@ -795,8 +833,8 @@ local function tonodes(head, node, run, glyphs)
if glyph.endactual then
setprop(node, endactual_p, true)
end
- local x_advance = glyph.x_advance + letterspace
- local width = fontglyph.width
+ local x_advance = glyph.x_advance
+ local width = fontglyph.width * hfactor
if width ~= x_advance then
-- The engine always uses the glyph width from the font, so we need
-- to insert a kern node if the x advance is different.
@@ -807,14 +845,18 @@ local function tonodes(head, node, run, glyphs)
elseif id == glue_t and getsubtype(node) == spaceskip_t then
-- If the glyph advance is different from the font space, then a
-- substitution or positioning was applied to the space glyph changing
- -- it from the default, so reset the glue using the new advance.
+ -- it from the default. We try to maintain as much as possible from the
+ -- original value because we assume that we want to keep spacefactors and
+ -- assume that we got mostly positioning applied. TODO: Handle the case that
+ -- we became a glyph in the process.
-- We are intentionally not comparing with the existing glue width as
-- spacing after the period is larger by default in TeX.
- local width = (glyph.x_advance + letterspace) * scale
- if fontdata.parameters.space ~= width then
- setwidth(node, width)
- setfield(node, "stretch", width / 2)
- setfield(node, "shrink", width / 3)
+ local width = glyph.x_advance * scale
+ -- if space > width + 2 or width > space + 2 then
+ if space ~= width then
+ setwidth(node, getwidth(node) - space + width)
+ -- setfield(node, "stretch", width / 2)
+ -- setfield(node, "shrink", width / 3)
end
elseif id == kern_t and getsubtype(node) == italiccorr_t then
-- If this is an italic correction node and the previous node is a
@@ -844,19 +886,15 @@ local function shape_run(head, current, run)
if not run.skip then
-- Font loaded with our loader and an HarfBuzz face is present, do our
-- shaping.
- local fontid = run.font
- local fontdata = font.getfont(fontid)
- local options = fontdata.specification.features.raw
-
local glyphs, offset
- head, glyphs, offset = shape(head, current, run)
+ head, current, glyphs, offset = shape(head, current, run)
return offset, tonodes(head, current, run, glyphs)
else
return 0, head, run.after
end
end
-function process(head, font, direction)
+function process(head, font, _attr, direction)
local newhead, current = head, head
local runs = itemize(head, font, direction)
diff --git a/macros/luatex/generic/luaotfload/luaotfload-init.lua b/macros/luatex/generic/luaotfload/luaotfload-init.lua
index 0f8d7b3206..e68741666a 100644
--- a/macros/luatex/generic/luaotfload/luaotfload-init.lua
+++ b/macros/luatex/generic/luaotfload/luaotfload-init.lua
@@ -7,8 +7,8 @@
local ProvidesLuaModule = {
name = "luaotfload-init",
- version = "3.12", --TAGVERSION
- date = "2020-02-02", --TAGDATE
+ version = "3.13", --TAGVERSION
+ date = "2020-05-01", --TAGDATE
description = "luaotfload submodule / initialization",
license = "GPL v2.0"
}
@@ -144,7 +144,7 @@ local context_modules = {
} --[[context_modules]]
-local load_context_modules = function (pth)
+local function load_context_modules (pth)
local load_module = luaotfload.loaders.context
local ignore_module = luaotfload.loaders.ignore
@@ -238,7 +238,7 @@ local function init_main(early_hook)
logreport ("log", 4, "init", "Concealing callback.register().")
local trapped_register = callback.register
- callback.register = function (id)
+ function callback.register (id)
logreport ("log", 4, "init",
"Dummy callback.register() invoked on %s.",
id)
@@ -319,7 +319,7 @@ local function init_main(early_hook)
--- of our fontloader package. Perhaps something’s wrong with the status
--- file which contains the datestamped filename? In any case, it can’t
--- hurt reporting it as a bug.
- logreport ("both", 0, "init", "Fontloader substitution failed, got “default”.")
+ logreport ("both", 0, "init", "Fontloader substitution failed, got \"default\".")
logreport ("log", 4, "init", "Falling back to reference fontloader.")
load_fontloader_module (luaotfload.fontloader_package)
@@ -392,36 +392,36 @@ local function init_main(early_hook)
elseif lfsisdir (fontloader) and verify_context_dir (fontloader) then
logreport ("log", 0, "init",
- "Loading Context files under prefix “%s”.",
+ "Loading Context files under prefix %q.",
fontloader)
load_context_modules (fontloader)
elseif lfs.isfile (fontloader) then
logreport ("log", 0, "init",
- "Loading fontloader from absolute path “%s”.",
+ "Loading fontloader from absolute path %q.",
fontloader)
local _void = assert (loadfile (fontloader, nil, context_environment)) ()
elseif kpsefind_file (fontloader) then
local path = kpsefind_file (fontloader)
logreport ("log", 0, "init",
- "Loading fontloader “%s” from kpse-resolved path “%s”.",
+ "Loading fontloader %q from kpse-resolved path %q.",
fontloader, path)
local _void = assert (loadfile (path, nil, context_environment)) ()
elseif kpsefind_file (("fontloader-%s.lua"):format(fontloader)) then
logreport ("log", 0, "init",
- "Using predefined fontloader “%s”.",
+ "Using predefined fontloader %q.",
fontloader)
load_fontloader_module (fontloader)
else
logreport ("both", 0, "init",
- "No match for requested fontloader “%s”.",
+ "No match for requested fontloader %q.",
fontloader)
fontloader = luaotfload.fontloader_package
logreport ("both", 0, "init",
- "Defaulting to predefined fontloader “%s”.",
+ "Defaulting to predefined fontloader %q.",
fontloader)
load_fontloader_module (fontloader)
end
@@ -429,7 +429,7 @@ local function init_main(early_hook)
---load_fontloader_module "font-odv.lua" --- <= Devanagari support from Context
logreport ("log", 0, "init",
- "Context OpenType loader version “%s”",
+ "Context OpenType loader version %q",
fonts.handlers.otf.version)
callback.register = trapped_register
nodes = context_environment.nodes
@@ -448,14 +448,19 @@ local init_post_install_callbacks = function ()
--doc]]--
+ -- The order is important here: multiscript=auto needs to look at the
+ -- fallback fonts, so they already have to be processed at that stage
+ local fallback = luaotfload.loaders.luaotfload "fallback".process
+ local multiscript = luaotfload.loaders.luaotfload "multiscript".process
+
-- MK Pass current text direction to simple_font_handler
local handler = luaotfload.fontloader.nodes.simple_font_handler
local callback = function(head, groupcode, _, _, direction)
if not direction then
direction = tex.get'textdir'
end
- domultiscript(head, nil, nil, nil, direction)
- dofallback(head, nil, nil, nil, direction)
+ multiscript(head, nil, nil, nil, direction)
+ fallback(head, nil, nil, nil, direction)
return handler(head, groupcode, nil, nil, direction)
end
luatexbase.add_to_callback("pre_linebreak_filter",
@@ -469,7 +474,7 @@ local init_post_install_callbacks = function ()
-- /MK
end
-local init_post_load_agl = function ()
+local function init_post_load_agl ()
--[[doc--
@@ -532,7 +537,7 @@ local init_post_load_agl = function ()
return nil
end
logreport ("both", 4, "init",
- "found Adobe glyph list file at ``%s``, using that.",
+ "found Adobe glyph list file at %q, using that.",
glyphlist)
local unicodes = dofile(glyphlist)
@@ -549,7 +554,7 @@ local init_post_actions = {
}
--- unit -> size_t
-local init_post = function ()
+local function init_post ()
--- hook for actions that need to take place after the fontloader is
--- installed
diff --git a/macros/luatex/generic/luaotfload/luaotfload-latex.pdf b/macros/luatex/generic/luaotfload/luaotfload-latex.pdf
index f374e6db89..673ae5f976 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-latex.tex b/macros/luatex/generic/luaotfload/luaotfload-latex.tex
index cdcb26e26e..dcf6507881 100644
--- a/macros/luatex/generic/luaotfload/luaotfload-latex.tex
+++ b/macros/luatex/generic/luaotfload/luaotfload-latex.tex
@@ -311,7 +311,7 @@
"NotoColorEmoji:mode=harf;"
}
)
- }
+ }
\def \listingpar {\endgraf}
\let \endlistingline \relax
@@ -540,7 +540,7 @@ function printctxfontlist ()
end
\end{luacode}
-
+\newcommand\gitissue[1]{\href{https://github.com/latex3/luaotfload/issues/#1}{(issue~\##1)}}
\begin {document}
\input {luaotfload-main.tex}
\clearpage
diff --git a/macros/luatex/generic/luaotfload/luaotfload-letterspace.lua b/macros/luatex/generic/luaotfload/luaotfload-letterspace.lua
index ce7d6fcd56..2825b87ea7 100644
--- a/macros/luatex/generic/luaotfload/luaotfload-letterspace.lua
+++ b/macros/luatex/generic/luaotfload/luaotfload-letterspace.lua
@@ -5,8 +5,8 @@
local ProvidesLuaModule = {
name = "luaotfload-letterspace",
- version = "3.12", --TAGVERSION
- date = "2020-02-02", --TAGDATE
+ version = "3.13", --TAGVERSION
+ date = "2020-05-01", --TAGDATE
description = "luaotfload submodule / color",
license = "GPL v2.0",
copyright = "PRAGMA ADE / ConTeXt Development Team",
@@ -165,7 +165,7 @@ end
---=================================================================---
-- UF changed 2017-07-14
-local kern_injector = function (fillup, kern)
+local function kern_injector (fillup, kern)
if fillup then
local g = new_node(glue_code)
setglue(g, 0, kern, 0, 1, 0)
@@ -177,7 +177,7 @@ local kern_injector = function (fillup, kern)
end
-- /UF
-local kernable_skip = function (n)
+local function kernable_skip (n)
local st = getsubtype (n)
return st == userskip_code
or st == spaceskip_code
@@ -452,7 +452,7 @@ end
--- (node_t -> node_t) -> string -> string list -> bool
local registered_as = { } --- procname -> callbacks
-local add_processor = function (processor, name, ...)
+local function add_processor (processor, name, ...)
local callbacks = { ... }
for i=1, #callbacks do
luatexbase.add_to_callback(callbacks[i], processor, name)
@@ -461,18 +461,6 @@ local add_processor = function (processor, name, ...)
return true
end
---- string -> bool
-local remove_processor = function (name)
- local callbacks = registered_as[name]
- if callbacks then
- for i=1, #callbacks do
- luatexbase.remove_from_callback(callbacks[i], name)
- end
- return true
- end
- return false --> unregistered
-end
-
--- When font kerning is requested, usually by defining a font with the
--- ``letterspace`` parameter, we inject a wrapper for the
--- ``kerncharacters()`` node processor in the relevant callbacks. This
@@ -482,9 +470,9 @@ end
--- performs all node operations on direct nodes.
--- unit -> bool
-local enablefontkerning = function ( )
+local function enablefontkerning ( )
- local handler = function (hd)
+ local function handler (hd)
local direct_hd = todirect (hd)
logreport ("term", 5, "letterspace",
"kerncharacters() invoked with node.direct interface \z
@@ -523,7 +511,7 @@ end
local fontkerning_enabled = false --- callback state
--- fontobj -> float -> unit
-local initializefontkerning = function (tfmdata, factor)
+local function initializefontkerning (tfmdata, factor)
if factor ~= "max" then
factor = tonumber (factor) or 0
end
@@ -548,6 +536,7 @@ otffeatures.register {
initializers = {
base = initializefontkerning,
node = initializefontkerning,
+ plug = initializefontkerning,
}
}
@@ -562,7 +551,7 @@ otffeatures.register {
--doc]]--
-local initializecompatfontkerning = function (tfmdata, percentage)
+local function initializecompatfontkerning (tfmdata, percentage)
local factor = tonumber (percentage)
if not factor then
logreport ("both", 0, "letterspace",
@@ -580,6 +569,7 @@ otffeatures.register {
initializers = {
base = initializecompatfontkerning,
node = initializecompatfontkerning,
+ plug = initializecompatfontkerning,
}
}
diff --git a/macros/luatex/generic/luaotfload/luaotfload-loaders.lua b/macros/luatex/generic/luaotfload/luaotfload-loaders.lua
index 0f24e4542e..3146fbd3c3 100644
--- a/macros/luatex/generic/luaotfload/luaotfload-loaders.lua
+++ b/macros/luatex/generic/luaotfload/luaotfload-loaders.lua
@@ -8,8 +8,8 @@
local ProvidesLuaModule = {
name = "luaotfload-loaders",
- version = "3.12", --TAGVERSION
- date = "2020-02-02", --TAGDATE
+ version = "3.13", --TAGVERSION
+ date = "2020-05-01", --TAGDATE
description = "luaotfload submodule / callback handling",
license = "GPL v2.0"
}
@@ -26,7 +26,7 @@ if not luaotfload then error "this module requires Luaotfload" end
local logreport = luaotfload.log and luaotfload.log.report or print
-local lua_reader = function (specification)
+local function lua_reader (specification)
local fullname = specification.resolved
if fullname then
local loader = loadfile (fullname)
@@ -35,19 +35,19 @@ local lua_reader = function (specification)
end
end
-local eval_reader = function (specification)
+local function eval_reader (specification)
local eval = specification.eval
if not eval or type (eval) ~= "function" then return nil end
logreport ("both", 0, "loaders",
- "eval: found tfmdata for “%s”, injecting.",
+ "eval: found tfmdata for %q, injecting.",
specification.name)
return eval ()
end
-local unsupported_reader = function (format)
+local function unsupported_reader (format)
return function (specification)
logreport ("both", 4, "loaders",
- "font format “%s” unsupported; cannot load %s.",
+ "font format %q unsupported; cannot load %s.",
format, tostring (specification.name))
end
end
@@ -55,7 +55,7 @@ end
local type1_reader = fonts.readers.afm
local tfm_reader = fonts.readers.tfm
-local install_formats = function ()
+local function install_formats ()
local fonts = fonts
if not fonts then return false end
@@ -65,17 +65,17 @@ local install_formats = function ()
local formats = fonts.formats
if not readers or not formats then return false end
- local aux = function (which, reader)
+ local function aux (which, reader)
if not which or type (which) ~= "string"
or not reader or type (reader) ~= "function" then
- logreport ("both", 2, "loaders", "Error installing reader for “%s”.", which)
+ logreport ("both", 2, "loaders", "Error installing reader for %q.", which)
return false
end
formats [which] = "type1"
readers [which] = reader
if not seqset [which] then
logreport ("both", 3, "loaders",
- "Extending reader sequence for “%s”.", which)
+ "Extending reader sequence for %q.", which)
sequence [#sequence + 1] = which
seqset [which] = true
end
@@ -92,7 +92,7 @@ local install_formats = function ()
and aux ("dfont", unsupported_reader "dfont")
end
-local not_found_msg = function (specification, size, id)
+local function not_found_msg (specification, size, id)
logreport ("both", 0, "loaders", "")
logreport ("both", 0, "loaders",
"--------------------------------------------------------")
@@ -132,7 +132,7 @@ do
return id
end
- local patch = function (specification, size, id)
+ local function patch (specification, size, id)
local fontdata = ctx_read (specification, size, id)
----if not fontdata then not_found_msg (specification, size, id) end
if type (fontdata) == "table" and fontdata.encodingbytes == 2 then
@@ -151,7 +151,7 @@ do
return id
end
- local mk_info = function (name)
+ local function mk_info (name)
local definer = name == "patch" and patch or read
return function (specification, size, id)
logreport ("both", 0, "loaders", "defining font no. %d", id)
@@ -199,7 +199,7 @@ end
--doc]]--
-local purge_define_font = function ()
+local function purge_define_font ()
local cdesc = luatexbase.callback_descriptions "define_font"
--- define_font is an “exclusive” callback, meaning that there can
--- only ever be one entry. Everything beyond that would indicate
@@ -210,10 +210,10 @@ local purge_define_font = function ()
if d2 then --> issue warning
logreport ("both", 0, "loaders",
"Callback table for define_font contains multiple entries: \z
- { [%d] = “%s” } -- seems fishy.", i, d2)
+ { [%d] = %q } -- seems fishy.", i, d2)
end
logreport ("log", 0, "loaders",
- "Entry ``%s`` present in define_font callback; overriding.", d)
+ "Entry %q present in define_font callback; overriding.", d)
luatexbase.remove_from_callback ("define_font", d)
end
end
diff --git a/macros/luatex/generic/luaotfload/luaotfload-log.lua b/macros/luatex/generic/luaotfload/luaotfload-log.lua
index 2cbacd597f..2a084772f5 100644
--- a/macros/luatex/generic/luaotfload/luaotfload-log.lua
+++ b/macros/luatex/generic/luaotfload/luaotfload-log.lua
@@ -6,8 +6,8 @@
local ProvidesLuaModule = {
name = "luaotfload-log",
- version = "3.12", --TAGVERSION
- date = "2020-02-02", --TAGDATE
+ version = "3.13", --TAGVERSION
+ date = "2020-05-01", --TAGDATE
description = "luaotfload submodule / logging",
license = "GPL v2.0",
author = "Khaled Hosny, Elie Roux, Philipp Gesang",
@@ -60,7 +60,7 @@ local loglevel = 0 --- default
local logout = "log"
--- int -> bool
-local set_loglevel = function (n)
+local function set_loglevel (n)
if type(n) == "number" then
loglevel = n
end
@@ -69,7 +69,7 @@ end
log.set_loglevel = set_loglevel
--- unit -> int
-local get_loglevel = function ( )
+local function get_loglevel ( )
return loglevel
end
log.get_loglevel = get_loglevel
@@ -85,7 +85,7 @@ to monitor the progress run "tail -f %s" in another terminal
local tmppath = os.getenv "TMPDIR" or "/tmp"
-local choose_logfile = function ( )
+local function choose_logfile ( )
if lfsisdir (tmppath) then
local fname
repeat --- ensure that file of that name doesn’t exist
@@ -98,7 +98,7 @@ local choose_logfile = function ( )
return false
end
-local set_logout = function (s, finalizers)
+local function set_logout (s, finalizers)
if s == "stdout" then
logout = "redirect"
elseif s == "file" then --- inject custom logger
@@ -149,14 +149,14 @@ log.set_logout = set_logout
local format_error_handler
if debug then
local debugtraceback = debug.traceback
- format_error_handler = function (err)
+ function format_error_handler (err)
print ""
print (stringformat ("luaotfload error: %q", err))
print (stringformat ("Lua interpreter %s", debugtraceback ()))
print ""
end
else
- format_error_handler = function (err)
+ function format_error_handler (err)
print ""
print (stringformat ("luaotfload error: %q", err))
print "Lua debug module not available; please enable for a backtrace"
@@ -164,7 +164,7 @@ else
end
end
-local basic_logger = function (category, fmt, ...)
+local function basic_logger (category, fmt, ...)
local res = { module_name, "|", category or "UNKNOWN", ":" }
if fmt then
local ok, val = xpcall (stringformat, format_error_handler, fmt, ...)
@@ -195,11 +195,11 @@ local kill_line = "\r\x1b[K"
if texjob == true then
--- We imitate the texio.* functions so the output is consistent.
- writeln = function (str)
+ function writeln (str)
iowrite "\n"
iowrite(str)
end
- statusln = function (str)
+ function statusln (str)
if first_status == false then
iowrite (kill_line)
else
@@ -208,11 +208,11 @@ if texjob == true then
iowrite (str)
end
else
- writeln = function (str)
+ function writeln (str)
iowrite(str)
iowrite "\n"
end
- statusln = function (str)
+ function statusln (str)
if first_status == false then
iowrite (kill_line)
end
@@ -220,7 +220,7 @@ else
end
end
-local stdout = function (writer, category, ...)
+local function stdout (writer, category, ...)
local res = { module_name, "|", category, ":" }
local nargs = select("#", ...)
if nargs == 0 then
@@ -331,7 +331,7 @@ local status_writer
local status_low = 99
local status_high = 99
-local status_start = function (low, high)
+local function status_start (low, high)
first_status = true
status_low = low
status_high = high
@@ -386,7 +386,7 @@ log.names_status_stop = status_stop
--doc]]--
-local texioreporter = function (message)
+local function texioreporter (message)
report ("log", 2, message)
end
diff --git a/macros/luatex/generic/luaotfload/luaotfload-main.lua b/macros/luatex/generic/luaotfload/luaotfload-main.lua
index 35378d91cb..1c962c3950 100644
--- a/macros/luatex/generic/luaotfload/luaotfload-main.lua
+++ b/macros/luatex/generic/luaotfload/luaotfload-main.lua
@@ -20,8 +20,8 @@ local authors = "\z
-- version number is used below!
local ProvidesLuaModule = {
name = "luaotfload-main",
- version = "3.12", --TAGVERSION
- date = "2020-02-02", --TAGDATE
+ version = "3.13", --TAGVERSION
+ date = "2020-05-01", --TAGDATE
description = "luaotfload entry point",
author = authors,
copyright = authors,
@@ -37,6 +37,7 @@ config = config or { }
luaotfload = luaotfload or { }
local luaotfload = luaotfload
luaotfload.log = luaotfload.log or { }
+local logreport
luaotfload.version = ProvidesLuaModule.version
luaotfload.loaders = { }
luaotfload.min_luatex_version = { 0, 95, 0 }
@@ -68,7 +69,7 @@ end
if not utf8 then
texio.write_nl("term and log", string.format("\z
\tluaotfload: module utf8 is unavailable\n\z
- \tutf8 is available in Lua 5.3+; engine\'s _VERSION is '%s'\n\z
+ \tutf8 is available in Lua 5.3+; engine\'s _VERSION is %q\n\z
\tThis probably means that the engine is not supported\n\z
\n",
_VERSION))
@@ -118,7 +119,7 @@ local type = type
--doc]]--
-local make_loader_name = function (prefix, name)
+local function make_loader_name (prefix, name)
local msg = luaotfload.log and luaotfload.log.report
or function (stream, lvl, cat, ...)
if lvl > 1 then --[[not pressing]] return end
@@ -129,14 +130,14 @@ local make_loader_name = function (prefix, name)
end
if not name then
msg ("both", 0, "load",
- "Fatal error: make_loader_name (“%s”, “%s”).",
+ "Fatal error: make_loader_name (%q, %q).",
tostring (prefix), tostring (name))
return "dummy-name"
end
name = tostring (name)
if prefix == false then
msg ("log", 9, "load",
- "No prefix requested, passing module name “%s” unmodified.",
+ "No prefix requested, passing module name %q unmodified.",
name)
return tostring (name) .. ".lua"
end
@@ -152,7 +153,7 @@ local timing_info = {
t_init = { },
}
-local make_loader = function (prefix, load_helper)
+local function make_loader (prefix, load_helper)
return function (name)
local t_0 = osgettimeofday ()
local modname = make_loader_name (prefix, name)
@@ -164,8 +165,8 @@ local make_loader = function (prefix, load_helper)
io.write "\n"
local msg = luaotfload.log and luaotfload.log.report or print
msg ("both", 0, "load", "FATAL ERROR")
- msg ("both", 0, "load", " × Failed to load module %q.",
- tostring (modname))
+ msg ("both", 0, "load", " × Failed to load %q module %q.",
+ tostring (prefix), tostring (name))
local lines = string.split (data, "\n\t")
if not lines then
msg ("both", 0, "load", " × Error message: %q", data)
@@ -194,9 +195,9 @@ end
called in the expected places.
--doc]]--
-local dummy_loader = function (name)
+local function dummy_loader (name)
luaotfload.log.report ("log", 3, "load",
- "Skipping module “%s” on purpose.",
+ "Skipping module %q on purpose.",
name)
end
@@ -205,14 +206,14 @@ luaotfload.fontloader = context_environment
local function context_isolated_load(name)
local fullname = kpse.find_file(name, 'lua')
if not fullname then
- error(string.format('Fontloader module "%s" could not be found.', name))
+ error(string.format('Fontloader module %q could not be found.', name))
end
return assert(loadfile(fullname, nil, context_environment))(name)
end
-local context_loader = function (name, path)
+local function context_loader (name, path)
luaotfload.log.report ("log", 3, "load",
- "Loading module “%s” from Context.",
+ "Loading module %q from Context.",
name)
local t_0 = osgettimeofday ()
local modname = make_loader_name (false, name)
@@ -220,12 +221,12 @@ local context_loader = function (name, path)
if path then
if lfs.isdir (path) then
luaotfload.log.report ("log", 3, "load",
- "Prepending path “%s”.",
+ "Prepending path %q.",
path)
modpath = file.join (path, modname)
else
luaotfload.log.report ("both", 0, "load",
- "Non-existant path “%s” specified, ignoring.",
+ "Non-existant path %q specified, ignoring.",
path)
end
end
@@ -239,12 +240,12 @@ local context_loader = function (name, path)
--- something isn’t right, but against HH’s coding practices. We’ll
--- silently ignore this ever happening on lower log levels.
luaotfload.log.report ("log", 4, "load",
- "Module “%s” returned “%s”.", ret)
+ "Module %q returned %q.", ret)
end
return ret
end
-local install_loaders = function ()
+local function install_loaders ()
local loaders = { }
local loadmodule = make_loader "luaotfload"
loaders.luaotfload = loadmodule
@@ -253,22 +254,21 @@ local install_loaders = function ()
loaders.ignore = dummy_loader
----loaders.plaintex = make_loader "luatex" --=> for Luatex-Plain
- loaders.initialize = function (name)
+ function loaders.initialize (name)
local tmp = loadmodule (name)
- local logreport = luaotfload.log.report
local init = type(tmp) == "table" and tmp.init or tmp
if init and type (init) == "function" then
local t_0 = osgettimeofday ()
if not init () then
logreport ("log", 0, "load",
- "Failed to load module “%s”.", name)
+ "Failed to load module %q.", name)
return
end
local t_end = osgettimeofday ()
local d_t = t_end - t_0
logreport ("log", 4, "load",
- "Module “%s” loaded in %d ms.",
- name, d_t)
+ "Module %q loaded in %g ms.",
+ name, d_t * 1000)
timing_info.t_init [name] = d_t
end
end
@@ -294,15 +294,22 @@ luaotfload.main = function ()
local initialize = loaders.initialize
local starttime = osgettimeofday ()
+
+ -- Feature detect HarfBuzz. This is done early to allow easy HarfBuzz
+ -- detection in other modules
+ local harfstatus, harfbuzz = pcall(require, 'luaharfbuzz')
+ if harfstatus then
+ luaotfload.harfbuzz = harfbuzz
+ end
+
local init = loadmodule "init" --- fontloader initialization
init (function ()
+ logreport = luaotfload.log.report
initialize "parsers" --- fonts.conf and syntax
initialize "configuration" --- configuration options
end)
- local logreport = luaotfload.log.report
-
initialize "loaders" --- Font loading; callbacks
initialize "database" --- Font management.
initialize "colors" --- Per-font colors.
@@ -316,18 +323,16 @@ luaotfload.main = function ()
initialize "features" --- font request and feature handling
- loadmodule "letterspace" --- extra character kerning
- loadmodule "embolden" --- fake bold
- loadmodule "notdef" --- missing glyph handling
- local harfstatus, harfbuzz = pcall(require, 'luaharfbuzz')
if harfstatus then
- luaotfload.harfbuzz = harfbuzz
loadmodule "harf-define"
loadmodule "harf-plug"
end
+ loadmodule "letterspace" --- extra character kerning
+ loadmodule "embolden" --- fake bold
+ loadmodule "notdef" --- missing glyph handling
+ loadmodule "suppress" --- suppress ligatures by adding ZWNJ
+ loadmodule "szss" --- missing glyph handling
initialize "auxiliary" --- additional high-level functionality
- loadmodule "fallback" --- ...
- loadmodule "multiscript" --- ...
loadmodule "tounicode"
luaotfload.aux.start_rewrite_fontname () --- to be migrated to fontspec
diff --git a/macros/luatex/generic/luaotfload/luaotfload-main.tex b/macros/luatex/generic/luaotfload/luaotfload-main.tex
index 79d7411b20..91983354bc 100644
--- a/macros/luatex/generic/luaotfload/luaotfload-main.tex
+++ b/macros/luatex/generic/luaotfload/luaotfload-main.tex
@@ -1,4 +1,4 @@
-%% Copyright (C) 2009-2018
+%% Copyright (C) 2009-2020
%%
%% by Elie Roux <elie.roux@telecom-bretagne.eu>
%% and Khaled Hosny <khaledhosny@eglug.org>
@@ -32,7 +32,7 @@
\beginfrontmatter
\setdocumenttitle {The \identifier{luaotfload} package}
- \setdocumentdate {2020-02-02 v3.12}
+ \setdocumentdate {2020-05-01 v3.13}
\setdocumentauthor {LaTeX3 Project\\
Elie Roux · Khaled Hosny · Philipp Gesang · Ulrike Fischer · Marcel Krüger\\
Home: \hyperlink {https://github.com/latex3/luaotfload}}
@@ -62,6 +62,25 @@ Supported is the \identifier{luatex} versions of a current TeXLive 2019 (and a c
\endsection
\beginsection{Changes}
+\beginsubsection {New in version 3.13 (by Ulrike Fischer/Marcel Krüger)}
+\begin{itemize}
+\item A\marginpar{\mbox{}\hfill \textbf{Change!}} problem with text fonts with minimal math table has been fixed \gitissue{148}:
+ In new luaotfload versions, math parameters will only be loaded for fonts with \texttt{script=math}.
+ If you do want to set math parameters for fonts with other scripts, add \texttt{-nomathparam}.
+ We strongly recommend against setting math parameters for text fonts because
+ these would overwrite parameters from actual math fonts.
+\item A bug in harf-mode that could lead to missing chars and freezing was corrected \gitissue{141}.
+\item A font size problem in harf-mode has been fixed \gitissue{147}.
+\item An error if the main function was called twice has been fixed \gitissue{145}.
+\item Allow .ttf fonts to be loaded with a map file with luahbtex \gitissue{142} \gitissue{143}.
+\item Fonts installed for a single user on windows are now found \gitissue{138}.
+\item A problem with wrong \TeX-ligatures in harf mode has been fixed \gitissue{139}.
+\item The debugging output has been changed \gitissue{131}.
+\item A missing \enquote{capital sharp s} (U+1E9E) in a font is replaced by SS instead of giving a missing character message:
+ ^^^^1e9e or {\sffamily ^^^^1e9e}
+\item The color handling has been improved so that it is now compatible with the luacolor package.
+\end{itemize}
+\endsubsection
\beginsubsection {New in version 3.12 (by Ulrike Fischer/Marcel Krüger)}
\begin{itemize}
\item Corrected a number of small bugs in harf mode.
@@ -71,13 +90,14 @@ coloring of specific output glyphs, see page~\pageref{color-glyphs}
\item A\marginpar{Experimental!} new \identifier{multiscript} key to allow to use a font
for more than one script, see page~\pageref{multiscript}
\end{itemize}
-
+\endsubsection
\beginsubsection {New in version 3.11 (by Ulrike Fischer/Marcel Krüger)}
\begin{itemize}
\item Changed the handling of the \identifier{script} key in harf mode to be more compatible with behaviour of the node mode. It now expects the name of a script that is actually in the font instead of a ISO 15924 script tag. See issue 117.
\item Corrected a number of small typos and bugs in harf mode.
\end{itemize}
-\beginsubsection {New in version 3.1 (by Ulrike Fischer/Marcel Krüger)}
+\endsubsection
+\beginsubsection {New in version 3.10 (by Ulrike Fischer/Marcel Krüger)}
\begin{itemize}
\item The package has been moved to the github of the LaTeX3 Project and is now maintained
officially by the LaTeX3 Project team.
@@ -1139,7 +1159,7 @@ obviously, \inlinecode{random}.
{
"DejaVuSans:mode=harf;script=grek;color=FF0000;",
"cmuserif:mode=node;script=cyrl;color=00FF00;",
- "NotoSansBengali:mode=harf;script=bng2;color=0000FF;"
+ "NotoSansBengali:mode=harf;script=bng2;color=0000FF;",
"NotoColorEmoji:mode=harf;"
}
)
@@ -2058,14 +2078,14 @@ are defined for which scripts.
\beginaltitem {aux.slot_of_name(id : int, name : string)}
Translates a name for a glyph in font \luaident{id} to the
corresponding glyph slot which can be used e.g.\ as an argument to
- \inlinecode{\char}. The number is assigned by the \identifier{luaotfload} code
+ \inlinecode{\char}. The number is assigned by the \identifier{luaotfload} code
and not related to the glyph index (GID) of the font as stored in the \identifier{[index]} field
of the lua-file.
\endaltitem
- \beginaltitem {aux.gid_of_name(id : int, name : string)}
+ \beginaltitem {aux.gid_of_name(id : int, name : string)}
Translates\marginpar{New version 3.12} a name for a glyph in font \luaident{id} to the
- corresponding glyph index (GID) as stored in the \identifier{[index]} field.
+ corresponding glyph index (GID) as stored in the \identifier{[index]} field.
\endaltitem
\beginaltitem {aux.name_of_slot(id : int, slot : int)}
diff --git a/macros/luatex/generic/luaotfload/luaotfload-multiscript.lua b/macros/luatex/generic/luaotfload/luaotfload-multiscript.lua
index f6a272ecab..5638d281c7 100644
--- a/macros/luatex/generic/luaotfload/luaotfload-multiscript.lua
+++ b/macros/luatex/generic/luaotfload/luaotfload-multiscript.lua
@@ -5,8 +5,8 @@
local ProvidesLuaModule = {
name = "luaotfload-multiscript",
- version = "3.12", --TAGVERSION
- date = "2020-02-02", --TAGDATE
+ version = "3.13", --TAGVERSION
+ date = "2020-05-01", --TAGDATE
description = "luaotfload submodule / multiscript",
license = "GPL v2.0",
author = "Marcel Krüger"
@@ -23,14 +23,30 @@ local getwhd = node.direct.getwhd
local insert_after = node.direct.insert_after
local traverse_char = node.direct.traverse_char
local protect_glyph = node.direct.protect_glyph
+local flush_node = node.direct.flush_node
+local remove = node.direct.remove
local otffeatures = fonts.constructors.newfeatures "otf"
-- local normalize = fonts.handlers.otf.features.normalize
local definers = fonts.definers
-local define_font = luaotfload.define_font
+local define_font -- = luaotfload.define_font % This is set when the first font is loaded.
local scripts_lib = require'luaotfload-scripts'.script
local script_to_iso = scripts_lib.to_iso
local script_to_ot = scripts_lib.to_ot
+local delayedremove, finishremove do
+ local removed
+ function finishremove()
+ if removed then
+ flush_node(removed)
+ end
+ removed = nil
+ end
+ function delayedremove(head, current)
+ finishremove()
+ removed = current
+ return remove(head, current)
+ end
+end
local harf = luaotfload.harfbuzz
local GSUBtag, GPOStag
if harf then
@@ -63,55 +79,56 @@ local script_extensions do
end
end
end
+local script_list = {}
local script_mapping do
-- We could extract these from PropertyValueAliases.txt...
local script_aliases = {
- Adlam = "Adlm", Caucasian_Albanian = "Aghb", Ahom = "Ahom", Arabic = "Arab",
- Imperial_Aramaic = "Armi", Armenian = "Armn", Avestan = "Avst",
- Balinese = "Bali", Bamum = "Bamu", Bassa_Vah = "Bass", Batak = "Batk",
- Bengali = "Beng", Bhaiksuki = "Bhks", Bopomofo = "Bopo", Brahmi = "Brah",
- Braille = "Brai", Buginese = "Bugi", Buhid = "Buhd", Chakma = "Cakm",
- Canadian_Aboriginal = "Cans", Carian = "Cari", Cham = "Cham",
- Cherokee = "Cher", Coptic = "Copt", Cypriot = "Cprt", Cyrillic = "Cyrl",
- Devanagari = "Deva", Dogra = "Dogr", Deseret = "Dsrt", Duployan = "Dupl",
- Egyptian_Hieroglyphs = "Egyp", Elbasan = "Elba", Elymaic = "Elym",
- Ethiopic = "Ethi", Georgian = "Geor", Glagolitic = "Glag",
- Gunjala_Gondi = "Gong", Masaram_Gondi = "Gonm", Gothic = "Goth",
- Grantha = "Gran", Greek = "Grek", Gujarati = "Gujr", Gurmukhi = "Guru",
- Hangul = "Hang", Han = "Hani", Hanunoo = "Hano", Hatran = "Hatr",
- Hebrew = "Hebr", Hiragana = "Hira", Anatolian_Hieroglyphs = "Hluw",
- Pahawh_Hmong = "Hmng", Nyiakeng_Puachue_Hmong = "Hmnp",
- Katakana_Or_Hiragana = "Hrkt", Old_Hungarian = "Hung", Old_Italic = "Ital",
- Javanese = "Java", Kayah_Li = "Kali", Katakana = "Kana",
- Kharoshthi = "Khar", Khmer = "Khmr", Khojki = "Khoj", Kannada = "Knda",
- Kaithi = "Kthi", Tai_Tham = "Lana", Lao = "Laoo", Latin = "Latn",
- Lepcha = "Lepc", Limbu = "Limb", Linear_A = "Lina", Linear_B = "Linb",
- Lisu = "Lisu", Lycian = "Lyci", Lydian = "Lydi", Mahajani = "Mahj",
- Makasar = "Maka", Mandaic = "Mand", Manichaean = "Mani", Marchen = "Marc",
- Medefaidrin = "Medf", Mende_Kikakui = "Mend", Meroitic_Cursive = "Merc",
- Meroitic_Hieroglyphs = "Mero", Malayalam = "Mlym", Modi = "Modi",
- Mongolian = "Mong", Mro = "Mroo", Meetei_Mayek = "Mtei", Multani = "Mult",
- Myanmar = "Mymr", Nandinagari = "Nand", Old_North_Arabian = "Narb",
- Nabataean = "Nbat", Newa = "Newa", Nko = "Nkoo", Nushu = "Nshu",
- Ogham = "Ogam", Ol_Chiki = "Olck", Old_Turkic = "Orkh", Oriya = "Orya",
- Osage = "Osge", Osmanya = "Osma", Palmyrene = "Palm", Pau_Cin_Hau = "Pauc",
- Old_Permic = "Perm", Phags_Pa = "Phag", Inscriptional_Pahlavi = "Phli",
- Psalter_Pahlavi = "Phlp", Phoenician = "Phnx", Miao = "Plrd",
- Inscriptional_Parthian = "Prti", Rejang = "Rjng", Hanifi_Rohingya = "Rohg",
- Runic = "Runr", Samaritan = "Samr", Old_South_Arabian = "Sarb",
- Saurashtra = "Saur", SignWriting = "Sgnw", Shavian = "Shaw",
- Sharada = "Shrd", Siddham = "Sidd", Khudawadi = "Sind", Sinhala = "Sinh",
- Sogdian = "Sogd", Old_Sogdian = "Sogo", Sora_Sompeng = "Sora",
- Soyombo = "Soyo", Sundanese = "Sund", Syloti_Nagri = "Sylo",
- Syriac = "Syrc", Tagbanwa = "Tagb", Takri = "Takr", Tai_Le = "Tale",
- New_Tai_Lue = "Talu", Tamil = "Taml", Tangut = "Tang", Tai_Viet = "Tavt",
- Telugu = "Telu", Tifinagh = "Tfng", Tagalog = "Tglg", Thaana = "Thaa",
- Thai = "Thai", Tibetan = "Tibt", Tirhuta = "Tirh", Ugaritic = "Ugar",
- Vai = "Vaii", Warang_Citi = "Wara", Wancho = "Wcho", Old_Persian = "Xpeo",
- Cuneiform = "Xsux", Yi = "Yiii", Zanabazar_Square = "Zanb",
- Inherited = "Zinh", Common = "Zyyy", Unknown = "Zzzz",
+ Adlam = "adlm", Caucasian_Albanian = "aghb", Ahom = "ahom", Arabic = "arab",
+ Imperial_Aramaic = "armi", Armenian = "armn", Avestan = "avst",
+ Balinese = "bali", Bamum = "bamu", Bassa_Vah = "bass", Batak = "batk",
+ Bengali = "beng", Bhaiksuki = "bhks", Bopomofo = "bopo", Brahmi = "brah",
+ Braille = "brai", Buginese = "bugi", Buhid = "buhd", Chakma = "cakm",
+ Canadian_Aboriginal = "cans", Carian = "cari", Cham = "cham",
+ Cherokee = "cher", Coptic = "copt", Cypriot = "cprt", Cyrillic = "cyrl",
+ Devanagari = "deva", Dogra = "dogr", Deseret = "dsrt", Duployan = "dupl",
+ Egyptian_Hieroglyphs = "egyp", Elbasan = "elba", Elymaic = "elym",
+ Ethiopic = "ethi", Georgian = "geor", Glagolitic = "glag",
+ Gunjala_Gondi = "gong", Masaram_Gondi = "gonm", Gothic = "goth",
+ Grantha = "gran", Greek = "grek", Gujarati = "gujr", Gurmukhi = "guru",
+ Hangul = "hang", Han = "hani", Hanunoo = "hano", Hatran = "hatr",
+ Hebrew = "hebr", Hiragana = "hira", Anatolian_Hieroglyphs = "hluw",
+ Pahawh_Hmong = "hmng", Nyiakeng_Puachue_Hmong = "hmnp",
+ Katakana_Or_Hiragana = "hrkt", Old_Hungarian = "hung", Old_Italic = "ital",
+ Javanese = "java", Kayah_Li = "kali", Katakana = "kana",
+ Kharoshthi = "khar", Khmer = "khmr", Khojki = "khoj", Kannada = "knda",
+ Kaithi = "kthi", Tai_Tham = "lana", Lao = "laoo", Latin = "latn",
+ Lepcha = "lepc", Limbu = "limb", Linear_A = "lina", Linear_B = "linb",
+ Lisu = "lisu", Lycian = "lyci", Lydian = "lydi", Mahajani = "mahj",
+ Makasar = "maka", Mandaic = "mand", Manichaean = "mani", Marchen = "marc",
+ Medefaidrin = "medf", Mende_Kikakui = "mend", Meroitic_Cursive = "merc",
+ Meroitic_Hieroglyphs = "mero", Malayalam = "mlym", Modi = "modi",
+ Mongolian = "mong", Mro = "mroo", Meetei_Mayek = "mtei", Multani = "mult",
+ Myanmar = "mymr", Nandinagari = "nand", Old_North_Arabian = "narb",
+ Nabataean = "nbat", Newa = "newa", Nko = "nkoo", Nushu = "nshu",
+ Ogham = "ogam", Ol_Chiki = "olck", Old_Turkic = "orkh", Oriya = "orya",
+ Osage = "osge", Osmanya = "osma", Palmyrene = "palm", Pau_Cin_Hau = "pauc",
+ Old_Permic = "perm", Phags_Pa = "phag", Inscriptional_Pahlavi = "phli",
+ Psalter_Pahlavi = "phlp", Phoenician = "phnx", Miao = "plrd",
+ Inscriptional_Parthian = "prti", Rejang = "rjng", Hanifi_Rohingya = "rohg",
+ Runic = "runr", Samaritan = "samr", Old_South_Arabian = "sarb",
+ Saurashtra = "saur", SignWriting = "sgnw", Shavian = "shaw",
+ Sharada = "shrd", Siddham = "sidd", Khudawadi = "sind", Sinhala = "sinh",
+ Sogdian = "sogd", Old_Sogdian = "sogo", Sora_Sompeng = "sora",
+ Soyombo = "soyo", Sundanese = "sund", Syloti_Nagri = "sylo",
+ Syriac = "syrc", Tagbanwa = "tagb", Takri = "takr", Tai_Le = "tale",
+ New_Tai_Lue = "talu", Tamil = "taml", Tangut = "tang", Tai_Viet = "tavt",
+ Telugu = "telu", Tifinagh = "tfng", Tagalog = "tglg", Thaana = "thaa",
+ Thai = "thai", Tibetan = "tibt", Tirhuta = "tirh", Ugaritic = "ugar",
+ Vai = "vaii", Warang_Citi = "wara", Wancho = "wcho", Old_Persian = "xpeo",
+ Cuneiform = "xsux", Yi = "yiii", Zanabazar_Square = "zanb",
+ Inherited = "zinh", Common = "zyyy", Unknown = "zzzz",
}
- local entry = lpeg.Cg(codepoint_range * sep * ((lpeg.R'AZ' + lpeg.R'az' + '_')^1/script_aliases/string.lower))^-1 * (1-lpeg.P'\n')^0 * '\n'
+ local entry = lpeg.Cg(codepoint_range * sep * ((lpeg.R'AZ' + lpeg.R'az' + '_')^1/script_aliases))^-1 * (1-lpeg.P'\n')^0 * '\n'
-- local entry = lpeg.Cg(codepoint_range * sep * lpeg.Cc(true))^-1 * (1-lpeg.P'\n')^0 * '\n'
local file = lpeg.Cf(
lpeg.Ct''
@@ -121,6 +138,23 @@ local script_mapping do
local f = io.open(kpse.find_file"Scripts.txt")
script_mapping = file:match(f:read'*a')
f:close()
+
+ for _, scr in next, script_aliases do
+ script_list[#script_list + 1] = scr
+ end
+end
+
+table.sort(script_list)
+local script_mark_offset = 0x200000
+local script_marks = {}
+do
+ for i=1,#script_list do
+ local codepoint = script_mark_offset - 1 + i
+ local scr = script_list[i]
+ -- script_mapping[codepoint] = scr
+ script_marks[scr] = codepoint
+ script_marks[codepoint] = scr
+ end
end
local function load_on_demand(specifications, size)
@@ -184,6 +218,7 @@ local function is_dominant_script(scripts, script, first, ...)
end
local function makecombifont(tfmdata, _, additional_scripts)
+ define_font = define_font or luaotfload.define_font -- Lazy loading because this file get's loaded before define_font is defined
local has_auto
additional_scripts = tostring(additional_scripts)
if additional_scripts:sub(1, 5) == "auto+" then
@@ -287,12 +322,12 @@ end
local glyph_id = node.id'glyph'
-- TODO: unset last_script, matching parentheses etc
-function domultiscript(head, _, _, _, direction)
+local function domultiscript(head, _, _, _, direction)
head = node.direct.todirect(head)
local last_fid, last_fonts, last_script
for cur, cid, fid in traverse_char(head) do
if fid ~= last_fid then
- last_fid, last_fonts, last_script = fid, additional_scripts_fonts[fid]
+ last_fid, last_fonts = fid, additional_scripts_fonts[fid]
end
if last_fonts then
local mapped_scr = script_mapping[cid]
@@ -321,8 +356,18 @@ function domultiscript(head, _, _, _, direction)
if mapped_font then
setfont(cur, mapped_font)
end
+ elseif fid == 0 then
+ local script_mark = script_marks[cid]
+ if script_mark then
+ head = delayedremove(head, current) -- Instead of removing them we could also keep them and suppress the missing glyph warning, but this seems cleaner
+ last_script = script_mark
+ end
+ else
+ last_script = nil
end
end
+ finishremove() -- Cleanup
+ return head
end
function luaotfload.add_multiscript(name, fonts)
@@ -336,6 +381,10 @@ function luaotfload.add_multiscript(name, fonts)
return name
end
+function luaotfload.get_script_mark(scr)
+ return script_marks[scr]
+end
+
otffeatures.register {
name = "multiscript",
description = "Combine fonts for multiple scripts",
@@ -349,4 +398,8 @@ otffeatures.register {
-- }
}
+return {
+ -- I would omit the table if that wouldn't cause the function to be used as initializer
+ process = domultiscript,
+}
--- vim:sw=2:ts=2:expandtab:tw=71
diff --git a/macros/luatex/generic/luaotfload/luaotfload-notdef.lua b/macros/luatex/generic/luaotfload/luaotfload-notdef.lua
index 3156882e86..7108e7d7df 100644
--- a/macros/luatex/generic/luaotfload/luaotfload-notdef.lua
+++ b/macros/luatex/generic/luaotfload/luaotfload-notdef.lua
@@ -5,8 +5,8 @@
local ProvidesLuaModule = {
name = "luaotfload-notdef",
- version = "3.12", --TAGVERSION
- date = "2020-02-02", --TAGDATE
+ version = "3.13", --TAGVERSION
+ date = "2020-05-01", --TAGDATE
description = "luaotfload submodule / color",
license = "GPL v2.0",
author = "Marcel Krüger"
@@ -16,6 +16,7 @@ if luatexbase and luatexbase.provides_module then
luatexbase.provides_module (ProvidesLuaModule)
end
+local harfbuzz = luaotfload.harfbuzz
local flush_node = node.direct.flush_node
local getfont = font.getfont
local getnext = node.direct.getnext
@@ -23,12 +24,21 @@ local getwhd = node.direct.getwhd
local insert = table.insert
local insert_after = node.direct.insert_after
local kern_id = node.id'kern'
+local disc_id = node.id'disc'
local nodenew = node.direct.new
+local nodecopy = node.direct.copy
local otfregister = fonts.constructors.features.otf.register
local protect_glyph = node.direct.protect_glyph
local remove = node.direct.remove
local setfont = node.direct.setfont
local traverse_char = node.direct.traverse_char
+local traverse_id = node.direct.traverse_id
+local setchar = node.direct.setchar
+local getwidth = node.direct.getwidth
+local setkern = node.direct.setkern
+local setattributelist = node.direct.setattributelist
+local getattributelist = node.direct.getattributelist
+local setmove = luaotfload.fontloader.nodes.injections.setmove
-- According to DerivedCoreProperties.txt, Default_Ignorable_Code_Point
-- is generated from:
@@ -154,42 +164,211 @@ otfregister {
}
}
-function fonts.handlers.otf.handlers.gsub_remove(head,char,dataset,sequence,replacement)
- local next
- head, next = remove(head, char)
- flush_node(char)
- if not head and not next then -- Avoid a double free if we were alone
- head = nodenew(kern_id)
- end
- return head, next, true, true
-end
+local font_invisible_replacement = setmetatable({}, {__index = function(t, fid)
+ local fontdata = font.getfont(fid)
+ local replacement = fontdata.shared.features.invisible
+ if replacement == "remove" then
+ t[fid] = false
+ return false
+ end
+ replacement = tonumber(replacement) or 32
+ local char = fontdata.characters[replacement]
+ if char then
+ t[fid] = {replacement, -char.width}
+ return t[fid]
+ else
+ t[fid] = false
+ return false
+ end
+end})
-local sequence = {
- features = {invisible = {["*"] = {["*"] = true}}},
+local push, pop do
+ local function checkprop(n)
+ local p = node.direct.getproperty(n)
+ return p and p.zwnj
+ end
+ local list = {}
+ function push(head)
+ head = node.direct.todirect(head)
+ local l = {}
+ list[#list+1] = l
+ for n, id in node.direct.traverse(head) do
+ if checkprop(n) then
+ head = node.direct.remove(head, n)
+ l[#l+1] = n
+ elseif id == disc_id then
+ local pre, post, replace = node.direct.getdisc(n)
+ for nn in node.direct.traverse(pre) do
+ if checkprop(nn) then
+ local after
+ pre, after = node.direct.remove(pre, nn)
+ l[#l+1] = {nn, n, 'pre'}
+ end
+ end
+ for nn in node.direct.traverse(post) do
+ if checkprop(nn) then
+ post = node.direct.remove(post, nn)
+ l[#l+1] = {nn, n, 'post'}
+ end
+ end
+ for nn in node.direct.traverse(replace) do
+ if checkprop(nn) then
+ replace = node.direct.remove(replace, nn)
+ l[#l+1] = {nn, n, 'replace'}
+ end
+ end
+ node.direct.setdisc(n, pre, post, replace)
+ end
+ end
+ return head
+ end
+ local getfield, setfield = node.direct.getfield, node.direct.setfield
+ local function pop(head)
+ head = node.direct.todirect(head)
+ local l = list[#list]
+ list[#list] = nil
+ for i = #l,1,-1 do
+ local e = l[i]
+ local n = tonumber(e)
+ local disc, thishead
+ if n then
+ thishead = head
+ else
+ disc, n = e[2], e[1]
+ thishead = getfield(disc, e[3])
+ end
+ local prev, next = node.direct.getboth(n)
+ if prev or not next then
+ thishead = node.direct.insert_after(thishead, prev, n)
+ else
+ thishead = node.direct.insert_before(thishead, next, n)
+ end
+ if disc then
+ setfield(disc, e[3], thishead)
+ else
+ head = thishead
+ end
+ end
+ return head
+ end
+ fonts.handlers.otf.handlers.marked_push = push
+ fonts.handlers.otf.handlers.marked_pop = pop
+end
+local sequence1 = {
+ features = {["semiignored-node"] = {["*"] = {["*"] = true}}},
flags = {false, false, false, false},
- name = "invisible",
- order = {"invisible"},
- nofsteps = 1,
- steps = {{
- coverage = ignorable_codepoints,
- index = 1,
- }},
- type = "gsub_remove",
+ name = "semiignored-node",
+ order = {"semiignored-node"},
+ type = "marked_push",
}
-local function invisibleinitialiser(tfmdata, value)
+local sequence2 = {
+ features = {["semiignored-node"] = {["*"] = {["*"] = true}}},
+ flags = {false, false, false, false},
+ name = "semiignored-node",
+ order = {"semiignored-node"},
+ type = "marked_pop",
+}
+local function pushpopinitialiser(tfmdata, value, features)
local resources = tfmdata.resources
local sequences = resources and resources.sequences
+ local first_gpos, last_gpos
if sequences then
- -- Now we get to the interesting part: At which point should our new sequence be inserted? Let's do it at the end, then they are still seen by all features.
- insert(sequences, sequence)
+ local alreadydone
+ for i=1,#sequences do
+ local sequence = sequences[i]
+ if sequence1 == sequence then
+ return
+ elseif sequence.type:sub(1,5) == "gpos_" then
+ if not first_gpos then
+ first_gpos = i
+ end
+ last_gpos = i
+ end
+ end
+ if first_gpos then
+ insert(sequences, last_gpos+1, sequence2)
+ insert(sequences, first_gpos, sequence1)
+ end
end
end
+
+otfregister {
+ name = 'semiignored-node',
+ description = 'Allow adding nodes which break ligatures but do not affect kerning',
+ default = true, -- Should basically never be disabled manually
+ initializers = {
+ node = pushpopinitialiser,
+ -- plug = ? -- TODO: Manually handle in luaotfload-harf-plug.lua
+ },
+}
+
+ignorable_replacement = {}
+
+local delayed_remove do
+ local delayed
+ function delayed_remove(n)
+ flush_node(delayed)
+ delayed = n
+ end
+end
+
+local function ignorablehandler(head, fid, ...) -- FIXME: The arguments are probably wrong
+ local fontparam = font_invisible_replacement[fid]
+ local replacement = fontparam and fontparam[1]
+ local font_kern = fontparam and fontparam[2]
+ for n, c, f in traverse_char(head) do if f == fid then
+ local lookup = ignorable_codepoints[c]
+ if lookup then
+ if replacement then
+ setchar(n, replacement)
+ if font_kern then
+ local k = nodenew(kern_id)
+ setkern(k, font_kern)
+ setattributelist(k, getattributelist(n))
+ head = insert_after(head, n, k)
+ end
+ else
+ local after
+ head, after = remove(head, n)
+ delayed_remove(n)
+ end
+ end
+ end end
+ delayed_remove()
+ for n in traverse_id(head, disc_id) do
+ local a, b, c = getdisc(n)
+ setdisc(ignorablehandler(a, fid), ignorablehandler(b, fid), ignorablehandler(c, fid))
+ end
+ return head
+end
+
+if harfbuzz then
+ local harf_settings = luaotfload.harf
+ local preserve_flag = harfbuzz.Buffer.FLAG_PRESERVE_DEFAULT_IGNORABLES or 0
+ local remove_flag = harfbuzz.Buffer.FLAG_REMOVE_DEFAULT_IGNORABLES or 0
+ local dotted_circle_flag = harfbuzz.Buffer.FLAG_DO_NOT_INSERT_DOTTED_CIRCLE or 0
+ harf_settings.default_buf_flags = (harf_settings.default_buf_flags & ~remove_flag) | preserve_flag | dotted_circle_flag
+ local function dottedcircleinitialize(tfmdata, value)
+ if not tfmdata.hb then return end
+ local hb = tfmdata.hb
+ hb.buf_flags = hb.buf_flags & ~dotted_circle_flag
+ end
+ otfregister {
+ name = 'dottedcircle',
+ description = 'Insert dotted circle to fix invalid clusters',
+ default = true,
+ initializers = {
+ plug = dottedcircleinitialize,
+ },
+ }
+end
otfregister {
name = 'invisible',
description = 'Remove invisible control characters',
default = true,
- initializers = {
- node = invisibleinitialiser,
+ processors = {
+ node = ignorablehandler,
+ plug = ignorablehandler,
},
}
diff --git a/macros/luatex/generic/luaotfload/luaotfload-parsers.lua b/macros/luatex/generic/luaotfload/luaotfload-parsers.lua
index 2cdd006378..c331cb4ef0 100644
--- a/macros/luatex/generic/luaotfload/luaotfload-parsers.lua
+++ b/macros/luatex/generic/luaotfload/luaotfload-parsers.lua
@@ -7,8 +7,8 @@
local ProvidesLuaModule = {
name = "luaotfload-parsers",
- version = "3.12", --TAGVERSION
- date = "2020-02-02", --TAGDATE
+ version = "3.13", --TAGVERSION
+ date = "2020-05-01", --TAGDATE
description = "luaotfload submodule / filelist",
license = "GPL v2.0"
}
@@ -147,7 +147,7 @@ local xml_attr_list = Cf(Ct"" * xml_attr^1, rawset)
scan_node creates a parser for a given xml tag.
--doc]]--
--- string -> bool -> lpeg_t
-local scan_node = function (tag)
+local function scan_node (tag)
--- Node attributes go into a table with the index “attributes”
--- (relevant for “prefix="xdg"” and the likes).
local p_tag = P(tag)
@@ -192,7 +192,7 @@ local p_cheapxml = header * root
of the nodes it managed to extract from the file.
--doc]]--
--- string -> path list
-local fonts_conf_scanner = function (path)
+local function fonts_conf_scanner (path)
logreport("both", 5, "db", "Read fontconfig file %s.", path)
local fh = ioopen(path, "r")
if not fh then
@@ -218,7 +218,7 @@ end
local p_conf = P".conf" * P(-1)
local p_filter = (1 - p_conf)^1 * p_conf
-local conf_filter = function (path)
+local function conf_filter (path)
if lpegmatch (p_filter, path) then
return true
end
@@ -248,18 +248,16 @@ end
--- -> string list -> string list -> string list
--- -> (string -> fun option -> string list)
--- -> tab * tab * tab
-local read_fonts_conf_indeed
--- MK Made basedir an explicit parameter to fix relative paths
-read_fonts_conf_indeed = function (depth,
- start,
- home,
- xdg_config_home,
- xdg_data_home,
- acc,
- done,
- dirs_done,
- find_files,
- basedir)
+local function read_fonts_conf_indeed (depth,
+ start,
+ home,
+ xdg_config_home,
+ xdg_data_home,
+ acc,
+ done,
+ dirs_done,
+ find_files,
+ basedir)
logreport ("both", 4, "db",
"Fontconfig scanner processing path %s.",
@@ -371,7 +369,6 @@ read_fonts_conf_indeed = function (depth,
--inspect(done)
return acc, done, dirs_done
end --- read_fonts_conf_indeed()
--- /MK
--[[doc--
read_fonts_conf() sets up an accumulator and two sets
@@ -386,7 +383,7 @@ end --- read_fonts_conf_indeed()
--- list -> (string -> function option -> string list) -> list
-local read_fonts_conf = function (path_list, find_files)
+local function read_fonts_conf (path_list, find_files)
local home = kpseexpand_path"~" --- could be os.getenv"HOME"
local xdg_config_home = kpseexpand_path"$XDG_CONFIG_HOME"
if xdg_config_home == "" then xdg_config_home = filejoin(home, ".config") end
@@ -502,7 +499,7 @@ local splitcomma = Ct((C(noncomma^1) + comma)^1)
--doc]]--
-local handle_xetex_option = function (val)
+local function handle_xetex_option (val)
return tostring(1 + tonumber(val))
end
@@ -514,7 +511,7 @@ end
--doc]]--
-local check_garbage = function (_,i, garbage)
+local function check_garbage (_,i, garbage)
if stringfind(garbage, "/") then
logreport("log", 0, "load", --- ffs use path!
"warning: path in file: lookups is deprecated; ")
@@ -536,7 +533,7 @@ local featuresep = comma + semicolon
we only support the shorthands for italic / bold / bold italic
shapes, as well as setting optical size, the rest is ignored.
--doc]]--
-local style_modifier = (P"BI" + P"IB" + P"bi" + P"ib" + S"biBI")
+local style_modifier = (S'bB' * S'iI'^-1 + S'iI' * S'bB'^-1)
/ stringlower
local size_modifier = S"Ss" * P"=" --- optical size
* Cc"optsize" * C(decimal)
@@ -697,7 +694,7 @@ local truth_ids = {
off = false,
}
-local maybe_cast = function (var)
+local function maybe_cast (var)
local bool = truth_ids[var]
if bool ~= nil then
return bool
@@ -705,7 +702,7 @@ local maybe_cast = function (var)
return tonumber (var) or var
end
-local escape = function (chr, repl)
+local function escape (chr, repl)
return (backslash * P(chr) / (repl or chr))
end
diff --git a/macros/luatex/generic/luaotfload/luaotfload-resolvers.lua b/macros/luatex/generic/luaotfload/luaotfload-resolvers.lua
index c49fa58fd9..e07c09cde6 100644
--- a/macros/luatex/generic/luaotfload/luaotfload-resolvers.lua
+++ b/macros/luatex/generic/luaotfload/luaotfload-resolvers.lua
@@ -11,8 +11,8 @@
local ProvidesLuaModule = {
name = "luaotfload-resolvers",
- version = "3.12", --TAGVERSION
- date = "2020-02-02", --TAGDATE
+ version = "3.13", --TAGVERSION
+ date = "2020-05-01", --TAGDATE
description = "luaotfload submodule / resolvers",
license = "GPL v2.0"
}
@@ -114,9 +114,9 @@ local function resolve_name (specification)
end
local resolved, subfont = resolver (specification)
if resolved then
- logreport ("log", 1, "resolve", "name lookup %q -> \"%s%s\"",
- specification.name, resolved,
- subfont and stringformat ("(%d)", subfont) or "")
+ logreport ("log", 1, "resolve", "name lookup %q -> %q",
+ specification.name, resolved ..
+ (subfont and stringformat ("(%d)", subfont) or ""))
return resolved, tonumber(subfont)
end
return resolve_file (specification)
@@ -149,7 +149,7 @@ end
local tex_formats = { "tfm", "ofm" }
local resolvers_findfile = luaotfload.fontloader.resolvers.findfile
-local resolve_tex_format = function (specification)
+local function resolve_tex_format (specification)
local name = specification.name
for i=1, #tex_formats do
local format = tex_formats [i]
@@ -160,7 +160,7 @@ local resolve_tex_format = function (specification)
end
end
-local resolve_path_if_exists = function (specification)
+local function resolve_path_if_exists (specification)
local spec = specification.specification
local exists = lfsisfile (spec)
if exists then
@@ -179,7 +179,7 @@ end
Custom file resolvers via callback.
--doc]]--
-local resolve_my = function (specification)
+local function resolve_my (specification)
return luatexbase.call_callback ("luaotfload.resolve_font", specification)
end
@@ -191,7 +191,7 @@ local resolve_methods = {
my = resolve_my,
}
-local resolve_sequence = function (seq, specification)
+local function resolve_sequence (seq, specification)
for i = 1, #seq do
local id = seq [i]
local mth = resolve_methods [id]
diff --git a/macros/luatex/generic/luaotfload/luaotfload-scripts.lua b/macros/luatex/generic/luaotfload/luaotfload-scripts.lua
index 814223b5ed..4a9ec0f6dc 100644
--- a/macros/luatex/generic/luaotfload/luaotfload-scripts.lua
+++ b/macros/luatex/generic/luaotfload/luaotfload-scripts.lua
@@ -5,8 +5,8 @@
local ProvidesLuaModule = {
name = "luaotfload-script",
- version = "3.12", --TAGVERSION
- date = "2020-02-02", --TAGDATE
+ version = "3.13", --TAGVERSION
+ date = "2020-05-01", --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 ed3324f304..02cf06f89c 100644
--- a/macros/luatex/generic/luaotfload/luaotfload-status.lua
+++ b/macros/luatex/generic/luaotfload/luaotfload-status.lua
@@ -1,14 +1,14 @@
return {
["hashes"]={
- { "fontloader-2020-01-26.lua", "010915906c0926fc7f5f4d064a879be4" },
+ { "fontloader-2020-04-30.lua", "e3b9c1d6344645b552f8002a97aa09ca" },
{ "fontloader-util-fil.lua", "4bb3e4dc72e308d8ed67cd7a80027fa7" },
- { "fontloader-util-str.lua", "2e4625b13a5f4be76b1d8664a32119ec" },
+ { "fontloader-util-str.lua", "2c1a12d8248d3719c0b5fc93184242bf" },
{ "fontloader-l-unicode.lua", "9bc311ce08ce498f9caacb6164ea1d9f" },
{ "fontloader-l-math.lua", "a373be3ed2db0d5f98588fa81abca48f" },
{ "fontloader-l-boolean.lua", "18ed6c4b2c40dd87224ea33229548d20" },
{ "fontloader-l-file.lua", "60ddd3948d9de7bde8b4a0f5c51ff9f5" },
{ "fontloader-l-io.lua", "a4042e9d6bce71c61fdd94e6e17f2bf4" },
- { "fontloader-l-table.lua", "a495e837874aa3e4fa57fea4dd05a26c" },
+ { "fontloader-l-table.lua", "20c03ae1b81e902217f3f76995b9d294" },
{ "fontloader-l-string.lua", "e1347bef0eeeff9f098df83b30b32df9" },
{ "fontloader-l-function.lua", "f771cc91839ebcdfc094083434fbe00f" },
{ "fontloader-l-lpeg.lua", "efe630e3a9a1d269120e59cfd8fba4ba" },
@@ -21,7 +21,7 @@ return {
{ "fontloader-fonts-enc.lua", "3e71a54297e8f85a1ac438bb0f20dd79" },
{ "fontloader-fonts-mis.lua", "bc9eb43c27f63ce9d0fff67e104fe1c6" },
{ "fontloader-basics-chr.lua", "58b7ef0c486e06090b362971b9f85e27" },
- { "fontloader-basics-nod.lua", "4ce2f7c752fdc4c1d6d9f74e8cd50be8" },
+ { "fontloader-basics-nod.lua", "68226d7dadd241bca55171af9ce1f243" },
{ "fontloader-font-imp-effects.lua", "73a660359a0ec71e44cc2b7225a715ac" },
{ "fontloader-font-imp-italics.lua", "fe1ca80fb5ea4a2f8d2d5c484e7ba913" },
{ "fontloader-font-imp-ligatures.lua", "043daa4fcccf2560868da359d71d3a4a" },
@@ -32,63 +32,64 @@ return {
{ "fontloader-font-one.lua", "987c5c5ed3754ad2feab80985067d59e" },
{ "fontloader-font-onr.lua", "22572ec0f86f53631e14b6d1ed43ee51" },
{ "fontloader-font-otc.lua", "1204a2fdc436e644127c0aa38ab69607" },
- { "fontloader-font-ocl.lua", "c1f4cbea3c4ec5002a04fc637b135711" },
- { "fontloader-font-osd.lua", "39e92f6e575741646d75ea79e3be87f3" },
- { "fontloader-font-ots.lua", "d0107799ec82da7f96dafe9626c5ee7f" },
- { "fontloader-font-ota.lua", "d6dfb94563d6a52675e274b2e673e4a6" },
- { "fontloader-font-otj.lua", "66c7a910d95d4a52b81061de776898e1" },
+ { "fontloader-font-ocl.lua", "e6b45379971219a6227e8655cda14aff" },
+ { "fontloader-font-osd.lua", "61f05fcf91add1aa5dac9bc8b235adc9" },
+ { "fontloader-font-ots.lua", "113b7ad0c40d4786bb026706e479c3f3" },
+ { "fontloader-font-ota.lua", "dd5f1c8ba28abaf4505fd960d04a3a98" },
+ { "fontloader-font-otj.lua", "c9ded1d935bfa43020657e1f408fb820" },
{ "fontloader-font-oto.lua", "24238a7c600d090a8ee88312321dd9b3" },
- { "fontloader-font-otl.lua", "ec0241b7465a7713e53c246e8e9fb2a8" },
- { "fontloader-font-oup.lua", "0cef35af01739f52fd09feb5401192ae" },
- { "fontloader-font-dsp.lua", "5d3db0184c903829b2c5bddcb8cdb14c" },
+ { "fontloader-font-otl.lua", "f111f9ac18d24049fadeb8883e4e8da5" },
+ { "fontloader-font-oup.lua", "1700a2dac4f8b105c187d4e5b84cecdf" },
+ { "fontloader-font-dsp.lua", "618e5e760ec5dceb0c898a83816dbe61" },
{ "fontloader-font-ttf.lua", "44e61cef50dab9b1aaf48130f9367c34" },
- { "fontloader-font-cff.lua", "c769020b41b39418f703347f3d328bc7" },
+ { "fontloader-font-cff.lua", "155821e11e84021437869ff973e75d93" },
{ "fontloader-font-ott.lua", "aba6d8335a5f38a5a62d3631492f3392" },
{ "fontloader-font-oti.lua", "dbae7722baae24d917a17176553825cf" },
{ "fontloader-font-otr.lua", "d96724dcb40c673ac294df7044a39925" },
{ "fontloader-font-vfc.lua", "94937140f2c909e9c831ba021f1ab303" },
- { "fontloader-font-map.lua", "f486746e90fe972de4b73e208ac7cbb2" },
+ { "fontloader-font-map.lua", "51d0362c19d2d0f621e5cb750410a809" },
{ "fontloader-font-cid.lua", "4d87988efa86020a14708ee03c23415f" },
- { "fontloader-font-con.lua", "b436bf6880a56216445779ac68fee877" },
+ { "fontloader-font-con.lua", "40e3a857b2f31be1959dc6d445aaa9c4" },
{ "fontloader-font-ini.lua", "4dee96e1e1474d324dd126bd5d375df8" },
{ "fontloader-data-con.lua", "de6ae0997b0e70a23bcc9afff5d8b072" },
- { "fontloader-reference.lua", "0c0e3262f5cc53d1142e459921526f69" },
- { "fontloader-basics-gen.lua", "b88f9848c3247e4222b7bb63b0ee3f35" },
+ { "fontloader-reference.lua", "87a3b4d84d8ca6551dc8ccb539d30fd8" },
+ { "fontloader-basics-gen.lua", "b21e91bbd534f77e368f0ec13f865aed" },
{ "mktests", "c7cff7025962922944376acc1ffa9c47" },
- { "mkstatus", "72f4b4ff15c9f4fd95b8ba942b541b20" },
+ { "mkstatus", "879eb12b7dc63a18d94ed61b90c4b3da" },
{ "mkcharacters", "92c24bb582fc84c0365634f29eb89863" },
- { "mkglyphlist", "557836886d4f0e6d656eac3ded4456a2" },
+ { "mkglyphlist", "95bbf91338214d40b2102114285ccd3f" },
{ "mkimport", "60e0b11a1a68719033e86a3e0f4d5e86" },
- { "luaotfload-glyphlist.lua", "0c2e6db4d2d944b5e4e6d83971edc166" },
- { "luaotfload-characters.lua", "593ce9dccf6ddc4f7d4be0514f581102" },
- { "luaotfload-tounicode.lua", "8c678ba2c2c809706a63a79a339d102b" },
- { "luaotfload-unicode.lua", "ec04cec91b4c7a73acace241f791a228" },
- { "luaotfload-resolvers.lua", "92c1c59341213f716a6eee355b847849" },
- { "luaotfload-parsers.lua", "ef73b50dee1935a1af4cd76ed303bba6" },
- { "luaotfload-multiscript.lua", "d5a1d602ecc4b4caad5f89772dd8affa" },
- { "luaotfload-loaders.lua", "084e6b89d85ccdc59d90102059d8020a" },
- { "luaotfload-harf-plug.lua", "09d1f0baf43fb6932d5619436d0ff950" },
- { "luaotfload-harf-define.lua", "e27975867cbe2eac101ea2ff366050dc" },
- { "luaotfload-notdef.lua", "1a4f3eeedfb374927fa0673849c5f95b" },
- { "luaotfload-embolden.lua", "8412b95b699231918ea78384ada0e3df" },
- { "luaotfload-letterspace.lua", "2ffa8128161281fa2ca7605fc056e13d" },
- { "luaotfload-features.lua", "2db4774ed71aa8ba4e859655e6076f1b" },
- { "luaotfload-database.lua", "c11b6638c72aa2216aaf0432278654cc" },
- { "luaotfload-configuration.lua", "d4c270b581eb22ded89bc2c6dffd7a78" },
- { "luaotfload-colors.lua", "693b527638ff44e88530bef81cff360c" },
- { "luaotfload-auxiliary.lua", "90307f9dc0fde714e7ade75ed8606de6" },
- { "luaotfload-filelist.lua", "629600766c33b11ebce09dd77dbd67c0" },
- { "luaotfload-tool.lua", "dfa990067c3f21fdebfcbd47b291fc9c" },
- { "luaotfload-diagnostics.lua", "7c13bd4abdd110073b6dd438c94d28ec" },
- { "luaotfload-log.lua", "c6e62cd69d185ea57605c21919ae103e" },
- { "luaotfload-init.lua", "0e156bb051ffa7c51dbdaca4afe0b5ae" },
- { "luaotfload-main.lua", "352cf2115d0b60e8537557baa9748f7a" },
+ { "luaotfload-glyphlist.lua", "d717ba808181ed805d7012259ceec613" },
+ { "luaotfload-characters.lua", "6a46f4749368e4f56a863da9c61b7bd6" },
+ { "luaotfload-tounicode.lua", "1423c465dd9674c1d048314566e4c9e5" },
+ { "luaotfload-unicode.lua", "2ef5d6f97171db54da3fbb304571bf4d" },
+ { "luaotfload-resolvers.lua", "028ada14621d61296d6c193113841a3c" },
+ { "luaotfload-parsers.lua", "1bb3f4e75cd433de2b29ea9961896dba" },
+ { "luaotfload-fallback.lua", "26ac47f65211bee402055d656ebedf30" },
+ { "luaotfload-multiscript.lua", "bc5cd5ca148d8938310317f8f70b51f4" },
+ { "luaotfload-loaders.lua", "b6bca1abc2fef454a4e14997b87c500e" },
+ { "luaotfload-harf-plug.lua", "e0b02973cd653b50d5ad8c0f971bbf44" },
+ { "luaotfload-harf-define.lua", "74026f364fd71375c6ac0fcdabaf2c69" },
+ { "luaotfload-notdef.lua", "feccfc85ad4ddb6ccaeb4974f50d93c1" },
+ { "luaotfload-embolden.lua", "faa7cdeb00ba548b7f8f4cf79f52ea62" },
+ { "luaotfload-letterspace.lua", "d12550ea62b1edb348f0f6d388b2701f" },
+ { "luaotfload-features.lua", "4941176787992fa1b319d3e8822672a6" },
+ { "luaotfload-database.lua", "6a17fb92cbb4d0e2ccdb435b7f33c052" },
+ { "luaotfload-configuration.lua", "5ba63b9b0731e3701c39c06a1217dbe4" },
+ { "luaotfload-colors.lua", "5fe6a37d50374deb75f041a4c26e08ce" },
+ { "luaotfload-auxiliary.lua", "f721a22653fe32413af7d057b6236382" },
+ { "luaotfload-filelist.lua", "b9383bafa3dbf4ef3140592f6ed47e54" },
+ { "luaotfload-tool.lua", "2b1a2aabe4f9c3f88836feb833c89e78" },
+ { "luaotfload-diagnostics.lua", "b32da598f5bbb68e2b76cce03a7df033" },
+ { "luaotfload-log.lua", "30158f122a25bc38eecd61ab86c4bc70" },
+ { "luaotfload-init.lua", "ab2d6107e6d94455f1d024afb8f6a8c1" },
+ { "luaotfload-main.lua", "6ee30f9b6f5d381df4d5f9c868bc9d9f" },
},
["notes"]={
["committer"]="Ulrike Fischer <fischer@troubleshooting-tex.de>",
- ["description"]="v3.12/2020-02-02",
- ["loader"]="fontloader-2020-01-26.lua",
- ["revision"]="df675afec78546b857a89f1c416dc0f2600c8ff0",
- ["timestamp"]="2020-02-02 22:36:36 +0100",
+ ["description"]="v3.13/2020-05-01",
+ ["loader"]="fontloader-2020-04-30.lua",
+ ["revision"]="aa279bff2274832c341338d7763132bad3941768",
+ ["timestamp"]="2020-05-01 15:37:41 +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
new file mode 100644
index 0000000000..eba776fe85
--- /dev/null
+++ b/macros/luatex/generic/luaotfload/luaotfload-suppress.lua
@@ -0,0 +1,89 @@
+-----------------------------------------------------------------------
+-- FILE: luaotfload-suppress.lua
+-- DESCRIPTION: part of luaotfload / suppress
+-----------------------------------------------------------------------
+
+local ProvidesLuaModule = {
+ name = "luaotfload-suppress",
+ version = "3.13", --TAGVERSION
+ date = "2020-05-01", --TAGDATE
+ description = "luaotfload submodule / suppress",
+ license = "GPL v2.0",
+ author = "Marcel Krüger"
+}
+
+if luatexbase and luatexbase.provides_module then
+ luatexbase.provides_module (ProvidesLuaModule)
+end
+
+local direct = node.direct
+local otfregister = fonts.constructors.features.otf.register
+
+local copy = direct.copy
+local getdisc = direct.getdisc
+local getnext = direct.getnext
+local insert_after = direct.insert_after
+local is_char = direct.is_char
+local setchar = direct.setchar
+local setdisc = direct.setdisc
+local getfont = font.getfont
+
+local disc_t = node.id'disc'
+
+local empty = {}
+
+local lpeg = lpeg or require'lpeg'
+local valueparser do
+ local digits = lpeg.R'09'^1/tonumber
+ local hexdigits = (lpeg.P'u+' + '"' + '0x') * (lpeg.R('09', 'AF', 'af')^1/function(s) return tonumber(s, 16) end)
+ local entry = lpeg.Cg((hexdigits + digits) * lpeg.Cc(true))
+ local sep = lpeg.P' '^0 * lpeg.S'/|,;' * lpeg.P' '^0
+ valueparser = lpeg.Cf(lpeg.Ct'' * entry * (sep * entry)^0, rawset) * -1
+end
+
+local function initializer(tfmdata, value, features)
+ local properties = tfmdata.properties
+ properties.suppress_liga = valueparser:match(value)
+ if not properties.suppress_liga then
+ error[[Invalid suppress value]]
+ end
+end
+
+local function processor(head,font) -- ,attr,direction)
+ local supp = getfont(font).properties.suppress_liga
+ if not supp then return head end
+ local n = head
+ while n do
+ local c, id = is_char(n, font)
+ if supp[c] then
+ local nn = copy(n)
+ setchar(nn, 0x200C)
+ head, n = insert_after(head, n, nn)
+ elseif id == disc_t then
+ local pre, post, replace = getdisc(n)
+ pre = processor(pre, font)
+ post = processor(post, font)
+ replace = processor(replace, font)
+ setdisc(n, pre, post, replace)
+ end
+ n = getnext(n)
+ end
+ return head
+end
+
+otfregister {
+ name = 'suppress',
+ description = 'Insert ZWNJ to suppress ligatures',
+ default = false,
+ initializers = {
+ -- node = initializer,
+ plug = initializer,
+ },
+ processors = {
+ position = 1,
+ -- node = processor,
+ plug = processor,
+ },
+}
+
+--- vim:sw=2:ts=2:expandtab:tw=71
diff --git a/macros/luatex/generic/luaotfload/luaotfload-szss.lua b/macros/luatex/generic/luaotfload/luaotfload-szss.lua
new file mode 100644
index 0000000000..23b479f33e
--- /dev/null
+++ b/macros/luatex/generic/luaotfload/luaotfload-szss.lua
@@ -0,0 +1,226 @@
+-----------------------------------------------------------------------
+-- FILE: luaotfload-szss.lua
+-- DESCRIPTION: part of luaotfload / szss
+-----------------------------------------------------------------------
+
+local ProvidesLuaModule = {
+ name = "luaotfload-szss",
+ version = "3.13", --TAGVERSION
+ date = "2020-05-01", --TAGDATE
+ description = "luaotfload submodule / color",
+ license = "GPL v2.0",
+ author = "Marcel Krüger"
+}
+
+if luatexbase and luatexbase.provides_module then
+ luatexbase.provides_module (ProvidesLuaModule)
+end
+
+local direct = node.direct
+local otfregister = fonts.constructors.features.otf.register
+
+local copy = direct.copy
+local getdisc = direct.getdisc
+local getnext = direct.getnext
+local insert_after = direct.insert_after
+local is_char = direct.is_char
+local setchar = direct.setchar
+local setdisc = direct.setdisc
+
+local disc_t = node.id'disc'
+
+local szsstable = setmetatable({}, { __index = function(t, i)
+ local v = font.getfont(i)
+ v = v and v.properties
+ v = v and v.transform_sz or false
+ t[i] = v
+ return v
+end})
+
+local function szssinitializer(tfmdata, value, features)
+ if value == 'auto' then
+ value = not tfmdata.characters[0x1E9E]
+ end
+ local properties = tfmdata.properties
+ properties.transform_sz = value
+end
+
+local function szssprocessor(head,font) -- ,attr,direction)
+ if not szsstable[font] then return end
+ local n = head
+ while n do
+ local c, id = is_char(n, font)
+ if c == 0x1E9E then
+ setchar(n, 0x53)
+ head, n = insert_after(head, n, copy(n))
+ elseif id == disc_t then
+ local pre, post, replace = getdisc(n)
+ pre = szssprocessor(pre, font)
+ post = szssprocessor(post, font)
+ replace = szssprocessor(replace, font)
+ setdisc(n, pre, post, replace)
+ end
+ n = getnext(n)
+ end
+ return head
+end
+
+otfregister {
+ name = 'szss',
+ description = 'Replace capital ß with SS',
+ default = 'auto',
+ initializers = {
+ node = szssinitializer,
+ plug = szssinitializer,
+ },
+ processors = {
+ position = 1,
+ node = szssprocessor,
+ plug = szssprocessor,
+ },
+}
+
+-- harf-only features (for node they are implemented in the fontloader
+
+otfregister {
+ name = 'extend',
+ description = 'Fake extend',
+ default = false,
+ manipulators = {
+ plug = function(tfmdata, _, value)
+ value = tonumber(value)
+ if not value then
+ error[[Invalid extend value]]
+ end
+ tfmdata.extend = value * 1000
+ tfmdata.hb.hscale = tfmdata.units_per_em * value
+ local parameters = tfmdata.parameters
+ parameters.slant = parameters.slant * value
+ parameters.space = parameters.space * value
+ parameters.space_stretch = parameters.space_stretch * value
+ parameters.space_shrink = parameters.space_shrink * value
+ parameters.quad = parameters.quad * value
+ parameters.extra_space = parameters.extra_space * value
+ local done = {}
+ for _, char in next, tfmdata.characters do
+ if char.width and not done[char] then
+ char.width = char.width * value
+ done[char] = true
+ end
+ end
+ end,
+ },
+}
+
+otfregister {
+ name = 'slant',
+ description = 'Fake slant',
+ default = false,
+ manipulators = {
+ plug = function(tfmdata, _, value)
+ value = tonumber(value)
+ if not value then
+ error[[Invalid slant value]]
+ end
+ tfmdata.slant = value * 1000
+ local parameters = tfmdata.parameters
+ parameters.slant = parameters.slant + value * 65536
+ end,
+ },
+}
+
+otfregister {
+ name = 'squeeze',
+ description = 'Fake squeeze',
+ default = false,
+ manipulators = {
+ plug = function(tfmdata, _, value)
+ value = tonumber(value)
+ if not value then
+ error[[Invalid squeeze value]]
+ end
+ tfmdata.squeeze = value * 1000
+ tfmdata.hb.vscale = tfmdata.units_per_em * value
+ local parameters = tfmdata.parameters
+ parameters.slant = parameters.slant / value
+ parameters.x_height = parameters.x_height * value
+ parameters[8] = parameters[8] * value
+ local done = {}
+ for _, char in next, tfmdata.characters do
+ if not done[char] then
+ if char.height then
+ char.height = char.height * value
+ end
+ if char.depth then
+ char.depth = char.depth * value
+ end
+ done[char] = true
+ end
+ end
+ end,
+ },
+}
+
+-- Legacy TeX Input Method Disguised as Font Ligatures hack.
+--
+-- Single replacements, keyed by character to replace. Handled separately
+-- because TeX ligaturing mechanism does not support one-to-one replacements.
+local trep = {
+ [0x0022] = 0x201D, -- ["]
+ [0x0027] = 0x2019, -- [']
+ [0x0060] = 0x2018, -- [`]
+}
+
+-- Ligatures. The value is a character "ligature" table as described in the
+-- manual.
+local tlig ={
+ [0x2013] = { [0x002D] = { char = 0x2014 } }, -- [---]
+ [0x002D] = { [0x002D] = { char = 0x2013 } }, -- [--]
+ [0x0060] = { [0x0060] = { char = 0x201C } }, -- [``]
+ [0x0027] = { [0x0027] = { char = 0x201D } }, -- ['']
+ [0x0021] = { [0x0060] = { char = 0x00A1 } }, -- [!`]
+ [0x003F] = { [0x0060] = { char = 0x00BF } }, -- [?`]
+ [0x002C] = { [0x002C] = { char = 0x201E } }, -- [,,]
+ [0x003C] = { [0x003C] = { char = 0x00AB } }, -- [<<]
+ [0x003E] = { [0x003E] = { char = 0x00BB } }, -- [>>]
+}
+
+local function tligprocessor(head, font)
+ local n = head
+ while n do
+ local c, id = is_char(n, font)
+ local rep = trep[c]
+ if rep then
+ setchar(n, rep)
+ elseif id == disc_t then
+ local pre, post, replace = getdisc(n)
+ tligprocessor(pre, font)
+ tligprocessor(post, font)
+ tligprocessor(replace, font)
+ end
+ n = getnext(n)
+ end
+end
+
+otfregister {
+ name = 'tlig',
+ description = 'Traditional TeX ligatures',
+ default = false,
+ manipulators = {
+ plug = function(tfmdata, _, value)
+ local characters = tfmdata.characters
+ for codepoint, ligatures in next, tlig do
+ local char = characters[codepoint]
+ if char then
+ char.ligatures = ligatures
+ end
+ end
+ end,
+ },
+ processors = {
+ position=1,
+ plug = tligprocessor,
+ },
+}
+
+--- vim:sw=2:ts=2:expandtab:tw=71
diff --git a/macros/luatex/generic/luaotfload/luaotfload-tool.1 b/macros/luatex/generic/luaotfload/luaotfload-tool.1
index 2d4ce7d16c..a2ea173474 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 "2020-02-02" "3.12" "text processing"
+.TH LUAOTFLOAD-TOOL 1 "2020-05-01" "3.13" "text processing"
.SH NAME
luaotfload-tool \- generate and query the Luaotfload font names database
.
@@ -177,7 +177,8 @@ containing \fB\->\fP be properly quoted!
.IP 3. 3
an expression of the form \fBfield:value\fP to
limit the output to entries whose \fBfield\fP
-matches \fBvalue\fP\&.
+matches \fBvalue\fP\&. The \fBvalue\fP can contain
+\fB*\fP to match an arbitrary number of characters.
.UNINDENT
.sp
For example, in order to output file names and
@@ -326,7 +327,7 @@ state.
.SS miscellaneous
.INDENT 0.0
.TP
-.BI \-\-verbose\fB= N\fR,\fB \ \-v
+.BI \-\-verbose\fB= N\fP,\fB \ \-v
Set verbosity level to \fIn\fP or the number of
repetitions of \fB\-v\fP\&.
.TP
diff --git a/macros/luatex/generic/luaotfload/luaotfload-tool.lua b/macros/luatex/generic/luaotfload/luaotfload-tool.lua
index de69173ed5..6994bfc755 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.12", --TAGVERSION
- date = "2020-02-02", --TAGDATE
+ version = "3.13", --TAGVERSION
+ date = "2020-05-01", --TAGDATE
description = "luaotfload-tool / database functionality",
license = "GPL v2.0"
}
@@ -42,7 +42,7 @@ This file is a wrapper for the luaotfload font names module
(luaotfload-database.lua). It is part of the luaotfload bundle, please
see the luaotfload documentation for more info. Report bugs to
- \url{https://github.com/lualatex/luaotfload/issues}.
+ \url{https://github.com/latex3/luaotfload/issues}.
--doc]]--
@@ -141,7 +141,7 @@ this. (Postponing the loading of the lualibs code is not an option
because the functionality is needed by basics-gen itself.)
--doc]]--
-local dummy_function = function ( ) end
+local function dummy_function ( ) end
local backup = {
write = texio.write,
write_nl = texio.write_nl,
@@ -177,7 +177,7 @@ fonts.names = fontsnames
local require_init = { }
-local loadmodule = function (name)
+local function loadmodule (name)
local v = require ("luaotfload-" .. name)
if v then
local mod = { }
@@ -204,7 +204,7 @@ loadmodule "resolvers" --- Font lookup
local logreport
-local init_modules = function ()
+local function init_modules ()
--- NB we don’t command the logger at this point.
local todo = #require_init
local ret = true
@@ -322,7 +322,7 @@ Enter 'luaotfload-tool --help' for a larger list of options.
]]
}
-local help_msg = function (version)
+local function help_msg (version)
local template = help_messages[version]
local paths = config.luaotfload.paths
local names_plain = paths.index_path_lua
@@ -340,10 +340,10 @@ local about = [[
%s:
Luaotfload font management and diagnostic utility.
License: GNU GPL v2.0.
- Report problems to <https://github.com/lualatex/luaotfload/issues>
+ Report problems to <https://github.com/latex3/luaotfload/issues>
]]
-local version_msg = function ( )
+local function version_msg ( )
local out = function (...) texiowrite_nl (stringformat (...)) end
local uname = os.uname ()
local meta = fonts.names.getmetadata ()
@@ -398,7 +398,7 @@ local currentdepth = 0
local counterstack = { } -- counters per level
local counterformat = "%d"
-local format_counter = function (stack)
+local function format_counter (stack)
local acc = { }
for lvl=1, #stack do
acc[#acc+1] = stringformat(counterformat, stack[lvl])
@@ -406,7 +406,7 @@ local format_counter = function (stack)
return tableconcat(acc, ".")
end
-local print_heading = function (title, level)
+local function print_heading (title, level)
if not title then return end
local structuredata
if currentdepth == level then -- top is current
@@ -447,7 +447,7 @@ local baseindent = " "
--doc]]--
-local show_info_table show_info_table = function (t, depth)
+local function show_info_table (t, depth)
depth = depth or 0
local indent = stringrep (baseindent, depth)
local keys = tablesortedkeys (t)
@@ -466,7 +466,7 @@ local show_info_table show_info_table = function (t, depth)
end
end
-local show_info_items = function (fontinfo)
+local function show_info_items (fontinfo)
print_heading (fontinfo.fullname, 1)
texiowrite_nl ""
show_info_table (fontinfo)
@@ -480,7 +480,7 @@ local p_word = C(p_wordchar^1)
local p_words = Ct(p_word * (p_whitespace * p_word)^0)
--- string -> int -> string list
-local reflow = function (text, width)
+local function reflow (text, width)
local words
local t_text = type (text)
if t_text == "string" then
@@ -521,7 +521,7 @@ local reflow = function (text, width)
end
--- string -> 'a -> string list
-local print_field = function (key, val)
+local function print_field (key, val)
val = tostring(val)
local lhs = stringformat(key_fmt, key) .. fieldseparator .. " "
local wd_lhs = #lhs
@@ -558,7 +558,7 @@ local general_fields = {
{ "capheight", "l", "capital height" },
}
-local display_general = function (fullinfo)
+local function display_general (fullinfo)
texiowrite_nl ""
print_heading("General Information", 2)
texiowrite_nl ""
@@ -609,7 +609,7 @@ local display_general = function (fullinfo)
end
end
-local print_features = function (features)
+local function print_features (features)
for tag, data in next, features do
print_heading(tag, 4)
for script, languages in next, data do
@@ -628,11 +628,11 @@ local print_features = function (features)
end
end
-local display_feature_set = function (set)
+local function display_feature_set (set)
print_features(set)
end
-local display_features_type = function (id, feat)
+local function display_features_type (id, feat)
if feat and next (feat) then
print_heading(id, 3)
display_feature_set(feat)
@@ -641,7 +641,7 @@ local display_features_type = function (id, feat)
return false
end
-local display_features = function (features)
+local function display_features (features)
texiowrite_nl ""
print_heading("Features", 2)
@@ -661,7 +661,7 @@ local display_features = function (features)
end
end
-local show_full_info = function (path, subfont)
+local function show_full_info (path, subfont)
local rawinfo, warn = fonts.handlers.otf.readers.loadfont (path, subfont)
if not rawinfo then
texiowrite_nl(stringformat([[cannot open font %s]], path))
@@ -671,8 +671,7 @@ local show_full_info = function (path, subfont)
display_features(rawinfo.resources.features)
end
-local subfont_by_name
-subfont_by_name = function (lst, askedname, n)
+local function subfont_by_name (lst, askedname, n)
for n = 1, #lst do
local font = lst[n]
if fonts.names.sanitize_fontname (font.fullname) == askedname then
@@ -690,7 +689,7 @@ The font info knows two levels of detail:
returned by readers.loadfont().
--doc]]--
-local show_font_info = function (basename, askedname, detail, subfont)
+local function show_font_info (basename, askedname, detail, subfont)
local filenames = fonts.names.data().files
local index = filenames.base[basename]
local fullname = filenames.full[index]
@@ -763,7 +762,7 @@ action_pending.generate = false --- this is the default action
local actions = { } --- (jobspec -> (bool * bool)) list
-actions.loglevel = function (job)
+function actions.loglevel (job)
local lvl = job.log_level
if lvl then
luaotfload.log.set_loglevel(lvl)
@@ -773,7 +772,7 @@ actions.loglevel = function (job)
return true, true
end
-actions.config = function (job)
+function actions.config (job)
local defaults = luaotfload.default_config
local vars = config.actions.read (job.extra_config)
config.luaotfload = config.actions.apply (defaults, vars)
@@ -787,22 +786,22 @@ actions.config = function (job)
return true, true
end
-actions.version = function (job)
+function actions.version (job)
version_msg()
return true, false
end
-actions.dumpconf = function (job)
+function actions.dumpconf (job)
config.actions.dump ()
return true, false
end
-actions.help = function (job)
+function actions.help (job)
help_msg (job.help_version or "luaotfload-tool")
return true, false
end
-actions.blacklist = function (job)
+function actions.blacklist (job)
fonts.names.read_blacklist()
local n = 0
for n, entry in next, tablesortedkeys(fonts.names.blacklist) do
@@ -811,7 +810,7 @@ actions.blacklist = function (job)
return true, false
end
-actions.generate = function (job)
+function actions.generate (job)
local _ = fonts.names.update ({ }, job.force_reload, job.dry_run)
local namedata = fonts.names.data ()
if namedata then
@@ -847,7 +846,7 @@ local bisect_status_fmt = [[
--doc]]--
--- state list -> bool
-local write_bisect_status = function (data)
+local function write_bisect_status (data)
local payload = tableserialize (data, true)
local status = stringformat (bisect_status_fmt,
osdate ("%Y-%m-d %H:%M:%S", os.time ()),
@@ -871,7 +870,7 @@ end
--doc]]--
--- unit -> state list
-local read_bisect_status = function ()
+local function read_bisect_status ()
logreport ("info", 4, "bisect",
"Testing for status file: %q.",
bisect_status_file)
@@ -900,7 +899,7 @@ end
--doc]]--
-local bisect_start = function ()
+local function bisect_start ()
if lfsisfile (bisect_status_file) then
logreport ("info", 0, "bisect",
"Bisect session in progress.",
@@ -929,7 +928,7 @@ end
--doc]]--
-local bisect_stop = function ()
+local function bisect_stop ()
logreport ("info", 3, "bisect",
"Erasing bisection state at %s.",
bisect_status_file)
@@ -962,7 +961,7 @@ end
--doc]]--
-local bisect_terminate = function (nsteps, culprit)
+local function bisect_terminate (nsteps, culprit)
logreport ("info", 1, "bisect",
"Bisection completed after %d steps.", nsteps)
logreport ("info", 0, "bisect",
@@ -978,7 +977,7 @@ end
--doc]]--
-local list_remainder = function (lo, hi)
+local function list_remainder (lo, hi)
local fonts = fonts.names.font_slice (lo, hi)
logreport ("info", 0, "bisect", "%d fonts left.", hi - lo + 1)
for i = 1, #fonts do
@@ -997,7 +996,7 @@ end
--doc]]--
-local bisect_set = function (outcome)
+local function bisect_set (outcome)
local status = read_bisect_status ()
if not status then
return false, false
@@ -1063,7 +1062,7 @@ end
--doc]]--
-local bisect_status = function ()
+local function bisect_status ()
local status = read_bisect_status ()
if not status then
return false, false
@@ -1092,7 +1091,7 @@ end
--doc]]--
-local bisect_run = function ()
+local function bisect_run ()
local status = read_bisect_status ()
if not status then
return false, false
@@ -1121,7 +1120,7 @@ local bisect_modes = {
run = bisect_run,
}
-actions.bisect = function (job)
+function actions.bisect (job)
local mode = job.bisect
local runner = bisect_modes[mode]
if not runner then
@@ -1131,7 +1130,7 @@ actions.bisect = function (job)
return runner (job)
end
-actions.flush = function (job)
+function actions.flush (job)
local success = fonts.names.flush_lookup_cache()
if success then
local success = fonts.names.save_lookups()
@@ -1143,7 +1142,7 @@ actions.flush = function (job)
return false, false
end
-local cache_directives = function ()
+local function cache_directives ()
--- These exist only after initialization.
return {
["purge"] = fonts.names.purge_cache,
@@ -1152,7 +1151,7 @@ local cache_directives = function ()
}
end
-actions.cache = function (job)
+function actions.cache (job)
local directive = cache_directives()[job.cache]
if not directive or type(directive) ~= "function" then
logreport ("info", 2, "cache",
@@ -1165,7 +1164,7 @@ actions.cache = function (job)
return false, false
end
-actions.query = function (job)
+function actions.query (job)
require "luaotfload-features"
@@ -1239,36 +1238,26 @@ end
---
--- --list=<criterion> --fields=<f1>,<f2>,<f3>,...<fn>
-local get_fields get_fields = function (entry, fields, acc, n)
- if not acc then
- return get_fields (entry, fields, { }, 1)
- end
-
- local field = fields [n]
- if field then
+local function get_fields (entry, fields)
+ local acc = {}
+ for n, field in ipairs(fields) do
local chain = stringsplit (field, "->")
local tmp = entry
- for i = 1, #chain - 1 do
+ for i = 1, #chain do
tmp = tmp [chain [i]]
if not tmp then
--- invalid field
break
end
end
- if tmp then
- local value = tmp [chain [#chain]]
- acc[#acc+1] = value or false
- else
- acc[#acc+1] = false
- end
- return get_fields (entry, fields, acc, n+1)
+ acc[n] = tmp or false
end
return acc
end
local separator = "\t" --- could be “,” for csv
-local format_fields format_fields = function (fields, acc, n)
+local function format_fields (fields, acc, n)
if not acc then
return format_fields(fields, { }, 1)
end
@@ -1285,8 +1274,7 @@ local format_fields format_fields = function (fields, acc, n)
return tableconcat(acc, separator)
end
-local set_primary_field
-set_primary_field = function (fields, addme, acc, n)
+local function set_primary_field (fields, addme, acc, n)
if not acc then
return set_primary_field(fields, addme, { addme }, 1)
end
@@ -1301,7 +1289,17 @@ set_primary_field = function (fields, addme, acc, n)
return acc
end
-actions.list = function (job)
+local function sane_pattern (p)
+ local l = lpeg or require'lpeg'
+ local special = l.Cg(l.P'*' * l.Cc'.*')
+ local pattern = l.Cs(l.Cc'^' * (special + (1 - special)^1/fonts.names.sanitize_fontname)^0 * l.Cc'$')
+ function sane_pattern (p)
+ return pattern:match(p)
+ end
+ return sane_pattern(p)
+end
+
+function actions.list (job)
local criterion = job.criterion
local asked_fields = job.asked_fields
local name_index = fonts.names.data ()
@@ -1336,6 +1334,7 @@ actions.list = function (job)
else
criterion = stringexplode(criterion, ":") --> { field, value }
local asked_value = criterion[2]
+ local sane_asked_pattern = sane_pattern(criterion[2])
criterion = criterion[1]
asked_fields = set_primary_field(asked_fields, criterion)
@@ -1347,8 +1346,9 @@ actions.list = function (job)
logreport (false, 2, "list", "Restricting to value %s", asked_value)
for i=1, nmappings do
local entry = mappings[i]
- if entry[criterion]
- and tostring(entry[criterion]) == asked_value
+ local entryvalue = tostring(entry[criterion])
+ if entryvalue
+ and (entryvalue == asked_value or entryvalue:match(sane_asked_pattern))
then
targets[#targets+1] = entry
end
@@ -1405,7 +1405,7 @@ actions.list = function (job)
return true, true
end
-actions.diagnose = function (job)
+function actions.diagnose (job)
--- diagnostics are loaded on demand
local diagnose = require "luaotfload-diagnostics.lua"
return diagnose (job)
@@ -1417,7 +1417,7 @@ local finalizers = { }
--- returns false if at least one of the actions failed, mainly
--- for closing io channels
-local finalize = function ()
+local function finalize ()
local success = true
for _, fun in next, finalizers do
if type (fun) == "function" then
@@ -1437,7 +1437,7 @@ environment.* namespace that could eliminate the dependency on
alt_getopt.
--]]--
-local process_cmdline = function ( ) -- unit -> jobspec
+local function process_cmdline ( ) -- unit -> jobspec
local result = { -- jobspec
force_reload = nil,
full_info = false,
@@ -1612,7 +1612,7 @@ local process_cmdline = function ( ) -- unit -> jobspec
return result
end
-local main = function ( ) -- unit -> int
+local function main ( ) -- unit -> int
if init_modules () == false then return -42 end
local retval = 0
diff --git a/macros/luatex/generic/luaotfload/luaotfload-tool.pdf b/macros/luatex/generic/luaotfload/luaotfload-tool.pdf
index eb2d6463bb..cbd3cd06b4 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 35ca195501..98168422c3 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: 2020-02-02
+:Date: 2020-05-01
:Copyright: GPL v2.0
-:Version: 3.12
+:Version: 3.13
:Manual section: 1
:Manual group: text processing
@@ -132,7 +132,8 @@ query mode
containing ``->`` be properly quoted!
3) an expression of the form ``field:value`` to
limit the output to entries whose ``field``
- matches ``value``.
+ matches ``value``. The ``value`` can contain
+ ``*`` to match an arbitrary number of characters.
For example, in order to output file names and
corresponding versions, sorted by the font
diff --git a/macros/luatex/generic/luaotfload/luaotfload-tounicode.lua b/macros/luatex/generic/luaotfload/luaotfload-tounicode.lua
index 509a0d782d..95e4b55b66 100644
--- a/macros/luatex/generic/luaotfload/luaotfload-tounicode.lua
+++ b/macros/luatex/generic/luaotfload/luaotfload-tounicode.lua
@@ -5,8 +5,8 @@
local ProvidesLuaModule = {
name = "luaotfload-tounicode",
- version = "3.12", --TAGVERSION
- date = "2020-02-02", --TAGDATE
+ version = "3.13", --TAGVERSION
+ date = "2020-05-01", --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 8c1f92cf31..79d196fb64 100644
--- a/macros/luatex/generic/luaotfload/luaotfload-unicode.lua
+++ b/macros/luatex/generic/luaotfload/luaotfload-unicode.lua
@@ -5,8 +5,8 @@
local ProvidesLuaModule = {
name = "luaotfload-unicode",
- version = "3.12", --TAGVERSION
- date = "2020-02-02", --TAGDATE
+ version = "3.13", --TAGVERSION
+ date = "2020-05-01", --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 9301e95805..151cc6aea2 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 "2020-02-02" "3.12" "text processing"
+.TH LUAOTFLOAD.CONF 5 "2020-05-01" "3.13" "text processing"
.SH NAME
luaotfload.conf \- Luaotfload configuration file
.
diff --git a/macros/luatex/generic/luaotfload/luaotfload.conf.rst b/macros/luatex/generic/luaotfload/luaotfload.conf.rst
index b862c8b9b8..779bcb7370 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: 2020-02-02
+:Date: 2020-05-01
:Copyright: GPL v2.0
-:Version: 3.12
+:Version: 3.13
:Manual section: 5
:Manual group: text processing
diff --git a/macros/luatex/generic/luaotfload/luaotfload.sty b/macros/luatex/generic/luaotfload/luaotfload.sty
index f779ecbf83..383bbde5fd 100644
--- a/macros/luatex/generic/luaotfload/luaotfload.sty
+++ b/macros/luatex/generic/luaotfload/luaotfload.sty
@@ -40,7 +40,7 @@
\fi
\ifdefined\ProvidesPackage
\ProvidesPackage{luaotfload}%
- [2020/02/02 v3.12 OpenType layout system]
+ [2020/05/01 v3.13 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 574765e148..16e1a6163d 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 49a6e2114f..285cb48353 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 0148482905..15775d568b 100644
--- a/macros/luatex/generic/luaotfload/shaper-demo.pdf
+++ b/macros/luatex/generic/luaotfload/shaper-demo.pdf
Binary files differ