summaryrefslogtreecommitdiff
path: root/macros/luatex
diff options
context:
space:
mode:
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.lua29
-rw-r--r--macros/luatex/generic/lualibs/lualibs-extended-merged.lua6
-rw-r--r--macros/luatex/generic/lualibs/lualibs-os.lua2
-rw-r--r--macros/luatex/generic/lualibs/lualibs-package.lua24
-rw-r--r--macros/luatex/generic/lualibs/lualibs-util-dim.lua18
-rw-r--r--macros/luatex/generic/lualibs/lualibs.dtx18
-rw-r--r--macros/luatex/generic/lualibs/lualibs.pdfbin81574 -> 81487 bytes
-rw-r--r--macros/luatex/generic/luaotfload/NEWS28
-rw-r--r--macros/luatex/generic/luaotfload/README.md4
-rw-r--r--macros/luatex/generic/luaotfload/filegraph.pdfbin40015 -> 40030 bytes
-rw-r--r--macros/luatex/generic/luaotfload/filegraph.tex2
-rw-r--r--macros/luatex/generic/luaotfload/fontloader-2020-12-30.lua (renamed from macros/luatex/generic/luaotfload/fontloader-2020-08-31.lua)575
-rw-r--r--macros/luatex/generic/luaotfload/fontloader-basics-nod.lua19
-rw-r--r--macros/luatex/generic/luaotfload/fontloader-font-dsp.lua2
-rw-r--r--macros/luatex/generic/luaotfload/fontloader-font-imp-effects.lua109
-rw-r--r--macros/luatex/generic/luaotfload/fontloader-font-one.lua19
-rw-r--r--macros/luatex/generic/luaotfload/fontloader-font-otl.lua35
-rw-r--r--macros/luatex/generic/luaotfload/fontloader-font-ots.lua311
-rw-r--r--macros/luatex/generic/luaotfload/fontloader-font-shp.lua4
-rw-r--r--macros/luatex/generic/luaotfload/fontloader-font-ttf.lua5
-rw-r--r--macros/luatex/generic/luaotfload/fontloader-reference.lua415
-rw-r--r--macros/luatex/generic/luaotfload/luaotfload-auxiliary.lua58
-rw-r--r--macros/luatex/generic/luaotfload/luaotfload-case.lua239
-rw-r--r--macros/luatex/generic/luaotfload/luaotfload-colors.lua11
-rw-r--r--macros/luatex/generic/luaotfload/luaotfload-conf.pdfbin77426 -> 77331 bytes
-rw-r--r--macros/luatex/generic/luaotfload/luaotfload-configuration.lua10
-rw-r--r--macros/luatex/generic/luaotfload/luaotfload-database.lua31
-rw-r--r--macros/luatex/generic/luaotfload/luaotfload-diagnostics.lua11
-rw-r--r--macros/luatex/generic/luaotfload/luaotfload-dvi.lua10
-rw-r--r--macros/luatex/generic/luaotfload/luaotfload-embolden.lua10
-rw-r--r--macros/luatex/generic/luaotfload/luaotfload-fallback.lua10
-rw-r--r--macros/luatex/generic/luaotfload/luaotfload-features.lua27
-rw-r--r--macros/luatex/generic/luaotfload/luaotfload-filelist.lua14
-rw-r--r--macros/luatex/generic/luaotfload/luaotfload-glyphlist.lua10
-rw-r--r--macros/luatex/generic/luaotfload/luaotfload-harf-define.lua10
-rw-r--r--macros/luatex/generic/luaotfload/luaotfload-harf-plug.lua563
-rw-r--r--macros/luatex/generic/luaotfload/luaotfload-init.lua50
-rw-r--r--macros/luatex/generic/luaotfload/luaotfload-latex.pdfbin486239 -> 493305 bytes
-rw-r--r--macros/luatex/generic/luaotfload/luaotfload-latex.tex2
-rw-r--r--macros/luatex/generic/luaotfload/luaotfload-letterspace.lua10
-rw-r--r--macros/luatex/generic/luaotfload/luaotfload-loaders.lua10
-rw-r--r--macros/luatex/generic/luaotfload/luaotfload-log.lua11
-rw-r--r--macros/luatex/generic/luaotfload/luaotfload-main.lua339
-rw-r--r--macros/luatex/generic/luaotfload/luaotfload-main.tex101
-rw-r--r--macros/luatex/generic/luaotfload/luaotfload-multiscript.lua10
-rw-r--r--macros/luatex/generic/luaotfload/luaotfload-notdef.lua10
-rw-r--r--macros/luatex/generic/luaotfload/luaotfload-parsers.lua11
-rw-r--r--macros/luatex/generic/luaotfload/luaotfload-resolvers.lua11
-rw-r--r--macros/luatex/generic/luaotfload/luaotfload-scripts.lua10
-rw-r--r--macros/luatex/generic/luaotfload/luaotfload-status.lua184
-rw-r--r--macros/luatex/generic/luaotfload/luaotfload-suppress.lua10
-rw-r--r--macros/luatex/generic/luaotfload/luaotfload-szss.lua10
-rw-r--r--macros/luatex/generic/luaotfload/luaotfload-tool.14
-rw-r--r--macros/luatex/generic/luaotfload/luaotfload-tool.lua10
-rw-r--r--macros/luatex/generic/luaotfload/luaotfload-tool.pdfbin76886 -> 76773 bytes
-rw-r--r--macros/luatex/generic/luaotfload/luaotfload-tool.rst4
-rw-r--r--macros/luatex/generic/luaotfload/luaotfload-tounicode.lua10
-rw-r--r--macros/luatex/generic/luaotfload/luaotfload-unicode.lua152
-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.lua375
-rw-r--r--macros/luatex/generic/luaotfload/luaotfload.sty4
-rw-r--r--macros/luatex/generic/luaotfload/scripts-demo.pdfbin21504 -> 21696 bytes
-rw-r--r--macros/luatex/generic/luaotfload/shaper-demo-graphite.pdfbin8468 -> 8566 bytes
-rw-r--r--macros/luatex/generic/luaotfload/shaper-demo.pdfbin8392 -> 8486 bytes
67 files changed, 2418 insertions, 1574 deletions
diff --git a/macros/luatex/generic/lualibs/NEWS b/macros/luatex/generic/lualibs/NEWS
index af54318e6e..4c80d06987 100644
--- a/macros/luatex/generic/lualibs/NEWS
+++ b/macros/luatex/generic/lualibs/NEWS
@@ -1,4 +1,7 @@
History of the lualibs package
+2020/12/30 v2.73/
+ * sync with Context current as of 2020/12/30.
+
2020/08/31 v2.72/
* sync with Context current as of 2020/08/31.
diff --git a/macros/luatex/generic/lualibs/README.md b/macros/luatex/generic/lualibs/README.md
index 351930040c..cf330df159 100644
--- a/macros/luatex/generic/lualibs/README.md
+++ b/macros/luatex/generic/lualibs/README.md
@@ -1,10 +1,10 @@
# The Lualibs Package
-VERSION: 2.72
+VERSION: 2.73
-DATE: 2020-08-31
+DATE: 2020-12-30
-FONTLOADERDATE: 2020-08-31
+FONTLOADERDATE: 2020-12-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 147cc33fa9..92e571a7cc 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 : Mon Aug 31 23:16:26 2020
+-- merge date : Wed Dec 30 17:55:54 2020
do -- begin closure to overcome local limits and interference
@@ -358,7 +358,10 @@ methods["already loaded"]=function(name)
return package.loaded[name]
end
methods["preload table"]=function(name)
- return builtin["preload table"](name)
+ local f=builtin["preload table"]
+ if f then
+ return f(name)
+ end
end
methods["qualified path"]=function(name)
return loadedbyname(addsuffix(lualibfile(name),"lua"),name)
@@ -370,15 +373,24 @@ methods["lib extra list"]=function(name)
return loadedbypath(addsuffix(lualibfile(name),os.libsuffix),name,getextralibpaths(),true,"lib")
end
methods["path specification"]=function(name)
- getluapaths()
- return builtin["path specification"](name)
+ local f=builtin["path specification"]
+ if f then
+ getluapaths()
+ return f(name)
+ end
end
methods["cpath specification"]=function(name)
- getlibpaths()
- return builtin["cpath specification"](name)
+ local f=builtin["cpath specification"]
+ if f then
+ getlibpaths()
+ return f(name)
+ end
end
methods["all in one fallback"]=function(name)
- return builtin["all in one fallback"](name)
+ local f=builtin["all in one fallback"]
+ if f then
+ return f(name)
+ end
end
methods["not loaded"]=function(name)
if helpers.trace then
@@ -3358,6 +3370,8 @@ elseif name=="macosx" then
platform="osx-intel"
elseif find(architecture,"x86_64",1,true) then
platform="osx-64"
+ elseif find(architecture,"arm64",1,true) then
+ platform="osx-64"
else
platform="osx-ppc"
end
@@ -4684,6 +4698,7 @@ if not modules then modules={} end modules ['l-unicode']={
license="see context related readme files"
}
utf=utf or {}
+-- unicode=nil
if not string.utfcharacters then
local gmatch=string.gmatch
function string.characters(str)
diff --git a/macros/luatex/generic/lualibs/lualibs-extended-merged.lua b/macros/luatex/generic/lualibs/lualibs-extended-merged.lua
index 89d384ac8a..cac8889ca3 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 : Mon Aug 31 23:16:16 2020
+-- merge date : Wed Dec 30 17:55:44 2020
do -- begin closure to overcome local limits and interference
@@ -2700,8 +2700,6 @@ local dimenfactors=allocate {
["pc"]=(1/12)/65536,
["dd"]=(1157/1238)/65536,
["cc"]=(1157/14856)/65536,
- ["nd"]=(20320/21681)/65536,
- ["nc"]=(5080/65043)/65536
}
local f_none=formatters["%s%s"]
local f_true=formatters["%0.5F%s"]
@@ -2733,8 +2731,6 @@ function number.tobasepoints (n,fmt) return numbertodimen(n,"bp",fmt) end
function number.topicas (n,fmt) return numbertodimen(n "pc",fmt) end
function number.todidots (n,fmt) return numbertodimen(n,"dd",fmt) end
function number.tociceros (n,fmt) return numbertodimen(n,"cc",fmt) end
-function number.tonewdidots (n,fmt) return numbertodimen(n,"nd",fmt) end
-function number.tonewciceros (n,fmt) return numbertodimen(n,"nc",fmt) end
local amount=(S("+-")^0*R("09")^0*P(".")^0*R("09")^0)+Cc("0")
local unit=R("az")^1+P("%")
local dimenpair=amount/tonumber*(unit^1/dimenfactors+Cc(1))
diff --git a/macros/luatex/generic/lualibs/lualibs-os.lua b/macros/luatex/generic/lualibs/lualibs-os.lua
index 1e01350947..73841074c4 100644
--- a/macros/luatex/generic/lualibs/lualibs-os.lua
+++ b/macros/luatex/generic/lualibs/lualibs-os.lua
@@ -358,6 +358,8 @@ elseif name == "macosx" then
platform = "osx-intel"
elseif find(architecture,"x86_64",1,true) then
platform = "osx-64"
+ elseif find(architecture,"arm64",1,true) then
+ platform = "osx-64"
else
platform = "osx-ppc"
end
diff --git a/macros/luatex/generic/lualibs/lualibs-package.lua b/macros/luatex/generic/lualibs/lualibs-package.lua
index 94607d4368..a35ec3e2a9 100644
--- a/macros/luatex/generic/lualibs/lualibs-package.lua
+++ b/macros/luatex/generic/lualibs/lualibs-package.lua
@@ -300,7 +300,10 @@ methods["already loaded"] = function(name)
end
methods["preload table"] = function(name)
- return builtin["preload table"](name)
+ local f = builtin["preload table"]
+ if f then
+ return f(name)
+ end
end
methods["qualified path"]=function(name)
@@ -316,17 +319,26 @@ methods["lib extra list"] = function(name)
end
methods["path specification"] = function(name)
- getluapaths() -- triggers list building and tracing
- return builtin["path specification"](name)
+ local f = builtin["path specification"]
+ if f then
+ getluapaths() -- triggers list building and tracing
+ return f(name)
+ end
end
methods["cpath specification"] = function(name)
- getlibpaths() -- triggers list building and tracing
- return builtin["cpath specification"](name)
+ local f = builtin["cpath specification"]
+ if f then
+ getlibpaths() -- triggers list building and tracing
+ return f(name)
+ end
end
methods["all in one fallback"] = function(name)
- return builtin["all in one fallback"](name)
+ local f = builtin["all in one fallback"]
+ if f then
+ return f(name)
+ end
end
methods["not loaded"] = function(name)
diff --git a/macros/luatex/generic/lualibs/lualibs-util-dim.lua b/macros/luatex/generic/lualibs/lualibs-util-dim.lua
index 76b5fd20bb..bb9eca9668 100644
--- a/macros/luatex/generic/lualibs/lualibs-util-dim.lua
+++ b/macros/luatex/generic/lualibs/lualibs-util-dim.lua
@@ -44,8 +44,8 @@ local dimenfactors = allocate {
["pc"] = ( 1/ 12)/65536,
["dd"] = ( 1157/ 1238)/65536,
["cc"] = ( 1157/14856)/65536,
- ["nd"] = (20320/21681)/65536,
- ["nc"] = ( 5080/65043)/65536
+ -- ["nd"] = (20320/21681)/65536,
+ -- ["nc"] = ( 5080/65043)/65536
}
-- print(table.serialize(dimenfactors))
@@ -61,9 +61,9 @@ local dimenfactors = allocate {
-- ["ex"]=6.103515625e-005,
-- ["in"]=2.1113586636917117e-007,
-- ["mm"]=5.3628510057769473e-008,
--- ["nc"]=1.1917446679504327e-006,
--- ["nd"]=1.4300936015405194e-005,
--- ["pc"]=1.2715657552083333e-006,
+-- --["nc"]=1.1917446679504327e-006,
+-- --["nd"]=1.4300936015405194e-005,
+-- --["pc"]=1.2715657552083333e-006,
-- ["pt"]=1.52587890625e-005,
-- ["sp"]=1,
-- }
@@ -79,8 +79,8 @@ local dimenfactors = allocate {
-- ["ex"]=0.00006103515625,
-- ["in"]=0.00000021113587,
-- ["mm"]=0.00000005362851,
--- ["nc"]=0.00000119174467,
--- ["nd"]=0.00001430093602,
+-- --["nc"]=0.00000119174467,
+-- --["nd"]=0.00001430093602,
-- ["pc"]=0.00000127156576,
-- ["pt"]=0.00001525878906,
-- ["sp"]=1,
@@ -128,8 +128,8 @@ function number.tobasepoints (n,fmt) return numbertodimen(n,"bp",fmt) end
function number.topicas (n,fmt) return numbertodimen(n "pc",fmt) end
function number.todidots (n,fmt) return numbertodimen(n,"dd",fmt) end
function number.tociceros (n,fmt) return numbertodimen(n,"cc",fmt) end
-function number.tonewdidots (n,fmt) return numbertodimen(n,"nd",fmt) end
-function number.tonewciceros (n,fmt) return numbertodimen(n,"nc",fmt) end
+-------- number.tonewdidots (n,fmt) return numbertodimen(n,"nd",fmt) end
+-------- number.tonewciceros (n,fmt) return numbertodimen(n,"nc",fmt) end
--[[ldx--
<p>More interesting it to implement a (sort of) dimen datatype, one
diff --git a/macros/luatex/generic/lualibs/lualibs.dtx b/macros/luatex/generic/lualibs/lualibs.dtx
index c98c752765..7246e8541e 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-08-31 v2.72 Lua additional functions.}
+\Msg{* Package: lualibs 2020-12-30 v2.73 Lua additional functions.}
\Msg{************************************************************************}
\keepsilent
@@ -107,7 +107,7 @@ and lualibs-extended.lua.
%<*driver>
\NeedsTeXFormat{LaTeX2e}
\ProvidesFile{lualibs.drv}
- [2020/08/31 v2.72 Lua Libraries.]
+ [2020/12/30 v2.73 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/08/31 v2.72}
+% \date{2020/12/30 v2.73}
% \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.72", --TAGVERSION
- date = "2020-08-31", --TAGDATE
+ version = "2.73", --TAGVERSION
+ date = "2020-12-30", --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.72", --TAGVERSION
- date = "2020-08-31", --TAGDATE
+ version = "2.73", --TAGVERSION
+ date = "2020-12-30", --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.72", --TAGVERSION
- date = "2020-08-31", --TAGDATE
+ version = "2.73", --TAGVERSION
+ date = "2020-12-30", --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 031fc8158e..10274b447b 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 658c5d420e..b0a7f124c1 100644
--- a/macros/luatex/generic/luaotfload/NEWS
+++ b/macros/luatex/generic/luaotfload/NEWS
@@ -1,6 +1,32 @@
Change History
--------------
-2020-08-31 luaotfload v3.15
+2020-12-31 luaotfload v3.16
+
+ * The fontloader has been synced with the context code from 2020-12-30
+ * The entry point is called luaotfload.lua instead of
+ luaotfload-main.lua (but the old name is still provided for
+ compatibility).
+ * pre/post_shaping_filter callbacks has been added.
+ * The number of lua-files and submodules shown in the log-file
+ has been reduced. But it is extended again by setting the environment
+ variable LUAOTFLOAD_TRACE_SUBMODULES=1.
+ * The HarfBuzz based shaper will in some situations drop hyphenation
+ points. This happens less frequently now since the new version uses
+ first/second discretionaries (the mechanism described in the LuaTeX manual,
+ section 5.6 for the of-f-ice example) to support a limited amount of
+ nesting.
+ * When the node shaper is used, experimental support for
+ OpenType variable fonts has been added. To use them, set the font
+ feature axis to a comma separated list of axis names and values.
+ (E.g. axis={weight=600}) The supported axis names and value
+ range depend on the font.
+ * The font features upper and lower can be used to map
+ the text of a font to upper or lowercase before displaying it. Currently
+ this implements the untailored Unicode case mapping algorithm, but it is
+ planned to add tailoring later.
+ * A number of small bugfixes.
+
+2020-09-02 luaotfload v3.15
* The font database is updated more reliably if fonts get deleted.
* In multiple error cases, error messages are shown instead of silently
generating bad output.
diff --git a/macros/luatex/generic/luaotfload/README.md b/macros/luatex/generic/luaotfload/README.md
index 626e1c9b8b..f19c4c5563 100644
--- a/macros/luatex/generic/luaotfload/README.md
+++ b/macros/luatex/generic/luaotfload/README.md
@@ -1,8 +1,8 @@
# The Luaotfload Package
-VERSION: 3.15
+VERSION: 3.16
-DATE: 2020-09-02
+DATE: 2020-12-31
## Description
diff --git a/macros/luatex/generic/luaotfload/filegraph.pdf b/macros/luatex/generic/luaotfload/filegraph.pdf
index 5e90db1544..ac40ce55f9 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/filegraph.tex b/macros/luatex/generic/luaotfload/filegraph.tex
index ee76912b78..1301319880 100644
--- a/macros/luatex/generic/luaotfload/filegraph.tex
+++ b/macros/luatex/generic/luaotfload/filegraph.tex
@@ -103,7 +103,7 @@ label={[name=mL3,font=\itshape,anchor=south]above:Lualibs -- Lua Libraries from
%>>>>>>>>>>>>>>>>
};
% m4
-\node[left=2cm of m3,fill=gray!20,draw=gray!30,thick,basic,inner sep=6mm] (m4) {luaotfload-main.lua};
+\node[left=2cm of m3,fill=gray!20,draw=gray!30,thick,basic,inner sep=6mm] (m4) {luaotfload.lua};
% m5
\node[fill=gray!20,draw=gray!30,dashed,basic,inner sep=6mm,anchor=south west] at (m3.south -|
m2.west)(m5){%
diff --git a/macros/luatex/generic/luaotfload/fontloader-2020-08-31.lua b/macros/luatex/generic/luaotfload/fontloader-2020-12-30.lua
index 01e1f8300c..835eca6695 100644
--- a/macros/luatex/generic/luaotfload/fontloader-2020-08-31.lua
+++ b/macros/luatex/generic/luaotfload/fontloader-2020-12-30.lua
@@ -1,6 +1,6 @@
--[[info-----------------------------------------------------------------------
Luaotfload fontloader package
- build 2020-08-31 23:33:48
+ build 2020-12-30 17:29:34
-------------------------------------------------------------------------------
© 2020 PRAGMA ADE / ConTeXt Development Team
@@ -63,7 +63,7 @@
--info]]-----------------------------------------------------------------------
-do --- [luaotfload, fontloader-2020-08-31.lua scope for “data-con” de6ae0997b0e70a23bcc9afff5d8b072] ---
+do --- [luaotfload, fontloader-2020-12-30.lua scope for “data-con” 23a0f5386d46a1c157ae82a373e35fa0] ---
if not modules then modules={} end modules ['data-con']={
version=1.100,
@@ -184,10 +184,10 @@ function containers.cleanname(name)
return (gsub(lower(name),"[^%w\128-\255]+","-"))
end
-end --- [luaotfload, fontloader-2020-08-31.lua scope for “data-con”] ---
+end --- [luaotfload, fontloader-2020-12-30.lua scope for “data-con”] ---
-do --- [luaotfload, fontloader-2020-08-31.lua scope for “basics-nod” e296bfb03d5654a596b43612348c4191] ---
+do --- [luaotfload, fontloader-2020-12-30.lua scope for “basics-nod” 4b5c3c63e19df1b3f37fae7f87c25bda] ---
if not modules then modules={} end modules ['luatex-fonts-nod']={
version=1.001,
@@ -265,6 +265,7 @@ nuts.getkern=direct.getkern
nuts.getlist=direct.getlist
nuts.getnext=direct.getnext
nuts.getoffsets=direct.getoffsets
+nuts.getoptions=direct.getoptions or function() return 0 end
nuts.getprev=direct.getprev
nuts.getsubtype=direct.getsubtype
nuts.getwidth=direct.getwidth
@@ -348,6 +349,15 @@ local traverse_id=nuts.traverse_id
local copy_node=nuts.copy_node
local glyph_code=nodes.nodecodes.glyph
local ligature_code=nodes.glyphcodes.ligature
+do
+ local p=nodecodes.localpar or nodecodes.local_par
+ if p then
+ nodecodes.par=p
+ nodecodes[p]="par"
+ nodecodes.localpar=p
+ nodecodes.local_par=p
+ end
+end
do
local get_components=node.direct.getcomponents
local set_components=node.direct.setcomponents
@@ -400,11 +410,14 @@ do
end
return 0
end
+ local function flush_components()
+ end
nuts.set_components=set_components
nuts.get_components=get_components
nuts.copy_only_glyphs=copy_only_glyphs
nuts.copy_no_components=copy_no_components
nuts.count_components=count_components
+ nuts.flush_components=flush_components
end
nuts.uses_font=direct.uses_font
do
@@ -437,10 +450,10 @@ do
end
end
-end --- [luaotfload, fontloader-2020-08-31.lua scope for “basics-nod”] ---
+end --- [luaotfload, fontloader-2020-12-30.lua scope for “basics-nod”] ---
-do --- [luaotfload, fontloader-2020-08-31.lua scope for “basics-chr” 58b7ef0c486e06090b362971b9f85e27] ---
+do --- [luaotfload, fontloader-2020-12-30.lua scope for “basics-chr” 64fafe4eaf55d64aead6513c1e74a024] ---
characters=characters or {}
@@ -4050,10 +4063,10 @@ characters.indicgroups={
},
}
-end --- [luaotfload, fontloader-2020-08-31.lua scope for “basics-chr”] ---
+end --- [luaotfload, fontloader-2020-12-30.lua scope for “basics-chr”] ---
-do --- [luaotfload, fontloader-2020-08-31.lua scope for “font-ini” 4dee96e1e1474d324dd126bd5d375df8] ---
+do --- [luaotfload, fontloader-2020-12-30.lua scope for “font-ini” 5343de60613adb24cdd7a8d2ee1d153c] ---
if not modules then modules={} end modules ['font-ini']={
version=1.001,
@@ -4094,10 +4107,10 @@ if node and not tex.getfontoffamily then
tex.getfontoffamily=node.family_font
end
-end --- [luaotfload, fontloader-2020-08-31.lua scope for “font-ini”] ---
+end --- [luaotfload, fontloader-2020-12-30.lua scope for “font-ini”] ---
-do --- [luaotfload, fontloader-2020-08-31.lua scope for “fonts-mis” bc9eb43c27f63ce9d0fff67e104fe1c6] ---
+do --- [luaotfload, fontloader-2020-12-30.lua scope for “fonts-mis” 17e967c9ec4d001deefd43ddf25e98f7] ---
if not modules then modules={} end modules ['luatex-font-mis']={
version=1.001,
@@ -4129,10 +4142,10 @@ function font.each()
return table.sortedhash(fonts.hashes.identifiers)
end
-end --- [luaotfload, fontloader-2020-08-31.lua scope for “fonts-mis”] ---
+end --- [luaotfload, fontloader-2020-12-30.lua scope for “fonts-mis”] ---
-do --- [luaotfload, fontloader-2020-08-31.lua scope for “font-con” cbccccc4a5016196d62332a365aa8b72] ---
+do --- [luaotfload, fontloader-2020-12-30.lua scope for “font-con” a3eb543fa5946fa1faf0e1e50d5b3b91] ---
if not modules then modules={} end modules ['font-con']={
version=1.001,
@@ -5497,10 +5510,10 @@ function constructors.addcoreunicodes(unicodes)
return unicodes
end
-end --- [luaotfload, fontloader-2020-08-31.lua scope for “font-con”] ---
+end --- [luaotfload, fontloader-2020-12-30.lua scope for “font-con”] ---
-do --- [luaotfload, fontloader-2020-08-31.lua scope for “fonts-enc” 3e71a54297e8f85a1ac438bb0f20dd79] ---
+do --- [luaotfload, fontloader-2020-12-30.lua scope for “fonts-enc” 5ff4ca50493d7c4ecea0e15c203099f0] ---
if not modules then modules={} end modules ['luatex-font-enc']={
version=1.001,
@@ -5569,10 +5582,10 @@ function encodings.load(filename)
return containers.write(encodings.cache,name,data)
end
-end --- [luaotfload, fontloader-2020-08-31.lua scope for “fonts-enc”] ---
+end --- [luaotfload, fontloader-2020-12-30.lua scope for “fonts-enc”] ---
-do --- [luaotfload, fontloader-2020-08-31.lua scope for “font-cid” 4d87988efa86020a14708ee03c23415f] ---
+do --- [luaotfload, fontloader-2020-12-30.lua scope for “font-cid” 22b0367742fb253deef84ef7ccf5e8de] ---
if not modules then modules={} end modules ['font-cid']={
version=1.001,
@@ -5723,10 +5736,10 @@ function cid.getmap(specification)
return found
end
-end --- [luaotfload, fontloader-2020-08-31.lua scope for “font-cid”] ---
+end --- [luaotfload, fontloader-2020-12-30.lua scope for “font-cid”] ---
-do --- [luaotfload, fontloader-2020-08-31.lua scope for “font-map” a03653ea3c5f042b457d54ed678d6df3] ---
+do --- [luaotfload, fontloader-2020-12-30.lua scope for “font-map” c4a39db5ad822b348aa61bca5f4a599a] ---
if not modules then modules={} end modules ['font-map']={
version=1.001,
@@ -6134,10 +6147,10 @@ function mappings.addtounicode(data,filename,checklookups,forceligatures)
end
end
-end --- [luaotfload, fontloader-2020-08-31.lua scope for “font-map”] ---
+end --- [luaotfload, fontloader-2020-12-30.lua scope for “font-map”] ---
-do --- [luaotfload, fontloader-2020-08-31.lua scope for “font-vfc” 04fa0ffad5c51198c7c19462949f54ed] ---
+do --- [luaotfload, fontloader-2020-12-30.lua scope for “font-vfc” a81c29eda98cd62cbebdb6c93544b50d] ---
if not modules then modules={} end modules ['font-vfc']={
version=1.001,
@@ -6234,10 +6247,10 @@ helpers.commands=utilities.storage.allocate {
dummy=dummy,
}
-end --- [luaotfload, fontloader-2020-08-31.lua scope for “font-vfc”] ---
+end --- [luaotfload, fontloader-2020-12-30.lua scope for “font-vfc”] ---
-do --- [luaotfload, fontloader-2020-08-31.lua scope for “font-otr” 7a2f7a9e9627b29158e1822ea3c650ab] ---
+do --- [luaotfload, fontloader-2020-12-30.lua scope for “font-otr” 64dcbbc7107538723990e1119a80a9f8] ---
if not modules then modules={} end modules ['font-otr']={
version=1.001,
@@ -8081,10 +8094,10 @@ function readers.extend(fontdata)
end
end
-end --- [luaotfload, fontloader-2020-08-31.lua scope for “font-otr”] ---
+end --- [luaotfload, fontloader-2020-12-30.lua scope for “font-otr”] ---
-do --- [luaotfload, fontloader-2020-08-31.lua scope for “font-oti” dbae7722baae24d917a17176553825cf] ---
+do --- [luaotfload, fontloader-2020-12-30.lua scope for “font-oti” 309a75f9c14b77d87e94eba827dc4e71] ---
if not modules then modules={} end modules ['font-oti']={
version=1.001,
@@ -8227,10 +8240,10 @@ function otffeatures.checkeddefaultlanguage(featuretype,autolanguage,languages)
end
end
-end --- [luaotfload, fontloader-2020-08-31.lua scope for “font-oti”] ---
+end --- [luaotfload, fontloader-2020-12-30.lua scope for “font-oti”] ---
-do --- [luaotfload, fontloader-2020-08-31.lua scope for “font-ott” 1249b7018dba80e080fc478a38aa6756] ---
+do --- [luaotfload, fontloader-2020-12-30.lua scope for “font-ott” 673ed11e1d159997f535bfec5fa73808] ---
if not modules then modules={} end modules ["font-ott"]={
version=1.001,
@@ -9346,10 +9359,10 @@ function otffeatures.normalize(features,wrap)
end
end
-end --- [luaotfload, fontloader-2020-08-31.lua scope for “font-ott”] ---
+end --- [luaotfload, fontloader-2020-12-30.lua scope for “font-ott”] ---
-do --- [luaotfload, fontloader-2020-08-31.lua scope for “font-cff” aa9038651d9fedd2b76cacd1f69fd742] ---
+do --- [luaotfload, fontloader-2020-12-30.lua scope for “font-cff” 802a10ad12ac32329f540881f940e3f2] ---
if not modules then modules={} end modules ['font-cff']={
version=1.001,
@@ -11544,10 +11557,10 @@ function readers.cffcheck(filename)
end
end
-end --- [luaotfload, fontloader-2020-08-31.lua scope for “font-cff”] ---
+end --- [luaotfload, fontloader-2020-12-30.lua scope for “font-cff”] ---
-do --- [luaotfload, fontloader-2020-08-31.lua scope for “font-ttf” 807599f6d56c775d53cf6f358d741f34] ---
+do --- [luaotfload, fontloader-2020-12-30.lua scope for “font-ttf” ffffc827e1bcddc33a2b615340ecff7f] ---
if not modules then modules={} end modules ['font-ttf']={
version=1.001,
@@ -11672,7 +11685,7 @@ local function mergecomposites(glyphs,shapes)
shape.components=nil
return contours,points
end
- for index=0,#glyphs-1 do
+ for index=0,#glyphs do
local shape=shapes[index]
if shape then
local components=shape.components
@@ -12102,7 +12115,7 @@ local function repackpoints(glyphs,shapes)
local result={}
local xpoints={}
local ypoints={}
- for index=0,#glyphs-1 do
+ for index=0,#glyphs do
local shape=shapes[index]
if shape then
local r=0
@@ -12718,10 +12731,10 @@ function readers.gvar(f,fontdata,specification,glyphdata,shapedata)
end
end
-end --- [luaotfload, fontloader-2020-08-31.lua scope for “font-ttf”] ---
+end --- [luaotfload, fontloader-2020-12-30.lua scope for “font-ttf”] ---
-do --- [luaotfload, fontloader-2020-08-31.lua scope for “font-dsp” e1c275ded4770aa6cbe0b1afbdfd0dde] ---
+do --- [luaotfload, fontloader-2020-12-30.lua scope for “font-dsp” 18c85a4857f45c31a3555bf1faac434a] ---
if not modules then modules={} end modules ['font-dsp']={
version=1.001,
@@ -13366,7 +13379,7 @@ local function readfirst(f,offset)
end
return { readushort(f) }
end
-function readarray(f,offset)
+local function readarray(f,offset)
if offset then
setposition(f,offset)
end
@@ -15999,10 +16012,10 @@ function readers.mvar(f,fontdata,specification)
end
end
-end --- [luaotfload, fontloader-2020-08-31.lua scope for “font-dsp”] ---
+end --- [luaotfload, fontloader-2020-12-30.lua scope for “font-dsp”] ---
-do --- [luaotfload, fontloader-2020-08-31.lua scope for “font-oup” 1700a2dac4f8b105c187d4e5b84cecdf] ---
+do --- [luaotfload, fontloader-2020-12-30.lua scope for “font-oup” 6f46aa00ae1c20c43f8ffaf329dc8695] ---
if not modules then modules={} end modules ['font-oup']={
version=1.001,
@@ -18643,10 +18656,10 @@ function readers.expand(data)
expandlookups(sublookups)
end
-end --- [luaotfload, fontloader-2020-08-31.lua scope for “font-oup”] ---
+end --- [luaotfload, fontloader-2020-12-30.lua scope for “font-oup”] ---
-do --- [luaotfload, fontloader-2020-08-31.lua scope for “font-otl” f111f9ac18d24049fadeb8883e4e8da5] ---
+do --- [luaotfload, fontloader-2020-12-30.lua scope for “font-otl” 6c4b718ceacfb0cbeb2c03c423f97aec] ---
if not modules then modules={} end modules ['font-otl']={
version=1.001,
@@ -18674,7 +18687,7 @@ local trace_defining=false registertracker("fonts.defining",function(v) trace_d
local report_otf=logs.reporter("fonts","otf loading")
local fonts=fonts
local otf=fonts.handlers.otf
-otf.version=3.111
+otf.version=3.112
otf.cache=containers.define("fonts","otl",otf.version,true)
otf.svgcache=containers.define("fonts","svg",otf.version,true)
otf.pngcache=containers.define("fonts","png",otf.version,true)
@@ -19039,7 +19052,6 @@ local function copytotfm(data,cache_id)
parameters.units=units
parameters.vheight=metadata.defaultvheight
properties.space=spacer
- properties.encodingbytes=2
properties.format=data.format or formats.otf
properties.filename=filename
properties.fontname=fontname
@@ -19047,6 +19059,9 @@ local function copytotfm(data,cache_id)
properties.psname=psname
properties.name=filename or fullname
properties.subfont=subfont
+if not CONTEXTLMTXMODE or CONTEXTLMTXMODE==0 then
+ properties.encodingbytes=2
+end
properties.private=properties.private or data.private or privateoffset
return {
characters=characters,
@@ -19350,10 +19365,10 @@ otf.coverup={
end
}
-end --- [luaotfload, fontloader-2020-08-31.lua scope for “font-otl”] ---
+end --- [luaotfload, fontloader-2020-12-30.lua scope for “font-otl”] ---
-do --- [luaotfload, fontloader-2020-08-31.lua scope for “font-oto” 24238a7c600d090a8ee88312321dd9b3] ---
+do --- [luaotfload, fontloader-2020-12-30.lua scope for “font-oto” 2b1d6bc63b2ebf8f2655a15e1cda6541] ---
if not modules then modules={} end modules ['font-oto']={
version=1.001,
@@ -19811,10 +19826,10 @@ registerotffeature {
}
otf.basemodeinitializer=featuresinitializer
-end --- [luaotfload, fontloader-2020-08-31.lua scope for “font-oto”] ---
+end --- [luaotfload, fontloader-2020-12-30.lua scope for “font-oto”] ---
-do --- [luaotfload, fontloader-2020-08-31.lua scope for “font-otj” a37a1007b8a92c9e7d24064180c2a772] ---
+do --- [luaotfload, fontloader-2020-12-30.lua scope for “font-otj” 8de59cb9b043e5f73c6b9f7cc8f6978e] ---
if not modules then modules={} end modules ['font-otj']={
version=1.001,
@@ -21309,10 +21324,10 @@ function injections.handler(head,where)
end
end
-end --- [luaotfload, fontloader-2020-08-31.lua scope for “font-otj”] ---
+end --- [luaotfload, fontloader-2020-12-30.lua scope for “font-otj”] ---
-do --- [luaotfload, fontloader-2020-08-31.lua scope for “font-ota” f31232af3a694ae3d50380a5a92f88d3] ---
+do --- [luaotfload, fontloader-2020-12-30.lua scope for “font-ota” ad1d5de06400f88829509e1f3ff2b473] ---
if not modules then modules={} end modules ['font-ota']={
version=1.001,
@@ -21806,10 +21821,10 @@ directives.register("otf.analyze.useunicodemarks",function(v)
analyzers.useunicodemarks=v
end)
-end --- [luaotfload, fontloader-2020-08-31.lua scope for “font-ota”] ---
+end --- [luaotfload, fontloader-2020-12-30.lua scope for “font-ota”] ---
-do --- [luaotfload, fontloader-2020-08-31.lua scope for “font-ots” c507280651dcbc549f1d8a5622da8667] ---
+do --- [luaotfload, fontloader-2020-12-30.lua scope for “font-ots” 91c79619c386e4a96954f3115f398b94] ---
if not modules then modules={} end modules ['font-ots']={
version=1.001,
@@ -21893,6 +21908,7 @@ local copy_only_glyphs=nuts.copy_only_glyphs
local count_components=nuts.count_components
local set_components=nuts.set_components
local get_components=nuts.get_components
+local flush_components=nuts.flush_components
local ischar=nuts.ischar
local usesfont=nuts.uses_font
local insert_node_after=nuts.insert_after
@@ -21915,7 +21931,7 @@ local glue_code=nodecodes.glue
local disc_code=nodecodes.disc
local math_code=nodecodes.math
local dir_code=nodecodes.dir
-local localpar_code=nodecodes.localpar
+local par_code=nodecodes.par
local lefttoright_code=nodes.dirvalues.lefttoright
local righttoleft_code=nodes.dirvalues.righttoleft
local discretionarydisc_code=disccodes.discretionary
@@ -22097,11 +22113,23 @@ local function markstoligature(head,start,stop,char)
setsubtype(base,ligatureglyph_code)
set_components(base,start)
setlink(prev,base,next)
+ flush_components(start)
return head,base
end
end
+local no_left_ligature_code=1
+local no_right_ligature_code=2
+local no_left_kern_code=4
+local no_right_kern_code=8
+local has_glyph_option=node.direct.has_glyph_option or function(n,c)
+ if c==no_left_ligature_code or c==no_right_ligature_code then
+ return getattr(n,a_noligature)==1
+ else
+ return false
+ end
+end
local function toligature(head,start,stop,char,dataset,sequence,skiphash,discfound,hasmarks)
- if getattr(start,a_noligature)==1 then
+ if has_glyph_option(start,no_right_ligature_code) then
return head,start
end
if start==stop and getchar(start)==char then
@@ -22165,6 +22193,7 @@ local function toligature(head,start,stop,char,dataset,sequence,skiphash,discfou
break
end
end
+ flush_components(components)
else
local discprev,discnext=getboth(discfound)
if discprev and discnext then
@@ -22451,78 +22480,86 @@ function handlers.gsub_ligature(head,start,dataset,sequence,ligature,rlmode,skip
return head,start,false,false
end
function handlers.gpos_single(head,start,dataset,sequence,kerns,rlmode,skiphash,step,injection)
- local startchar=getchar(start)
- local format=step.format
- if format=="single" or type(kerns)=="table" then
- local dx,dy,w,h=setposition(0,start,factor,rlmode,kerns,injection)
- if trace_kerns then
- logprocess("%s: shifting single %s by %s xy (%p,%p) and wh (%p,%p)",pref(dataset,sequence),gref(startchar),format,dx,dy,w,h)
- end
+ if has_glyph_option(start,no_right_kern_code) then
+ return head,start,false
else
- local k=(format=="move" and setmove or setkern)(start,factor,rlmode,kerns,injection)
- if trace_kerns then
- logprocess("%s: shifting single %s by %s %p",pref(dataset,sequence),gref(startchar),format,k)
+ local startchar=getchar(start)
+ local format=step.format
+ if format=="single" or type(kerns)=="table" then
+ local dx,dy,w,h=setposition(0,start,factor,rlmode,kerns,injection)
+ if trace_kerns then
+ logprocess("%s: shifting single %s by %s xy (%p,%p) and wh (%p,%p)",pref(dataset,sequence),gref(startchar),format,dx,dy,w,h)
+ end
+ else
+ local k=(format=="move" and setmove or setkern)(start,factor,rlmode,kerns,injection)
+ if trace_kerns then
+ logprocess("%s: shifting single %s by %s %p",pref(dataset,sequence),gref(startchar),format,k)
+ end
end
+ return head,start,true
end
- return head,start,true
end
function handlers.gpos_pair(head,start,dataset,sequence,kerns,rlmode,skiphash,step,injection)
- local snext=getnext(start)
- if not snext then
+ if has_glyph_option(start,no_right_kern_code) then
return head,start,false
else
- local prev=start
- while snext do
- local nextchar=ischar(snext,currentfont)
- if nextchar then
- if skiphash and skiphash[nextchar] then
- prev=snext
- snext=getnext(snext)
- else
- local krn=kerns[nextchar]
- if not krn then
- break
- end
- local format=step.format
- if format=="pair" then
- local a=krn[1]
- local b=krn[2]
- if a==true then
- elseif a then
- local x,y,w,h=setposition(1,start,factor,rlmode,a,injection)
- if trace_kerns then
- local startchar=getchar(start)
- logprocess("%s: shifting first of pair %s and %s by xy (%p,%p) and wh (%p,%p) as %s",pref(dataset,sequence),gref(startchar),gref(nextchar),x,y,w,h,injection or "injections")
- end
+ local snext=getnext(start)
+ if not snext then
+ return head,start,false
+ else
+ local prev=start
+ while snext do
+ local nextchar=ischar(snext,currentfont)
+ if nextchar then
+ if skiphash and skiphash[nextchar] then
+ prev=snext
+ snext=getnext(snext)
+ else
+ local krn=kerns[nextchar]
+ if not krn then
+ break
end
- if b==true then
- start=snext
- elseif b then
- local x,y,w,h=setposition(2,snext,factor,rlmode,b,injection)
+ local format=step.format
+ if format=="pair" then
+ local a=krn[1]
+ local b=krn[2]
+ if a==true then
+ elseif a then
+ local x,y,w,h=setposition(1,start,factor,rlmode,a,injection)
+ if trace_kerns then
+ local startchar=getchar(start)
+ logprocess("%s: shifting first of pair %s and %s by xy (%p,%p) and wh (%p,%p) as %s",pref(dataset,sequence),gref(startchar),gref(nextchar),x,y,w,h,injection or "injections")
+ end
+ end
+ if b==true then
+ start=snext
+ elseif b then
+ local x,y,w,h=setposition(2,snext,factor,rlmode,b,injection)
+ if trace_kerns then
+ local startchar=getchar(start)
+ logprocess("%s: shifting second of pair %s and %s by xy (%p,%p) and wh (%p,%p) as %s",pref(dataset,sequence),gref(startchar),gref(nextchar),x,y,w,h,injection or "injections")
+ end
+ start=snext
+ elseif forcepairadvance then
+ start=snext
+ end
+ return head,start,true
+ elseif krn~=0 then
+ local k=(format=="move" and setmove or setkern)(snext,factor,rlmode,krn,injection)
if trace_kerns then
- local startchar=getchar(start)
- logprocess("%s: shifting second of pair %s and %s by xy (%p,%p) and wh (%p,%p) as %s",pref(dataset,sequence),gref(startchar),gref(nextchar),x,y,w,h,injection or "injections")
+ logprocess("%s: inserting %s %p between %s and %s as %s",pref(dataset,sequence),format,k,gref(getchar(prev)),gref(nextchar),injection or "injections")
end
- start=snext
- elseif forcepairadvance then
- start=snext
- end
- return head,start,true
- elseif krn~=0 then
- local k=(format=="move" and setmove or setkern)(snext,factor,rlmode,krn,injection)
- if trace_kerns then
- logprocess("%s: inserting %s %p between %s and %s as %s",pref(dataset,sequence),format,k,gref(getchar(prev)),gref(nextchar),injection or "injections")
+ return head,start,true
+ else
+ break
end
- return head,start,true
- else
- break
end
+ else
+ break
end
- else
- break
end
+ return head,start,false
end
- return head,start,false
end
end
function handlers.gpos_mark2base(head,start,dataset,sequence,markanchors,rlmode,skiphash)
@@ -22952,89 +22989,93 @@ function chainprocs.gsub_ligature(head,start,stop,dataset,sequence,currentlookup
return head,start,false,0,false
end
function chainprocs.gpos_single(head,start,stop,dataset,sequence,currentlookup,rlmode,skiphash,chainindex)
- local mapping=currentlookup.mapping
- if mapping==nil then
- mapping=getmapping(dataset,sequence,currentlookup)
- end
- if mapping then
- local startchar=getchar(start)
- local kerns=mapping[startchar]
- if kerns then
- local format=currentlookup.format
- if format=="single" then
- local dx,dy,w,h=setposition(0,start,factor,rlmode,kerns)
- if trace_kerns then
- logprocess("%s: shifting single %s by %s (%p,%p) and correction (%p,%p)",cref(dataset,sequence),gref(startchar),format,dx,dy,w,h)
- end
- else
- local k=(format=="move" and setmove or setkern)(start,factor,rlmode,kerns,injection)
- if trace_kerns then
- logprocess("%s: shifting single %s by %s %p",cref(dataset,sequence),gref(startchar),format,k)
+ if not has_glyph_option(start,no_right_kern_code) then
+ local mapping=currentlookup.mapping
+ if mapping==nil then
+ mapping=getmapping(dataset,sequence,currentlookup)
+ end
+ if mapping then
+ local startchar=getchar(start)
+ local kerns=mapping[startchar]
+ if kerns then
+ local format=currentlookup.format
+ if format=="single" then
+ local dx,dy,w,h=setposition(0,start,factor,rlmode,kerns)
+ if trace_kerns then
+ logprocess("%s: shifting single %s by %s (%p,%p) and correction (%p,%p)",cref(dataset,sequence),gref(startchar),format,dx,dy,w,h)
+ end
+ else
+ local k=(format=="move" and setmove or setkern)(start,factor,rlmode,kerns,injection)
+ if trace_kerns then
+ logprocess("%s: shifting single %s by %s %p",cref(dataset,sequence),gref(startchar),format,k)
+ end
end
+ return head,start,true
end
- return head,start,true
end
end
return head,start,false
end
-function chainprocs.gpos_pair(head,start,stop,dataset,sequence,currentlookup,rlmode,skiphash,chainindex)
- local mapping=currentlookup.mapping
- if mapping==nil then
- mapping=getmapping(dataset,sequence,currentlookup)
- end
- if mapping then
- local snext=getnext(start)
- if snext then
- local startchar=getchar(start)
- local kerns=mapping[startchar]
- if kerns then
- local prev=start
- while snext do
- local nextchar=ischar(snext,currentfont)
- if not nextchar then
- break
- end
- if skiphash and skiphash[nextchar] then
- prev=snext
- snext=getnext(snext)
- else
- local krn=kerns[nextchar]
- if not krn then
+function chainprocs.gpos_pair(head,start,stop,dataset,sequence,currentlookup,rlmode,skiphash,chainindex)
+ if not has_glyph_option(start,no_right_kern_code) then
+ local mapping=currentlookup.mapping
+ if mapping==nil then
+ mapping=getmapping(dataset,sequence,currentlookup)
+ end
+ if mapping then
+ local snext=getnext(start)
+ if snext then
+ local startchar=getchar(start)
+ local kerns=mapping[startchar]
+ if kerns then
+ local prev=start
+ while snext do
+ local nextchar=ischar(snext,currentfont)
+ if not nextchar then
break
end
- local format=currentlookup.format
- if format=="pair" then
- local a=krn[1]
- local b=krn[2]
- if a==true then
- elseif a then
- local x,y,w,h=setposition(1,start,factor,rlmode,a,"injections")
- if trace_kerns then
- local startchar=getchar(start)
- logprocess("%s: shifting first of pair %s and %s by (%p,%p) and correction (%p,%p)",cref(dataset,sequence),gref(startchar),gref(nextchar),x,y,w,h)
- end
+ if skiphash and skiphash[nextchar] then
+ prev=snext
+ snext=getnext(snext)
+ else
+ local krn=kerns[nextchar]
+ if not krn then
+ break
end
- if b==true then
- start=snext
- elseif b then
- local x,y,w,h=setposition(2,snext,factor,rlmode,b,"injections")
+ local format=currentlookup.format
+ if format=="pair" then
+ local a=krn[1]
+ local b=krn[2]
+ if a==true then
+ elseif a then
+ local x,y,w,h=setposition(1,start,factor,rlmode,a,"injections")
+ if trace_kerns then
+ local startchar=getchar(start)
+ logprocess("%s: shifting first of pair %s and %s by (%p,%p) and correction (%p,%p)",cref(dataset,sequence),gref(startchar),gref(nextchar),x,y,w,h)
+ end
+ end
+ if b==true then
+ start=snext
+ elseif b then
+ local x,y,w,h=setposition(2,snext,factor,rlmode,b,"injections")
+ if trace_kerns then
+ local startchar=getchar(start)
+ logprocess("%s: shifting second of pair %s and %s by (%p,%p) and correction (%p,%p)",cref(dataset,sequence),gref(startchar),gref(nextchar),x,y,w,h)
+ end
+ start=snext
+ elseif forcepairadvance then
+ start=snext
+ end
+ return head,start,true
+ elseif krn~=0 then
+ local k=(format=="move" and setmove or setkern)(snext,factor,rlmode,krn)
if trace_kerns then
- local startchar=getchar(start)
- logprocess("%s: shifting second of pair %s and %s by (%p,%p) and correction (%p,%p)",cref(dataset,sequence),gref(startchar),gref(nextchar),x,y,w,h)
+ logprocess("%s: inserting %s %p between %s and %s",cref(dataset,sequence),format,k,gref(getchar(prev)),gref(nextchar))
end
- start=snext
- elseif forcepairadvance then
- start=snext
- end
- return head,start,true
- elseif krn~=0 then
- local k=(format=="move" and setmove or setkern)(snext,factor,rlmode,krn)
- if trace_kerns then
- logprocess("%s: inserting %s %p between %s and %s",cref(dataset,sequence),format,k,gref(getchar(prev)),gref(nextchar))
+ return head,start,true
+ else
+ break
end
- return head,start,true
- else
- break
end
end
end
@@ -24856,7 +24897,7 @@ do
checkstep(head)
end
local initialrl=0
- if getid(head)==localpar_code and start_of_par(head) then
+ if getid(head)==par_code and start_of_par(head) then
initialrl=pardirstate(head)
elseif direction==righttoleft_code then
initialrl=-1
@@ -25401,10 +25442,10 @@ registerotffeature {
},
}
-end --- [luaotfload, fontloader-2020-08-31.lua scope for “font-ots”] ---
+end --- [luaotfload, fontloader-2020-12-30.lua scope for “font-ots”] ---
-do --- [luaotfload, fontloader-2020-08-31.lua scope for “font-osd” 61f05fcf91add1aa5dac9bc8b235adc9] ---
+do --- [luaotfload, fontloader-2020-12-30.lua scope for “font-osd” 73c9531c79df5ada320cb20777f7ed49] ---
if not modules then modules={} end modules ['font-osd']={
version=1.001,
@@ -27837,10 +27878,10 @@ for i=1,nofscripts do
methods[scripts_two[i]]=method_two
end
-end --- [luaotfload, fontloader-2020-08-31.lua scope for “font-osd”] ---
+end --- [luaotfload, fontloader-2020-12-30.lua scope for “font-osd”] ---
-do --- [luaotfload, fontloader-2020-08-31.lua scope for “font-ocl” ab81576f20e2d37bc8707e1dbd3decf2] ---
+do --- [luaotfload, fontloader-2020-12-30.lua scope for “font-ocl” 797b5c71bf819c5f4fb314a4d646e9a7] ---
if not modules then modules={} end modules ['font-ocl']={
version=1.001,
@@ -28383,10 +28424,10 @@ if context then
}
end
-end --- [luaotfload, fontloader-2020-08-31.lua scope for “font-ocl”] ---
+end --- [luaotfload, fontloader-2020-12-30.lua scope for “font-ocl”] ---
-do --- [luaotfload, fontloader-2020-08-31.lua scope for “font-otc” 1204a2fdc436e644127c0aa38ab69607] ---
+do --- [luaotfload, fontloader-2020-12-30.lua scope for “font-otc” 0f12230ea07b5151f75d52726977e91f] ---
if not modules then modules={} end modules ['font-otc']={
version=1.001,
@@ -29143,10 +29184,10 @@ end
otf.enhancers.enhance=enhance
otf.enhancers.register("check extra features",enhance)
-end --- [luaotfload, fontloader-2020-08-31.lua scope for “font-otc”] ---
+end --- [luaotfload, fontloader-2020-12-30.lua scope for “font-otc”] ---
-do --- [luaotfload, fontloader-2020-08-31.lua scope for “font-onr” 7a9ece7bf3e36b5f0adf295a9a2a2989] ---
+do --- [luaotfload, fontloader-2020-12-30.lua scope for “font-onr” 6d161533f3437435e12a0ad64866df44] ---
if not modules then modules={} end modules ['font-onr']={
version=1.001,
@@ -29519,10 +29560,10 @@ function readers.getinfo(filename)
end
end
-end --- [luaotfload, fontloader-2020-08-31.lua scope for “font-onr”] ---
+end --- [luaotfload, fontloader-2020-12-30.lua scope for “font-onr”] ---
-do --- [luaotfload, fontloader-2020-08-31.lua scope for “font-one” 1402ae8e4e96186c848fa2742388fb24] ---
+do --- [luaotfload, fontloader-2020-12-30.lua scope for “font-one” 53cd565030e919da984b50471cc3be37] ---
if not modules then modules={} end modules ['font-one']={
version=1.001,
@@ -30021,7 +30062,6 @@ local function copytotfm(data)
parameters.descender=abs(metadata.descender or 0)
parameters.units=1000
properties.spacer=spacer
- properties.encodingbytes=2
properties.format=fonts.formats[filename] or "type1"
properties.filename=filename
properties.fontname=fontname
@@ -30029,6 +30069,9 @@ local function copytotfm(data)
properties.psname=fullname
properties.name=filename or fullname or fontname
properties.private=properties.private or data.private or privateoffset
+if not CONTEXTLMTXMODE or CONTEXTLMTXMODE==0 then
+ properties.encodingbytes=2
+end
if next(characters) then
return {
characters=characters,
@@ -30234,10 +30277,10 @@ registerafmenhancer("normalize features",enhance_normalize_features)
registerafmenhancer("check extra features",otfenhancers.enhance)
registerafmenhancer("fix names",enhance_fix_names)
-end --- [luaotfload, fontloader-2020-08-31.lua scope for “font-one”] ---
+end --- [luaotfload, fontloader-2020-12-30.lua scope for “font-one”] ---
-do --- [luaotfload, fontloader-2020-08-31.lua scope for “font-afk” 54d554530e75c57c56ee76234724e26d] ---
+do --- [luaotfload, fontloader-2020-12-30.lua scope for “font-afk” 9da14e0fb22129c053acc599d1312544] ---
if not modules then modules={} end modules ['font-afk']={
version=1.001,
@@ -30404,10 +30447,10 @@ fonts.handlers.afm.helpdata={
}
}
-end --- [luaotfload, fontloader-2020-08-31.lua scope for “font-afk”] ---
+end --- [luaotfload, fontloader-2020-12-30.lua scope for “font-afk”] ---
-do --- [luaotfload, fontloader-2020-08-31.lua scope for “fonts-tfm” 3bbba3214fd0b8c6f35ad85592fc2917] ---
+do --- [luaotfload, fontloader-2020-12-30.lua scope for “fonts-tfm” f0eb5e2a8068b17ad401bb7efdba1630] ---
if not modules then modules={} end modules ['luatex-fonts-tfm']={
version=1.001,
@@ -30922,10 +30965,10 @@ registertfmfeature {
}
}
-end --- [luaotfload, fontloader-2020-08-31.lua scope for “fonts-tfm”] ---
+end --- [luaotfload, fontloader-2020-12-30.lua scope for “fonts-tfm”] ---
-do --- [luaotfload, fontloader-2020-08-31.lua scope for “font-lua” 55b281fb98f7bd848fc19928f376f647] ---
+do --- [luaotfload, fontloader-2020-12-30.lua scope for “font-lua” 1fbfdf7b689b2bdfd0e3bb9bf74ce136] ---
if not modules then modules={} end modules ['font-lua']={
version=1.001,
@@ -30965,10 +31008,10 @@ function readers.lua(specification)
return check_lua(specification,fullname)
end
-end --- [luaotfload, fontloader-2020-08-31.lua scope for “font-lua”] ---
+end --- [luaotfload, fontloader-2020-12-30.lua scope for “font-lua”] ---
-do --- [luaotfload, fontloader-2020-08-31.lua scope for “font-def” 226b4d26ede7fa7be8e45b7f0d93e781] ---
+do --- [luaotfload, fontloader-2020-12-30.lua scope for “font-def” b9d908c2338b7dc443ce9d1e9fcb7139] ---
if not modules then modules={} end modules ['font-def']={
version=1.001,
@@ -31368,10 +31411,10 @@ if not context then
callbacks.register('define_font',definers.read,"definition of fonts (tfmdata preparation)")
end
-end --- [luaotfload, fontloader-2020-08-31.lua scope for “font-def”] ---
+end --- [luaotfload, fontloader-2020-12-30.lua scope for “font-def”] ---
-do --- [luaotfload, fontloader-2020-08-31.lua scope for “font-shp” c4a8c14513597ce3579d3ad4c580fe51] ---
+do --- [luaotfload, fontloader-2020-12-30.lua scope for “font-shp” 5ff497c993112d4fef4c148348d964eb] ---
if not modules then modules={} end modules ['font-shp']={
version=1.001,
@@ -31382,7 +31425,7 @@ if not modules then modules={} end modules ['font-shp']={
}
local tonumber,next=tonumber,next
local concat=table.concat
-local formatters=string.formatters
+local formatters,lower=string.formatters,string.lower
local otf=fonts.handlers.otf
local afm=fonts.handlers.afm
local pfb=fonts.handlers.pfb
@@ -31575,7 +31618,7 @@ end
local function loadstreams(cache,filename,sub,instance)
local base=file.basename(filename)
local name=file.removesuffix(base)
- local kind=file.suffix(filename)
+ local kind=lower(file.suffix(filename))
local attr=lfs.attributes(filename)
local size=attr and attr.size or 0
local time=attr and attr.modification or 0
@@ -31736,10 +31779,10 @@ callback.register("glyph_stream_provider",function(id,index,mode)
return ""
end)
-end --- [luaotfload, fontloader-2020-08-31.lua scope for “font-shp”] ---
+end --- [luaotfload, fontloader-2020-12-30.lua scope for “font-shp”] ---
-do --- [luaotfload, fontloader-2020-08-31.lua scope for “fonts-def” 5ad79120ebc5e60f4d322fb3ee13bffe] ---
+do --- [luaotfload, fontloader-2020-12-30.lua scope for “fonts-def” f435e0875f203f343157baeff876ec9c] ---
if not modules then modules={} end modules ['luatex-fonts-def']={
version=1.001,
@@ -31820,10 +31863,10 @@ function fonts.definers.applypostprocessors(tfmdata)
return tfmdata
end
-end --- [luaotfload, fontloader-2020-08-31.lua scope for “fonts-def”] ---
+end --- [luaotfload, fontloader-2020-12-30.lua scope for “fonts-def”] ---
-do --- [luaotfload, fontloader-2020-08-31.lua scope for “fonts-ext” 01015ab3758cdc2af29394e6d502a91a] ---
+do --- [luaotfload, fontloader-2020-12-30.lua scope for “fonts-ext” 32013cbc5d5d336be8b1d1e5879d86c4] ---
if not modules then modules={} end modules ['luatex-fonts-ext']={
version=1.001,
@@ -32009,10 +32052,10 @@ registerotffeature {
}
}
-end --- [luaotfload, fontloader-2020-08-31.lua scope for “fonts-ext”] ---
+end --- [luaotfload, fontloader-2020-12-30.lua scope for “fonts-ext”] ---
-do --- [luaotfload, fontloader-2020-08-31.lua scope for “font-imp-tex” 77c374b0ef00c2fb12188ec42beb4257] ---
+do --- [luaotfload, fontloader-2020-12-30.lua scope for “font-imp-tex” ceb087ef6fa2f89aed7179f60ddf8f35] ---
if not modules then modules={} end modules ['font-imp-tex']={
version=1.001,
@@ -32111,10 +32154,10 @@ registerotffeature {
description="arabic digits",
}
-end --- [luaotfload, fontloader-2020-08-31.lua scope for “font-imp-tex”] ---
+end --- [luaotfload, fontloader-2020-12-30.lua scope for “font-imp-tex”] ---
-do --- [luaotfload, fontloader-2020-08-31.lua scope for “font-imp-ligatures” 043daa4fcccf2560868da359d71d3a4a] ---
+do --- [luaotfload, fontloader-2020-12-30.lua scope for “font-imp-ligatures” 26ffcf089391445f7af59536c8814364] ---
if not modules then modules={} end modules ['font-imp-ligatures']={
version=1.001,
@@ -32228,10 +32271,10 @@ if context then
}
end
-end --- [luaotfload, fontloader-2020-08-31.lua scope for “font-imp-ligatures”] ---
+end --- [luaotfload, fontloader-2020-12-30.lua scope for “font-imp-ligatures”] ---
-do --- [luaotfload, fontloader-2020-08-31.lua scope for “font-imp-italics” 058fb834c11c6ac30c280b29e496966e] ---
+do --- [luaotfload, fontloader-2020-12-30.lua scope for “font-imp-italics” ae563638fa29a4ff3e8e4d1e81fd35ae] ---
if not modules then modules={} end modules ['font-imp-italics']={
version=1.001,
@@ -32335,10 +32378,10 @@ if context then
registerafmfeature(dimensions_specification)
end
-end --- [luaotfload, fontloader-2020-08-31.lua scope for “font-imp-italics”] ---
+end --- [luaotfload, fontloader-2020-12-30.lua scope for “font-imp-italics”] ---
-do --- [luaotfload, fontloader-2020-08-31.lua scope for “font-imp-effects” 582f9dd5031e9d67fff389efd16a874f] ---
+do --- [luaotfload, fontloader-2020-12-30.lua scope for “font-imp-effects” a2dde5e071fcb3fc7b90f2bcd5aa4f22] ---
if not modules then modules={} end modules ['font-imp-effects']={
version=1.001,
@@ -32522,56 +32565,74 @@ local rules={
"FractionRuleThickness",
"UnderbarRuleThickness",
}
-local function setmathparameters(tfmdata,characters,mathparameters,dx,dy,squeeze)
- if delta~=0 then
- for i=1,#rules do
- local name=rules[i]
- local value=mathparameters[name]
- if value then
- mathparameters[name]=(squeeze or 1)*(value+dx)
+local setmathparameters
+local setmathcharacters
+if CONTEXTLMTXMODE and CONTEXTLMTXMODE>0 then
+ setmathparameters=function(tfmdata,characters,mathparameters,dx,dy,squeeze,multiplier)
+ if delta~=0 then
+ for i=1,#rules do
+ local name=rules[i]
+ local value=mathparameters[name]
+ if value then
+ mathparameters[name]=(squeeze or 1)*(value+dy)
+ end
end
end
end
-end
-local function setmathcharacters(tfmdata,characters,mathparameters,dx,dy,squeeze,wdelta,hdelta,ddelta)
- local function wdpatch(char)
- if wsnap~=0 then
- char.width=char.width+wdelta/2
- end
+ setmathcharacters=function()
end
- local function htpatch(char)
- if hsnap~=0 then
- local height=char.height
- if height then
- char.height=char.height+2*dy
+else
+ setmathparameters=function(tfmdata,characters,mathparameters,dx,dy,squeeze,multiplier)
+ if delta~=0 then
+ for i=1,#rules do
+ local name=rules[i]
+ local value=mathparameters[name]
+ if value then
+ mathparameters[name]=(squeeze or 1)*(value+dy)
+ end
end
end
end
- local character=characters[0x221A]
- if character and character.next then
- local char=character
- local next=character.next
- wdpatch(char)
- htpatch(char)
- while next do
- char=characters[next]
+ setmathcharacters=function(tfmdata,characters,mathparameters,dx,dy,squeeze,wdelta,hdelta,ddelta)
+ local function wdpatch(char)
+ if wsnap~=0 then
+ char.width=char.width+wdelta/2
+ end
+ end
+ local function htpatch(char)
+ if hsnap~=0 then
+ local height=char.height
+ if height then
+ char.height=char.height+2*dy
+ end
+ end
+ end
+ local character=characters[0x221A]
+ if character and character.next then
+ local char=character
+ local next=character.next
wdpatch(char)
htpatch(char)
- next=char.next
- end
- if char then
- local v=char.vert_variants
- if v then
- local top=v[#v]
- if top then
- local char=characters[top.glyph]
- htpatch(char)
+ while next do
+ char=characters[next]
+ wdpatch(char)
+ htpatch(char)
+ next=char.next
+ end
+ if char then
+ local v=char.vert_variants
+ if v then
+ local top=v[#v]
+ if top then
+ local char=characters[top.glyph]
+ htpatch(char)
+ end
end
end
end
end
end
-local shiftmode=CONTEXTLMTXMODE>0
+local shiftmode=CONTEXTLMTXMODE and CONTEXTLMTXMODE>0
local function manipulateeffect(tfmdata)
local effect=tfmdata.properties.effect
if effect then
@@ -32643,7 +32704,7 @@ local function manipulateeffect(tfmdata)
end
end
if mathparameters then
- setmathparameters(tfmdata,characters,mathparameters,dx,dy,squeeze)
+ setmathparameters(tfmdata,characters,mathparameters,dx,dy,squeeze,multiplier)
setmathcharacters(tfmdata,characters,mathparameters,dx,dy,squeeze,wdelta,hdelta,ddelta)
end
parameters.factor=factor
@@ -32703,10 +32764,10 @@ local specification={
registerotffeature(specification)
registerafmfeature(specification)
-end --- [luaotfload, fontloader-2020-08-31.lua scope for “font-imp-effects”] ---
+end --- [luaotfload, fontloader-2020-12-30.lua scope for “font-imp-effects”] ---
-do --- [luaotfload, fontloader-2020-08-31.lua scope for “fonts-lig” b9dbe77ce747d4c35bb2a20ffbe5aa51] ---
+do --- [luaotfload, fontloader-2020-12-30.lua scope for “fonts-lig” fbd251eea3810a43a8d5542319361d68] ---
fonts.handlers.otf.addfeature {
@@ -34775,10 +34836,10 @@ fonts.handlers.otf.addfeature {
["type"]="ligature",
}
-end --- [luaotfload, fontloader-2020-08-31.lua scope for “fonts-lig”] ---
+end --- [luaotfload, fontloader-2020-12-30.lua scope for “fonts-lig”] ---
-do --- [luaotfload, fontloader-2020-08-31.lua scope for “fonts-gbn” d25472d54c4841db43a745764a63533e] ---
+do --- [luaotfload, fontloader-2020-12-30.lua scope for “fonts-gbn” 10ecdf01e7c926e5128ad8a9dff4d677] ---
if not modules then modules={} end modules ['luatex-fonts-gbn']={
version=1.001,
@@ -35043,7 +35104,7 @@ function nodes.simple_font_handler(head,groupcode,size,packtype,direction)
return head
end
-end --- [luaotfload, fontloader-2020-08-31.lua scope for “fonts-gbn”] ---
+end --- [luaotfload, fontloader-2020-12-30.lua scope for “fonts-gbn”] ---
--- vim:ft=lua:sw=2:ts=8:et:tw=79
diff --git a/macros/luatex/generic/luaotfload/fontloader-basics-nod.lua b/macros/luatex/generic/luaotfload/fontloader-basics-nod.lua
index 67abf707b1..25f5473a5a 100644
--- a/macros/luatex/generic/luaotfload/fontloader-basics-nod.lua
+++ b/macros/luatex/generic/luaotfload/fontloader-basics-nod.lua
@@ -107,6 +107,7 @@ nuts.getkern = direct.getkern
nuts.getlist = direct.getlist
nuts.getnext = direct.getnext
nuts.getoffsets = direct.getoffsets
+nuts.getoptions = direct.getoptions or function() return 0 end
nuts.getprev = direct.getprev
nuts.getsubtype = direct.getsubtype
nuts.getwidth = direct.getwidth
@@ -206,6 +207,19 @@ local copy_node = nuts.copy_node
local glyph_code = nodes.nodecodes.glyph
local ligature_code = nodes.glyphcodes.ligature
+do -- this is consistent with the rest of context, not that we need it
+
+ local p = nodecodes.localpar or nodecodes.local_par
+
+ if p then
+ nodecodes.par = p
+ nodecodes[p] = "par"
+ nodecodes.localpar = p -- for old times sake
+ nodecodes.local_par = p -- for old times sake
+ end
+
+end
+
do
local get_components = node.direct.getcomponents
@@ -264,11 +278,16 @@ do
return 0
end
+ local function flush_components()
+ -- this is a no-op in mkiv / generic
+ end
+
nuts.set_components = set_components
nuts.get_components = get_components
nuts.copy_only_glyphs = copy_only_glyphs
nuts.copy_no_components = copy_no_components
nuts.count_components = count_components
+ nuts.flush_components = flush_components
end
diff --git a/macros/luatex/generic/luaotfload/fontloader-font-dsp.lua b/macros/luatex/generic/luaotfload/fontloader-font-dsp.lua
index 0cff896e8d..91ee83b19b 100644
--- a/macros/luatex/generic/luaotfload/fontloader-font-dsp.lua
+++ b/macros/luatex/generic/luaotfload/fontloader-font-dsp.lua
@@ -823,7 +823,7 @@ end
-- quite often 0, 1, 2
-function readarray(f,offset)
+local function readarray(f,offset)
if offset then
setposition(f,offset)
end
diff --git a/macros/luatex/generic/luaotfload/fontloader-font-imp-effects.lua b/macros/luatex/generic/luaotfload/fontloader-font-imp-effects.lua
index bd6cce8795..43ce82b71a 100644
--- a/macros/luatex/generic/luaotfload/fontloader-font-imp-effects.lua
+++ b/macros/luatex/generic/luaotfload/fontloader-font-imp-effects.lua
@@ -215,62 +215,88 @@ local rules = {
-- end
-- end
-local function setmathparameters(tfmdata,characters,mathparameters,dx,dy,squeeze)
- if delta ~= 0 then
- for i=1,#rules do
- local name = rules[i]
- local value = mathparameters[name]
- if value then
- mathparameters[name] = (squeeze or 1) * (value + dx)
+-- radicals are not yet ok
+
+local setmathparameters
+local setmathcharacters
+
+if CONTEXTLMTXMODE and CONTEXTLMTXMODE > 0 then
+
+ setmathparameters = function(tfmdata,characters,mathparameters,dx,dy,squeeze,multiplier)
+ if delta ~= 0 then
+ for i=1,#rules do
+ local name = rules[i]
+ local value = mathparameters[name]
+ if value then
+ mathparameters[name] = (squeeze or 1) * (value + dy)
+ end
end
end
end
-end
-local function setmathcharacters(tfmdata,characters,mathparameters,dx,dy,squeeze,wdelta,hdelta,ddelta)
+ setmathcharacters = function()
+ end
- local function wdpatch(char)
- if wsnap ~= 0 then
- char.width = char.width + wdelta/2
+else
+
+ setmathparameters = function(tfmdata,characters,mathparameters,dx,dy,squeeze,multiplier)
+ if delta ~= 0 then
+ for i=1,#rules do
+ local name = rules[i]
+ local value = mathparameters[name]
+ if value then
+ mathparameters[name] = (squeeze or 1) * (value + dy)
+ end
+ end
end
end
- local function htpatch(char)
- if hsnap ~= 0 then
- local height = char.height
- if height then
- char.height = char.height + 2 * dy
+ setmathcharacters = function(tfmdata,characters,mathparameters,dx,dy,squeeze,wdelta,hdelta,ddelta)
+
+ -- still not the perfect rule
+
+ local function wdpatch(char)
+ if wsnap ~= 0 then
+ char.width = char.width + wdelta/2
+ end
+ end
+
+ local function htpatch(char)
+ if hsnap ~= 0 then
+ local height = char.height
+ if height then
+ char.height = char.height + 2 * dy
+ end
end
end
- end
- local character = characters[0x221A]
+ local character = characters[0x221A]
- if character and character.next then
--- print("base char",0x221A,table.sequenced(character))
- local char = character
- local next = character.next
- wdpatch(char)
- htpatch(char)
- while next do
- char = characters[next]
+ if character and character.next then
+ local char = character
+ local next = character.next
wdpatch(char)
htpatch(char)
--- print("next char",next,table.sequenced(char))
- next = char.next
- end
- if char then
- local v = char.vert_variants
- if v then
- local top = v[#v]
- if top then
- local char = characters[top.glyph]
--- print("top char",top.glyph,table.sequenced(char))
- htpatch(char)
+ while next do
+ char = characters[next]
+ wdpatch(char)
+ htpatch(char)
+ next = char.next
+ end
+ if char then
+ local v = char.vert_variants
+ if v then
+ local top = v[#v]
+ if top then
+ local char = characters[top.glyph]
+ htpatch(char)
+ end
end
end
end
+
end
+
end
-- local show_effect = { "lua", function(f,c)
@@ -278,10 +304,7 @@ end
-- inspect(fonts.hashes.characters[f][c])
-- end }
--- local show_effect = { "lua", "print('!')" }
-
------ shiftmode = false -- test in mkiv and lmtx
-local shiftmode = CONTEXTLMTXMODE > 0
+local shiftmode = CONTEXTLMTXMODE and CONTEXTLMTXMODE > 0
local function manipulateeffect(tfmdata)
local effect = tfmdata.properties.effect
@@ -358,7 +381,7 @@ local function manipulateeffect(tfmdata)
end
end
if mathparameters then
- setmathparameters(tfmdata,characters,mathparameters,dx,dy,squeeze)
+ setmathparameters(tfmdata,characters,mathparameters,dx,dy,squeeze,multiplier)
setmathcharacters(tfmdata,characters,mathparameters,dx,dy,squeeze,wdelta,hdelta,ddelta)
end
parameters.factor = factor
diff --git a/macros/luatex/generic/luaotfload/fontloader-font-one.lua b/macros/luatex/generic/luaotfload/fontloader-font-one.lua
index a76c929859..5ef6e47497 100644
--- a/macros/luatex/generic/luaotfload/fontloader-font-one.lua
+++ b/macros/luatex/generic/luaotfload/fontloader-font-one.lua
@@ -592,15 +592,18 @@ local function copytotfm(data)
parameters.descender = abs(metadata.descender or 0)
parameters.units = 1000
--
- properties.spacer = spacer
+ properties.spacer = spacer
+ properties.format = fonts.formats[filename] or "type1"
+ properties.filename = filename
+ properties.fontname = fontname
+ properties.fullname = fullname
+ properties.psname = fullname
+ properties.name = filename or fullname or fontname
+ properties.private = properties.private or data.private or privateoffset
+ --
+if not CONTEXTLMTXMODE or CONTEXTLMTXMODE == 0 then
properties.encodingbytes = 2
- properties.format = fonts.formats[filename] or "type1"
- properties.filename = filename
- properties.fontname = fontname
- properties.fullname = fullname
- properties.psname = fullname
- properties.name = filename or fullname or fontname
- properties.private = properties.private or data.private or privateoffset
+end
--
if next(characters) then
return {
diff --git a/macros/luatex/generic/luaotfload/fontloader-font-otl.lua b/macros/luatex/generic/luaotfload/fontloader-font-otl.lua
index aff4cc8c8d..b8e13f1070 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.111 -- beware: also sync font-mis.lua and in mtx-fonts
+otf.version = 3.112 -- beware: also sync font-mis.lua and in mtx-fonts
otf.cache = containers.define("fonts", "otl", otf.version, true)
otf.svgcache = containers.define("fonts", "svg", otf.version, true)
otf.pngcache = containers.define("fonts", "png", otf.version, true)
@@ -486,23 +486,26 @@ local function copytotfm(data,cache_id)
end
end
--
- parameters.designsize = (designsize/10)*65536
- parameters.minsize = (minsize /10)*65536
- parameters.maxsize = (maxsize /10)*65536
- parameters.ascender = abs(metadata.ascender or 0)
- parameters.descender = abs(metadata.descender or 0)
- parameters.units = units
- parameters.vheight = metadata.defaultvheight
+ parameters.designsize = (designsize/10)*65536
+ parameters.minsize = (minsize /10)*65536
+ parameters.maxsize = (maxsize /10)*65536
+ parameters.ascender = abs(metadata.ascender or 0)
+ parameters.descender = abs(metadata.descender or 0)
+ parameters.units = units
+ parameters.vheight = metadata.defaultvheight
--
- properties.space = spacer
+ properties.space = spacer
+ properties.format = data.format or formats.otf
+ properties.filename = filename
+ properties.fontname = fontname
+ properties.fullname = fullname
+ properties.psname = psname
+ properties.name = filename or fullname
+ properties.subfont = subfont
+ --
+if not CONTEXTLMTXMODE or CONTEXTLMTXMODE == 0 then
properties.encodingbytes = 2
- properties.format = data.format or formats.otf
- properties.filename = filename
- properties.fontname = fontname
- properties.fullname = fullname
- properties.psname = psname
- properties.name = filename or fullname
- properties.subfont = subfont
+end
--
-- properties.name = specification.name
-- properties.sub = specification.sub
diff --git a/macros/luatex/generic/luaotfload/fontloader-font-ots.lua b/macros/luatex/generic/luaotfload/fontloader-font-ots.lua
index 490f28de69..1f4806ee25 100644
--- a/macros/luatex/generic/luaotfload/fontloader-font-ots.lua
+++ b/macros/luatex/generic/luaotfload/fontloader-font-ots.lua
@@ -13,7 +13,7 @@ with plain <l n='tex'/> it has to be so. This module is part of <l n='context'/>
and discussion about improvements and functionality mostly happens on the
<l n='context'/> mailing list.</p>
-<p>The specification of OpenType is (or at least a decade ago was) kind of vague.
+<p>The specification of OpenType is (or at least decades ago was) kind of vague.
Apart from a lack of a proper free specifications there's also the problem that
Microsoft and Adobe may have their own interpretation of how and in what order to
apply features. In general the Microsoft website has more detailed specifications
@@ -218,6 +218,7 @@ local copy_only_glyphs = nuts.copy_only_glyphs
local count_components = nuts.count_components
local set_components = nuts.set_components
local get_components = nuts.get_components
+local flush_components = nuts.flush_components
---------------------------------------------------------------------------------------
@@ -251,7 +252,7 @@ local glue_code = nodecodes.glue
local disc_code = nodecodes.disc
local math_code = nodecodes.math
local dir_code = nodecodes.dir
-local localpar_code = nodecodes.localpar
+local par_code = nodecodes.par
local lefttoright_code = nodes.dirvalues.lefttoright
local righttoleft_code = nodes.dirvalues.righttoleft
@@ -488,6 +489,7 @@ local function markstoligature(head,start,stop,char)
setsubtype(base,ligatureglyph_code)
set_components(base,start)
setlink(prev,base,next)
+ flush_components(start)
return head, base
end
end
@@ -500,9 +502,25 @@ end
-- in the not discfound branch then. We now have skiphash too so we can be more
-- selective if needed (todo).
+-- we can have more granularity here but for now we only do a simple check
+
+local no_left_ligature_code = 1
+local no_right_ligature_code = 2
+local no_left_kern_code = 4
+local no_right_kern_code = 8
+
+local has_glyph_option = node.direct.has_glyph_option or function(n,c)
+ if c == no_left_ligature_code or c == no_right_ligature_code then
+ return getattr(n,a_noligature) == 1
+ else
+ return false
+ end
+end
+
+-- in lmtx we need to check the components and can be slightly more clever
+
local function toligature(head,start,stop,char,dataset,sequence,skiphash,discfound,hasmarks) -- brr head
- if getattr(start,a_noligature) == 1 then
- -- so we can do: e\noligature{ff}e e\noligature{f}fie (we only look at the first)
+ if has_glyph_option(start,no_right_ligature_code) then
return head, start
end
if start == stop and getchar(start) == char then
@@ -572,6 +590,7 @@ local function toligature(head,start,stop,char,dataset,sequence,skiphash,discfou
break
end
end
+ flush_components(components)
else
-- discfound ... forget about marks .. probably no scripts that hyphenate and have marks
local discprev, discnext = getboth(discfound)
@@ -902,81 +921,89 @@ function handlers.gsub_ligature(head,start,dataset,sequence,ligature,rlmode,skip
end
function handlers.gpos_single(head,start,dataset,sequence,kerns,rlmode,skiphash,step,injection)
- local startchar = getchar(start)
- local format = step.format
- if format == "single" or type(kerns) == "table" then -- the table check can go
- local dx, dy, w, h = setposition(0,start,factor,rlmode,kerns,injection)
- if trace_kerns then
- logprocess("%s: shifting single %s by %s xy (%p,%p) and wh (%p,%p)",pref(dataset,sequence),gref(startchar),format,dx,dy,w,h)
- end
+ if has_glyph_option(start,no_right_kern_code) then
+ return head, start, false
else
- local k = (format == "move" and setmove or setkern)(start,factor,rlmode,kerns,injection)
- if trace_kerns then
- logprocess("%s: shifting single %s by %s %p",pref(dataset,sequence),gref(startchar),format,k)
+ local startchar = getchar(start)
+ local format = step.format
+ if format == "single" or type(kerns) == "table" then -- the table check can go
+ local dx, dy, w, h = setposition(0,start,factor,rlmode,kerns,injection)
+ if trace_kerns then
+ logprocess("%s: shifting single %s by %s xy (%p,%p) and wh (%p,%p)",pref(dataset,sequence),gref(startchar),format,dx,dy,w,h)
+ end
+ else
+ local k = (format == "move" and setmove or setkern)(start,factor,rlmode,kerns,injection)
+ if trace_kerns then
+ logprocess("%s: shifting single %s by %s %p",pref(dataset,sequence),gref(startchar),format,k)
+ end
end
+ return head, start, true
end
- return head, start, true
end
function handlers.gpos_pair(head,start,dataset,sequence,kerns,rlmode,skiphash,step,injection)
- local snext = getnext(start)
- if not snext then
+ if has_glyph_option(start,no_right_kern_code) then
return head, start, false
else
- local prev = start
- while snext do
- local nextchar = ischar(snext,currentfont)
- if nextchar then
- if skiphash and skiphash[nextchar] then -- includes marks too when flag
- prev = snext
- snext = getnext(snext)
- else
- local krn = kerns[nextchar]
- if not krn then
- break
- end
- local format = step.format
- if format == "pair" then
- local a = krn[1]
- local b = krn[2]
- if a == true then
- -- zero
- elseif a then -- #a > 0
- local x, y, w, h = setposition(1,start,factor,rlmode,a,injection)
- if trace_kerns then
- local startchar = getchar(start)
- logprocess("%s: shifting first of pair %s and %s by xy (%p,%p) and wh (%p,%p) as %s",pref(dataset,sequence),gref(startchar),gref(nextchar),x,y,w,h,injection or "injections")
- end
+ local snext = getnext(start)
+ if not snext then
+ return head, start, false
+ else
+ local prev = start
+ while snext do
+ local nextchar = ischar(snext,currentfont)
+ if nextchar then
+ if skiphash and skiphash[nextchar] then -- includes marks too when flag
+ prev = snext
+ snext = getnext(snext)
+ else
+ local krn = kerns[nextchar]
+ if not krn then
+ break
end
- if b == true then
- -- zero
- start = snext -- cf spec
- elseif b then -- #b > 0
- local x, y, w, h = setposition(2,snext,factor,rlmode,b,injection)
+ local format = step.format
+ if format == "pair" then
+ local a = krn[1]
+ local b = krn[2]
+ if a == true then
+ -- zero
+ elseif a then -- #a > 0
+ local x, y, w, h = setposition(1,start,factor,rlmode,a,injection)
+ if trace_kerns then
+ local startchar = getchar(start)
+ logprocess("%s: shifting first of pair %s and %s by xy (%p,%p) and wh (%p,%p) as %s",pref(dataset,sequence),gref(startchar),gref(nextchar),x,y,w,h,injection or "injections")
+ end
+ end
+ if b == true then
+ -- zero
+ start = snext -- cf spec
+ elseif b then -- #b > 0
+ local x, y, w, h = setposition(2,snext,factor,rlmode,b,injection)
+ if trace_kerns then
+ local startchar = getchar(start)
+ logprocess("%s: shifting second of pair %s and %s by xy (%p,%p) and wh (%p,%p) as %s",pref(dataset,sequence),gref(startchar),gref(nextchar),x,y,w,h,injection or "injections")
+ end
+ start = snext -- cf spec
+ elseif forcepairadvance then
+ start = snext -- for testing, not cf spec
+ end
+ return head, start, true
+ elseif krn ~= 0 then
+ local k = (format == "move" and setmove or setkern)(snext,factor,rlmode,krn,injection)
if trace_kerns then
- local startchar = getchar(start)
- logprocess("%s: shifting second of pair %s and %s by xy (%p,%p) and wh (%p,%p) as %s",pref(dataset,sequence),gref(startchar),gref(nextchar),x,y,w,h,injection or "injections")
+ logprocess("%s: inserting %s %p between %s and %s as %s",pref(dataset,sequence),format,k,gref(getchar(prev)),gref(nextchar),injection or "injections")
end
- start = snext -- cf spec
- elseif forcepairadvance then
- start = snext -- for testing, not cf spec
- end
- return head, start, true
- elseif krn ~= 0 then
- local k = (format == "move" and setmove or setkern)(snext,factor,rlmode,krn,injection)
- if trace_kerns then
- logprocess("%s: inserting %s %p between %s and %s as %s",pref(dataset,sequence),format,k,gref(getchar(prev)),gref(nextchar),injection or "injections")
+ return head, start, true
+ else -- can't happen
+ break
end
- return head, start, true
- else -- can't happen
- break
end
+ else
+ break
end
- else
- break
end
+ return head, start, false
end
- return head, start, false
end
end
@@ -1505,92 +1532,98 @@ function chainprocs.gsub_ligature(head,start,stop,dataset,sequence,currentlookup
end
function chainprocs.gpos_single(head,start,stop,dataset,sequence,currentlookup,rlmode,skiphash,chainindex)
- local mapping = currentlookup.mapping
- if mapping == nil then
- mapping = getmapping(dataset,sequence,currentlookup)
- end
- if mapping then
- local startchar = getchar(start)
- local kerns = mapping[startchar]
- if kerns then
- local format = currentlookup.format
- if format == "single" then
- local dx, dy, w, h = setposition(0,start,factor,rlmode,kerns) -- currentlookup.flags ?
- if trace_kerns then
- logprocess("%s: shifting single %s by %s (%p,%p) and correction (%p,%p)",cref(dataset,sequence),gref(startchar),format,dx,dy,w,h)
- end
- else -- needs checking .. maybe no kerns format for single
- local k = (format == "move" and setmove or setkern)(start,factor,rlmode,kerns,injection)
- if trace_kerns then
- logprocess("%s: shifting single %s by %s %p",cref(dataset,sequence),gref(startchar),format,k)
+ -- we actually should check no_left_kern_code with next
+ if not has_glyph_option(start,no_right_kern_code) then
+ local mapping = currentlookup.mapping
+ if mapping == nil then
+ mapping = getmapping(dataset,sequence,currentlookup)
+ end
+ if mapping then
+ local startchar = getchar(start)
+ local kerns = mapping[startchar]
+ if kerns then
+ local format = currentlookup.format
+ if format == "single" then
+ local dx, dy, w, h = setposition(0,start,factor,rlmode,kerns) -- currentlookup.flags ?
+ if trace_kerns then
+ logprocess("%s: shifting single %s by %s (%p,%p) and correction (%p,%p)",cref(dataset,sequence),gref(startchar),format,dx,dy,w,h)
+ end
+ else -- needs checking .. maybe no kerns format for single
+ local k = (format == "move" and setmove or setkern)(start,factor,rlmode,kerns,injection)
+ if trace_kerns then
+ logprocess("%s: shifting single %s by %s %p",cref(dataset,sequence),gref(startchar),format,k)
+ end
end
+ return head, start, true
end
- return head, start, true
end
end
return head, start, false
end
function chainprocs.gpos_pair(head,start,stop,dataset,sequence,currentlookup,rlmode,skiphash,chainindex) -- todo: injections ?
- local mapping = currentlookup.mapping
- if mapping == nil then
- mapping = getmapping(dataset,sequence,currentlookup)
- end
- if mapping then
- local snext = getnext(start)
- if snext then
- local startchar = getchar(start)
- local kerns = mapping[startchar] -- always 1 step
- if kerns then
- local prev = start
- while snext do
- local nextchar = ischar(snext,currentfont)
- if not nextchar then
- break
- end
- if skiphash and skiphash[nextchar] then
- prev = snext
- snext = getnext(snext)
- else
- local krn = kerns[nextchar]
- if not krn then
+ -- we actually should check no_left_kern_code with next
+ if not has_glyph_option(start,no_right_kern_code) then
+ local mapping = currentlookup.mapping
+ if mapping == nil then
+ mapping = getmapping(dataset,sequence,currentlookup)
+ end
+ if mapping then
+ local snext = getnext(start)
+ if snext then
+ local startchar = getchar(start)
+ local kerns = mapping[startchar] -- always 1 step
+ if kerns then
+ local prev = start
+ while snext do
+ local nextchar = ischar(snext,currentfont)
+ if not nextchar then
break
end
- local format = currentlookup.format
- if format == "pair" then
- local a = krn[1]
- local b = krn[2]
- if a == true then
- -- zero
- elseif a then
- local x, y, w, h = setposition(1,start,factor,rlmode,a,"injections") -- currentlookups flags?
- if trace_kerns then
- local startchar = getchar(start)
- logprocess("%s: shifting first of pair %s and %s by (%p,%p) and correction (%p,%p)",cref(dataset,sequence),gref(startchar),gref(nextchar),x,y,w,h)
- end
+ if skiphash and skiphash[nextchar] then
+ prev = snext
+ snext = getnext(snext)
+ else
+ local krn = kerns[nextchar]
+ if not krn then
+ break
end
- if b == true then
- -- zero
- start = snext -- cf spec
- elseif b then -- #b > 0
- local x, y, w, h = setposition(2,snext,factor,rlmode,b,"injections")
+ local format = currentlookup.format
+ if format == "pair" then
+ local a = krn[1]
+ local b = krn[2]
+ if a == true then
+ -- zero
+ elseif a then
+ local x, y, w, h = setposition(1,start,factor,rlmode,a,"injections") -- currentlookups flags?
+ if trace_kerns then
+ local startchar = getchar(start)
+ logprocess("%s: shifting first of pair %s and %s by (%p,%p) and correction (%p,%p)",cref(dataset,sequence),gref(startchar),gref(nextchar),x,y,w,h)
+ end
+ end
+ if b == true then
+ -- zero
+ start = snext -- cf spec
+ elseif b then -- #b > 0
+ local x, y, w, h = setposition(2,snext,factor,rlmode,b,"injections")
+ if trace_kerns then
+ local startchar = getchar(start)
+ logprocess("%s: shifting second of pair %s and %s by (%p,%p) and correction (%p,%p)",cref(dataset,sequence),gref(startchar),gref(nextchar),x,y,w,h)
+ end
+ start = snext -- cf spec
+ elseif forcepairadvance then
+ start = snext -- for testing, not cf spec
+ end
+ return head, start, true
+ elseif krn ~= 0 then
+ local k = (format == "move" and setmove or setkern)(snext,factor,rlmode,krn)
if trace_kerns then
- local startchar = getchar(start)
- logprocess("%s: shifting second of pair %s and %s by (%p,%p) and correction (%p,%p)",cref(dataset,sequence),gref(startchar),gref(nextchar),x,y,w,h)
+ logprocess("%s: inserting %s %p between %s and %s",cref(dataset,sequence),format,k,gref(getchar(prev)),gref(nextchar))
end
- start = snext -- cf spec
- elseif forcepairadvance then
- start = snext -- for testing, not cf spec
- end
- return head, start, true
- elseif krn ~= 0 then
- local k = (format == "move" and setmove or setkern)(snext,factor,rlmode,krn)
- if trace_kerns then
- logprocess("%s: inserting %s %p between %s and %s",cref(dataset,sequence),format,k,gref(getchar(prev)),gref(nextchar))
+ return head, start, true
+ else
+ break
end
- return head, start, true
- else
- break
end
end
end
@@ -3759,7 +3792,7 @@ do
local initialrl = 0
- if getid(head) == localpar_code and start_of_par(head) then
+ if getid(head) == par_code and start_of_par(head) then
initialrl = pardirstate(head)
elseif direction == righttoleft_code then
initialrl = -1
@@ -3913,7 +3946,7 @@ do
elseif id == dir_code then
topstack, rlmode = txtdirstate(start,dirstack,topstack,rlparmode)
start = getnext(start)
- -- elseif id == localpar_code and start_of_par(start) then
+ -- elseif id == par_code and start_of_par(start) then
-- rlparmode, rlmode = pardirstate(start)
-- start = getnext(start)
else
@@ -3997,7 +4030,7 @@ do
elseif id == dir_code then
topstack, rlmode = txtdirstate(start,dirstack,topstack,rlparmode)
start = getnext(start)
- -- elseif id == localpar_code and start_of_par(start) then
+ -- elseif id == par_code and start_of_par(start) then
-- rlparmode, rlmode = pardirstate(start)
-- start = getnext(start)
else
@@ -4108,7 +4141,7 @@ do
elseif id == dir_code then
topstack, rlmode = txtdirstate(start,dirstack,topstack,rlparmode)
start = getnext(start)
- -- elseif id == localpar_code and start_of_par(start) then
+ -- elseif id == par_code and start_of_par(start) then
-- rlparmode, rlmode = pardirstate(start)
-- start = getnext(start)
else
diff --git a/macros/luatex/generic/luaotfload/fontloader-font-shp.lua b/macros/luatex/generic/luaotfload/fontloader-font-shp.lua
index c3fea6d460..78e8597b93 100644
--- a/macros/luatex/generic/luaotfload/fontloader-font-shp.lua
+++ b/macros/luatex/generic/luaotfload/fontloader-font-shp.lua
@@ -8,7 +8,7 @@ if not modules then modules = { } end modules ['font-shp'] = {
local tonumber, next = tonumber, next
local concat = table.concat
-local formatters = string.formatters
+local formatters, lower = string.formatters, string.lower
local otf = fonts.handlers.otf
local afm = fonts.handlers.afm
@@ -221,7 +221,7 @@ end
local function loadstreams(cache,filename,sub,instance)
local base = file.basename(filename)
local name = file.removesuffix(base)
- local kind = file.suffix(filename)
+ local kind = lower(file.suffix(filename))
local attr = lfs.attributes(filename)
local size = attr and attr.size or 0
local time = attr and attr.modification or 0
diff --git a/macros/luatex/generic/luaotfload/fontloader-font-ttf.lua b/macros/luatex/generic/luaotfload/fontloader-font-ttf.lua
index 865f8e6e30..a2732aa5f2 100644
--- a/macros/luatex/generic/luaotfload/fontloader-font-ttf.lua
+++ b/macros/luatex/generic/luaotfload/fontloader-font-ttf.lua
@@ -163,8 +163,7 @@ local function mergecomposites(glyphs,shapes)
return contours, points
end
--- for index=1,#glyphs do
- for index=0,#glyphs-1 do
+ for index=0,#glyphs do
local shape = shapes[index]
if shape then
local components = shape.components
@@ -659,7 +658,7 @@ local function repackpoints(glyphs,shapes)
local result = { } -- reused
local xpoints = { } -- reused
local ypoints = { } -- reused
- for index=0,#glyphs-1 do
+ for index=0,#glyphs do
local shape = shapes[index]
if shape then
local r = 0
diff --git a/macros/luatex/generic/luaotfload/fontloader-reference.lua b/macros/luatex/generic/luaotfload/fontloader-reference.lua
index df4f3593c2..0b220327c3 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 : 2020-08-31 22:01
+-- merge date : 2020-12-30 16:42
do -- begin closure to overcome local limits and interference
@@ -4939,6 +4939,7 @@ nuts.getkern=direct.getkern
nuts.getlist=direct.getlist
nuts.getnext=direct.getnext
nuts.getoffsets=direct.getoffsets
+nuts.getoptions=direct.getoptions or function() return 0 end
nuts.getprev=direct.getprev
nuts.getsubtype=direct.getsubtype
nuts.getwidth=direct.getwidth
@@ -5022,6 +5023,15 @@ local traverse_id=nuts.traverse_id
local copy_node=nuts.copy_node
local glyph_code=nodes.nodecodes.glyph
local ligature_code=nodes.glyphcodes.ligature
+do
+ local p=nodecodes.localpar or nodecodes.local_par
+ if p then
+ nodecodes.par=p
+ nodecodes[p]="par"
+ nodecodes.localpar=p
+ nodecodes.local_par=p
+ end
+end
do
local get_components=node.direct.getcomponents
local set_components=node.direct.setcomponents
@@ -5074,11 +5084,14 @@ do
end
return 0
end
+ local function flush_components()
+ end
nuts.set_components=set_components
nuts.get_components=get_components
nuts.copy_only_glyphs=copy_only_glyphs
nuts.copy_no_components=copy_no_components
nuts.count_components=count_components
+ nuts.flush_components=flush_components
end
nuts.uses_font=direct.uses_font
do
@@ -15147,7 +15160,7 @@ local function mergecomposites(glyphs,shapes)
shape.components=nil
return contours,points
end
- for index=0,#glyphs-1 do
+ for index=0,#glyphs do
local shape=shapes[index]
if shape then
local components=shape.components
@@ -15577,7 +15590,7 @@ local function repackpoints(glyphs,shapes)
local result={}
local xpoints={}
local ypoints={}
- for index=0,#glyphs-1 do
+ for index=0,#glyphs do
local shape=shapes[index]
if shape then
local r=0
@@ -16840,7 +16853,7 @@ local function readfirst(f,offset)
end
return { readushort(f) }
end
-function readarray(f,offset)
+local function readarray(f,offset)
if offset then
setposition(f,offset)
end
@@ -20766,7 +20779,7 @@ local trace_defining=false registertracker("fonts.defining",function(v) trace_d
local report_otf=logs.reporter("fonts","otf loading")
local fonts=fonts
local otf=fonts.handlers.otf
-otf.version=3.111
+otf.version=3.112
otf.cache=containers.define("fonts","otl",otf.version,true)
otf.svgcache=containers.define("fonts","svg",otf.version,true)
otf.pngcache=containers.define("fonts","png",otf.version,true)
@@ -21131,7 +21144,6 @@ local function copytotfm(data,cache_id)
parameters.units=units
parameters.vheight=metadata.defaultvheight
properties.space=spacer
- properties.encodingbytes=2
properties.format=data.format or formats.otf
properties.filename=filename
properties.fontname=fontname
@@ -21139,6 +21151,9 @@ local function copytotfm(data,cache_id)
properties.psname=psname
properties.name=filename or fullname
properties.subfont=subfont
+if not CONTEXTLMTXMODE or CONTEXTLMTXMODE==0 then
+ properties.encodingbytes=2
+end
properties.private=properties.private or data.private or privateoffset
return {
characters=characters,
@@ -26617,6 +26632,7 @@ local copy_only_glyphs=nuts.copy_only_glyphs
local count_components=nuts.count_components
local set_components=nuts.set_components
local get_components=nuts.get_components
+local flush_components=nuts.flush_components
local ischar=nuts.ischar
local usesfont=nuts.uses_font
local insert_node_after=nuts.insert_after
@@ -26639,7 +26655,7 @@ local glue_code=nodecodes.glue
local disc_code=nodecodes.disc
local math_code=nodecodes.math
local dir_code=nodecodes.dir
-local localpar_code=nodecodes.localpar
+local par_code=nodecodes.par
local lefttoright_code=nodes.dirvalues.lefttoright
local righttoleft_code=nodes.dirvalues.righttoleft
local discretionarydisc_code=disccodes.discretionary
@@ -26821,11 +26837,23 @@ local function markstoligature(head,start,stop,char)
setsubtype(base,ligatureglyph_code)
set_components(base,start)
setlink(prev,base,next)
+ flush_components(start)
return head,base
end
end
+local no_left_ligature_code=1
+local no_right_ligature_code=2
+local no_left_kern_code=4
+local no_right_kern_code=8
+local has_glyph_option=node.direct.has_glyph_option or function(n,c)
+ if c==no_left_ligature_code or c==no_right_ligature_code then
+ return getattr(n,a_noligature)==1
+ else
+ return false
+ end
+end
local function toligature(head,start,stop,char,dataset,sequence,skiphash,discfound,hasmarks)
- if getattr(start,a_noligature)==1 then
+ if has_glyph_option(start,no_right_ligature_code) then
return head,start
end
if start==stop and getchar(start)==char then
@@ -26889,6 +26917,7 @@ local function toligature(head,start,stop,char,dataset,sequence,skiphash,discfou
break
end
end
+ flush_components(components)
else
local discprev,discnext=getboth(discfound)
if discprev and discnext then
@@ -27175,78 +27204,86 @@ function handlers.gsub_ligature(head,start,dataset,sequence,ligature,rlmode,skip
return head,start,false,false
end
function handlers.gpos_single(head,start,dataset,sequence,kerns,rlmode,skiphash,step,injection)
- local startchar=getchar(start)
- local format=step.format
- if format=="single" or type(kerns)=="table" then
- local dx,dy,w,h=setposition(0,start,factor,rlmode,kerns,injection)
- if trace_kerns then
- logprocess("%s: shifting single %s by %s xy (%p,%p) and wh (%p,%p)",pref(dataset,sequence),gref(startchar),format,dx,dy,w,h)
- end
+ if has_glyph_option(start,no_right_kern_code) then
+ return head,start,false
else
- local k=(format=="move" and setmove or setkern)(start,factor,rlmode,kerns,injection)
- if trace_kerns then
- logprocess("%s: shifting single %s by %s %p",pref(dataset,sequence),gref(startchar),format,k)
+ local startchar=getchar(start)
+ local format=step.format
+ if format=="single" or type(kerns)=="table" then
+ local dx,dy,w,h=setposition(0,start,factor,rlmode,kerns,injection)
+ if trace_kerns then
+ logprocess("%s: shifting single %s by %s xy (%p,%p) and wh (%p,%p)",pref(dataset,sequence),gref(startchar),format,dx,dy,w,h)
+ end
+ else
+ local k=(format=="move" and setmove or setkern)(start,factor,rlmode,kerns,injection)
+ if trace_kerns then
+ logprocess("%s: shifting single %s by %s %p",pref(dataset,sequence),gref(startchar),format,k)
+ end
end
+ return head,start,true
end
- return head,start,true
end
function handlers.gpos_pair(head,start,dataset,sequence,kerns,rlmode,skiphash,step,injection)
- local snext=getnext(start)
- if not snext then
+ if has_glyph_option(start,no_right_kern_code) then
return head,start,false
else
- local prev=start
- while snext do
- local nextchar=ischar(snext,currentfont)
- if nextchar then
- if skiphash and skiphash[nextchar] then
- prev=snext
- snext=getnext(snext)
- else
- local krn=kerns[nextchar]
- if not krn then
- break
- end
- local format=step.format
- if format=="pair" then
- local a=krn[1]
- local b=krn[2]
- if a==true then
- elseif a then
- local x,y,w,h=setposition(1,start,factor,rlmode,a,injection)
- if trace_kerns then
- local startchar=getchar(start)
- logprocess("%s: shifting first of pair %s and %s by xy (%p,%p) and wh (%p,%p) as %s",pref(dataset,sequence),gref(startchar),gref(nextchar),x,y,w,h,injection or "injections")
- end
+ local snext=getnext(start)
+ if not snext then
+ return head,start,false
+ else
+ local prev=start
+ while snext do
+ local nextchar=ischar(snext,currentfont)
+ if nextchar then
+ if skiphash and skiphash[nextchar] then
+ prev=snext
+ snext=getnext(snext)
+ else
+ local krn=kerns[nextchar]
+ if not krn then
+ break
end
- if b==true then
- start=snext
- elseif b then
- local x,y,w,h=setposition(2,snext,factor,rlmode,b,injection)
+ local format=step.format
+ if format=="pair" then
+ local a=krn[1]
+ local b=krn[2]
+ if a==true then
+ elseif a then
+ local x,y,w,h=setposition(1,start,factor,rlmode,a,injection)
+ if trace_kerns then
+ local startchar=getchar(start)
+ logprocess("%s: shifting first of pair %s and %s by xy (%p,%p) and wh (%p,%p) as %s",pref(dataset,sequence),gref(startchar),gref(nextchar),x,y,w,h,injection or "injections")
+ end
+ end
+ if b==true then
+ start=snext
+ elseif b then
+ local x,y,w,h=setposition(2,snext,factor,rlmode,b,injection)
+ if trace_kerns then
+ local startchar=getchar(start)
+ logprocess("%s: shifting second of pair %s and %s by xy (%p,%p) and wh (%p,%p) as %s",pref(dataset,sequence),gref(startchar),gref(nextchar),x,y,w,h,injection or "injections")
+ end
+ start=snext
+ elseif forcepairadvance then
+ start=snext
+ end
+ return head,start,true
+ elseif krn~=0 then
+ local k=(format=="move" and setmove or setkern)(snext,factor,rlmode,krn,injection)
if trace_kerns then
- local startchar=getchar(start)
- logprocess("%s: shifting second of pair %s and %s by xy (%p,%p) and wh (%p,%p) as %s",pref(dataset,sequence),gref(startchar),gref(nextchar),x,y,w,h,injection or "injections")
+ logprocess("%s: inserting %s %p between %s and %s as %s",pref(dataset,sequence),format,k,gref(getchar(prev)),gref(nextchar),injection or "injections")
end
- start=snext
- elseif forcepairadvance then
- start=snext
- end
- return head,start,true
- elseif krn~=0 then
- local k=(format=="move" and setmove or setkern)(snext,factor,rlmode,krn,injection)
- if trace_kerns then
- logprocess("%s: inserting %s %p between %s and %s as %s",pref(dataset,sequence),format,k,gref(getchar(prev)),gref(nextchar),injection or "injections")
+ return head,start,true
+ else
+ break
end
- return head,start,true
- else
- break
end
+ else
+ break
end
- else
- break
end
+ return head,start,false
end
- return head,start,false
end
end
function handlers.gpos_mark2base(head,start,dataset,sequence,markanchors,rlmode,skiphash)
@@ -27676,89 +27713,93 @@ function chainprocs.gsub_ligature(head,start,stop,dataset,sequence,currentlookup
return head,start,false,0,false
end
function chainprocs.gpos_single(head,start,stop,dataset,sequence,currentlookup,rlmode,skiphash,chainindex)
- local mapping=currentlookup.mapping
- if mapping==nil then
- mapping=getmapping(dataset,sequence,currentlookup)
- end
- if mapping then
- local startchar=getchar(start)
- local kerns=mapping[startchar]
- if kerns then
- local format=currentlookup.format
- if format=="single" then
- local dx,dy,w,h=setposition(0,start,factor,rlmode,kerns)
- if trace_kerns then
- logprocess("%s: shifting single %s by %s (%p,%p) and correction (%p,%p)",cref(dataset,sequence),gref(startchar),format,dx,dy,w,h)
- end
- else
- local k=(format=="move" and setmove or setkern)(start,factor,rlmode,kerns,injection)
- if trace_kerns then
- logprocess("%s: shifting single %s by %s %p",cref(dataset,sequence),gref(startchar),format,k)
+ if not has_glyph_option(start,no_right_kern_code) then
+ local mapping=currentlookup.mapping
+ if mapping==nil then
+ mapping=getmapping(dataset,sequence,currentlookup)
+ end
+ if mapping then
+ local startchar=getchar(start)
+ local kerns=mapping[startchar]
+ if kerns then
+ local format=currentlookup.format
+ if format=="single" then
+ local dx,dy,w,h=setposition(0,start,factor,rlmode,kerns)
+ if trace_kerns then
+ logprocess("%s: shifting single %s by %s (%p,%p) and correction (%p,%p)",cref(dataset,sequence),gref(startchar),format,dx,dy,w,h)
+ end
+ else
+ local k=(format=="move" and setmove or setkern)(start,factor,rlmode,kerns,injection)
+ if trace_kerns then
+ logprocess("%s: shifting single %s by %s %p",cref(dataset,sequence),gref(startchar),format,k)
+ end
end
+ return head,start,true
end
- return head,start,true
end
end
return head,start,false
end
-function chainprocs.gpos_pair(head,start,stop,dataset,sequence,currentlookup,rlmode,skiphash,chainindex)
- local mapping=currentlookup.mapping
- if mapping==nil then
- mapping=getmapping(dataset,sequence,currentlookup)
- end
- if mapping then
- local snext=getnext(start)
- if snext then
- local startchar=getchar(start)
- local kerns=mapping[startchar]
- if kerns then
- local prev=start
- while snext do
- local nextchar=ischar(snext,currentfont)
- if not nextchar then
- break
- end
- if skiphash and skiphash[nextchar] then
- prev=snext
- snext=getnext(snext)
- else
- local krn=kerns[nextchar]
- if not krn then
+function chainprocs.gpos_pair(head,start,stop,dataset,sequence,currentlookup,rlmode,skiphash,chainindex)
+ if not has_glyph_option(start,no_right_kern_code) then
+ local mapping=currentlookup.mapping
+ if mapping==nil then
+ mapping=getmapping(dataset,sequence,currentlookup)
+ end
+ if mapping then
+ local snext=getnext(start)
+ if snext then
+ local startchar=getchar(start)
+ local kerns=mapping[startchar]
+ if kerns then
+ local prev=start
+ while snext do
+ local nextchar=ischar(snext,currentfont)
+ if not nextchar then
break
end
- local format=currentlookup.format
- if format=="pair" then
- local a=krn[1]
- local b=krn[2]
- if a==true then
- elseif a then
- local x,y,w,h=setposition(1,start,factor,rlmode,a,"injections")
- if trace_kerns then
- local startchar=getchar(start)
- logprocess("%s: shifting first of pair %s and %s by (%p,%p) and correction (%p,%p)",cref(dataset,sequence),gref(startchar),gref(nextchar),x,y,w,h)
- end
+ if skiphash and skiphash[nextchar] then
+ prev=snext
+ snext=getnext(snext)
+ else
+ local krn=kerns[nextchar]
+ if not krn then
+ break
end
- if b==true then
- start=snext
- elseif b then
- local x,y,w,h=setposition(2,snext,factor,rlmode,b,"injections")
+ local format=currentlookup.format
+ if format=="pair" then
+ local a=krn[1]
+ local b=krn[2]
+ if a==true then
+ elseif a then
+ local x,y,w,h=setposition(1,start,factor,rlmode,a,"injections")
+ if trace_kerns then
+ local startchar=getchar(start)
+ logprocess("%s: shifting first of pair %s and %s by (%p,%p) and correction (%p,%p)",cref(dataset,sequence),gref(startchar),gref(nextchar),x,y,w,h)
+ end
+ end
+ if b==true then
+ start=snext
+ elseif b then
+ local x,y,w,h=setposition(2,snext,factor,rlmode,b,"injections")
+ if trace_kerns then
+ local startchar=getchar(start)
+ logprocess("%s: shifting second of pair %s and %s by (%p,%p) and correction (%p,%p)",cref(dataset,sequence),gref(startchar),gref(nextchar),x,y,w,h)
+ end
+ start=snext
+ elseif forcepairadvance then
+ start=snext
+ end
+ return head,start,true
+ elseif krn~=0 then
+ local k=(format=="move" and setmove or setkern)(snext,factor,rlmode,krn)
if trace_kerns then
- local startchar=getchar(start)
- logprocess("%s: shifting second of pair %s and %s by (%p,%p) and correction (%p,%p)",cref(dataset,sequence),gref(startchar),gref(nextchar),x,y,w,h)
+ logprocess("%s: inserting %s %p between %s and %s",cref(dataset,sequence),format,k,gref(getchar(prev)),gref(nextchar))
end
- start=snext
- elseif forcepairadvance then
- start=snext
- end
- return head,start,true
- elseif krn~=0 then
- local k=(format=="move" and setmove or setkern)(snext,factor,rlmode,krn)
- if trace_kerns then
- logprocess("%s: inserting %s %p between %s and %s",cref(dataset,sequence),format,k,gref(getchar(prev)),gref(nextchar))
+ return head,start,true
+ else
+ break
end
- return head,start,true
- else
- break
end
end
end
@@ -29580,7 +29621,7 @@ do
checkstep(head)
end
local initialrl=0
- if getid(head)==localpar_code and start_of_par(head) then
+ if getid(head)==par_code and start_of_par(head) then
initialrl=pardirstate(head)
elseif direction==righttoleft_code then
initialrl=-1
@@ -34675,7 +34716,6 @@ local function copytotfm(data)
parameters.descender=abs(metadata.descender or 0)
parameters.units=1000
properties.spacer=spacer
- properties.encodingbytes=2
properties.format=fonts.formats[filename] or "type1"
properties.filename=filename
properties.fontname=fontname
@@ -34683,6 +34723,9 @@ local function copytotfm(data)
properties.psname=fullname
properties.name=filename or fullname or fontname
properties.private=properties.private or data.private or privateoffset
+if not CONTEXTLMTXMODE or CONTEXTLMTXMODE==0 then
+ properties.encodingbytes=2
+end
if next(characters) then
return {
characters=characters,
@@ -35993,7 +36036,7 @@ if not modules then modules={} end modules ['font-shp']={
}
local tonumber,next=tonumber,next
local concat=table.concat
-local formatters=string.formatters
+local formatters,lower=string.formatters,string.lower
local otf=fonts.handlers.otf
local afm=fonts.handlers.afm
local pfb=fonts.handlers.pfb
@@ -36186,7 +36229,7 @@ end
local function loadstreams(cache,filename,sub,instance)
local base=file.basename(filename)
local name=file.removesuffix(base)
- local kind=file.suffix(filename)
+ local kind=lower(file.suffix(filename))
local attr=lfs.attributes(filename)
local size=attr and attr.size or 0
local time=attr and attr.modification or 0
@@ -37084,56 +37127,74 @@ local rules={
"FractionRuleThickness",
"UnderbarRuleThickness",
}
-local function setmathparameters(tfmdata,characters,mathparameters,dx,dy,squeeze)
- if delta~=0 then
- for i=1,#rules do
- local name=rules[i]
- local value=mathparameters[name]
- if value then
- mathparameters[name]=(squeeze or 1)*(value+dx)
+local setmathparameters
+local setmathcharacters
+if CONTEXTLMTXMODE and CONTEXTLMTXMODE>0 then
+ setmathparameters=function(tfmdata,characters,mathparameters,dx,dy,squeeze,multiplier)
+ if delta~=0 then
+ for i=1,#rules do
+ local name=rules[i]
+ local value=mathparameters[name]
+ if value then
+ mathparameters[name]=(squeeze or 1)*(value+dy)
+ end
end
end
end
-end
-local function setmathcharacters(tfmdata,characters,mathparameters,dx,dy,squeeze,wdelta,hdelta,ddelta)
- local function wdpatch(char)
- if wsnap~=0 then
- char.width=char.width+wdelta/2
- end
+ setmathcharacters=function()
end
- local function htpatch(char)
- if hsnap~=0 then
- local height=char.height
- if height then
- char.height=char.height+2*dy
+else
+ setmathparameters=function(tfmdata,characters,mathparameters,dx,dy,squeeze,multiplier)
+ if delta~=0 then
+ for i=1,#rules do
+ local name=rules[i]
+ local value=mathparameters[name]
+ if value then
+ mathparameters[name]=(squeeze or 1)*(value+dy)
+ end
end
end
end
- local character=characters[0x221A]
- if character and character.next then
- local char=character
- local next=character.next
- wdpatch(char)
- htpatch(char)
- while next do
- char=characters[next]
+ setmathcharacters=function(tfmdata,characters,mathparameters,dx,dy,squeeze,wdelta,hdelta,ddelta)
+ local function wdpatch(char)
+ if wsnap~=0 then
+ char.width=char.width+wdelta/2
+ end
+ end
+ local function htpatch(char)
+ if hsnap~=0 then
+ local height=char.height
+ if height then
+ char.height=char.height+2*dy
+ end
+ end
+ end
+ local character=characters[0x221A]
+ if character and character.next then
+ local char=character
+ local next=character.next
wdpatch(char)
htpatch(char)
- next=char.next
- end
- if char then
- local v=char.vert_variants
- if v then
- local top=v[#v]
- if top then
- local char=characters[top.glyph]
- htpatch(char)
+ while next do
+ char=characters[next]
+ wdpatch(char)
+ htpatch(char)
+ next=char.next
+ end
+ if char then
+ local v=char.vert_variants
+ if v then
+ local top=v[#v]
+ if top then
+ local char=characters[top.glyph]
+ htpatch(char)
+ end
end
end
end
end
end
-local shiftmode=CONTEXTLMTXMODE>0
+local shiftmode=CONTEXTLMTXMODE and CONTEXTLMTXMODE>0
local function manipulateeffect(tfmdata)
local effect=tfmdata.properties.effect
if effect then
@@ -37205,7 +37266,7 @@ local function manipulateeffect(tfmdata)
end
end
if mathparameters then
- setmathparameters(tfmdata,characters,mathparameters,dx,dy,squeeze)
+ setmathparameters(tfmdata,characters,mathparameters,dx,dy,squeeze,multiplier)
setmathcharacters(tfmdata,characters,mathparameters,dx,dy,squeeze,wdelta,hdelta,ddelta)
end
parameters.factor=factor
diff --git a/macros/luatex/generic/luaotfload/luaotfload-auxiliary.lua b/macros/luatex/generic/luaotfload/luaotfload-auxiliary.lua
index 14a66da359..2d4e757bc0 100644
--- a/macros/luatex/generic/luaotfload/luaotfload-auxiliary.lua
+++ b/macros/luatex/generic/luaotfload/luaotfload-auxiliary.lua
@@ -4,19 +4,14 @@
-- AUTHOR: Khaled Hosny, Élie Roux, Philipp Gesang
-----------------------------------------------------------------------
-local ProvidesLuaModule = {
+assert(luaotfload_module, "This is a part of luaotfload and should not be loaded independently") {
name = "luaotfload-auxiliary",
- version = "3.15", --TAGVERSION
- date = "2020-09-02", --TAGDATE
+ version = "3.16", --TAGVERSION
+ date = "2020-12-31", --TAGDATE
description = "luaotfload submodule / auxiliary functions",
license = "GPL v2.0"
}
-if luatexbase and luatexbase.provides_module then
- luatexbase.provides_module (ProvidesLuaModule)
-end
-
-
luaotfload = luaotfload or { }
local log = luaotfload.log
local logreport = log.report
@@ -912,6 +907,53 @@ function aux.get_quad(font_id)
end
-----------------------------------------------------------------------
+--- Script/language fixup
+-----------------------------------------------------------------------
+local otftables = fonts.constructors.handlers.otf.tables
+local function setscript(tfmdata, value)
+ if value then
+ local cleanvalue = string.lower(value)
+ local scripts = otftables and otftables.scripts
+ local properties = tfmdata.properties
+ if not scripts then
+ properties.script = cleanvalue
+ elseif scripts[value] then
+ properties.script = cleanvalue
+ else
+ properties.script = "dflt"
+ end
+ end
+ local resources = tfmdata.resources
+ local features = resources and resources.features
+ if features then
+ local properties = tfmdata.properties
+ local script, language = properties.script, properties.language
+ local script_found, language_found = false, false
+ for _, data in next, features do for _, feature_data in next, data do
+ local scr = feature_data[script]
+ if scr then
+ script_found = true
+ if scr[language] then
+ language_found = true
+ goto double_break
+ end
+ end
+ end end
+ ::double_break::
+ if not script_found then properties.script = "dflt" end
+ if not language_found then properties.language = "dflt" end
+ end
+end
+fonts.constructors.features.otf.register {
+ name = "script",
+ initializers = {
+ base = setscript,
+ node = setscript,
+ plug = setscript,
+ },
+}
+
+-----------------------------------------------------------------------
--- initialization
-----------------------------------------------------------------------
diff --git a/macros/luatex/generic/luaotfload/luaotfload-case.lua b/macros/luatex/generic/luaotfload/luaotfload-case.lua
new file mode 100644
index 0000000000..33bb1bc924
--- /dev/null
+++ b/macros/luatex/generic/luaotfload/luaotfload-case.lua
@@ -0,0 +1,239 @@
+local unicode_data = require'luaotfload-unicode'
+
+local mapping_tables = unicode_data.casemapping
+local soft_dotted = unicode_data.soft_dotted
+local ccc = unicode_data.ccc
+
+local uppercase = mapping_tables.uppercase
+local lowercase = mapping_tables.lowercase
+local cased = mapping_tables.cased
+local case_ignorable = mapping_tables.case_ignorable
+
+local otfregister = fonts.constructors.features.otf.register
+
+local direct = node.direct
+local is_char = direct.is_char
+local has_glyph = direct.has_glyph
+local uses_font = direct.uses_font
+local getnext = direct.getnext
+local setchar = direct.setchar
+local setdisc = direct.setdisc
+local getdisc = direct.getdisc
+local getfield = direct.getfield
+local remove = direct.remove
+local copy = direct.copy
+local insert_after = direct.insert_after
+local traverse = direct.traverse
+
+local disc = node.id'disc'
+
+--[[ We make some implicit assumptions about contexts in SpecialCasing.txt here which happened to be true when I wrote the code:
+--
+-- * Before_Dot only appears as Not_Before_Dot
+-- * No other context appears with Not_
+-- * Final_Sigma is never language dependent
+-- * Other contexts are always language dependent
+-- * The only languages with special mappings are Lithuanian (lt/"LTH "/lit), Turkish (tr/"TRK "/tur), and Azeri/Azerbaijani (az/"AZE "/aze)
+]]
+
+local font_lang = setmetatable({}, {__index = function(t, fid)
+ local f = font.getfont(fid)
+ local lang = f.specification.features.normal.language
+ lang = lang == 'lth' and 'lt' or lang == 'trk' and 'tr' or lang == 'aze' and 'az' or false
+ t[fid] = lang
+ return lang
+end})
+
+local function is_Final_Sigma(font, mapping, n, after)
+ mapping = mapping.Final_Sigma
+ if not mapping then return false end
+ mapping = mapping._
+ if not mapping then return false end
+ n = getnext(n)
+ repeat
+ while n do
+ local char, id = is_char(n, font)
+ if id == disc then
+ after = getnext(n)
+ n = getfield(n, 'replace')
+ char, id = is_char(n, font)
+ elseif char then
+ if not case_ignorable[char] then
+ return not cased[char] and mapping
+ end
+ n = getnext(n)
+ else
+ return mapping
+ end
+ end
+ n, after = after
+ until not n
+ return mapping
+end
+
+local function is_More_Above(font, mapping, n, after)
+ mapping = mapping.More_Above
+ if not mapping then return false end
+ mapping = mapping._
+ if not mapping then return false end
+ n = getnext(n)
+ repeat
+ while n do
+ local char, id = is_char(n, font)
+ if id == disc then
+ after = getnext(n)
+ n = getfield(n, 'replace')
+ char, id = is_char(n, font)
+ elseif char then
+ local char_ccc = ccc[char]
+ if not char_ccc then
+ return false
+ elseif char_ccc == 230 then
+ return mapping
+ end
+ n = getnext(n)
+ else
+ return false
+ end
+ end
+ n, after = after
+ until not n
+ return false
+end
+
+local function is_Not_Before_Dot(font, mapping, n, after)
+ mapping = mapping.Not_Before_Dot
+ if not mapping then return false end
+ mapping = mapping._
+ if not mapping then return false end
+ n = getnext(n)
+ repeat
+ while n do
+ local char, id = is_char(n, font)
+ if id == disc then
+ after = getnext(n)
+ n = getfield(n, 'replace')
+ char, id = is_char(n, font)
+ elseif char then
+ local char_ccc = ccc[char]
+ if not char_ccc then
+ return mapping
+ elseif char_ccc == 230 then
+ return char ~= 0x0307 and mapping
+ end
+ n = getnext(n)
+ else
+ return mapping
+ end
+ end
+ n, after = after
+ until not n
+ return mapping
+end
+
+local function is_Language_Mapping(font, mapping, n, after, seen_soft_dotted, seen_I)
+ if not mapping then return false end
+ if seen_soft_dotted then
+ local mapping = mapping.After_Soft_Dotted
+ mapping = mapping and mapping._
+ if mapping then
+ return mapping
+ end
+ end
+ if seen_I then
+ local mapping = mapping.After_I
+ mapping = mapping and mapping._
+ if mapping then
+ return mapping
+ end
+ end
+ return is_More_Above(font, mapping, n, after) or is_Not_Before_Dot(font, mapping, n, after) or mapping._ -- Might be nil
+end
+
+local function process(table)
+ local function processor(head, font, after, seen_cased, seen_soft_dotted, seen_I)
+ local lang = font_lang[font]
+ local n = head
+ while n do
+ do
+ local new = has_glyph(n)
+ if n ~= new then
+ seen_cased, seen_soft_dotted, seen_I = nil
+ end
+ n = new
+ end
+ if not n then break end
+ local char, id = is_char(n, font)
+ if char then
+ local mapping = table[char]
+ if mapping then
+ if tonumber(mapping) then
+ setchar(n, mapping)
+ else
+ mapping = seen_cased and is_Final_Sigma(font, mapping, n, after)
+ or lang and is_Language_Mapping(font, mapping[lang], n, after, seen_soft_dotted, seen_I)
+ or mapping._
+ if #mapping == 0 then
+ head, n = remove(head, n)
+ goto continue
+ else
+ setchar(n, mapping[1])
+ for i=2, #mapping do
+ head, n = insert_after(head, n, copy(n))
+ setchar(n, mapping[i])
+ end
+ end
+ end
+ end
+ if not case_ignorable[char] then
+ seen_cased = cased[char] or nil
+ end
+ local char_ccc = ccc[char]
+ if not char_ccc or char_ccc == 230 then
+ seen_I = char == 0x49 or nil
+ seen_soft_dotted = soft_dotted[char]
+ end
+ elseif id == disc and uses_font(n, font) then
+ local pre, post, rep = getdisc(n)
+ local after = getnext(n)
+ pre, post, rep, seen_cased, seen_soft_dotted, seen_I =
+ processor(pre, font, nil, seen_cased, seen_soft_dotted, seen_I),
+ processor(post, font, after),
+ processor(rep, font, after, seen_cased, seen_soft_dotted, seen_I)
+ setdisc(n, pre, post, rep)
+ else
+ seen_cased, seen_soft_dotted, seen_I = nil
+ end
+ n = getnext(n)
+ ::continue::
+ end
+ return head, seen_cased, seen_soft_dotted, seen_I
+ end
+ return function(head, font) return (processor(head, font)) end
+end
+
+local upper_process = process(uppercase)
+otfregister {
+ name = 'upper',
+ description = 'Map to uppercase',
+ default = false,
+ processors = {
+ position = 1,
+ plug = upper_process,
+ node = upper_process,
+ base = upper_process,
+ },
+}
+
+local lower_process = process(lowercase)
+otfregister {
+ name = 'lower',
+ description = 'Map to lowercase',
+ default = false,
+ processors = {
+ position = 1,
+ plug = lower_process,
+ node = lower_process,
+ base = lower_process,
+ },
+}
diff --git a/macros/luatex/generic/luaotfload/luaotfload-colors.lua b/macros/luatex/generic/luaotfload/luaotfload-colors.lua
index e8a8e996a8..c1f8a63a8e 100644
--- a/macros/luatex/generic/luaotfload/luaotfload-colors.lua
+++ b/macros/luatex/generic/luaotfload/luaotfload-colors.lua
@@ -3,21 +3,16 @@
-- DESCRIPTION: part of luaotfload / font colors
-----------------------------------------------------------------------
-local ProvidesLuaModule = {
+assert(luaotfload_module, "This is a part of luaotfload and should not be loaded independently") {
name = "luaotfload-colors",
- version = "3.15", --TAGVERSION
- date = "2020-09-02", --TAGDATE
+ version = "3.16", --TAGVERSION
+ date = "2020-12-31", --TAGDATE
description = "luaotfload submodule / color",
license = "GPL v2.0",
author = "Khaled Hosny, Elie Roux, Philipp Gesang, Dohyun Kim, David Carlisle",
copyright = "Luaotfload Development Team"
}
-if luatexbase and luatexbase.provides_module then
- luatexbase.provides_module (ProvidesLuaModule)
-end
-
-
--[[doc--
buggy coloring with the pre_output_filter when expansion is enabled
diff --git a/macros/luatex/generic/luaotfload/luaotfload-conf.pdf b/macros/luatex/generic/luaotfload/luaotfload-conf.pdf
index 85768faf2f..52137882d4 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 8f04190a43..e5e1ed24f0 100644
--- a/macros/luatex/generic/luaotfload/luaotfload-configuration.lua
+++ b/macros/luatex/generic/luaotfload/luaotfload-configuration.lua
@@ -5,18 +5,14 @@
-- AUTHOR: Dohyun Kim <nomosnomos@gmail.com>
-------------------------------------------------------------------------------
-local ProvidesLuaModule = {
+assert(luaotfload_module, "This is a part of luaotfload and should not be loaded independently") {
name = "luaotfload-configuration",
- version = "3.15", --TAGVERSION
- date = "2020-09-02", --TAGDATE
+ version = "3.16", --TAGVERSION
+ date = "2020-12-31", --TAGDATE
description = "luaotfload submodule / config file reader",
license = "GPL v2.0"
}
-if luatexbase and luatexbase.provides_module then
- luatexbase.provides_module (ProvidesLuaModule)
-end
-
------------------------------
local status_file = "luaotfload-status"
diff --git a/macros/luatex/generic/luaotfload/luaotfload-database.lua b/macros/luatex/generic/luaotfload/luaotfload-database.lua
index 6d0bcff414..da2d9965a3 100644
--- a/macros/luatex/generic/luaotfload/luaotfload-database.lua
+++ b/macros/luatex/generic/luaotfload/luaotfload-database.lua
@@ -3,19 +3,15 @@
-- DESCRIPTION: part of luaotfload / luaotfload-tool / font database
-----------------------------------------------------------------------
do -- block to avoid to many local variables error
- local ProvidesLuaModule = {
+ assert(luaotfload_module, "This is a part of luaotfload and should not be loaded independently") {
name = "luaotfload-database",
- version = "3.15", --TAGVERSION
- date = "2020-09-02", --TAGDATE
+ version = "3.16", --TAGVERSION
+ date = "2020-12-31", --TAGDATE
description = "luaotfload submodule / database",
license = "GPL v2.0",
author = "Khaled Hosny, Elie Roux, Philipp Gesang, Marcel Krüger",
copyright = "Luaotfload Development Team",
}
-
- if luatexbase and luatexbase.provides_module then
- luatexbase.provides_module (ProvidesLuaModule)
- end
end
--[[doc--
@@ -2335,8 +2331,7 @@ local path_separator = os.type == "windows" and ";" or ":"
--[[doc--
collect_font_filenames_texmf -- Scan texmf tree for font files
- relying on the kpathsea variables $OPENTYPEFONTS and $TTFONTS of
- texmf.cnf.
+ relying on kpathsea search paths for the respective file types.
The current working directory comes as “.” (texlive) or absolute
path (miktex) and will always be filtered out.
@@ -2362,16 +2357,20 @@ local function collect_font_filenames_texmf ()
end
end
- fontdirs = kpseexpand_path "$OPENTYPEFONTS"
- fontdirs = fontdirs .. path_separator .. kpseexpand_path "$TTFONTS"
- fontdirs = fontdirs .. path_separator .. kpseexpand_path "$T1FONTS"
- fontdirs = fontdirs .. path_separator .. kpseexpand_path "$AFMFONTS"
+ local show_path = kpse.show_path
- if stringis_empty (fontdirs) then
- return { }
+ local function expanded_path (file_type)
+ return kpseexpand_path (show_path (file_type))
end
- local tasks = filter_out_pwd (filesplitpath (fontdirs))
+ local fontdirs = expanded_path "opentype fonts"
+ fontdirs = fontdirs .. path_separator .. expanded_path "truetype fonts"
+ fontdirs = fontdirs .. path_separator .. expanded_path "type1 fonts"
+ fontdirs = fontdirs .. path_separator .. expanded_path "afm"
+
+ fontdirs = filesplitpath (fontdirs) or { }
+
+ local tasks = filter_out_pwd (fontdirs)
logreport ("both", 3, "db",
"Initiating scan of %d directories.", #tasks)
diff --git a/macros/luatex/generic/luaotfload/luaotfload-diagnostics.lua b/macros/luatex/generic/luaotfload/luaotfload-diagnostics.lua
index be3183cf65..366c7c98ec 100644
--- a/macros/luatex/generic/luaotfload/luaotfload-diagnostics.lua
+++ b/macros/luatex/generic/luaotfload/luaotfload-diagnostics.lua
@@ -5,19 +5,14 @@
-- AUTHOR: Philipp Gesang <phg@phi-gamma.net>
-----------------------------------------------------------------------
-local ProvidesLuaModule = {
+assert(luaotfload_module, "This is a part of luaotfload and should not be loaded independently") {
name = "luaotfload-diagnostics",
- version = "3.15", --TAGVERSION
- date = "2020-09-02", --TAGDATE
+ version = "3.16", --TAGVERSION
+ date = "2020-12-31", --TAGDATE
description = "luaotfload-tool submodule / diagnostics",
license = "GPL v2.0"
}
-if luatexbase and luatexbase.provides_module then
- luatexbase.provides_module (ProvidesLuaModule)
-end
-
-
local names = fonts.names
local kpse = require "kpse"
diff --git a/macros/luatex/generic/luaotfload/luaotfload-dvi.lua b/macros/luatex/generic/luaotfload/luaotfload-dvi.lua
index b57934fdb6..33083045d4 100644
--- a/macros/luatex/generic/luaotfload/luaotfload-dvi.lua
+++ b/macros/luatex/generic/luaotfload/luaotfload-dvi.lua
@@ -4,20 +4,16 @@
-------------------------------------------------------------------------------
-local ProvidesLuaModule = {
+assert(luaotfload_module, "This is a part of luaotfload and should not be loaded independently") {
name = "luaotfload-dvi",
- version = "3.15", --TAGVERSION
- date = "2020-09-02", --TAGDATE
+ version = "3.16", --TAGVERSION
+ date = "2020-12-31", --TAGDATE
description = "luaotfload submodule / DVI",
license = "GPL v2.0",
author = "Marcel Krüger",
copyright = "Luaotfload Development Team",
}
-if luatexbase and luatexbase.provides_module then
- luatexbase.provides_module (ProvidesLuaModule)
-end
-
local getfont = font.getfont
local setfont = node.direct.setfont
local getdisc = node.direct.getdisc
diff --git a/macros/luatex/generic/luaotfload/luaotfload-embolden.lua b/macros/luatex/generic/luaotfload/luaotfload-embolden.lua
index d1d4e478c8..73993eead8 100644
--- a/macros/luatex/generic/luaotfload/luaotfload-embolden.lua
+++ b/macros/luatex/generic/luaotfload/luaotfload-embolden.lua
@@ -3,19 +3,15 @@
-- DESCRIPTION: part of luaotfload / embolden
-----------------------------------------------------------------------
-local ProvidesLuaModule = {
+assert(luaotfload_module, "This is a part of luaotfload and should not be loaded independently") {
name = "luaotfload-embolden",
- version = "3.15", --TAGVERSION
- date = "2020-09-02", --TAGDATE
+ version = "3.16", --TAGVERSION
+ date = "2020-12-31", --TAGDATE
description = "luaotfload submodule / embolden",
license = "GPL v2.0",
author = "Marcel Krüger"
}
-if luatexbase and luatexbase.provides_module then
- luatexbase.provides_module (ProvidesLuaModule)
-end
-
local otffeatures = fonts.constructors.newfeatures "otf"
local function enableembolden(tfmdata, _, embolden)
diff --git a/macros/luatex/generic/luaotfload/luaotfload-fallback.lua b/macros/luatex/generic/luaotfload/luaotfload-fallback.lua
index eee107c709..17bd7ca404 100644
--- a/macros/luatex/generic/luaotfload/luaotfload-fallback.lua
+++ b/macros/luatex/generic/luaotfload/luaotfload-fallback.lua
@@ -3,19 +3,15 @@
-- DESCRIPTION: part of luaotfload / fallback
-----------------------------------------------------------------------
-local ProvidesLuaModule = {
+assert(luaotfload_module, "This is a part of luaotfload and should not be loaded independently") {
name = "luaotfload-fallback",
- version = "3.15", --TAGVERSION
- date = "2020-09-02", --TAGDATE
+ version = "3.16", --TAGVERSION
+ date = "2020-12-31", --TAGDATE
description = "luaotfload submodule / fallback",
license = "GPL v2.0",
author = "Marcel Krüger"
}
-if luatexbase and luatexbase.provides_module then
- luatexbase.provides_module (ProvidesLuaModule)
-end
-
local nodenew = node.direct.new
local getfont = font.getfont
local setfont = node.direct.setfont
diff --git a/macros/luatex/generic/luaotfload/luaotfload-features.lua b/macros/luatex/generic/luaotfload/luaotfload-features.lua
index 2d83df10ff..67c9f93565 100644
--- a/macros/luatex/generic/luaotfload/luaotfload-features.lua
+++ b/macros/luatex/generic/luaotfload/luaotfload-features.lua
@@ -3,21 +3,16 @@
-- DESCRIPTION: part of luaotfload / font features
-----------------------------------------------------------------------
-local ProvidesLuaModule = {
+assert(luaotfload_module, "This is a part of luaotfload and should not be loaded independently") {
name = "luaotfload-features",
- version = "3.15", --TAGVERSION
- date = "2020-09-02", --TAGDATE
+ version = "3.16", --TAGVERSION
+ date = "2020-12-31", --TAGDATE
description = "luaotfload submodule / features",
license = "GPL v2.0",
author = "Hans Hagen, Khaled Hosny, Elie Roux, Philipp Gesang, Marcel Krüger",
copyright = "PRAGMA ADE / ConTeXt Development Team",
}
-if luatexbase and luatexbase.provides_module then
- luatexbase.provides_module (ProvidesLuaModule)
-end
-
-
local type = type
local next = next
local tonumber = tonumber
@@ -45,12 +40,18 @@ local otf = handlers.otf
local config = config or { luaotfload = { run = { } } }
-local as_script = true
-local normalize = function () end
+local as_script = config.luaotfload.run.live
+local normalize
-if config.luaotfload.run.live ~= false then
+if as_script then
+ function normalize(features)
+ return {
+ axis = features and features.axis,
+ instance = features and features.instance,
+ }
+ end
+else
normalize = otf.features.normalize
- as_script = false
end
--[[HH (font-xtx) --
@@ -663,7 +664,7 @@ end
do
local function mathfontdimen(tfmdata, _, value)
- if not next(tfmdata.mathparameters) then return end
+ if not (tfmdata.mathparameters and next(tfmdata.mathparameters)) then return end
local parameters = tfmdata.parameters
local mathparameters = tfmdata.mathparameters
if value == 'xetex' then
diff --git a/macros/luatex/generic/luaotfload/luaotfload-filelist.lua b/macros/luatex/generic/luaotfload/luaotfload-filelist.lua
index b8ab343402..69195603ed 100644
--- a/macros/luatex/generic/luaotfload/luaotfload-filelist.lua
+++ b/macros/luatex/generic/luaotfload/luaotfload-filelist.lua
@@ -4,19 +4,13 @@
-- AUTHOR: Ulrike Fischer, <fischer@troubleshooting-tex.de>
-----------------------------------------------------------------------
-local ProvidesLuaModule = {
+if luaotfload_module then luaotfload_module {
name = "luaotfload-filelist",
- version = "3.15", --TAGVERSION
- date = "2020-09-02", --TAGDATE
+ version = "3.16", --TAGVERSION
+ date = "2020-12-31", --TAGDATE
description = "luaotfload submodule / filelist",
license = "GPL v2.0"
-}
-
-if luatexbase and luatexbase.provides_module then
- luatexbase.provides_module (ProvidesLuaModule)
-end
-
-
+} end
--[[doc--
diff --git a/macros/luatex/generic/luaotfload/luaotfload-glyphlist.lua b/macros/luatex/generic/luaotfload/luaotfload-glyphlist.lua
index 19f5c2082b..aefc8369c6 100644
--- a/macros/luatex/generic/luaotfload/luaotfload-glyphlist.lua
+++ b/macros/luatex/generic/luaotfload/luaotfload-glyphlist.lua
@@ -1,12 +1,14 @@
-local ProvidesLuaModule = {
+if luaotfload_module then
+ luaotfload_module {
name = "luaotfload-glyphlist",
- version = "3.15", --TAGVERSION
- date = "2020-09-02", --TAGDATE
+ version = "3.16", --TAGVERSION
+ date = "2020-12-31", --TAGDATE
description = "luaotfload submodule / autogenerated glyphlist",
copyright = "derived from https://raw.githubusercontent.com/adobe-type-tools/agl-aglfn/master/glyphlist.txt",
original = "Adobe Glyph List, version 2.0, September 20, 2002",
dataonly = true
-}
+ }
+end
if context then
logs.report("fatal error","this module is not for context")
diff --git a/macros/luatex/generic/luaotfload/luaotfload-harf-define.lua b/macros/luatex/generic/luaotfload/luaotfload-harf-define.lua
index 37ada59d00..5be4acfa65 100644
--- a/macros/luatex/generic/luaotfload/luaotfload-harf-define.lua
+++ b/macros/luatex/generic/luaotfload/luaotfload-harf-define.lua
@@ -3,19 +3,15 @@
-- DESCRIPTION: part of luaotfload / HarfBuzz / font definition
-----------------------------------------------------------------------
do -- block to avoid to many local variables error
- local ProvidesLuaModule = {
+ assert(luaotfload_module, "This is a part of luaotfload and should not be loaded independently") {
name = "luaotfload-harf-define",
- version = "3.15", --TAGVERSION
- date = "2020-09-02", --TAGDATE
+ version = "3.16", --TAGVERSION
+ date = "2020-12-31", --TAGDATE
description = "luaotfload submodule / HarfBuzz font loading",
license = "GPL v2.0",
author = "Khaled Hosny, Marcel Krüger",
copyright = "Luaotfload Development Team",
}
-
- if luatexbase and luatexbase.provides_module then
- luatexbase.provides_module (ProvidesLuaModule)
- end
end
local unpack = string.unpack
diff --git a/macros/luatex/generic/luaotfload/luaotfload-harf-plug.lua b/macros/luatex/generic/luaotfload/luaotfload-harf-plug.lua
index 6759747fbf..c40aa3b72e 100644
--- a/macros/luatex/generic/luaotfload/luaotfload-harf-plug.lua
+++ b/macros/luatex/generic/luaotfload/luaotfload-harf-plug.lua
@@ -3,19 +3,15 @@
-- DESCRIPTION: part of luaotfload / HarfBuzz / fontloader plugin
-----------------------------------------------------------------------
do -- block to avoid to many local variables error
- local ProvidesLuaModule = {
+ assert(luaotfload_module, "This is a part of luaotfload and should not be loaded independently") {
name = "luaotfload-harf-plug",
- version = "3.15", --TAGVERSION
- date = "2020-09-02", --TAGDATE
+ version = "3.16", --TAGVERSION
+ date = "2020-12-31", --TAGDATE
description = "luaotfload submodule / HarfBuzz shaping",
license = "GPL v2.0",
author = "Khaled Hosny, Marcel Krüger",
copyright = "Luaotfload Development Team",
}
-
- if luatexbase and luatexbase.provides_module then
- luatexbase.provides_module (ProvidesLuaModule)
- end
end
local hb = luaotfload.harfbuzz
@@ -36,6 +32,7 @@ local direct = node.direct
local tonode = direct.tonode
local todirect = direct.todirect
local traverse = direct.traverse
+local traverse_list = direct.traverse_list
local insertbefore = direct.insert_before
local insertafter = direct.insert_after
local protectglyph = direct.protect_glyph
@@ -46,6 +43,7 @@ local removenode = direct.remove
local copynodelist = direct.copy_list
local ischar = direct.is_char
local uses_font = direct.uses_font
+local length = direct.length
local getattrs = direct.getattributelist
local setattrs = direct.setattributelist
@@ -78,13 +76,15 @@ local getsubtype = direct.getsubtype
local setsubtype = direct.setsubtype
local getwidth = direct.getwidth
local setwidth = direct.setwidth
+local setlist = direct.setlist
local is_char = direct.is_char
local tail = direct.tail
+local getboth = direct.getboth
+local setlink = direct.setlink
local properties = direct.get_properties_table()
-local imgnode = img.node
-
+local hlist_t = node.id("hlist")
local disc_t = node.id("disc")
local glue_t = node.id("glue")
local glyph_t = node.id("glyph")
@@ -94,7 +94,10 @@ local localpar_t = node.id("local_par")
local whatsit_t = node.id("whatsit")
local pdfliteral_t = node.subtype("pdf_literal")
+local line_t = 1
local explicitdisc_t = 1
+local firstdisc_t = 4
+local seconddisc_t = 5
local fontkern_t = 0
local italiccorr_t = 3
local regulardisc_t = 3
@@ -179,8 +182,12 @@ local function itemize(head, fontid, direction)
local currdir = direction or 0
local lastskip, lastdir = true
local lastrun = {}
+ local lastdisc
+ local in_disc
- for n, id, subtype in direct.traverse(head) do
+ for n, id, subtype in traverse(head) do
+ if in_disc == n then in_disc = nil end
+ local disc
local code = 0xFFFC -- OBJECT REPLACEMENT CHARACTER
local skip = lastskip
local props = properties[n]
@@ -189,8 +196,9 @@ local function itemize(head, fontid, direction)
code = 0x200C
-- skip = false -- Not sure about this, but lastskip should be a bit faster
elseif id == glyph_t then
- if is_char(n) and getfont(n) == fontid then
- code = getchar(n)
+ local char = is_char(n, fontid)
+ if char then
+ code = char
skip = false
else
skip = true
@@ -199,8 +207,28 @@ local function itemize(head, fontid, direction)
code = 0x0020 -- SPACE
elseif id == disc_t then
if uses_font(n, fontid) then
- code = 0x00AD -- SOFT HYPHEN
+ local _, _, rep, _, _, rep_tail = getdisc(n, true)
+ setfield(n, 'replace', nil)
+ local prev, next = getboth(n)
+ in_disc = next
+ disc = {
+ disc = n,
+ anchor_cluster = #codes - (lastrun.start or 0) + 1,
+ after_cluster = #codes - (lastrun.start or 0) + 1 + length(rep),
+ }
+ if rep then
+ setlink(rep_tail, next)
+ setnext(n, rep) -- This one is just to keep the loop going
+ n = rep
+ else
+ n = next
+ end
+ setlink(prev, n)
+ code = nil
skip = false
+ if not prev then
+ head = n
+ end
else
skip = true
end
@@ -220,26 +248,39 @@ local function itemize(head, fontid, direction)
currdir = getdirection(n)
end
- codes[#codes + 1] = code
+ local ncodes = #codes -- Necessary to count discs correctly
+ codes[ncodes + 1] = code
- if lastdir ~= currdir or lastskip ~= skip then
+ if (disc or not in_disc) and (lastdir ~= currdir or lastskip ~= skip) then
+ if disc then
+ disc.after_cluster = disc.after_cluster - disc.anchor_cluster
+ disc.anchor_cluster = 0
+ end
lastrun.after = n
lastrun = {
- start = #codes,
- len = 1,
+ start = ncodes + 1,
+ len = code and 1 or 0,
font = fontid,
dir = currdir == 1 and dir_rtl or dir_ltr,
skip = skip,
codes = codes,
+ discs = disc,
}
runs[#runs + 1] = lastrun
- lastdir, lastskip = currdir, skip
- else
+ lastdir, lastskip, lastdisc = currdir, skip, disc
+ elseif code then
lastrun.len = lastrun.len + 1
+ elseif disc then
+ if lastdisc then
+ lastdisc.next = disc
+ lastdisc = disc
+ else
+ lastrun.discs, lastdisc = disc, disc
+ end
end
end
- return runs
+ return head, runs
end
@@ -260,7 +301,6 @@ local function makesub(run, codes, nodelist)
font = run.font,
dir = run.dir,
fordisc = true,
- node = nodelist,
codes = codes,
}
local glyphs
@@ -294,14 +334,12 @@ end
function shape(head, firstnode, run)
local node = firstnode
local codes = run.codes
- local offset = run.start
- local nodeindex = offset
- run.start = offset
+ local offset = run.start - 1 -- -1 because we want the cluster
local len = run.len
local fontid = run.font
local dir = run.dir
- local fordisc = run.fordisc
- local cluster = offset - 2
+ local cluster
+ local discs = (not run.fordisc) and run.discs
local fontdata = font.getfont(fontid)
local hbdata = fontdata.hb
@@ -323,7 +361,7 @@ function shape(head, firstnode, run)
buf:set_script(script)
buf:set_language(lang)
buf:set_cluster_level(buf.CLUSTER_LEVEL_MONOTONE_CHARACTERS)
- buf:add_codepoints(codes, offset - 1, len)
+ buf:add_codepoints(codes, offset, len)
local hscale = hbdata.hscale
local vscale = hbdata.vscale
@@ -333,7 +371,7 @@ function shape(head, firstnode, run)
features = table.merged(features) -- We don't want to modify the global features
local current_features = {}
local n = node
- for i = offset-1, offset+len-2 do
+ for i = offset, offset+len-1 do
local props = properties[n] or empty_table
if props then
local local_feat = props.glyph_features or empty_table
@@ -371,187 +409,260 @@ function shape(head, firstnode, run)
local glyphs = buf:get_glyphs()
+ local break_glyph, break_cluster, break_node = 1, offset, node
+ local disc_glyph, disc_cluster, disc_node
+ local disc_cluster
local i = 0
- while i < #glyphs do
- i = i + 1
- local glyph = glyphs[i]
-
- -- Calculate the Unicode code points of this glyph. If cluster did not
- -- change then this is a glyph inside a complex cluster and will be
- -- handled with the start of its cluster.
- if cluster ~= glyph.cluster then
- cluster = glyph.cluster
- for i = nodeindex, cluster do node = getnext(node) end
- nodeindex = cluster + 1
- local hex = ""
- local str = ""
- local nextcluster
- for j = i+1, #glyphs do
- nextcluster = glyphs[j].cluster
- if cluster ~= nextcluster then
- glyph.nglyphs = j - i
- goto NEXTCLUSTERFOUND -- break
- end
- end -- else -- only executed if the loop reached the end without
- -- finding another cluster
- nextcluster = offset + len - 1
- glyph.nglyphs = #glyphs + 1 - i
- ::NEXTCLUSTERFOUND:: -- end
- glyph.nextcluster = nextcluster
- do
- local node = node
- for j = cluster,nextcluster-1 do
- local id = getid(node)
- if id == glyph_t or (id == glue_t and getsubtype(node) == spaceskip_t) then
- local code = codes[j + 1]
- hex = hex..to_utf16_hex(code)
- str = str..utf8.char(code)
- end
+ local glyph
+ -- The following is a repeat {...} while glyph {...} loop.
+ while true do
+ repeat
+ i = i+1
+ glyph = glyphs[i]
+ until not glyph or glyph.cluster ~= cluster
+ do
+ local oldcluster = cluster
+ cluster = glyph and glyph.cluster or offset + len
+ if oldcluster then
+ for _ = oldcluster+1, cluster do
+ node = getnext(node)
end
- glyph.tounicode = hex
- glyph.string = str
end
- if not fordisc then
- local discindex = nil
- local disc = node
- for j = cluster + 1, nextcluster do
- local props = properties[disc]
- if (not (props and props.zwnj)) and getid(disc) == disc_t then
- discindex = j
- break
+ end
+
+ -- Is this a safe breakpoint?
+ if discs and ((not glyph) or codes[cluster] == 0x20 or codes[cluster+1] == 0x20 or codes[cluster+1] == 0xFFFC
+ or not unsafetobreak(glyph)) then
+ -- Should we change the discretionary state?
+ local anchor_cluster, after_cluster = offset + discs.anchor_cluster, offset + discs.after_cluster
+ local saved_anchor, saved_after = (discs.next and discs.next.anchor_cluster or math.huge) + offset
+ while disc_cluster and after_cluster <= cluster
+ or not disc_cluster and anchor_cluster <= cluster do
+ if disc_cluster then
+ if not saved_after and saved_anchor < cluster then
+ saved_after = discs.next.after_cluster + offset
+ if saved_after > cluster then
+ saved_after, after_cluster = after_cluster, saved_after
+ break
+ end
+ elseif saved_after then
+ saved_after, after_cluster = after_cluster, saved_after
end
- disc = getnext(disc)
- end
- if discindex then
- -- Discretionary found.
- local startindex, stopindex = nil, nil
- local startglyph, stopglyph = nil, nil
-
- -- Find the previous glyph that is safe to break at.
- local startglyph = i
- while startglyph > 1
- and codes[glyphs[startglyph - 1].cluster + 1] ~= 0x20
- and codes[glyphs[startglyph - 1].cluster + 1] ~= 0xFFFC
- and (unsafetobreak(glyphs[startglyph])
- or glyphs[startglyph].cluster == glyphs[startglyph-1].cluster) do
- startglyph = startglyph - 1
+ local rep_glyphs = table.move(glyphs, disc_glyph, i - 1, 1, {})
+ for j = 1, #rep_glyphs do
+ local glyph = rep_glyphs[j]
+ glyph.cluster = glyph.cluster - disc_cluster
+ glyph.nextcluster = glyph.nextcluster - disc_cluster
end
- -- Get the corresponding character index.
- startindex = glyphs[startglyph].cluster + 1
-
- -- Find the next glyph that is safe to break at.
- stopglyph = i + 1
- local lastcluster = glyphs[i].cluster
- while stopglyph <= #glyphs
- and codes[glyphs[stopglyph].cluster + 1] ~= 0x20
- and codes[glyphs[stopglyph].cluster + 1] ~= 0xFFFC
- and (unsafetobreak(glyphs[stopglyph])
- or lastcluster == glyphs[stopglyph].cluster) do
- lastcluster = glyphs[stopglyph].cluster
- stopglyph = stopglyph + 1
+ do
+ local cluster_offset = disc_cluster - cluster + (saved_after and 2 or 1) -- The offset the glyph indices will move
+ for j = i, #glyphs do
+ local glyph = glyphs[j]
+ glyph.cluster = glyph.cluster + cluster_offset
+ end
+ len = len + cluster_offset
+ table.move(glyphs, i, #glyphs + i - disc_glyph, disc_glyph + (saved_after and 2 or 1))
+
+ local discs = discs.next
+ while discs do
+ discs.anchor_cluster = discs.anchor_cluster + cluster_offset
+ discs.after_cluster = discs.after_cluster + cluster_offset
+ discs = discs.next
+ end
end
- stopindex = stopglyph <= #glyphs and glyphs[stopglyph].cluster + 1
- or offset + len
-
- local startnode, stopnode = node, node
- for j=nodeindex - 1, startindex, -1 do
- startnode = getprev(startnode)
+ local pre, post, _, _, lastpost, _ = getdisc(discs.disc, true)
+ local precodes, postcodes, repcodes = {}, {}
+ table.move(codes, disc_cluster + 1, anchor_cluster, 1, precodes)
+ for n in traverse(pre) do
+ precodes[#precodes + 1] = is_char(n, fontid) or 0xFFFC
end
- for j=nodeindex + 1, stopindex do
- stopnode = getnext(stopnode)
+ for n in traverse(post) do
+ postcodes[#postcodes + 1] = is_char(n, fontid) or 0xFFFC
end
+ table.move(codes, after_cluster + 1, cluster, #postcodes + 1, postcodes)
- glyphs[startglyph] = glyph
- glyph.cluster = startindex - 1
- glyph.nextcluster = startindex
- for j = stopglyph, #glyphs do
- local glyph = glyphs[j]
- glyph.cluster = glyph.cluster - (stopindex - startindex) + 1
+ if saved_after then
+ repcodes = table.move(codes, disc_cluster + 1, cluster, 1, {})
+ table.move(codes, cluster + 1, #codes + cluster - disc_cluster, disc_cluster + 3)
+ codes[disc_cluster + 1], codes[disc_cluster + 2] = 0xFFFC, 0xFFFC
+ else
+ table.move(codes, cluster + 1, #codes + cluster - disc_cluster, disc_cluster + 2)
+ codes[disc_cluster + 1] = 0xFFFC
end
- len = len - (stopindex - startindex) + 1
- table.move(glyphs, stopglyph, #glyphs + stopglyph - startglyph - 1, startglyph + 1)
- local subcodes, subindex = {}
do
- local node = startnode
- while node ~= stopnode do
- if node == disc then
- subindex = #subcodes
- startindex = startindex + 1
- node = getnext(node)
- elseif getid(node) == disc_t then
- local oldnode = node
- startnode, node = removenode(startnode, node)
- freenode(oldnode)
- tableremove(codes, startindex)
- else
- subcodes[#subcodes + 1] = tableremove(codes, startindex)
- node = getnext(node)
- end
+ local iter = disc_node
+ for _ = disc_cluster, anchor_cluster-1 do iter = getnext(iter) end
+ if iter ~= disc_node then
+ local newpre = copynodelist(disc_node, iter)
+ setlink(tail(newpre), pre)
+ pre = newpre
+ end
+ for _ = anchor_cluster, after_cluster-1 do iter = getnext(iter) end
+ if post then
+ setlink(lastpost, copynodelist(iter, node))
+ else
+ post = copynodelist(iter, node)
end
end
-
- local pre, post, rep, lastpre, lastpost, lastrep = getdisc(disc, true)
- local precodes, postcodes, repcodes = {}, {}, {}
- table.move(subcodes, 1, subindex, 1, repcodes)
- for n, id, subtype in traverse(rep) do
- repcodes[#repcodes + 1] = getfont(n) == fontid and getchar(n) or 0xFFFC
- end
- table.move(subcodes, subindex + 1, #subcodes, #repcodes + 1, repcodes)
- table.move(subcodes, 1, subindex, 1, precodes)
- for n, id, subtype in traverse(pre) do
- precodes[#precodes + 1] = getfont(n) == fontid and getchar(n) or 0xFFFC
- end
- for n, id, subtype in traverse(post) do
- postcodes[#postcodes + 1] = getfont(n) == fontid and getchar(n) or 0xFFFC
- end
- table.move(subcodes, subindex + 1, #subcodes, #postcodes + 1, postcodes)
- if startnode ~= disc then
- local newpre = copynodelist(startnode, disc)
- setnext(tail(newpre), pre)
- pre = newpre
+ local prev = getprev(disc_node)
+ if disc_cluster ~= cluster then
+ setprev(disc_node, nil)
+ setnext(getprev(node), nil)
end
- if post then
- setnext(lastpost, copynodelist(getnext(disc), stopnode))
- else
- post = copynodelist(getnext(disc), stopnode)
+ setlink(prev, discs.disc, node)
+ if disc_node == firstnode then
+ firstnode = discs.disc
+ if head == disc_node then
+ head = firstnode
+ end
end
- if startnode ~= disc then
- local predisc = getprev(disc)
- setnext(predisc, rep)
- setprev(rep, predisc)
- if firstnode == startnode then
- firstnode = disc
+ glyphs[disc_glyph] = {
+ replace = {
+ glyphs = rep_glyphs,
+ head = disc_node ~= node and disc_node or nil,
+ run = {
+ start = 1,
+ font = run.font,
+ dir = run.dir,
+ },
+ },
+ pre = makesub(run, precodes, pre),
+ post = makesub(run, postcodes, post),
+ cluster = disc_cluster,
+ nextcluster = disc_cluster + 1,
+ codepoint = 0xFFFC,
+ }
+ if saved_after then
+ local next_disc = discs.next
+ setlink(discs.disc, next_disc.disc, node)
+ local next_pre, next_post, _, _, next_lastpost, _ = getdisc(next_disc.disc, true)
+ local next_rep = copynodelist(next_pre)
+ -- Let's play the game again. We need three parts:
+ -- The pre and post branches in the outer post branch
+ local next_precodes, next_postcodes, next_repcodes = {}, {}, {}
+ do
+ local saved_offset = length(post) - cluster
+ local saved_anchor, saved_after = saved_anchor + saved_offset, saved_after + saved_offset
+ table.move(postcodes, 1, saved_anchor, 1, next_precodes)
+ for n in traverse(next_pre) do
+ next_precodes[#next_precodes + 1] = is_char(n, fontid) or 0xFFFC
+ end
+ for n in traverse(next_post) do
+ next_postcodes[#next_postcodes + 1] = is_char(n, fontid) or 0xFFFC
+ end
+ table.move(postcodes, saved_after + 1, #postcodes, #next_postcodes + 1, next_postcodes)
+
+ local iter = post
+ for _ = 1, saved_anchor do iter = getnext(iter) end
+ if iter ~= post then
+ local newpre = copynodelist(post, iter)
+ setlink(tail(newpre), next_pre)
+ next_pre = newpre
+ end
+ for _ = saved_anchor, saved_after - 1 do iter = getnext(iter) end
+ if next_post then
+ setlink(next_lastpost, copynodelist(iter))
+ else
+ next_post = copynodelist(iter)
+ end
end
- if startnode == head then
- head = disc
- else
- local before = getprev(startnode)
- setnext(before, disc)
- setprev(disc, before)
+ -- The pre branch in the outer replace branch. The post branch is implicitly the same as the previous one
+ do
+ local saved_anchor = saved_anchor - disc_cluster
+ table.move(repcodes, 1, saved_anchor, 1, next_repcodes)
+ for n in traverse(next_rep) do
+ next_repcodes[#next_repcodes + 1] = is_char(n, fontid) or 0xFFFC
+ end
+
+ local rep = glyphs[disc_glyph].replace.head
+ local iter = rep
+ for _ = 1, saved_anchor do iter = getnext(iter) end
+ if iter ~= rep then
+ local newpre = copynodelist(rep, iter)
+ setlink(tail(newpre), next_rep)
+ next_rep = newpre
+ end
end
- setprev(startnode, nil)
- rep = startnode
- lastrep = lastrep or predisc
+ setsubtype(discs.disc, firstdisc_t)
+ setsubtype(next_disc.disc, seconddisc_t)
+ discs = discs.next
+ disc_glyph = disc_glyph + 1
+ disc_cluster = disc_cluster + 1
+ glyphs[disc_glyph] = {
+ replace = makesub(run, next_repcodes, next_rep),
+ pre = makesub(run, next_precodes, next_pre),
+ post = makesub(run, next_postcodes, next_post),
+ cluster = disc_cluster,
+ nextcluster = disc_cluster + 1,
+ codepoint = 0xFFFC,
+ }
+ end
+ i = disc_glyph + 1
+ assert(node == getnext(discs.disc))
+ cluster = disc_cluster + 1
+
+ disc_cluster = nil
+ discs = discs.next
+ while discs and discs.anchor_cluster + offset < cluster do
+ freenode(discs.disc)
+ discs = discs.next
end
- if getnext(disc) ~= stopnode then
- setnext(getprev(stopnode), nil)
- setprev(stopnode, disc)
- setprev(getnext(disc), lastrep)
- setnext(lastrep, getnext(disc))
- rep = rep or getnext(disc)
- setnext(disc, stopnode)
+ if not discs then break end
+ anchor_cluster, after_cluster = offset + discs.anchor_cluster, offset + discs.after_cluster
+ saved_anchor, saved_after = (discs.next and discs.next.anchor_cluster or math.huge) + offset
+ elseif anchor_cluster == cluster then
+ disc_glyph, disc_cluster, disc_node = i, cluster, node
+ else
+ disc_glyph, disc_cluster, disc_node = break_glyph, break_cluster, break_node
+ end
+ end
+ break_glyph, break_cluster, break_node = i, cluster, node
+ end
+
+ if not glyph then break end
+
+ local nextcluster
+ for j = i+1, #glyphs do
+ nextcluster = glyphs[j].cluster
+ if cluster ~= nextcluster then
+ glyph.nglyphs = j - i
+ goto NEXTCLUSTERFOUND -- break
+ end
+ end -- else -- only executed if the loop reached the end without
+ -- finding another cluster
+ nextcluster = offset + len
+ glyph.nglyphs = #glyphs + 1 - i
+ ::NEXTCLUSTERFOUND:: -- end
+ glyph.nextcluster = nextcluster
+
+ local disc, discindex
+ -- Calculate the Unicode code points of this glyph. If cluster did not
+ -- change then this is a glyph inside a complex cluster and will be
+ -- handled with the start of its cluster.
+ do
+ local hex = ""
+ local str = ""
+ local node = node
+ for j = cluster+1,nextcluster do
+ local char, id = is_char(node, fontid)
+ if char then
+ -- assert(char == codes[j])
+ hex = hex .. to_utf16_hex(char)
+ str = str .. utf8.char(char)
+ elseif not discindex and id == disc_t then
+ local props = properties[disc]
+ if not (props and props.zwnj) then
+ disc, discindex = node, j
end
- glyph.replace = makesub(run, repcodes, rep)
- glyph.pre = makesub(run, precodes, pre)
- glyph.post = makesub(run, postcodes, post)
- i = startglyph
- node = disc
- cluster = glyph.cluster
- nodeindex = cluster + 1
end
+ node = getnext(node)
end
+ glyph.tounicode = hex
+ glyph.string = str
+ end
+ if not fordisc and discindex then
end
end
return head, firstnode, glyphs, run.len - len
@@ -587,7 +698,7 @@ local function color_to_rgba(color)
end
end
--- Cache of color glyph PNG data for bookkeeping, only because I couldn’t
+-- Cache of color glyph PNG data for bookkeeping, only because I couldn't
-- figure how to make the engine load the image from the binary data directly.
local pngcache = {}
local pngcachefiles = {}
@@ -672,7 +783,7 @@ local function tonodes(head, node, run, glyphs)
end
local gid = glyph.codepoint
local char = nominals[gid] or gid_offset + gid
- local id = getid(node)
+ local orig_char, id = is_char(node, fontid)
if glyph.replace then
-- For discretionary the glyph itself is skipped and a discretionary node
@@ -681,17 +792,12 @@ local function tonodes(head, node, run, glyphs)
setdisc(node, tonodes(pre.head, pre.head, pre.run, pre.glyphs),
tonodes(post.head, post.head, post.run, post.glyphs),
- tonodes(rep.head, rep.head, rep.run, rep.glyphs))
+ (tonodes(rep.head, rep.head, rep.run, rep.glyphs)))
node = getnext(node)
nodeindex = nodeindex + 1
- elseif glyph.skip then
- local oldnode = node
- head, node = removenode(head, node)
- freenode(oldnode)
- nodeindex = nodeindex + 1
else
if lastprops and lastprops.zwnj and nodeindex == glyph.cluster + 1 then
- elseif id == glyph_t then
+ elseif orig_char then
local done
local fontglyph = fontglyphs[gid]
local character = characters[char]
@@ -717,7 +823,7 @@ local function tonodes(head, node, run, glyphs)
character.depth = layerchar.depth
end
-- color_index has a special value, 0x10000, that mean use text
- -- color, we don’t check for it here explicitly since we will
+ -- color, we don't check for it here explicitly since we will
-- get nil anyway.
local color = palette[layer.color_index]
if not color or color.alpha ~= 0 then
@@ -787,7 +893,7 @@ local function tonodes(head, node, run, glyphs)
-- Color bitmap font with no glyph outlines (like Noto
-- Color Emoji) but has no bitmap for current glyph (most likely
-- `.notdef` glyph). The engine does not know how to embed such
- -- fonts, so we don’t want them to reach the backend as it will cause
+ -- fonts, so we don't want them to reach the backend as it will cause
-- a fatal error. We use `nullfont` instead. That is a hack, but I
-- think it is good enough for now. We could make the glyph virtual
-- with empty commands suh that LuaTeX ignores it, but we still want
@@ -799,7 +905,7 @@ local function tonodes(head, node, run, glyphs)
end
end
if not done then
- local oldcharacter = characters[getchar(node)]
+ local oldcharacter = characters[orig_char]
-- If the glyph index of current font character is the same as shaped
-- glyph, keep the node char unchanged. Helps with primitives that
-- take characters as input but actually work on glyphs, like
@@ -824,7 +930,7 @@ local function tonodes(head, node, run, glyphs)
-- overfull messages, otherwise it will be trying to print our
-- invalid pseudo Unicode code points.
-- If the string is empty it means this glyph is part of a larger
- -- cluster and we don’t to print anything for it as the first glyph
+ -- cluster and we don't to print anything for it as the first glyph
-- in the cluster will have the string of the whole cluster.
local props = properties[node]
if not props then
@@ -837,7 +943,7 @@ local function tonodes(head, node, run, glyphs)
-- * Find how many characters in this cluster and how many glyphs,
-- * If there is more than 0 characters
-- * One glyph: one to one or one to many mapping, can be
- -- represented by font’s /ToUnicode
+ -- represented by font's /ToUnicode
-- * More than one: many to one or many to many mapping, can be
-- represented by /ActualText spans.
-- * If there are zero characters, then this glyph is part of complex
@@ -883,7 +989,7 @@ local function tonodes(head, node, run, glyphs)
end
elseif id == kern_t and getsubtype(node) == italiccorr_t then
-- If this is an italic correction node and the previous node is a
- -- glyph, update its kern value with the glyph’s italic correction.
+ -- glyph, update its kern value with the glyph's italic correction.
local prevchar, prevfontid = ischar(getprev(node))
if prevfontid == fontid and prevchar and prevchar > 0 then
local italic = characters[prevchar].italic
@@ -919,8 +1025,8 @@ local function shape_run(head, current, run)
end
function process(head, font, _attr, direction)
- local newhead, current = head, head
- local runs = itemize(head, font, direction)
+ local newhead, runs = itemize(head, font, direction)
+ local current = newhead
local offset = 0
for i = 1,#runs do
@@ -954,29 +1060,39 @@ local function post_process(head)
if startactual then
local actualtext = "/Span<</ActualText<FEFF"..startactual..">>>BDC"
head = insertbefore(head, n, pageliteral(actualtext))
+ props[startactual_p] = nil
end
if endactual then
head = insertafter(head, n, pageliteral("EMC"))
+ props[endactual_p] = nil
end
local replace = getfield(n, "replace")
if replace then
setfield(n, "replace", post_process(replace))
end
+ end
+ return head
+end
- local subhead = getfield(n, "head")
- if subhead then
- setfield(n, "head", post_process(subhead))
+local function post_process_vlist(head)
+ for n, id, subtype, list in traverse_list(head) do
+ if id == hlist_t and subtype == line_t then
+ setlist(n, post_process(list))
end
end
- return head
+ return true
end
-local function post_process_nodes(head, groupcode)
+local function post_process_nodes(head)
return tonode(post_process(todirect(head)))
end
+local function post_process_vlist_nodes(head)
+ return tonode(post_process_vlist(todirect(head)))
+end
+
local function run_cleanup()
-- Remove temporary PNG files that we created, if any.
-- FIXME: It would be nice if we wouldn't need this
@@ -1032,29 +1148,10 @@ end
fonts.handlers.otf.registerplugin('harf', process)
--- luatexbase does not know how to handle `wrapup_run` callback, teach it.
--- TODO: Move these into ltluatex
-luatexbase.callbacktypes.wrapup_run = 1 -- simple
-luatexbase.callbacktypes.glyph_info = 1 -- simple
-
-local base_callback_descriptions = luatexbase.callback_descriptions
-local base_add_to_callback = luatexbase.add_to_callback
-local base_remove_from_callback = luatexbase.remove_from_callback
-
--- Remove all existing functions from given callback, insert ours, then
--- reinsert the removed ones, so ours takes a priority.
-local function add_to_callback(name, func)
- local saved_callbacks = {}, ff, dd
- for k, v in next, base_callback_descriptions(name) do
- saved_callbacks[k] = { base_remove_from_callback(name, v) }
- end
- base_add_to_callback(name, func, "Harf "..name.." callback")
- for _, v in next, saved_callbacks do
- base_add_to_callback(name, v[1], v[2])
- end
-end
+local add_to_callback = luatexbase.add_to_callback
-add_to_callback('pre_output_filter', post_process_nodes) -- FIXME: Wrong callback, but I want to get rid of the whole function anyway
-add_to_callback('wrapup_run', run_cleanup)
-add_to_callback('finish_pdffile', set_tounicode)
-add_to_callback('glyph_info', get_glyph_info)
+add_to_callback('post_linebreak_filter', post_process_vlist_nodes, 'luaotfload.harf.finalize_vlist')
+add_to_callback('hpack_filter', post_process_nodes, 'luaotfload.harf.finalize_hlist')
+add_to_callback('wrapup_run', run_cleanup, 'luaotfload.cleanup_files')
+add_to_callback('finish_pdffile', set_tounicode, 'luaotfload.harf.finalize_unicode')
+add_to_callback('glyph_info', get_glyph_info, 'luaotfload.glyphinfo')
diff --git a/macros/luatex/generic/luaotfload/luaotfload-init.lua b/macros/luatex/generic/luaotfload/luaotfload-init.lua
index cfbcb68eab..3b67738fe5 100644
--- a/macros/luatex/generic/luaotfload/luaotfload-init.lua
+++ b/macros/luatex/generic/luaotfload/luaotfload-init.lua
@@ -5,17 +5,13 @@
-- AUTHOR: Philipp Gesang (Phg), <phg@phi-gamma.net>, Marcel Krüger
-----------------------------------------------------------------------
-local ProvidesLuaModule = {
+assert(luaotfload_module, "This is a part of luaotfload and should not be loaded independently") {
name = "luaotfload-init",
- version = "3.15", --TAGVERSION
- date = "2020-09-02", --TAGDATE
+ version = "3.16", --TAGVERSION
+ date = "2020-12-31", --TAGDATE
description = "luaotfload submodule / initialization",
license = "GPL v2.0"
}
-
-if luatexbase and luatexbase.provides_module then
- luatexbase.provides_module (ProvidesLuaModule)
-end
-----------------------------------------------------------------------
@@ -299,7 +295,6 @@ local function init_main(early_hook)
local saved_exit = os.exit
local errmsg
function texio.reporter(msg, ...)
- print(...)
errmsg = msg
end
function os.exit()
@@ -407,6 +402,11 @@ local function init_main(early_hook)
-- fontloader
end --- [init_main]
+if not luatexbase.callbacktypes.pre_shaping_filter then
+ luatexbase.create_callback('pre_shaping_filter', 'list')
+ luatexbase.create_callback('post_shaping_filter', 'reverselist')
+end
+
local init_post_install_callbacks = function ()
--[[doc--
@@ -423,17 +423,42 @@ local init_post_install_callbacks = function ()
local fallback = luaotfload.loaders.luaotfload "fallback".process
local multiscript = luaotfload.loaders.luaotfload "multiscript".process
- -- MK Pass current text direction to simple_font_handler
+ local call_callback = luatexbase.call_callback
+ local tex_get = tex.get
+ local flush_list = node.flush_list
local handler = luaotfload.fontloader.nodes.simple_font_handler
- local callback = function(head, groupcode, _, _, direction)
+ local function callback(head, groupcode, _, _, direction)
if not direction then
- direction = tex.get'textdirection'
+ direction = tex_get'textdirection'
else
direction = direction == "TRT" and 1 or 0
end
+ local result = call_callback("pre_shaping_filter", head, groupcode, direction)
+ if result == false then
+ return false
+ elseif result ~= true then
+ head = result
+ end
multiscript(head, nil, nil, nil, direction)
fallback(head, nil, nil, nil, direction)
- return handler(head, groupcode, nil, nil, direction)
+ result = handler(head, groupcode, nil, nil, direction)
+ -- handler never returns a boolean and only returns nil if it was passed in
+ -- We keep it general though for consistency
+ if result == false then
+ flush_list(head)
+ return nil
+ elseif result ~= true then
+ head = result
+ end
+ result = call_callback("post_shaping_filter", head, groupcode, direction)
+ if result == false then
+ flush_list(head)
+ return nil
+ elseif result == true then
+ return head
+ else
+ return result
+ end
end
luatexbase.add_to_callback("pre_linebreak_filter",
callback,
@@ -443,7 +468,6 @@ local init_post_install_callbacks = function ()
callback,
"luaotfload.node_processor",
1)
- -- /MK
local streams = fonts.hashes.streams
luatexbase.add_to_callback("glyph_stream_provider",function(id,index,mode)
diff --git a/macros/luatex/generic/luaotfload/luaotfload-latex.pdf b/macros/luatex/generic/luaotfload/luaotfload-latex.pdf
index df1a8e0e86..299ff211aa 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 dcf6507881..40b01af0de 100644
--- a/macros/luatex/generic/luaotfload/luaotfload-latex.tex
+++ b/macros/luatex/generic/luaotfload/luaotfload-latex.tex
@@ -260,7 +260,7 @@
local stringsub = string.sub
local stringgsub = string.gsub
%local backslash = unicode.utf8.char (0x200c)
- local backslash = unicode.utf8.char (0x5c)
+ local backslash = string.char(0x5c)
local escaped = [[\string\string\string\]]
document.printlines = function (buffer)
local lines = string.explode (buffer, "\noexpand\n")
diff --git a/macros/luatex/generic/luaotfload/luaotfload-letterspace.lua b/macros/luatex/generic/luaotfload/luaotfload-letterspace.lua
index f9c24a1335..c1a3d6f1b7 100644
--- a/macros/luatex/generic/luaotfload/luaotfload-letterspace.lua
+++ b/macros/luatex/generic/luaotfload/luaotfload-letterspace.lua
@@ -3,20 +3,16 @@
-- DESCRIPTION: part of luaotfload / letterspacing
-----------------------------------------------------------------------
-local ProvidesLuaModule = {
+assert(luaotfload_module, "This is a part of luaotfload and should not be loaded independently") {
name = "luaotfload-letterspace",
- version = "3.15", --TAGVERSION
- date = "2020-09-02", --TAGDATE
+ version = "3.16", --TAGVERSION
+ date = "2020-12-31", --TAGDATE
description = "luaotfload submodule / letterspacing",
license = "GPL v2.0",
copyright = "PRAGMA ADE / ConTeXt Development Team",
author = "Hans Hagen, PRAGMA-ADE, Hasselt NL; adapted by Philipp Gesang, Ulrike Fischer, Marcel Krüger"
}
-if luatexbase and luatexbase.provides_module then
- luatexbase.provides_module (ProvidesLuaModule)
-end
-
--- This code diverged quite a bit from its origin in Context. Please
--- do *not* report bugs on the Context list.
diff --git a/macros/luatex/generic/luaotfload/luaotfload-loaders.lua b/macros/luatex/generic/luaotfload/luaotfload-loaders.lua
index a63506237a..84c5555f5d 100644
--- a/macros/luatex/generic/luaotfload/luaotfload-loaders.lua
+++ b/macros/luatex/generic/luaotfload/luaotfload-loaders.lua
@@ -6,17 +6,13 @@
-- AUTHOR: Hans Hagen, Khaled Hosny, Elie Roux, David Carlisle
-----------------------------------------------------------------------
-local ProvidesLuaModule = {
+assert(luaotfload_module, "This is a part of luaotfload and should not be loaded independently") {
name = "luaotfload-loaders",
- version = "3.15", --TAGVERSION
- date = "2020-09-02", --TAGDATE
+ version = "3.16", --TAGVERSION
+ date = "2020-12-31", --TAGDATE
description = "luaotfload submodule / callback handling",
license = "GPL v2.0"
}
-
-if luatexbase and luatexbase.provides_module then
- luatexbase.provides_module (ProvidesLuaModule)
-end
-----------------------------------------------------------------------
diff --git a/macros/luatex/generic/luaotfload/luaotfload-log.lua b/macros/luatex/generic/luaotfload/luaotfload-log.lua
index b102da65bf..58fc403e62 100644
--- a/macros/luatex/generic/luaotfload/luaotfload-log.lua
+++ b/macros/luatex/generic/luaotfload/luaotfload-log.lua
@@ -4,21 +4,16 @@
-------------------------------------------------------------------------------
-local ProvidesLuaModule = {
+assert(luaotfload_module, "This is a part of luaotfload and should not be loaded independently") {
name = "luaotfload-log",
- version = "3.15", --TAGVERSION
- date = "2020-09-02", --TAGDATE
+ version = "3.16", --TAGVERSION
+ date = "2020-12-31", --TAGDATE
description = "luaotfload submodule / logging",
license = "GPL v2.0",
author = "Khaled Hosny, Elie Roux, Philipp Gesang",
copyright = "Luaotfload Development Team",
}
-if luatexbase and luatexbase.provides_module then
- luatexbase.provides_module (ProvidesLuaModule)
-end
-
-
--[[doc--
The logging system is slow in general, as we always have the function
call overhead even if we aren’t going to output anything. On the other
diff --git a/macros/luatex/generic/luaotfload/luaotfload-main.lua b/macros/luatex/generic/luaotfload/luaotfload-main.lua
index 5fa8c54ad3..1b029bd514 100644
--- a/macros/luatex/generic/luaotfload/luaotfload-main.lua
+++ b/macros/luatex/generic/luaotfload/luaotfload-main.lua
@@ -1,341 +1,6 @@
-----------------------------------------------------------------------
-- FILE: luaotfload-main.lua
--- DESCRIPTION: OpenType layout system / luaotfload entry point
--- REQUIREMENTS: luatex v.0.95.0 or later; package lualibs
--- AUTHOR: Élie Roux, Khaled Hosny, Philipp Gesang, Ulrike Fischer, Marcel Krüger
+-- DESCRIPTION: OpenType layout system / compatibility wrapper
-----------------------------------------------------------------------
-local authors = "\z
- Hans Hagen,\z
- Khaled Hosny,\z
- Elie Roux,\z
- Will Robertson,\z
- Philipp Gesang,\z
- Dohyun Kim,\z
- Reuben Thomas,\z
- David Carlisle,\
- Ulrike Fischer,\z
- Marcel Krüger\z
-"
--- version number is used below!
-local ProvidesLuaModule = {
- name = "luaotfload-main",
- version = "3.15", --TAGVERSION
- date = "2020-09-02", --TAGDATE
- description = "luaotfload entry point",
- author = authors,
- copyright = authors,
- license = "GPL v2.0"
-}
-
-if luatexbase and luatexbase.provides_module then
- luatexbase.provides_module (ProvidesLuaModule)
-end
-
-local osgettimeofday = os.gettimeofday
-config = config or { }
-luaotfload = luaotfload or { }
-local luaotfload = luaotfload
-luaotfload.log = luaotfload.log or { }
-local logreport
-luaotfload.version = ProvidesLuaModule.version
-luaotfload.loaders = { }
-luaotfload.fontloader_package = "reference" --- default: from current Context
-
-if not tex or not tex.luatexversion then
- error "this program must be run in TeX mode" --- or call tex.initialize() =)
-end
-
---- version check
-local revno = tonumber(tex.luatexrevision)
-local minimum = { 110, 0 }
-if tex.luatexversion < minimum[1] or tex.luatexversion == minimum[1] and revno < minimum[2] then
- texio.write_nl ("term and log",
- string.format ("\tFATAL ERROR\n\z
- \tLuaotfload requires a Luatex version >= %d.%d.%d.\n\z
- \tPlease update your TeX distribution!\n\n",
- math.floor(minimum[1] / 100), minimum[1] % 100, minimum[2]))
- error "version check failed"
-end
-
-if not utf8 then
- texio.write_nl("term and log", string.format("\z
- \tluaotfload: module utf8 is unavailable\n\z
- \tutf8 is available in Lua 5.3+; engine\'s _VERSION is %q\n\z
- \tThis probably means that the engine is not supported\n\z
- \n",
- _VERSION))
- error "module utf8 is unavailable"
-end
-
-if status.safer_option ~= 0 then
- texio.write_nl("term and log","luaotfload can't run with option --safer. Aborting")
- error("safer_option used")
-end
-
-
-
-
---[[doc--
-
- This file initializes the system and loads the font loader. To
- minimize potential conflicts between other packages and the code
- imported from \CONTEXT, several precautions are in order. Some of
- the functionality that the font loader expects to be present, like
- raw access to callbacks, are assumed to have been disabled by
- \identifier{luatexbase} when this file is processed. In some cases
- it is possible to trick it by putting dummies into place and
- restoring the behavior from \identifier{luatexbase} after
- initilization. Other cases such as attribute allocation require
- that we hook the functionality from \identifier{luatexbase} into
- locations where they normally wouldn’t be.
-
- Anyways we can import the code base without modifications, which is
- due mostly to the extra effort by Hans Hagen to make \LUATEX-Fonts
- self-contained and encapsulate it, and especially due to his
- willingness to incorporate our suggestions.
-
---doc]]--
-
-local luatexbase = luatexbase
-local require = require
-local type = type
-
-
---[[doc--
-
- \subsection{Module loading}
- We load the files imported from \CONTEXT with function derived this way. It
- automatically prepends a prefix to its argument, so we can refer to the
- files with their actual \CONTEXT name.
-
---doc]]--
-
-local function make_loader_name (prefix, name)
- local msg = luaotfload.log and luaotfload.log.report
- or function (stream, lvl, cat, ...)
- if lvl > 1 then --[[not pressing]] return end
- texio.write_nl ("log",
- string.format ("luaotfload | %s : ",
- tostring (cat)))
- texio.write (string.format (...))
- end
- if not name then
- msg ("both", 0, "load",
- "Fatal error: make_loader_name (%q, %q).",
- tostring (prefix), tostring (name))
- return "dummy-name"
- end
- name = tostring (name)
- if prefix == false then
- msg ("log", 9, "load",
- "No prefix requested, passing module name %q unmodified.",
- name)
- return tostring (name) .. ".lua"
- end
- prefix = tostring (prefix)
- msg ("log", 9, "load",
- "Composing module name from constituents %s, %s.",
- prefix, name)
- return prefix .. "-" .. name .. ".lua"
-end
-
-local timing_info = {
- t_load = { },
- t_init = { },
-}
-
-local function make_loader (prefix, load_helper)
- return function (name)
- local t_0 = osgettimeofday ()
- local modname = make_loader_name (prefix, name)
- --- We don’t want the stack info from inside, so just pcall().
- local ok, data = pcall (load_helper or require, modname)
- local t_end = osgettimeofday ()
- timing_info.t_load [name] = t_end - t_0
- if not ok then
- io.write "\n"
- local msg = luaotfload.log and luaotfload.log.report or print
- msg ("both", 0, "load", "FATAL ERROR")
- msg ("both", 0, "load", " × Failed to load %q module %q.",
- tostring (prefix), tostring (name))
- local lines = string.split (data, "\n\t")
- if not lines then
- msg ("both", 0, "load", " × Error message: %q", data)
- else
- msg ("both", 0, "load", " × Error message:")
- for i = 1, #lines do
- msg ("both", 0, "load", " × %q.", lines [i])
- end
- end
- io.write "\n\n"
- local debug = debug
- if debug then
- io.write (debug.traceback())
- io.write "\n\n"
- end
- os.exit(-1)
- end
- return data
- end
-end
-
---[[doc--
- Certain files are kept around that aren’t loaded because they are part of
- the imported fontloader. In order to keep the initialization structure
- intact we also provide a no-op version of the module loader that can be
- called in the expected places.
---doc]]--
-
-local function dummy_loader (name)
- luaotfload.log.report ("log", 3, "load",
- "Skipping module %q on purpose.",
- name)
-end
-
-local context_environment = setmetatable({}, {__index = _G})
-luaotfload.fontloader = context_environment
-local function context_isolated_load(name)
- local fullname = kpse.find_file(name, 'lua')
- if not fullname then
- error(string.format('Fontloader module %q could not be found.', name))
- end
- return assert(loadfile(fullname, nil, context_environment))(name)
-end
-
-local function context_loader (name, path)
- luaotfload.log.report ("log", 3, "load",
- "Loading module %q from Context.",
- name)
- local t_0 = osgettimeofday ()
- local modname = make_loader_name (false, name)
- local modpath = modname
- if path then
- if lfs.isdir (path) then
- luaotfload.log.report ("log", 3, "load",
- "Prepending path %q.",
- path)
- modpath = file.join (path, modname)
- else
- luaotfload.log.report ("both", 0, "load",
- "Non-existant path %q specified, ignoring.",
- path)
- end
- end
- local ret = context_isolated_load (modpath)
- local t_end = osgettimeofday ()
- timing_info.t_load [name] = t_end - t_0
-
- if ret ~= nil then
- --- require () returns “true” upon success unless the loaded file
- --- yields a non-zero exit code. This isn’t per se indicating that
- --- something isn’t right, but against HH’s coding practices. We’ll
- --- silently ignore this ever happening on lower log levels.
- luaotfload.log.report ("log", 4, "load",
- "Module %q returned %q.", modname, ret)
- end
- return ret
-end
-
-local function install_loaders ()
- local loaders = { }
- local loadmodule = make_loader "luaotfload"
- loaders.luaotfload = loadmodule
- loaders.fontloader = make_loader ("fontloader", context_isolated_load)
- loaders.context = context_loader
- loaders.ignore = dummy_loader
-----loaders.plaintex = make_loader "luatex" --=> for Luatex-Plain
-
- function loaders.initialize (name)
- local tmp = loadmodule (name)
- local init = type(tmp) == "table" and tmp.init or tmp
- if init and type (init) == "function" then
- local t_0 = osgettimeofday ()
- if not init () then
- logreport ("log", 0, "load",
- "Failed to load module %q.", name)
- return
- end
- local t_end = osgettimeofday ()
- local d_t = t_end - t_0
- logreport ("log", 4, "load",
- "Module %q loaded in %g ms.",
- name, d_t * 1000)
- timing_info.t_init [name] = d_t
- end
- end
-
- return loaders
-end
-
-local luaotfload_initialized = false --- prevent multiple invocations
-
-luaotfload.main = function ()
-
- if luaotfload_initialized then
- logreport ("log", 0, "load",
- "Luaotfload initialization requested but is already \z
- loaded, ignoring.")
- return
- end
- luaotfload_initialized = true
-
- luaotfload.loaders = install_loaders ()
- local loaders = luaotfload.loaders
- local loadmodule = loaders.luaotfload
- local initialize = loaders.initialize
-
- local starttime = osgettimeofday ()
-
- -- Feature detect HarfBuzz. This is done early to allow easy HarfBuzz
- -- detection in other modules
- local harfstatus, harfbuzz = pcall(require, 'luaharfbuzz')
- if harfstatus then
- luaotfload.harfbuzz = harfbuzz
- end
-
- local init = loadmodule "init" --- fontloader initialization
- init (function ()
-
- logreport = luaotfload.log.report
- initialize "parsers" --- fonts.conf and syntax
- initialize "configuration" --- configuration options
- end)
-
- initialize "loaders" --- Font loading; callbacks
- initialize "database" --- Font management.
- initialize "colors" --- Per-font colors.
-
- local init_resolvers = loadmodule "resolvers" --- Font lookup
- init_resolvers ()
-
- if not config.actions.reconfigure () then
- logreport ("log", 0, "load", "Post-configuration hooks failed.")
- end
-
- initialize "features" --- font request and feature handling
-
- if harfstatus then
- loadmodule "harf-define"
- loadmodule "harf-plug"
- end
- loadmodule "letterspace" --- extra character kerning
- loadmodule "embolden" --- fake bold
- loadmodule "notdef" --- missing glyph handling
- loadmodule "suppress" --- suppress ligatures by adding ZWNJ
- loadmodule "szss" --- missing glyph handling
- initialize "auxiliary" --- additional high-level functionality
- loadmodule "tounicode"
- if tex.outputmode == 0 then
- loadmodule "dvi" --- allow writing fonts to DVI files
- end
-
- luaotfload.aux.start_rewrite_fontname () --- to be migrated to fontspec
-
- logreport ("log", 1, "main",
- "initialization completed in %0.3f seconds\n",
- osgettimeofday() - starttime)
-----inspect (timing_info)
-end
-
--- vim:tw=79:sw=4:ts=4:et
+return require'luaotfload'
diff --git a/macros/luatex/generic/luaotfload/luaotfload-main.tex b/macros/luatex/generic/luaotfload/luaotfload-main.tex
index a1f79b7da4..d1f698f684 100644
--- a/macros/luatex/generic/luaotfload/luaotfload-main.tex
+++ b/macros/luatex/generic/luaotfload/luaotfload-main.tex
@@ -32,7 +32,7 @@
\beginfrontmatter
\setdocumenttitle {The \identifier{luaotfload} package}
- \setdocumentdate {2020-09-02 v3.15}
+ \setdocumentdate {2020-12-31 v3.16}
\setdocumentauthor {LaTeX3 Project\\
Elie Roux · Khaled Hosny · Philipp Gesang · Ulrike Fischer · Marcel Krüger\\
Home: \hyperlink {https://github.com/latex3/luaotfload}}
@@ -62,6 +62,30 @@ Supported is the \identifier{luatex} versions of a current TeXLive 2019 (and a c
\endsection
\beginsection{Changes}
+\beginsubsection {New in version 3.16 (by Ulrike Fischer/Marcel Krüger)}
+\begin{itemize}
+ \item The entry point is called \identifier{luaotfload.lua} instead of
+ \identifier{luaotfload-main.lua} (but the old name is still provided for compatibility).
+ \item \inlinecode{pre/post_shaping_filter} callbacks has been added.
+ \item The number of \abbrev{lua}-files and submodules shown in the \abbrev{log}-file has been reduced. But it
+ is extended again by setting the environment variable \inlinecode{LUAOTFLOAD_TRACE_SUBMODULES=1}.
+ \item The HarfBuzz based shaper will in some situations drop hyphenation
+ points. This happens less frequently now since the new version uses
+ first/second discretionaries (the mechanism described in the LuaTeX manual,
+ section 5.6 for the of-f-ice example) to support a limited amount of
+ nesting.
+ \item When the \texttt{node} shaper is used, experimental support for OpenType variable
+ fonts has been added. To use them, set the font feature \texttt{axis} to
+ a comma separated list of axis names and values. (E.g. \texttt{axis={weight=600}})
+ The supported axis names and value range depend on the font (see~page~\pageref{variablefonts}).
+ \item The font features \texttt{upper} and \texttt{lower} can be used to map
+ the text of a font to upper or lowercase before displaying it. Currently
+ this implements the untailored Unicode case mapping algorithm, but it is
+ planned to add tailoring later (see~page~\pageref{upperlower}).
+ \item A number of small bugfixes.
+ \end{itemize}
+\endsubsection
+
\beginsubsection {New in version 3.15 (by Ulrike Fischer/Marcel Krüger)}
\begin{itemize}
\item The font database is updated more reliably if fonts get deleted.
@@ -1166,8 +1190,8 @@ obviously, \inlinecode{random}.
\endaltitem
- \beginaltitem {multiscript}\phantomsection\label{multiscript}
- In\marginpar{New in 3.12 -- experimental} fonts many shaping rules are implemented only for specific scripts and so you get correct typesetting only if the \identifier{script} feature is correctly set. This means that to write a text which uses more than one script you have to declare a font for each script and switch fonts even if the font contains glyphs for all scripts.
+ \beginaltitem {multiscript}
+ In\phantomsection\label{multiscript}\marginpar{New in 3.12 -- experimental} fonts many shaping rules are implemented only for specific scripts and so you get correct typesetting only if the \identifier{script} feature is correctly set. This means that to write a text which uses more than one script you have to declare a font for each script and switch fonts even if the font contains glyphs for all scripts.
\identifier{multiscript} tries to help here. The feature is experimental and bound to change. Feedback is welcome but you use it at your risk.
\identifier{multiscript} allows you to declare fonts for various script. The value is either \identifier{auto} described below, or a name which has been previously declared or a combination of both. An example for such a named multiscript could look like this (the colors are only for demonstration):
@@ -1221,8 +1245,10 @@ obviously, \inlinecode{random}.
\endaltitem
- \beginaltitem {fallback}\label{fallback}
- This\marginpar{New in 3.12 -- experimental} allows you to define a chain of fonts which are used if glyphs are missing in the main font. It works only for text fonts, not for math fonts set with the \identifier{unicode-math} package.
+ \beginaltitem {fallback}
+ This\label{fallback}\marginpar{New in 3.12 -- experimental}
+ allows you to define a chain of fonts which are used if glyphs are missing in the main font.
+ It works only for text fonts, not for math fonts set with the \identifier{unicode-math} package.
The feature is experimental and bound to change. Feedback is welcome but you use it at your risk.
For example
@@ -1276,7 +1302,69 @@ obviously, \inlinecode{random}.
As with the \identifier{multiscript} key more control over the used glyph and script in edge cases will be needed.
\endaltitem
-\enddescriptions
+
+ \beginaltitem {upper/lower}
+ The\phantomsection\label{upperlower}\marginpar{New in 3.16}
+ font features \texttt{upper} and \texttt{lower} can be used to map
+ the text of a font to upper or lowercase before displaying it. Currently
+ this implements the untailored Unicode case mapping algorithm, but it is
+ planned to add tailoring later. For example
+
+ \beginlisting
+ \font\test={name:LatinModernRoman:mode=node;+upper;}
+ \test Grüße
+ \endlisting
+
+ {\Large\font\test={name:LatinModernRoman:mode=node;+upper;}\test Grüße}
+
+ \endaltitem
+
+ \beginaltitem {Variable fonts}
+ When\phantomsection\label{variablefonts}\marginpar{New in 3.16}
+ the \texttt{node} shaper is used,
+ experimental support for OpenType variable
+ fonts has been added. To use them, set the font feature \texttt{axis} to
+ a comma separated list of axis names and values. (E.g. \texttt{axis={weight=600}})
+ The supported axis names and value range depend on the font (see~page~\pageref{variablefonts}).
+ The following listing shows an example with the Source Code Variable font:
+
+ \begin{lstlisting}[columns=fullflexible]
+\documentclass{article}
+ \DeclareFontFamily{TU}{sourcecode-variable}{}
+ \newcommand\DeclareSourceVariable[2]{%
+ \DeclareFontShape{TU}{sourcecode-variable}{#1}{n}{%
+ <-> \UnicodeFontFile{SourceCodeVariable-Roman.otf}
+ {\UnicodeFontTeXLigatures axis={weight=#2};}%
+ }{}%
+ \DeclareFontShape{TU}{sourcecode-variable}{#1}{it}{%
+ <-> \UnicodeFontFile{SourceCodeVariable-Italic.otf}
+ {\UnicodeFontTeXLigatures axis={weight=#2};}%
+ }{}%
+ }
+ \DeclareSourceVariable{ul}{200}
+ \DeclareSourceVariable{el}{250}
+ \DeclareSourceVariable{l}{300}
+ \DeclareSourceVariable{sl}{350}
+ \DeclareSourceVariable{m}{400}
+ \DeclareSourceVariable{sb}{500}
+ \DeclareSourceVariable{b}{600}
+ \DeclareSourceVariable{eb}{700}
+ \DeclareSourceVariable{ub}{900}
+ \begin{document}
+ \fontfamily{sourcecode-variable}\selectfont
+ \fontseries{ul}\selectfont a\textit{b}
+ \fontseries{el}\selectfont c\textit{d}
+ \fontseries{l}\selectfont e\textit{f}
+ \fontseries{sl}\selectfont g\textit{h}
+ \fontseries{m}\selectfont i\textit{j}
+ \fontseries{sb}\selectfont k\textit{l}
+ \fontseries{b}\selectfont m\textit{n}
+ \fontseries{eb}\selectfont o\textit{p}
+ \fontseries{ub}\selectfont q\textit{r}
+ \end{document}
+\end{lstlisting}
+
+ \enddescriptions
\endsubsection
@@ -1339,6 +1427,7 @@ Currently (2014) there are three of them:
\enddescriptions
\endsubsection
+
\endsection
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
diff --git a/macros/luatex/generic/luaotfload/luaotfload-multiscript.lua b/macros/luatex/generic/luaotfload/luaotfload-multiscript.lua
index aae924c9de..a632ab4c6a 100644
--- a/macros/luatex/generic/luaotfload/luaotfload-multiscript.lua
+++ b/macros/luatex/generic/luaotfload/luaotfload-multiscript.lua
@@ -3,19 +3,15 @@
-- DESCRIPTION: part of luaotfload / multiscript
-----------------------------------------------------------------------
-local ProvidesLuaModule = {
+assert(luaotfload_module, "This is a part of luaotfload and should not be loaded independently") {
name = "luaotfload-multiscript",
- version = "3.15", --TAGVERSION
- date = "2020-09-02", --TAGDATE
+ version = "3.16", --TAGVERSION
+ date = "2020-12-31", --TAGDATE
description = "luaotfload submodule / multiscript",
license = "GPL v2.0",
author = "Marcel Krüger"
}
-if luatexbase and luatexbase.provides_module then
- luatexbase.provides_module (ProvidesLuaModule)
-end
-
local nodenew = node.direct.new
local getfont = font.getfont
local setfont = node.direct.setfont
diff --git a/macros/luatex/generic/luaotfload/luaotfload-notdef.lua b/macros/luatex/generic/luaotfload/luaotfload-notdef.lua
index f2043a7ad7..7b9664fa7e 100644
--- a/macros/luatex/generic/luaotfload/luaotfload-notdef.lua
+++ b/macros/luatex/generic/luaotfload/luaotfload-notdef.lua
@@ -3,19 +3,15 @@
-- DESCRIPTION: part of luaotfload / notdef
-----------------------------------------------------------------------
-local ProvidesLuaModule = {
+assert(luaotfload_module, "This is a part of luaotfload and should not be loaded independently") {
name = "luaotfload-notdef",
- version = "3.15", --TAGVERSION
- date = "2020-09-02", --TAGDATE
+ version = "3.16", --TAGVERSION
+ date = "2020-12-31", --TAGDATE
description = "luaotfload submodule / notdef",
license = "GPL v2.0",
author = "Marcel Krüger"
}
-if luatexbase and luatexbase.provides_module then
- luatexbase.provides_module (ProvidesLuaModule)
-end
-
local harfbuzz = luaotfload.harfbuzz
local flush_node = node.direct.flush_node
local getfont = font.getfont
diff --git a/macros/luatex/generic/luaotfload/luaotfload-parsers.lua b/macros/luatex/generic/luaotfload/luaotfload-parsers.lua
index f321e9733f..7810c3a49e 100644
--- a/macros/luatex/generic/luaotfload/luaotfload-parsers.lua
+++ b/macros/luatex/generic/luaotfload/luaotfload-parsers.lua
@@ -5,19 +5,14 @@
-- AUTHOR: Philipp Gesang (Phg), <phg@phi-gamma.net>, Marcel Krüger
-------------------------------------------------------------------------------
-local ProvidesLuaModule = {
+assert(luaotfload_module, "This is a part of luaotfload and should not be loaded independently") {
name = "luaotfload-parsers",
- version = "3.15", --TAGVERSION
- date = "2020-09-02", --TAGDATE
+ version = "3.16", --TAGVERSION
+ date = "2020-12-31", --TAGDATE
description = "luaotfload submodule / parsers",
license = "GPL v2.0"
}
-if luatexbase and luatexbase.provides_module then
- luatexbase.provides_module (ProvidesLuaModule)
-end
-
-
local traversal_maxdepth = 42 --- prevent stack overflows
local rawset = rawset
diff --git a/macros/luatex/generic/luaotfload/luaotfload-resolvers.lua b/macros/luatex/generic/luaotfload/luaotfload-resolvers.lua
index b7ca21ec87..2ea85de781 100644
--- a/macros/luatex/generic/luaotfload/luaotfload-resolvers.lua
+++ b/macros/luatex/generic/luaotfload/luaotfload-resolvers.lua
@@ -9,19 +9,14 @@
--- The bare fontloader uses a set of simplistic file name resolvers
--- that must be overloaded by the user (i. e. us).
-local ProvidesLuaModule = {
+assert(luaotfload_module, "This is a part of luaotfload and should not be loaded independently") {
name = "luaotfload-resolvers",
- version = "3.15", --TAGVERSION
- date = "2020-09-02", --TAGDATE
+ version = "3.16", --TAGVERSION
+ date = "2020-12-31", --TAGDATE
description = "luaotfload submodule / resolvers",
license = "GPL v2.0"
}
-if luatexbase and luatexbase.provides_module then
- luatexbase.provides_module (ProvidesLuaModule)
-end
-
-
if not lualibs then error "this module requires Luaotfload" end
if not luaotfload then error "this module requires Luaotfload" end
diff --git a/macros/luatex/generic/luaotfload/luaotfload-scripts.lua b/macros/luatex/generic/luaotfload/luaotfload-scripts.lua
index 6ac19f14d5..b6c34b9e3e 100644
--- a/macros/luatex/generic/luaotfload/luaotfload-scripts.lua
+++ b/macros/luatex/generic/luaotfload/luaotfload-scripts.lua
@@ -3,19 +3,15 @@
-- DESCRIPTION: part of luaotfload / script
-----------------------------------------------------------------------
-local ProvidesLuaModule = {
+assert(luaotfload_module, "This is a part of luaotfload and should not be loaded independently") {
name = "luaotfload-script",
- version = "3.15", --TAGVERSION
- date = "2020-09-02", --TAGDATE
+ version = "3.16", --TAGVERSION
+ date = "2020-12-31", --TAGDATE
description = "luaotfload submodule / Script helpers",
license = "CC0 1.0 Universal",
author = "Marcel Krüger"
}
-if luatexbase and luatexbase.provides_module then
- luatexbase.provides_module (ProvidesLuaModule)
-end
-
local canonical_name = {
dflt = "DFLT",
hira = "kana",
diff --git a/macros/luatex/generic/luaotfload/luaotfload-status.lua b/macros/luatex/generic/luaotfload/luaotfload-status.lua
index dd38631cc8..0ad3c01ead 100644
--- a/macros/luatex/generic/luaotfload/luaotfload-status.lua
+++ b/macros/luatex/generic/luaotfload/luaotfload-status.lua
@@ -1,97 +1,99 @@
return {
["hashes"]={
- { "fontloader-2020-08-31.lua", "70a72561e3869bcaa8554921083b3872" },
- { "fontloader-util-fil.lua", "aae2a2add764144bb58dd8216fd59260" },
- { "fontloader-util-str.lua", "c975ff7bbd178163cf47d9e9296c8b4b" },
- { "fontloader-l-unicode.lua", "f368874f11f3c525de5864fd413e4b24" },
- { "fontloader-l-math.lua", "082add08e0bb79f39191ae9534a79849" },
- { "fontloader-l-boolean.lua", "abe28515dd33e8f6c416c09bca351cf8" },
- { "fontloader-l-file.lua", "352b42b8360ada02ceb26a41f0bd2a76" },
- { "fontloader-l-io.lua", "bbcc4824d0ded30b415d7d2d5763028a" },
- { "fontloader-l-table.lua", "0330da8b3a08d39876def70df8d9c0e5" },
- { "fontloader-l-string.lua", "9457f2af85723e0e6c46d0b5122e9000" },
- { "fontloader-l-function.lua", "a7e68a9703c35238729da41a474e951b" },
- { "fontloader-l-lpeg.lua", "10bdaef44175902917691835010ae5f5" },
- { "fontloader-l-lua.lua", "420bc442e6d81f4624728a6c56fcd175" },
- { "fontloader-fonts-gbn.lua", "10ecdf01e7c926e5128ad8a9dff4d677" },
- { "fontloader-fonts-lig.lua", "fbd251eea3810a43a8d5542319361d68" },
- { "fontloader-fonts-ext.lua", "32013cbc5d5d336be8b1d1e5879d86c4" },
- { "fontloader-fonts-def.lua", "f435e0875f203f343157baeff876ec9c" },
- { "fontloader-fonts-tfm.lua", "f0eb5e2a8068b17ad401bb7efdba1630" },
- { "fontloader-fonts-enc.lua", "5ff4ca50493d7c4ecea0e15c203099f0" },
- { "fontloader-fonts-mis.lua", "17e967c9ec4d001deefd43ddf25e98f7" },
- { "fontloader-basics-chr.lua", "64fafe4eaf55d64aead6513c1e74a024" },
- { "fontloader-basics-nod.lua", "335e61ffb6dec00f88f737854a2d9ab4" },
- { "fontloader-font-imp-effects.lua", "d9b935e9b73f250a175ddd71a226b8e9" },
- { "fontloader-font-imp-italics.lua", "ae563638fa29a4ff3e8e4d1e81fd35ae" },
- { "fontloader-font-imp-ligatures.lua", "26ffcf089391445f7af59536c8814364" },
- { "fontloader-font-imp-tex.lua", "ceb087ef6fa2f89aed7179f60ddf8f35" },
- { "fontloader-font-def.lua", "b9d908c2338b7dc443ce9d1e9fcb7139" },
- { "fontloader-font-lua.lua", "1fbfdf7b689b2bdfd0e3bb9bf74ce136" },
- { "fontloader-font-afk.lua", "9da14e0fb22129c053acc599d1312544" },
- { "fontloader-font-one.lua", "5a2f244c88c8178e997c16a9b628bb6f" },
- { "fontloader-font-onr.lua", "6d161533f3437435e12a0ad64866df44" },
- { "fontloader-font-otc.lua", "0f12230ea07b5151f75d52726977e91f" },
- { "fontloader-font-ocl.lua", "797b5c71bf819c5f4fb314a4d646e9a7" },
- { "fontloader-font-osd.lua", "73c9531c79df5ada320cb20777f7ed49" },
- { "fontloader-font-ots.lua", "f018ae1f355a8ef5c8d403cc5489e3d3" },
- { "fontloader-font-ota.lua", "ad1d5de06400f88829509e1f3ff2b473" },
- { "fontloader-font-otj.lua", "8de59cb9b043e5f73c6b9f7cc8f6978e" },
- { "fontloader-font-oto.lua", "2b1d6bc63b2ebf8f2655a15e1cda6541" },
- { "fontloader-font-otl.lua", "b168cf69300873d6668203bc7afe1f56" },
- { "fontloader-font-oup.lua", "6f46aa00ae1c20c43f8ffaf329dc8695" },
- { "fontloader-font-dsp.lua", "5d6528c0673b7651600ca6b763b51df5" },
- { "fontloader-font-ttf.lua", "786a535ba0385446b7015260388bc415" },
- { "fontloader-font-cff.lua", "802a10ad12ac32329f540881f940e3f2" },
- { "fontloader-font-ott.lua", "673ed11e1d159997f535bfec5fa73808" },
- { "fontloader-font-oti.lua", "309a75f9c14b77d87e94eba827dc4e71" },
- { "fontloader-font-otr.lua", "64dcbbc7107538723990e1119a80a9f8" },
- { "fontloader-font-vfc.lua", "a81c29eda98cd62cbebdb6c93544b50d" },
- { "fontloader-font-map.lua", "c4a39db5ad822b348aa61bca5f4a599a" },
- { "fontloader-font-cid.lua", "22b0367742fb253deef84ef7ccf5e8de" },
- { "fontloader-font-con.lua", "a3eb543fa5946fa1faf0e1e50d5b3b91" },
- { "fontloader-font-ini.lua", "5343de60613adb24cdd7a8d2ee1d153c" },
- { "fontloader-data-con.lua", "23a0f5386d46a1c157ae82a373e35fa0" },
- { "fontloader-reference.lua", "c10086745bc0b8b2303572fdea86d61c" },
- { "fontloader-basics-gen.lua", "4bc43036e9796fccb0b8869f4b05bf2e" },
- { "mktests", "918cb50be9ee8bd645ac1a27dc501e8c" },
- { "mkstatus", "49692433db8a578cf3a03fbedfb2ea9c" },
- { "mkcharacters", "bfca0e96e1e351afe7077502f9595af9" },
- { "mkglyphlist", "7a8a8fdc0eac7fac2f13ec8f4e8e7aa9" },
- { "mkimport", "7d62f1042e548f8b9368f26b9ba4be5c" },
- { "luaotfload-glyphlist.lua", "af60521c7ea3f5828c83ed1d1fa23b45" },
- { "luaotfload-characters.lua", "76415ca3ede312cad6e09038323489ae" },
- { "luaotfload-tounicode.lua", "24601f0255c35508eddbb427a6e18873" },
- { "luaotfload-unicode.lua", "c7d3f282db7a0f9588cc57d8f079a3cb" },
- { "luaotfload-resolvers.lua", "ac9e134e0614ab7ab69122ec0fd99e54" },
- { "luaotfload-parsers.lua", "10afafb81544840cb0fd0ecaac3c3344" },
- { "luaotfload-fallback.lua", "9d70a346c2584834f40d83be25d53a6a" },
- { "luaotfload-szss.lua", "0e29a05f35bbd05388e5af674059c242" },
- { "luaotfload-scripts.lua", "9a1e50e55ddef481ca3863004f33703e" },
- { "luaotfload-multiscript.lua", "8a828bf429dc73742ea78ad73332d219" },
- { "luaotfload-loaders.lua", "f13bafee1dca48db5073fe4390dc8ec4" },
- { "luaotfload-harf-plug.lua", "f43e0d894cf9ca3f31ff405d1684a5ff" },
- { "luaotfload-harf-define.lua", "0aecef4ea82a6edc305be2eed7b8e9c9" },
- { "luaotfload-notdef.lua", "73762a6d7662aa090f8f950a34d55835" },
- { "luaotfload-embolden.lua", "3444350537a12803b8e255f56b33b50d" },
- { "luaotfload-letterspace.lua", "6ac6c8d6f54107984ad338a94f0acd86" },
- { "luaotfload-features.lua", "b42fbc57c4fb1306dc23bf4e3bf6cd98" },
- { "luaotfload-database.lua", "8e11e69cf6a83bc1723c95e4788cdc70" },
- { "luaotfload-configuration.lua", "d1f4d64caa58bfc5feb524ea7cd365f6" },
- { "luaotfload-colors.lua", "5d1e7e10b5a8dda7ccf3742ae90f002e" },
- { "luaotfload-auxiliary.lua", "6d4e31212b8852e5f1425dc0ea49e016" },
- { "luaotfload-filelist.lua", "5e4c15ea6e5aafc19a533289b6ac2709" },
- { "luaotfload-tool.lua", "9caf618c38bf58cf9a29f2b2d4449346" },
- { "luaotfload-diagnostics.lua", "797176921da30591e6112831ed7459a7" },
- { "luaotfload-log.lua", "932117045a6abfe303314a295c24d338" },
- { "luaotfload-init.lua", "eb1bfca3833688aba31521032ed38883" },
- { "luaotfload-main.lua", "133ee97a73e07f3116d0417c9373398b" },
+ { "fontloader-2020-12-30.lua", "68ad807e7fdc2161801a16d1d404e1c4" },
+ { "fontloader-util-fil.lua", "a617cad49fc028e99f0f30bce8b2b623" },
+ { "fontloader-util-str.lua", "a2041dad54b982ad124cbc764f5de43b" },
+ { "fontloader-l-unicode.lua", "a4464b61c123f0454bea92c1cf502891" },
+ { "fontloader-l-math.lua", "a373be3ed2db0d5f98588fa81abca48f" },
+ { "fontloader-l-boolean.lua", "18ed6c4b2c40dd87224ea33229548d20" },
+ { "fontloader-l-file.lua", "60ddd3948d9de7bde8b4a0f5c51ff9f5" },
+ { "fontloader-l-io.lua", "a4042e9d6bce71c61fdd94e6e17f2bf4" },
+ { "fontloader-l-table.lua", "20c03ae1b81e902217f3f76995b9d294" },
+ { "fontloader-l-string.lua", "e1347bef0eeeff9f098df83b30b32df9" },
+ { "fontloader-l-function.lua", "f771cc91839ebcdfc094083434fbe00f" },
+ { "fontloader-l-lpeg.lua", "c3407de16bcedd73652250b000b39e98" },
+ { "fontloader-l-lua.lua", "c8dbb33df962e1b945b91b906b3c15c4" },
+ { "fontloader-fonts-gbn.lua", "d25472d54c4841db43a745764a63533e" },
+ { "fontloader-fonts-lig.lua", "b9dbe77ce747d4c35bb2a20ffbe5aa51" },
+ { "fontloader-fonts-ext.lua", "01015ab3758cdc2af29394e6d502a91a" },
+ { "fontloader-fonts-def.lua", "5ad79120ebc5e60f4d322fb3ee13bffe" },
+ { "fontloader-fonts-tfm.lua", "3bbba3214fd0b8c6f35ad85592fc2917" },
+ { "fontloader-fonts-enc.lua", "3e71a54297e8f85a1ac438bb0f20dd79" },
+ { "fontloader-fonts-mis.lua", "bc9eb43c27f63ce9d0fff67e104fe1c6" },
+ { "fontloader-basics-chr.lua", "58b7ef0c486e06090b362971b9f85e27" },
+ { "fontloader-basics-nod.lua", "6549c88db8cf4c6ae005a2e08f223d4b" },
+ { "fontloader-font-imp-effects.lua", "231cda056b88f6dc282fab9d7643d380" },
+ { "fontloader-font-imp-italics.lua", "058fb834c11c6ac30c280b29e496966e" },
+ { "fontloader-font-imp-ligatures.lua", "043daa4fcccf2560868da359d71d3a4a" },
+ { "fontloader-font-imp-tex.lua", "77c374b0ef00c2fb12188ec42beb4257" },
+ { "fontloader-font-shp.lua", "72de6029980ac796ec6ec76fa3ec8684" },
+ { "fontloader-font-def.lua", "226b4d26ede7fa7be8e45b7f0d93e781" },
+ { "fontloader-font-lua.lua", "55b281fb98f7bd848fc19928f376f647" },
+ { "fontloader-font-afk.lua", "54d554530e75c57c56ee76234724e26d" },
+ { "fontloader-font-one.lua", "2e52d1e42764f68b779522bda9569480" },
+ { "fontloader-font-onr.lua", "7a9ece7bf3e36b5f0adf295a9a2a2989" },
+ { "fontloader-font-ocl.lua", "ab81576f20e2d37bc8707e1dbd3decf2" },
+ { "fontloader-font-osd.lua", "61f05fcf91add1aa5dac9bc8b235adc9" },
+ { "fontloader-font-otc.lua", "1204a2fdc436e644127c0aa38ab69607" },
+ { "fontloader-font-ots.lua", "a83d5992a82b706c0ffdb5c2778534f1" },
+ { "fontloader-font-ota.lua", "f31232af3a694ae3d50380a5a92f88d3" },
+ { "fontloader-font-oup.lua", "1700a2dac4f8b105c187d4e5b84cecdf" },
+ { "fontloader-font-otj.lua", "a37a1007b8a92c9e7d24064180c2a772" },
+ { "fontloader-font-oto.lua", "24238a7c600d090a8ee88312321dd9b3" },
+ { "fontloader-font-otl.lua", "70237f19b76c4bc75f0c6e89038fb49a" },
+ { "fontloader-font-ott.lua", "1249b7018dba80e080fc478a38aa6756" },
+ { "fontloader-font-oti.lua", "dbae7722baae24d917a17176553825cf" },
+ { "fontloader-font-dsp.lua", "10eb256f4bcb9c5eabd48048e2da5eab" },
+ { "fontloader-font-ttf.lua", "ebef049a169c04edd19902fd66ddea44" },
+ { "fontloader-font-cff.lua", "aa9038651d9fedd2b76cacd1f69fd742" },
+ { "fontloader-font-otr.lua", "7a2f7a9e9627b29158e1822ea3c650ab" },
+ { "fontloader-font-vfc.lua", "04fa0ffad5c51198c7c19462949f54ed" },
+ { "fontloader-font-map.lua", "a03653ea3c5f042b457d54ed678d6df3" },
+ { "fontloader-font-cid.lua", "4d87988efa86020a14708ee03c23415f" },
+ { "fontloader-font-con.lua", "cbccccc4a5016196d62332a365aa8b72" },
+ { "fontloader-font-ini.lua", "4dee96e1e1474d324dd126bd5d375df8" },
+ { "fontloader-data-con.lua", "de6ae0997b0e70a23bcc9afff5d8b072" },
+ { "fontloader-reference.lua", "957f358a48ea6fcbc78a8701f947d7e5" },
+ { "fontloader-basics-gen.lua", "7bcfb5e4f48a1a34be6ddfcee2b1e49d" },
+ { "mktests", "c7cff7025962922944376acc1ffa9c47" },
+ { "mkstatus", "f3b00b5999440afce64bdc448f3fda9a" },
+ { "mkcharacters", "92c24bb582fc84c0365634f29eb89863" },
+ { "mkglyphlist", "95bbf91338214d40b2102114285ccd3f" },
+ { "mkimport", "5dacc09f3358ba9b90cf3a804f9a535c" },
+ { "luaotfload-glyphlist.lua", "bb6a9912a0944b3b21a61fce247dd728" },
+ { "luaotfload-characters.lua", "6a46f4749368e4f56a863da9c61b7bd6" },
+ { "luaotfload-dvi.lua", "34e1550905555da63304e07797168c69" },
+ { "luaotfload-tounicode.lua", "09fa475eeb7b160d3eb124e9107d4e03" },
+ { "luaotfload-unicode.lua", "153f97b086fd38dcb7f4850d95a41016" },
+ { "luaotfload-resolvers.lua", "2441b9624775fbcea6617e6cc72b424d" },
+ { "luaotfload-parsers.lua", "623d33f43813eda562cbfef5528753de" },
+ { "luaotfload-fallback.lua", "ec702c1c9407eba7bfe80b59c36f3f67" },
+ { "luaotfload-szss.lua", "ee4c0c070dcacf4d3e43f52948611392" },
+ { "luaotfload-scripts.lua", "14a19085cd5288592ebd5e24acf8514a" },
+ { "luaotfload-multiscript.lua", "4a283df608be713b0b666515fb6b9789" },
+ { "luaotfload-loaders.lua", "f0eeb293d8f448413631b1ffff554e39" },
+ { "luaotfload-harf-plug.lua", "34182344e7985d1267dacde37f387433" },
+ { "luaotfload-harf-define.lua", "252c36178f4f9ab066bdc15adfe809f1" },
+ { "luaotfload-notdef.lua", "06278786a6f2f8ddd3749b5d75f611db" },
+ { "luaotfload-embolden.lua", "8bdfebc528d078086c7fd0747815df74" },
+ { "luaotfload-letterspace.lua", "57d6026196fa62f9891d7a7a7300f63f" },
+ { "luaotfload-features.lua", "2219adcecef7362bbbe46da2e5ed005b" },
+ { "luaotfload-database.lua", "e2bea14191641d3a18b04064752d0fd4" },
+ { "luaotfload-configuration.lua", "dfa0521ef327c68573ea587ed7b989c8" },
+ { "luaotfload-colors.lua", "32bf6714aa19f6c291922cd1be01b629" },
+ { "luaotfload-auxiliary.lua", "4c18ffcc0d1cbef3ad4db2b6440a863e" },
+ { "luaotfload-filelist.lua", "8bb0a321254e6f04a1fa776d2f67747f" },
+ { "luaotfload-tool.lua", "ac7b0adfd9d0096228bed8ae61540a70" },
+ { "luaotfload-diagnostics.lua", "21bca70ad0b6f7dd1d9d57c7b1513809" },
+ { "luaotfload-log.lua", "d9c45eff233d71c3824f3a579694d737" },
+ { "luaotfload-init.lua", "265f1bfe8789fbb0cc3bff3a780f5494" },
+ { "luaotfload-main.lua", "f5f771d1cf5c8c4a2519a8d46aed1241" },
},
["notes"]={
- ["committer"]="Marcel Fabian Krüger <tex@2krueger.de>",
- ["description"]="v3.15/2020-09-02",
- ["loader"]="fontloader-2020-08-31.lua",
- ["revision"]="77eede02640bef0cb596d24aa79661328a68b448",
- ["timestamp"]="2020-09-02 21:02:40 +0200",
+ ["committer"]="Ulrike Fischer <fischer@troubleshooting-tex.de>",
+ ["description"]="v3.16/2020-12-31",
+ ["loader"]="fontloader-2020-12-30.lua",
+ ["revision"]="d1423b56efe2649e2881657747cee8d54cf64e12",
+ ["timestamp"]="2020-12-31 12:35:44 +0100",
},
} \ No newline at end of file
diff --git a/macros/luatex/generic/luaotfload/luaotfload-suppress.lua b/macros/luatex/generic/luaotfload/luaotfload-suppress.lua
index 768cf81402..c4c0c1010e 100644
--- a/macros/luatex/generic/luaotfload/luaotfload-suppress.lua
+++ b/macros/luatex/generic/luaotfload/luaotfload-suppress.lua
@@ -3,19 +3,15 @@
-- DESCRIPTION: part of luaotfload / suppress
-----------------------------------------------------------------------
-local ProvidesLuaModule = {
+assert(luaotfload_module, "This is a part of luaotfload and should not be loaded independently") {
name = "luaotfload-suppress",
- version = "3.15", --TAGVERSION
- date = "2020-09-02", --TAGDATE
+ version = "3.16", --TAGVERSION
+ date = "2020-12-31", --TAGDATE
description = "luaotfload submodule / suppress",
license = "GPL v2.0",
author = "Marcel Krüger"
}
-if luatexbase and luatexbase.provides_module then
- luatexbase.provides_module (ProvidesLuaModule)
-end
-
local direct = node.direct
local otfregister = fonts.constructors.features.otf.register
diff --git a/macros/luatex/generic/luaotfload/luaotfload-szss.lua b/macros/luatex/generic/luaotfload/luaotfload-szss.lua
index 751964cdd1..4c7de4d11b 100644
--- a/macros/luatex/generic/luaotfload/luaotfload-szss.lua
+++ b/macros/luatex/generic/luaotfload/luaotfload-szss.lua
@@ -3,19 +3,15 @@
-- DESCRIPTION: part of luaotfload / szss
-----------------------------------------------------------------------
-local ProvidesLuaModule = {
+assert(luaotfload_module, "This is a part of luaotfload and should not be loaded independently") {
name = "luaotfload-szss",
- version = "3.15", --TAGVERSION
- date = "2020-09-02", --TAGDATE
+ version = "3.16", --TAGVERSION
+ date = "2020-12-31", --TAGDATE
description = "luaotfload submodule / Special feature handling",
license = "GPL v2.0",
author = "Marcel Krüger"
}
-if luatexbase and luatexbase.provides_module then
- luatexbase.provides_module (ProvidesLuaModule)
-end
-
local direct = node.direct
local otfregister = fonts.constructors.features.otf.register
diff --git a/macros/luatex/generic/luaotfload/luaotfload-tool.1 b/macros/luatex/generic/luaotfload/luaotfload-tool.1
index ea2d12e9eb..7cd4934ab0 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-09-02" "3.15" "text processing"
+.TH LUAOTFLOAD-TOOL 1 "2020-12-31" "3.16" "text processing"
.SH NAME
luaotfload-tool \- generate and query the Luaotfload font names database
.
@@ -327,7 +327,7 @@ state.
.SS miscellaneous
.INDENT 0.0
.TP
-.BI \-\-verbose\fB= N\fP,\fB \ \-v
+.BI \-\-verbose\fB= N\fR,\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 18334d5ab3..fd66a9f79c 100644
--- a/macros/luatex/generic/luaotfload/luaotfload-tool.lua
+++ b/macros/luatex/generic/luaotfload/luaotfload-tool.lua
@@ -9,15 +9,13 @@
local ProvidesLuaModule = {
name = "luaotfload-tool",
- version = "3.15", --TAGVERSION
- date = "2020-09-02", --TAGDATE
+ version = "3.16", --TAGVERSION
+ date = "2020-12-31", --TAGDATE
description = "luaotfload-tool / database functionality",
license = "GPL v2.0"
}
-if luatexbase and luatexbase.provides_module then
- luatexbase.provides_module (ProvidesLuaModule)
-end
+function luaotfload_module(module) end -- We don't log module loading here
luaotfload = luaotfload or { }
@@ -70,7 +68,7 @@ do
local revn = tonumber (status.luatex_revision) or 0 --[[ : string ]]
if status.luatex_version < minimum[1]
- or status.luatex_version == minimum[1] and status.luatex_revision < minimum[2] then
+ or status.luatex_version == minimum[1] and tonumber(status.luatex_revision) < minimum[2] then
texio.write_nl ("term and log",
string.format ("\tFATAL ERROR\n\z
\tLuaotfload requires a Luatex version >= %d.%d.%d.\n\z
diff --git a/macros/luatex/generic/luaotfload/luaotfload-tool.pdf b/macros/luatex/generic/luaotfload/luaotfload-tool.pdf
index 6697476a0e..e35752ab17 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 c030ab81f2..c4c15d916f 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-09-02
+:Date: 2020-12-31
:Copyright: GPL v2.0
-:Version: 3.15
+:Version: 3.16
:Manual section: 1
:Manual group: text processing
diff --git a/macros/luatex/generic/luaotfload/luaotfload-tounicode.lua b/macros/luatex/generic/luaotfload/luaotfload-tounicode.lua
index 028aef9d12..f4eeec1125 100644
--- a/macros/luatex/generic/luaotfload/luaotfload-tounicode.lua
+++ b/macros/luatex/generic/luaotfload/luaotfload-tounicode.lua
@@ -3,20 +3,16 @@
-- DESCRIPTION: part of luaotfload / tounicode overwrites
-----------------------------------------------------------------------
-local ProvidesLuaModule = {
+assert(luaotfload_module, "This is a part of luaotfload and should not be loaded independently") {
name = "luaotfload-tounicode",
- version = "3.15", --TAGVERSION
- date = "2020-09-02", --TAGDATE
+ version = "3.16", --TAGVERSION
+ date = "2020-12-31", --TAGDATE
description = "luaotfload submodule / tounicode",
license = "GPL v2.0",
author = "Hans Hagen, Khaled Hosny, Elie Roux, Philipp Gesang, Marcel Krüger",
copyright = "PRAGMA ADE / ConTeXt Development Team",
}
-if luatexbase and luatexbase.provides_module then
- luatexbase.provides_module (ProvidesLuaModule)
-end
-
local overloads = {
-- rougly based on texglyphlist-g2u.txt
diff --git a/macros/luatex/generic/luaotfload/luaotfload-unicode.lua b/macros/luatex/generic/luaotfload/luaotfload-unicode.lua
index 2e9b28cf79..a05c660a36 100644
--- a/macros/luatex/generic/luaotfload/luaotfload-unicode.lua
+++ b/macros/luatex/generic/luaotfload/luaotfload-unicode.lua
@@ -3,19 +3,15 @@
-- DESCRIPTION: part of luaotfload / unicode
-----------------------------------------------------------------------
-local ProvidesLuaModule = {
+assert(luaotfload_module, "This is a part of luaotfload and should not be loaded independently") {
name = "luaotfload-unicode",
- version = "3.15", --TAGVERSION
- date = "2020-09-02", --TAGDATE
+ version = "3.16", --TAGVERSION
+ date = "2020-12-31", --TAGDATE
description = "luaotfload submodule / Unicode helpers",
license = "CC0 1.0 Universal",
author = "Marcel Krüger"
}
-if luatexbase and luatexbase.provides_module then
- luatexbase.provides_module (ProvidesLuaModule)
-end
-
local utf8codes = utf8.codes
local utf8char = utf8.char
local sub = string.sub
@@ -103,7 +99,149 @@ local alphnum_only do
end
end
+local uppercase, lowercase, ccc, cased, case_ignorable, titlecase = {}, {}, {}, {}, {}, nil do
+ titlecase = nil -- Not implemented yet(?)
+ local ignored_field = (1-lpeg.P';')^0 * ';'
+ local cased_category = lpeg.P'Ll;' + 'Lu;' + 'Lt;'
+ local case_ignore_category = lpeg.P'Mn;' + 'Me;' + 'Cf;' + 'Lm;' + 'Sk;'
+
+ local simple_entry =
+ codepoint/0 * ';'
+ * ignored_field -- Name
+ * (ignored_field - cased_category - case_ignore_category) -- General_Category
+ * '0;' -- ccc
+ * ignored_field -- Bidi
+ * ignored_field -- Decomp
+ * ignored_field -- Numeric
+ * ignored_field -- Numeric
+ * ignored_field -- Numeric
+ * ignored_field -- Mirrored
+ * ignored_field -- Obsolete
+ * ignored_field -- Obsolete
+ * ';;\n'
+ local entry = simple_entry
+ + codepoint * ';'
+ * ignored_field -- Name
+ * (cased_category * lpeg.Cc(cased) + case_ignore_category * lpeg.Cc(case_ignorable) + ignored_field * lpeg.Cc(nil)) -- General_Category
+ * ('0;' * lpeg.Cc(nil) + lpeg.R'09'^1/tonumber * ';') -- ccc
+ * ignored_field -- Bidi
+ * ignored_field -- Decomp
+ * ignored_field -- Numeric
+ * ignored_field -- Numeric
+ * ignored_field -- Numeric
+ * ignored_field -- Mirrored
+ * ignored_field -- Obsolete
+ * ignored_field -- Obsolete
+ * (codepoint + lpeg.Cc(nil)) * ';' -- uppercase
+ * (codepoint + lpeg.Cc(nil)) * ';' -- lowercase
+ * (codepoint + lpeg.Cc(nil)) * '\n' -- titlecase
+ / function(codepoint, cased_flag, ccc_val, upper, lower, title)
+ if cased_flag then cased_flag[codepoint] = true end
+ ccc[codepoint] = ccc_val
+ uppercase[codepoint] = upper
+ lowercase[codepoint] = lower
+ -- if title then titlecase[codepoint] = title end -- Not implemented yet(?)
+ end
+ local file = entry^0 * -1
+
+ local f = io.open(kpse.find_file"UnicodeData.txt")
+ assert(file:match(f:read'*a'))
+ f:close()
+end
+
+local props do
+ local ws = lpeg.P' '^0
+ local nl = ws * ('#' * (1-lpeg.P'\n')^0)^-1 * '\n'
+ local entry = codepoint * (".." * codepoint + lpeg.Cc(false)) * ws * ";" * ws * lpeg.C(lpeg.R("AZ", "az", "__")^1) * nl
+ local file = lpeg.Cf(
+ lpeg.Ct(
+ lpeg.Cg(lpeg.Ct"", "Soft_Dotted")
+ * lpeg.Cg(lpeg.Cc(cased), "Other_Lowercase")
+ * lpeg.Cg(lpeg.Cc(cased), "Other_Uppercase"))
+ * (lpeg.Cg(entry) + nl)^0
+ , function(t, cp_start, cp_end, prop)
+ local prop_table = t[prop]
+ if prop_table then
+ for cp = cp_start, cp_end or cp_start do
+ prop_table[cp] = true
+ end
+ end
+ return t
+ end) * -1
+
+ local f = io.open(kpse.find_file"PropList.txt")
+ props = file:match(f:read'*a')
+ f:close()
+end
+
+do
+ local ws = lpeg.P' '^0
+ local nl = ws * ('#' * (1-lpeg.P'\n')^0)^-1 * '\n'
+ local file = (codepoint * (".." * codepoint + lpeg.Cc(false)) * ws * ";" * ws * (lpeg.P'Single_Quote' + 'MidLetter' + 'MidNumLet') * nl / function(cp_start, cp_end)
+ for cp = cp_start, cp_end or cp_start do
+ case_ignorable[cp] = true
+ end
+ end + (1-lpeg.P'\n')^0 * '\n')^0 * -1
+
+ local f = io.open(kpse.find_file"WordBreakProperty.txt")
+ assert(file:match(f:read'*a'))
+ f:close()
+end
+
+do
+ local ws = lpeg.P' '^0
+ local nl = ws * ('#' * (1-lpeg.P'\n')^0)^-1 * '\n'
+ local empty = {}
+ local function set(t, cp, condition, value)
+ local old = t[cp] or cp
+ if not condition then
+ if #value == 1 and tonumber(old) then
+ t[cp] = value[1]
+ return
+ end
+ condition = empty
+ end
+ if tonumber(old or cp) then
+ old = {_ = {old}}
+ t[cp] = old
+ end
+ for i=1, #condition do
+ local cond = condition[i]
+ local step = old[cond]
+ if not step then
+ step = {}
+ old[cond] = step
+ end
+ old = step
+ end
+ old._ = value
+ end
+ local entry = codepoint * ";"
+ * lpeg.Ct((ws * codepoint)^1 + ws) * ";"
+ * lpeg.Ct((ws * codepoint)^1 + ws) * ";"
+ * lpeg.Ct((ws * codepoint)^1 + ws) * ";"
+ * (lpeg.Ct((ws * lpeg.C(lpeg.R('AZ', 'az', '__')^1))^1) * ";")^-1
+ * ws * nl / function(cp, lower, title, upper, condition)
+ set(lowercase, cp, condition, lower)
+ set(uppercase, cp, condition, upper)
+ end
+ local file = (entry + nl)^0 * -1
+
+ local f = io.open(kpse.find_file"SpecialCasing.txt")
+ assert(file:match(f:read'*a'))
+ f:close()
+end
+
return {
casefold = casefold,
alphnum_only = alphnum_only,
+ casemapping = {
+ uppercase = uppercase,
+ lowercase = lowercase,
+ cased = cased,
+ case_ignorable = case_ignorable,
+ -- titlecase = titlecase,
+ },
+ ccc = ccc,
+ soft_dotted = props.Soft_Dotted,
}
diff --git a/macros/luatex/generic/luaotfload/luaotfload.conf.5 b/macros/luatex/generic/luaotfload/luaotfload.conf.5
index 0035ce834f..4620ef0f2f 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-09-02" "3.15" "text processing"
+.TH LUAOTFLOAD.CONF 5 "2020-12-31" "3.16" "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 d40cb3a967..5905eb3811 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-09-02
+:Date: 2020-12-31
:Copyright: GPL v2.0
-:Version: 3.15
+:Version: 3.16
:Manual section: 5
:Manual group: text processing
diff --git a/macros/luatex/generic/luaotfload/luaotfload.lua b/macros/luatex/generic/luaotfload/luaotfload.lua
new file mode 100644
index 0000000000..843c84a3bf
--- /dev/null
+++ b/macros/luatex/generic/luaotfload/luaotfload.lua
@@ -0,0 +1,375 @@
+-----------------------------------------------------------------------
+-- FILE: luaotfload.lua
+-- DESCRIPTION: OpenType layout system / luaotfload entry point
+-- REQUIREMENTS: luatex v.0.95.0 or later; package lualibs
+-- AUTHOR: Élie Roux, Khaled Hosny, Philipp Gesang, Ulrike Fischer, Marcel Krüger
+-----------------------------------------------------------------------
+
+local authors = "\z
+ Hans Hagen,\z
+ Khaled Hosny,\z
+ Elie Roux,\z
+ Will Robertson,\z
+ Philipp Gesang,\z
+ Dohyun Kim,\z
+ Reuben Thomas,\z
+ David Carlisle,\
+ Ulrike Fischer,\z
+ Marcel Krüger\z
+"
+-- version number is used below!
+local ProvidesLuaModule = {
+ name = "luaotfload",
+ version = "3.16", --TAGVERSION
+ date = "2020-12-31", --TAGDATE
+ description = "Lua based OpenType font support",
+ author = authors,
+ copyright = authors,
+ license = "GPL v2.0"
+}
+
+if luatexbase and luatexbase.provides_module then
+ luatexbase.provides_module (ProvidesLuaModule)
+end
+
+if luaotfload_module == nil then
+ local print_warning = luatexbase and luatexbase.module_warning or function(module, text)
+ return texio.write_nl("%s WARNING: %s", module, text)
+ end
+ local saved_version = ProvidesLuaModule.version
+ local trace_submodules = tonumber(os.getenv'LUAOTFLOAD_TRACE_SUBMODULES')
+ if luatexbase and luatexbase.provides_module and trace_submodules and trace_submodules ~= 0 then
+ luaotfload_module = luatexbase.provides_module
+ else
+ function luaotfload_module(module)
+ local module_version = module.version
+ if module_version ~= saved_version then
+ local filenames
+ if debug then
+ filenames = string.format("luaotfload.lua is found at\n%q\n%s.lua is found at\n%q\n",
+ debug.getinfo(1, "S").source:sub(2),
+ module.name,
+ debug.getinfo(2, "S").source:sub(2))
+ else
+ filenames = ""
+ end
+ print_warning("luaotfload", string.format("Version inconsistency detected.\n\z
+ luaotfload is loaded in version %s, while %q is loaded \z
+ in version %s.\n%sI will try to continue anyway.\nHIC SUNT DRACONES",
+ saved_version, module.name, module_version, filenames))
+ end
+ end
+ end
+else
+ error[[luaotfload is reloading itself nested. This can't happen.]]
+end
+
+local osgettimeofday = os.gettimeofday
+config = config or { }
+luaotfload = luaotfload or { }
+local luaotfload = luaotfload
+luaotfload.log = luaotfload.log or { }
+local logreport
+luaotfload.version = ProvidesLuaModule.version
+luaotfload.loaders = { }
+luaotfload.fontloader_package = "reference" --- default: from current Context
+
+if not tex or not tex.luatexversion then
+ error "this program must be run in TeX mode" --- or call tex.initialize() =)
+end
+
+--- version check
+local revno = tonumber(tex.luatexrevision)
+local minimum = { 110, 0 }
+if tex.luatexversion < minimum[1] or tex.luatexversion == minimum[1] and revno < minimum[2] then
+ texio.write_nl ("term and log",
+ string.format ("\tFATAL ERROR\n\z
+ \tLuaotfload requires a Luatex version >= %d.%d.%d.\n\z
+ \tPlease update your TeX distribution!\n\n",
+ math.floor(minimum[1] / 100), minimum[1] % 100, minimum[2]))
+ error "version check failed"
+end
+
+if not utf8 then
+ texio.write_nl("term and log", string.format("\z
+ \tluaotfload: module utf8 is unavailable\n\z
+ \tutf8 is available in Lua 5.3+; engine\'s _VERSION is %q\n\z
+ \tThis probably means that the engine is not supported\n\z
+ \n",
+ _VERSION))
+ error "module utf8 is unavailable"
+end
+
+if status.safer_option ~= 0 then
+ texio.write_nl("term and log","luaotfload can't run with option --safer. Aborting")
+ error("safer_option used")
+end
+
+
+
+
+--[[doc--
+
+ This file initializes the system and loads the font loader. To
+ minimize potential conflicts between other packages and the code
+ imported from \CONTEXT, several precautions are in order. Some of
+ the functionality that the font loader expects to be present, like
+ raw access to callbacks, are assumed to have been disabled by
+ \identifier{luatexbase} when this file is processed. In some cases
+ it is possible to trick it by putting dummies into place and
+ restoring the behavior from \identifier{luatexbase} after
+ initilization. Other cases such as attribute allocation require
+ that we hook the functionality from \identifier{luatexbase} into
+ locations where they normally wouldn’t be.
+
+ Anyways we can import the code base without modifications, which is
+ due mostly to the extra effort by Hans Hagen to make \LUATEX-Fonts
+ self-contained and encapsulate it, and especially due to his
+ willingness to incorporate our suggestions.
+
+--doc]]--
+
+local luatexbase = luatexbase
+local require = require
+local type = type
+
+
+--[[doc--
+
+ \subsection{Module loading}
+ We load the files imported from \CONTEXT with function derived this way. It
+ automatically prepends a prefix to its argument, so we can refer to the
+ files with their actual \CONTEXT name.
+
+--doc]]--
+
+local function make_loader_name (prefix, name)
+ local msg = luaotfload.log and luaotfload.log.report
+ or function (stream, lvl, cat, ...)
+ if lvl > 1 then --[[not pressing]] return end
+ texio.write_nl ("log",
+ string.format ("luaotfload | %s : ",
+ tostring (cat)))
+ texio.write (string.format (...))
+ end
+ if not name then
+ msg ("both", 0, "load",
+ "Fatal error: make_loader_name (%q, %q).",
+ tostring (prefix), tostring (name))
+ return "dummy-name"
+ end
+ name = tostring (name)
+ if prefix == false then
+ msg ("log", 9, "load",
+ "No prefix requested, passing module name %q unmodified.",
+ name)
+ return tostring (name) .. ".lua"
+ end
+ prefix = tostring (prefix)
+ msg ("log", 9, "load",
+ "Composing module name from constituents %s, %s.",
+ prefix, name)
+ return prefix .. "-" .. name .. ".lua"
+end
+
+local timing_info = {
+ t_load = { },
+ t_init = { },
+}
+
+local function make_loader (prefix, load_helper)
+ return function (name)
+ local t_0 = osgettimeofday ()
+ local modname = make_loader_name (prefix, name)
+ --- We don’t want the stack info from inside, so just pcall().
+ local ok, data = pcall (load_helper or require, modname)
+ local t_end = osgettimeofday ()
+ timing_info.t_load [name] = t_end - t_0
+ if not ok then
+ io.write "\n"
+ local msg = luaotfload.log and luaotfload.log.report or print
+ msg ("both", 0, "load", "FATAL ERROR")
+ msg ("both", 0, "load", " × Failed to load %q module %q.",
+ tostring (prefix), tostring (name))
+ local lines = string.split (data, "\n\t")
+ if not lines then
+ msg ("both", 0, "load", " × Error message: %q", data)
+ else
+ msg ("both", 0, "load", " × Error message:")
+ for i = 1, #lines do
+ msg ("both", 0, "load", " × %q.", lines [i])
+ end
+ end
+ io.write "\n\n"
+ local debug = debug
+ if debug then
+ io.write (debug.traceback())
+ io.write "\n\n"
+ end
+ os.exit(-1)
+ end
+ return data
+ end
+end
+
+--[[doc--
+ Certain files are kept around that aren’t loaded because they are part of
+ the imported fontloader. In order to keep the initialization structure
+ intact we also provide a no-op version of the module loader that can be
+ called in the expected places.
+--doc]]--
+
+local function dummy_loader (name)
+ luaotfload.log.report ("log", 3, "load",
+ "Skipping module %q on purpose.",
+ name)
+end
+
+local context_environment = setmetatable({}, {__index = _G})
+luaotfload.fontloader = context_environment
+local function context_isolated_load(name)
+ local fullname = kpse.find_file(name, 'lua')
+ if not fullname then
+ error(string.format('Fontloader module %q could not be found.', name))
+ end
+ return assert(loadfile(fullname, nil, context_environment))(name)
+end
+
+local function context_loader (name, path)
+ luaotfload.log.report ("log", 3, "load",
+ "Loading module %q from Context.",
+ name)
+ local t_0 = osgettimeofday ()
+ local modname = make_loader_name (false, name)
+ local modpath = modname
+ if path then
+ if lfs.isdir (path) then
+ luaotfload.log.report ("log", 3, "load",
+ "Prepending path %q.",
+ path)
+ modpath = file.join (path, modname)
+ else
+ luaotfload.log.report ("both", 0, "load",
+ "Non-existant path %q specified, ignoring.",
+ path)
+ end
+ end
+ local ret = context_isolated_load (modpath)
+ local t_end = osgettimeofday ()
+ timing_info.t_load [name] = t_end - t_0
+
+ if ret ~= nil then
+ --- require () returns “true” upon success unless the loaded file
+ --- yields a non-zero exit code. This isn’t per se indicating that
+ --- something isn’t right, but against HH’s coding practices. We’ll
+ --- silently ignore this ever happening on lower log levels.
+ luaotfload.log.report ("log", 4, "load",
+ "Module %q returned %q.", modname, ret)
+ end
+ return ret
+end
+
+local function install_loaders ()
+ local loaders = { }
+ local loadmodule = make_loader "luaotfload"
+ loaders.luaotfload = loadmodule
+ loaders.fontloader = make_loader ("fontloader", context_isolated_load)
+ loaders.context = context_loader
+ loaders.ignore = dummy_loader
+----loaders.plaintex = make_loader "luatex" --=> for Luatex-Plain
+
+ function loaders.initialize (name)
+ local tmp = loadmodule (name)
+ local init = type(tmp) == "table" and tmp.init or tmp
+ if init and type (init) == "function" then
+ local t_0 = osgettimeofday ()
+ if not init () then
+ logreport ("log", 0, "load",
+ "Failed to load module %q.", name)
+ return
+ end
+ local t_end = osgettimeofday ()
+ local d_t = t_end - t_0
+ logreport ("log", 4, "load",
+ "Module %q loaded in %g ms.",
+ name, d_t * 1000)
+ timing_info.t_init [name] = d_t
+ end
+ end
+
+ return loaders
+end
+
+local luaotfload_initialized = false --- prevent multiple invocations
+
+luaotfload.main = function ()
+
+ if luaotfload_initialized then
+ logreport ("log", 0, "load",
+ "Luaotfload initialization requested but is already \z
+ loaded, ignoring.")
+ return
+ end
+ luaotfload_initialized = true
+
+ luaotfload.loaders = install_loaders ()
+ local loaders = luaotfload.loaders
+ local loadmodule = loaders.luaotfload
+ local initialize = loaders.initialize
+
+ local starttime = osgettimeofday ()
+
+ -- Feature detect HarfBuzz. This is done early to allow easy HarfBuzz
+ -- detection in other modules
+ local harfstatus, harfbuzz = pcall(require, 'luaharfbuzz')
+ if harfstatus then
+ luaotfload.harfbuzz = harfbuzz
+ end
+
+ local init = loadmodule "init" --- fontloader initialization
+ init (function ()
+
+ logreport = luaotfload.log.report
+ initialize "parsers" --- fonts.conf and syntax
+ initialize "configuration" --- configuration options
+ end)
+
+ initialize "loaders" --- Font loading; callbacks
+ initialize "database" --- Font management.
+ initialize "colors" --- Per-font colors.
+
+ local init_resolvers = loadmodule "resolvers" --- Font lookup
+ init_resolvers ()
+
+ if not config.actions.reconfigure () then
+ logreport ("log", 0, "load", "Post-configuration hooks failed.")
+ end
+
+ initialize "features" --- font request and feature handling
+
+ if harfstatus then
+ loadmodule "harf-define"
+ loadmodule "harf-plug"
+ end
+ loadmodule "letterspace" --- extra character kerning
+ loadmodule "embolden" --- fake bold
+ loadmodule "notdef" --- missing glyph handling
+ loadmodule "suppress" --- suppress ligatures by adding ZWNJ
+ loadmodule "szss" --- missing glyph handling
+ initialize "auxiliary" --- additional high-level functionality
+ loadmodule "tounicode"
+ loadmodule "case"
+ if tex.outputmode == 0 then
+ loadmodule "dvi" --- allow writing fonts to DVI files
+ end
+
+ luaotfload.aux.start_rewrite_fontname () --- to be migrated to fontspec
+
+ logreport ("log", 1, "main",
+ "initialization completed in %0.3f seconds\n",
+ osgettimeofday() - starttime)
+----inspect (timing_info)
+ luaotfload_module = nil
+end
+
+-- vim:tw=79:sw=4:ts=4:et
diff --git a/macros/luatex/generic/luaotfload/luaotfload.sty b/macros/luatex/generic/luaotfload/luaotfload.sty
index 33e15ba7c3..d9a3397d14 100644
--- a/macros/luatex/generic/luaotfload/luaotfload.sty
+++ b/macros/luatex/generic/luaotfload/luaotfload.sty
@@ -39,11 +39,11 @@
\fi
\ifdefined\ProvidesPackage
\ProvidesPackage{luaotfload}%
- [2020/09/02 v3.15 OpenType layout system]
+ [2020/12/31 v3.16 OpenType layout system]
\fi
\directlua{
if xpcall(function ()%
- require('luaotfload-main')%
+ require('luaotfload')%
end,texio.write_nl) then %
local _void = luaotfload.main ()%
else %
diff --git a/macros/luatex/generic/luaotfload/scripts-demo.pdf b/macros/luatex/generic/luaotfload/scripts-demo.pdf
index 60b7e524de..5c00e2f4a6 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 8eb287e081..fa1bda41bb 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 77a7463630..b19632bbc7 100644
--- a/macros/luatex/generic/luaotfload/shaper-demo.pdf
+++ b/macros/luatex/generic/luaotfload/shaper-demo.pdf
Binary files differ